diff options
author | mlaier <mlaier@FreeBSD.org> | 2004-02-18 00:04:52 +0000 |
---|---|---|
committer | mlaier <mlaier@FreeBSD.org> | 2004-02-18 00:04:52 +0000 |
commit | 60723c32606f318dd3816d81ba433654f812312b (patch) | |
tree | 8161989612a5d1dd2b4c63580a9c95cb85146c14 /sys/netinet/ip_output.c | |
parent | 9a383d1448d0eecb2082f01c9fa00232399e77a0 (diff) | |
download | FreeBSD-src-60723c32606f318dd3816d81ba433654f812312b.zip FreeBSD-src-60723c32606f318dd3816d81ba433654f812312b.tar.gz |
Backout MT_TAG removal (i.e. bring back MT_TAGs) for now, as dummynet is
not working properly with the patch in place.
Approved by: bms(mentor)
Diffstat (limited to 'sys/netinet/ip_output.c')
-rw-r--r-- | sys/netinet/ip_output.c | 113 |
1 files changed, 53 insertions, 60 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 4ab1528..368d3c5 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -90,7 +90,6 @@ static MALLOC_DEFINE(M_IPMOPTS, "ip_moptions", "internet multicast options"); #endif /*FAST_IPSEC*/ #include <netinet/ip_fw.h> -#include <netinet/ip_divert.h> #include <netinet/ip_dummynet.h> #define print_ip(x, a, y) printf("%s %d.%d.%d.%d%s",\ @@ -131,11 +130,12 @@ extern struct protosw inetsw[]; * inserted, so must have a NULL opt pointer. */ int -ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, +ip_output(struct mbuf *m0, struct mbuf *opt, struct route *ro, int flags, struct ip_moptions *imo, struct inpcb *inp) { struct ip *ip; struct ifnet *ifp = NULL; /* keep compiler happy */ + struct mbuf *m; int hlen = sizeof (struct ip); int len, off, error = 0; struct sockaddr_in *dst = NULL; /* keep compiler happy */ @@ -143,13 +143,11 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int isbroadcast, sw_csum; struct in_addr pkt_dst; struct route iproute; - struct m_tag *dummytag; /* dummynet packet tag */ - struct m_tag *mtag; - struct mbuf *m0; /* XXX */ #ifdef IPSEC struct secpolicy *sp = NULL; #endif #ifdef FAST_IPSEC + struct m_tag *mtag; struct secpolicy *sp = NULL; struct tdb_ident *tdbi; int s; @@ -159,7 +157,42 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, args.eh = NULL; args.rule = NULL; - args.next_hop = ip_claim_next_hop(m); + args.next_hop = NULL; + args.divert_rule = 0; /* divert cookie */ + + /* Grab info from MT_TAG mbufs prepended to the chain. */ + for (; m0 && m0->m_type == MT_TAG; m0 = m0->m_next) { + switch(m0->_m_tag_id) { + default: + printf("ip_output: unrecognised MT_TAG tag %d\n", + m0->_m_tag_id); + break; + + case PACKET_TAG_DUMMYNET: + /* + * the packet was already tagged, so part of the + * processing was already done, and we need to go down. + * Get parameters from the header. + */ + args.rule = ((struct dn_pkt *)m0)->rule; + opt = NULL ; + ro = & ( ((struct dn_pkt *)m0)->ro ) ; + imo = NULL ; + dst = ((struct dn_pkt *)m0)->dn_dst ; + ifp = ((struct dn_pkt *)m0)->ifp ; + flags = ((struct dn_pkt *)m0)->flags ; + break; + + case PACKET_TAG_DIVERT: + args.divert_rule = (intptr_t)m0->m_data & 0xffff; + break; + + case PACKET_TAG_IPFORWARD: + args.next_hop = (struct sockaddr_in *)m0->m_data; + break; + } + } + m = m0; M_ASSERTPKTHDR(m); @@ -171,34 +204,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, if (inp != NULL) INP_LOCK_ASSERT(inp); - /* - * When packet comes from dummynet restore state from - * previous processing instead of the header. Yech! - * - * XXX add conditional compilation? - */ - dummytag = m_tag_find(m, PACKET_TAG_DUMMYNET, NULL); - if (dummytag != NULL) { - struct dn_pkt_tag *dt = (struct dn_pkt_tag *)(dummytag+1); - - /* - * NB: the route in the tag is known to have a - * reference that must be free'd, but doing this - * before the storage is reclaimed is painful due - * to some of the contorted code in this routine. - * So instead unlink the tag from the mbuf so it - * doesn't get reclaimed and do the cleanup explicitly - * below. We should be able to do this automatically - * using a uma dtor method when m_tag's can be - * allocated from zones. - */ - m_tag_unlink(m, dummytag); - - args.rule = dt->rule; - ro = &dt->ro; - dst = dt->dn_dst; - ifp = dt->ifp; - + if (args.rule != NULL) { /* dummynet already saw us */ ip = mtod(m, struct ip *); hlen = ip->ip_hl << 2 ; if (ro->ro_rt) @@ -551,7 +557,7 @@ sendit: dst = (struct sockaddr_in *)state.dst; if (error) { /* mbuf is already reclaimed in ipsec4_output. */ - m = NULL; + m0 = NULL; switch (error) { case EHOSTUNREACH: case ENETUNREACH: @@ -791,13 +797,11 @@ spd_done: } #ifdef IPDIVERT if (off != 0 && (off & IP_FW_PORT_DYNT_FLAG) == 0) { - struct mbuf *clone; + struct mbuf *clone = NULL; /* Clone packet if we're doing a 'tee' */ if ((off & IP_FW_PORT_TEE_FLAG) != 0) - clone = divert_clone(m); - else - clone = NULL; + clone = m_dup(m, M_DONTWAIT); /* * XXX @@ -814,7 +818,7 @@ spd_done: ip->ip_off = htons(ip->ip_off); /* Deliver packet to divert input routine */ - divert_packet(m, 0); + divert_packet(m, 0, off & 0xffff, args.divert_rule); /* If 'tee', continue with original packet */ if (clone != NULL) { @@ -892,31 +896,26 @@ spd_done: break; } if (ia) { /* tell ip_input "dont filter" */ - mtag = m_tag_get(PACKET_TAG_IPFORWARD, - sizeof(struct sockaddr_in *), - M_NOWAIT); - if (mtag == NULL) { - /* XXX statistic */ - error = ENOBUFS; /* XXX */ - goto bad; - } - *(struct sockaddr_in **)(mtag+1) = - args.next_hop; - m_tag_prepend(m, mtag); + struct m_hdr tag; + + tag.mh_type = MT_TAG; + tag.mh_flags = PACKET_TAG_IPFORWARD; + tag.mh_data = (caddr_t)args.next_hop; + tag.mh_next = m; + tag.mh_nextpkt = NULL; if (m->m_pkthdr.rcvif == NULL) m->m_pkthdr.rcvif = ifunit("lo0"); if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { m->m_pkthdr.csum_flags |= CSUM_DATA_VALID | CSUM_PSEUDO_HDR; - m->m_pkthdr.csum_data = 0xffff; + m0->m_pkthdr.csum_data = 0xffff; } m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED | CSUM_IP_VALID; ip->ip_len = htons(ip->ip_len); ip->ip_off = htons(ip->ip_off); - /* XXX netisr_queue(NETISR_IP, m); */ - ip_input(m); + ip_input((struct mbuf *)&tag); goto done; } /* @@ -1073,12 +1072,6 @@ done: RTFREE(ro->ro_rt); ro->ro_rt = NULL; } - if (dummytag) { - struct dn_pkt_tag *dt = (struct dn_pkt_tag *)(dummytag+1); - if (dt->ro.ro_rt) - RTFREE(dt->ro.ro_rt); - m_tag_free(dummytag); - } #ifdef IPSEC if (sp != NULL) { KEYDEBUG(KEYDEBUG_IPSEC_STAMP, |