Date: Mon, 24 Nov 2003 20:24:25 -0800 (PST) From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 43027 for review Message-ID: <200311250424.hAP4OPol057180@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=43027 Change 43027 by sam@sam_ebb on 2003/11/24 20:23:57 Poof! MT_TAG is gone. Replace the last vestiges with m_tag's or, in the case of PACKET_TAG_IPFASTFWD_OURS (which should never have been created) use an mbuf proto flag. Affected files ... .. //depot/projects/netperf/sys/netinet/ip_fastfwd.c#5 edit .. //depot/projects/netperf/sys/netinet/ip_input.c#27 edit .. //depot/projects/netperf/sys/netinet/ip_output.c#20 edit .. //depot/projects/netperf/sys/netinet/ip_var.h#15 edit .. //depot/projects/netperf/sys/netinet/tcp_input.c#14 edit .. //depot/projects/netperf/sys/sys/mbuf.h#9 edit Differences ... ==== //depot/projects/netperf/sys/netinet/ip_fastfwd.c#5 (text+ko) ==== @@ -133,7 +133,7 @@ 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; @@ -151,16 +151,6 @@ 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); @@ -613,38 +603,24 @@ 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); ==== //depot/projects/netperf/sys/netinet/ip_input.c#27 (text+ko) ==== @@ -300,9 +300,9 @@ struct in_ifaddr *ia = NULL; struct ifaddr *ifa; int i, checkif, hlen = 0; - int ours = 0; u_short sum; struct in_addr pkt_dst; + struct m_tag *mtag; #ifdef IPDIVERT u_int32_t divert_info; /* packet divert/tee info */ #endif @@ -312,7 +312,6 @@ struct in_addr odst; /* original dst address */ #endif #ifdef FAST_IPSEC - struct m_tag *mtag; struct tdb_ident *tdbi; struct secpolicy *sp; int s, error; @@ -320,48 +319,15 @@ args.eh = NULL; args.oif = NULL; - args.next_hop = NULL; - - /* - * Grab info from MT_TAG mbufs prepended to the chain. - * - * XXX: This is ugly. These pseudo mbuf prepend tags should really - * be real m_tags. Before these have always been allocated on the - * callers stack, so we didn't have to free them. Now with - * ip_fastforward they are true mbufs and we have to free them - * otherwise we have a leak. Must rewrite ipfw to use m_tags. - */ - for (; m && m->m_type == MT_TAG;) { - struct mbuf *m0; - - switch(m->_m_tag_id) { - default: - printf("ip_input: unrecognised MT_TAG tag %d\n", - m->_m_tag_id); - break; - - case PACKET_TAG_IPFORWARD: - args.next_hop = (struct sockaddr_in *)m->m_hdr.mh_data; - break; - - case PACKET_TAG_IPFASTFWD_OURS: - ours = 1; - break; - } - - m0 = m; - m = m->m_next; - /* XXX: This is set by ip_fastforward */ - if (m0->m_nextpkt == (struct mbuf *)1) - m_free(m0); - } + args.next_hop = ip_claim_next_hop(m); args.rule = ip_dn_find_rule(m); M_ASSERTPKTHDR(m); - if (ours) /* ip_fastforward firewall changed dest to local */ + if (m->m_flags & M_FASTFWD_OURS) { + /* ip_fastforward firewall changed dest to local */ goto ours; - + } if (args.rule) { /* dummynet already filtered us */ ip = mtod(m, struct ip *); hlen = ip->ip_hl << 2; @@ -960,19 +926,18 @@ ipstat.ips_delivered++; NET_PICKUP_GIANT(); if (args.next_hop && ip->ip_p == IPPROTO_TCP) { - /* TCP needs IPFORWARD info if available */ - 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; - - (*inetsw[ip_protox[ip->ip_p]].pr_input)( - (struct mbuf *)&tag, hlen); - } else - (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen); + /* attach next hop info for TCP */ + mtag = m_tag_get(PACKET_TAG_IPFORWARD, + sizeof(struct sockaddr_in *), M_NOWAIT); + if (mtag == NULL) { + /* XXX statistic */ + NET_DROP_GIANT(); + goto bad; + } + *(struct sockaddr_in **)(mtag+1) = args.next_hop; + m_tag_prepend(m, mtag); + } + (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen); NET_DROP_GIANT(); return; bad: @@ -1755,6 +1720,7 @@ struct in_ifaddr *ia; int error, type = 0, code = 0; struct mbuf *mcopy; + struct m_tag *mtag; n_long dest; struct in_addr pkt_dst; struct ifnet *destifp; @@ -1887,21 +1853,18 @@ RTFREE(rt); } - { - struct m_hdr tag; - if (next_hop) { - /* Pass IPFORWARD info if available */ - - tag.mh_type = MT_TAG; - tag.mh_flags = PACKET_TAG_IPFORWARD; - tag.mh_data = (caddr_t)next_hop; - tag.mh_next = m; - tag.mh_nextpkt = NULL; - m = (struct mbuf *)&tag; + mtag = m_tag_get(PACKET_TAG_IPFORWARD, + sizeof(struct sockaddr_in *), M_NOWAIT); + if (mtag == NULL) { + /* XXX statistic */ + m_freem(m); + return; + } + *(struct sockaddr_in **)(mtag+1) = next_hop; + m_tag_prepend(m, mtag); } error = ip_output(m, (struct mbuf *)0, NULL, IP_FORWARDING, 0, NULL); - } if (error) ipstat.ips_cantforward++; else { ==== //depot/projects/netperf/sys/netinet/ip_output.c#20 (text+ko) ==== @@ -131,12 +131,11 @@ * inserted, so must have a NULL opt pointer. */ int -ip_output(struct mbuf *m0, struct mbuf *opt, struct route *ro, +ip_output(struct mbuf *m, 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 */ @@ -145,12 +144,13 @@ 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 socket *so; struct secpolicy *sp = NULL; #endif #ifdef FAST_IPSEC - struct m_tag *mtag; struct secpolicy *sp = NULL; struct tdb_ident *tdbi; int s; @@ -160,22 +160,7 @@ args.eh = NULL; args.rule = NULL; - args.next_hop = NULL; - - /* 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_IPFORWARD: - args.next_hop = (struct sockaddr_in *)m0->m_data; - break; - } - } - m = m0; + args.next_hop = ip_claim_next_hop(m); #ifdef IPSEC so = ipsec_getsocket(m); @@ -916,26 +901,31 @@ break; } if (ia) { /* tell ip_input "dont filter" */ - struct m_hdr tag; + 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); - 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; - m0->m_pkthdr.csum_data = 0xffff; + m->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); - ip_input((struct mbuf *)&tag); + /* XXX netisr_queue(NETISR_IP, m); */ + ip_input(m); goto done; } /* ==== //depot/projects/netperf/sys/netinet/ip_var.h#15 (text+ko) ==== @@ -195,6 +195,23 @@ extern void (*ip_rsvp_force_done)(struct socket *); extern void (*rsvp_input_p)(struct mbuf *m, int off); +#define M_FASTFWD_OURS M_PROTO1 /* sent by ip_fastforward to ip_input */ + +/* + * Return the next hop address associated with the mbuf; if any. + * If a tag is present it is also removed. + */ +static __inline struct sockaddr_in * +ip_claim_next_hop(struct mbuf *m) +{ + struct m_tag *mtag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL); + if (mtag) { + struct sockaddr_in *sin = *(struct sockaddr_in **)(mtag+1); + m_tag_delete(m, mtag); + return sin; + } else + return NULL; +} #ifdef PFIL_HOOKS extern struct pfil_head inet_pfil_hook; ==== //depot/projects/netperf/sys/netinet/tcp_input.c#14 (text+ko) ==== @@ -359,7 +359,7 @@ struct tcpopt to; /* options in this segment */ struct rmxp_tao tao; /* our TAO cache entry */ int headlocked = 0; - struct sockaddr_in *next_hop = NULL; + struct sockaddr_in *next_hop; int rstreason; /* For badport_bandlim accounting purposes */ struct ip6_hdr *ip6 = NULL; @@ -379,11 +379,7 @@ short ostate = 0; #endif - /* Grab info from MT_TAG mbufs prepended to the chain. */ - for (;m && m->m_type == MT_TAG; m = m->m_next) { - if (m->_m_tag_id == PACKET_TAG_IPFORWARD) - next_hop = (struct sockaddr_in *)m->m_hdr.mh_data; - } + next_hop = ip_claim_next_hop(m); #ifdef INET6 isipv6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; #endif ==== //depot/projects/netperf/sys/sys/mbuf.h#9 (text+ko) ==== @@ -220,8 +220,8 @@ #if 0 #define MT_RIGHTS 12 /* access rights */ #define MT_IFADDR 13 /* interface address */ +#define MT_TAG 13 /* deprecated: use m_tag's instead */ #endif -#define MT_TAG 13 /* volatile metadata associated to pkts */ #define MT_CONTROL 14 /* extra-data protocol message */ #define MT_OOBDATA 15 /* expedited data */ #define MT_NTYPES 16 /* number of mbuf types for mbtypes[] */ @@ -538,28 +538,11 @@ #define PACKET_TAG_IPSEC_SOCKET 12 /* IPSEC socket ref */ #define PACKET_TAG_IPSEC_HISTORY 13 /* IPSEC history */ #define PACKET_TAG_IPV6_INPUT 14 /* IPV6 input processing */ - -/* - * As a temporary and low impact solution to replace the even uglier - * approach used so far in some parts of the network stack (which relies - * on global variables), packet tag-like annotations are stored in MT_TAG - * mbufs (or lookalikes) prepended to the actual mbuf chain. - * - * m_type = MT_TAG - * m_flags = m_tag_id - * m_next = next buffer in chain. - * - * BE VERY CAREFUL not to pass these blocks to the mbuf handling routines. - */ -#define _m_tag_id m_hdr.mh_flags - -/* Packet tags used in the FreeBSD network stack. */ #define PACKET_TAG_DUMMYNET 15 /* dummynet info */ #define PACKET_TAG_IPFW 16 /* ipfw classification */ #define PACKET_TAG_DIVERT 17 /* divert info */ #define PACKET_TAG_IPFORWARD 18 /* ipforward info */ #define PACKET_TAG_MACLABEL (19 | MTAG_PERSISTENT) /* MAC label */ -#define PACKET_TAG_IPFASTFWD_OURS 20 /* IP fastforward dropback */ /* Packet tag routines. */ struct m_tag *m_tag_alloc(u_int32_t, int, int, int);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200311250424.hAP4OPol057180>