summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_fastfwd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/ip_fastfwd.c')
-rw-r--r--sys/netinet/ip_fastfwd.c85
1 files changed, 18 insertions, 67 deletions
diff --git a/sys/netinet/ip_fastfwd.c b/sys/netinet/ip_fastfwd.c
index 4041712..3db615d 100644
--- a/sys/netinet/ip_fastfwd.c
+++ b/sys/netinet/ip_fastfwd.c
@@ -110,6 +110,7 @@
#include <machine/in_cksum.h>
#include <netinet/ip_fw.h>
+#include <netinet/ip_divert.h>
#include <netinet/ip_dummynet.h>
static int ipfastforward_active = 0;
@@ -132,7 +133,7 @@ ip_fastforward(struct mbuf *m)
struct ip *tip;
struct mbuf *teem = NULL;
#endif
- struct mbuf *tag = NULL;
+ struct m_tag *mtag;
struct route ro;
struct sockaddr_in *dst = NULL;
struct in_ifaddr *ia = NULL;
@@ -150,16 +151,6 @@ ip_fastforward(struct mbuf *m)
if (!ipfastforward_active || !ipforwarding)
return 0;
- /*
- * If there is any MT_TAG we fall back to ip_input because we can't
- * handle TAGs here. Should never happen as we get directly called
- * from the if_output routines.
- */
- if (m->m_type == MT_TAG) {
- KASSERT(0, ("%s: packet with MT_TAG not expected", __func__));
- return 0;
- }
-
M_ASSERTVALID(m);
M_ASSERTPKTHDR(m);
@@ -373,25 +364,13 @@ fallback:
/*
* See if this is a fragment
*/
- if (ip->ip_off & (IP_MF | IP_OFFMASK)) {
- MGETHDR(tag, M_DONTWAIT, MT_TAG);
- if (tag == NULL)
- goto drop;
- tag->m_flags = PACKET_TAG_DIVERT;
- tag->m_data = (caddr_t)(intptr_t)args.divert_rule;
- tag->m_next = m;
- /* XXX: really bloody hack, see ip_input */
- tag->m_nextpkt = (struct mbuf *)1;
- m = tag;
- tag = NULL;
-
+ if (ip->ip_off & (IP_MF | IP_OFFMASK))
goto droptoours;
- }
/*
* Tee packet
*/
if ((ipfw & IP_FW_PORT_TEE_FLAG) != 0)
- teem = m_dup(m, M_DONTWAIT);
+ teem = divert_clone(m);
else
teem = m;
if (teem == NULL)
@@ -413,7 +392,7 @@ fallback:
/*
* Deliver packet to divert input routine
*/
- divert_packet(teem, 0, ipfw & 0xffff, args.divert_rule);
+ divert_packet(teem, 0);
/*
* If this was not tee, we are done
*/
@@ -560,27 +539,13 @@ passin:
/*
* See if this is a fragment
*/
- if (ip->ip_off & (IP_MF | IP_OFFMASK)) {
- MGETHDR(tag, M_DONTWAIT, MT_TAG);
- if (tag == NULL) {
- RTFREE(ro.ro_rt);
- goto drop;
- }
- tag->m_flags = PACKET_TAG_DIVERT;
- tag->m_data = (caddr_t)(intptr_t)args.divert_rule;
- tag->m_next = m;
- /* XXX: really bloody hack, see ip_input */
- tag->m_nextpkt = (struct mbuf *)1;
- m = tag;
- tag = NULL;
-
+ if (ip->ip_off & (IP_MF | IP_OFFMASK))
goto droptoours;
- }
/*
* Tee packet
*/
if ((ipfw & IP_FW_PORT_TEE_FLAG) != 0)
- teem = m_dup(m, M_DONTWAIT);
+ teem = divert_clone(m);
else
teem = m;
if (teem == NULL)
@@ -602,7 +567,7 @@ passin:
/*
* Deliver packet to divert input routine
*/
- divert_packet(teem, 0, ipfw & 0xffff, args.divert_rule);
+ divert_packet(teem, 0);
/*
* If this was not tee, we are done
*/
@@ -638,38 +603,24 @@ passout:
if (IA_SIN(ia)->sin_addr.s_addr == ip->ip_dst.s_addr) {
forwardlocal:
if (args.next_hop) {
- /* XXX leak */
- MGETHDR(tag, M_DONTWAIT, MT_TAG);
- if (tag == NULL) {
+ mtag = m_tag_get(PACKET_TAG_IPFORWARD,
+ sizeof(struct sockaddr_in *),
+ M_NOWAIT);
+ if (mtag == NULL) {
+ /* XXX statistic */
if (ro.ro_rt)
RTFREE(ro.ro_rt);
goto drop;
}
- tag->m_flags = PACKET_TAG_IPFORWARD;
- tag->m_data = (caddr_t)args.next_hop;
- tag->m_next = m;
- /* XXX: really bloody hack,
- * see ip_input */
- tag->m_nextpkt = (struct mbuf *)1;
- m = tag;
- tag = NULL;
+ *(struct sockaddr_in **)(mtag+1) =
+ args.next_hop;
+ m_tag_prepend(m, mtag);
}
#ifdef IPDIVERT
droptoours: /* Used for DIVERT */
#endif
- MGETHDR(tag, M_DONTWAIT, MT_TAG);
- if (tag == NULL) {
- if (ro.ro_rt)
- RTFREE(ro.ro_rt);
- goto drop;
- }
- tag->m_flags = PACKET_TAG_IPFASTFWD_OURS;
- tag->m_data = NULL;
- tag->m_next = m;
- /* XXX: really bloody hack, see ip_input */
- tag->m_nextpkt = (struct mbuf *)1;
- m = tag;
- tag = NULL;
+ /* NB: ip_input understands this */
+ m->m_flags |= M_FASTFWD_OURS;
/* ip still points to the real packet */
ip->ip_len = htons(ip->ip_len);
OpenPOWER on IntegriCloud