diff options
Diffstat (limited to 'sys/netinet/ip_fastfwd.c')
-rw-r--r-- | sys/netinet/ip_fastfwd.c | 85 |
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); |