From owner-svn-src-head@freebsd.org Thu Oct 26 10:11:37 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7D65FE44784; Thu, 26 Oct 2017 10:11:37 +0000 (UTC) (envelope-from truckman@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 580AB73EA0; Thu, 26 Oct 2017 10:11:37 +0000 (UTC) (envelope-from truckman@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v9QABa6Y085473; Thu, 26 Oct 2017 10:11:36 GMT (envelope-from truckman@FreeBSD.org) Received: (from truckman@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v9QABZDk085463; Thu, 26 Oct 2017 10:11:35 GMT (envelope-from truckman@FreeBSD.org) Message-Id: <201710261011.v9QABZDk085463@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: truckman set sender to truckman@FreeBSD.org using -f From: Don Lewis Date: Thu, 26 Oct 2017 10:11:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r325008 - head/sys/netpfil/ipfw X-SVN-Group: head X-SVN-Commit-Author: truckman X-SVN-Commit-Paths: head/sys/netpfil/ipfw X-SVN-Commit-Revision: 325008 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Oct 2017 10:11:37 -0000 Author: truckman Date: Thu Oct 26 10:11:35 2017 New Revision: 325008 URL: https://svnweb.freebsd.org/changeset/base/325008 Log: Fix Dummynet AQM packet marking function ecn_mark() and fq_codel / fq_pie schedulers packet classification functions in layer2 (bridge mode). Dummynet AQM packet marking function ecn_mark() and fq_codel/fq_pie schedulers packet classification functions (fq_codel_classify_flow() and fq_pie_classify_flow()) assume mbuf is pointing at L3 (IP) packet. However, this assumption is incorrect if ipfw/dummynet is used to manage layer2 traffic (bridge mode) since mbuf will point at L2 frame. This patch solves this problem by identifying the source of the frame/packet (L2 or L3) and adding ETHER_HDR_LEN offset when converting an mbuf pointer to ip pointer if the traffic is from layer2. More specifically, in dummynet packet tagging function, tag_mbuf(), iphdr_off is set to ETHER_HDR_LEN if the traffic is from layer2 and set to zero otherwise. Whenever an access to IP header is required, mtodo(m, dn_tag_get(m)->iphdr_off) is used instead of mtod(m, struct ip *) to correctly convert mbuf pointer to ip pointer in both L2 and L3 traffic. Submitted by: lstewart MFC after: 2 weeks Relnotes: yes Differential Revision: https://reviews.freebsd.org/D12506 Modified: head/sys/netpfil/ipfw/dn_sched_fifo.c head/sys/netpfil/ipfw/dn_sched_fq_codel.c head/sys/netpfil/ipfw/dn_sched_fq_pie.c head/sys/netpfil/ipfw/dn_sched_prio.c head/sys/netpfil/ipfw/dn_sched_qfq.c head/sys/netpfil/ipfw/dn_sched_rr.c head/sys/netpfil/ipfw/dn_sched_wf2q.c head/sys/netpfil/ipfw/ip_dn_io.c head/sys/netpfil/ipfw/ip_dn_private.h Modified: head/sys/netpfil/ipfw/dn_sched_fifo.c ============================================================================== --- head/sys/netpfil/ipfw/dn_sched_fifo.c Thu Oct 26 09:29:35 2017 (r325007) +++ head/sys/netpfil/ipfw/dn_sched_fifo.c Thu Oct 26 10:11:35 2017 (r325008) @@ -33,13 +33,16 @@ #include #include #include +#include #include #include +#include #include /* IFNAMSIZ */ #include #include /* ipfw_rule_ref */ #include /* flow_id */ #include +#include #include #include #ifdef NEW_AQM Modified: head/sys/netpfil/ipfw/dn_sched_fq_codel.c ============================================================================== --- head/sys/netpfil/ipfw/dn_sched_fq_codel.c Thu Oct 26 09:29:35 2017 (r325007) +++ head/sys/netpfil/ipfw/dn_sched_fq_codel.c Thu Oct 26 10:11:35 2017 (r325008) @@ -218,13 +218,14 @@ fq_codel_classify_flow(struct mbuf *m, uint16_t fcount uint8_t tuple[41]; uint16_t hash=0; + ip = (struct ip *)mtodo(m, dn_tag_get(m)->iphdr_off); //#ifdef INET6 struct ip6_hdr *ip6; int isip6; - isip6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; + isip6 = (ip->ip_v == 6); if(isip6) { - ip6 = mtod(m, struct ip6_hdr *); + ip6 = (struct ip6_hdr *)ip; *((uint8_t *) &tuple[0]) = ip6->ip6_nxt; *((uint32_t *) &tuple[1]) = si->perturbation; memcpy(&tuple[5], ip6->ip6_src.s6_addr, 16); @@ -253,7 +254,6 @@ fq_codel_classify_flow(struct mbuf *m, uint16_t fcount //#endif /* IPv4 */ - ip = mtod(m, struct ip *); *((uint8_t *) &tuple[0]) = ip->ip_p; *((uint32_t *) &tuple[1]) = si->perturbation; *((uint32_t *) &tuple[5]) = ip->ip_src.s_addr; Modified: head/sys/netpfil/ipfw/dn_sched_fq_pie.c ============================================================================== --- head/sys/netpfil/ipfw/dn_sched_fq_pie.c Thu Oct 26 09:29:35 2017 (r325007) +++ head/sys/netpfil/ipfw/dn_sched_fq_pie.c Thu Oct 26 10:11:35 2017 (r325008) @@ -792,13 +792,14 @@ fq_pie_classify_flow(struct mbuf *m, uint16_t fcount, uint8_t tuple[41]; uint16_t hash=0; + ip = (struct ip *)mtodo(m, dn_tag_get(m)->iphdr_off); //#ifdef INET6 struct ip6_hdr *ip6; int isip6; - isip6 = (mtod(m, struct ip *)->ip_v == 6) ? 1 : 0; + isip6 = (ip->ip_v == 6); if(isip6) { - ip6 = mtod(m, struct ip6_hdr *); + ip6 = (struct ip6_hdr *)ip; *((uint8_t *) &tuple[0]) = ip6->ip6_nxt; *((uint32_t *) &tuple[1]) = si->perturbation; memcpy(&tuple[5], ip6->ip6_src.s6_addr, 16); @@ -826,7 +827,6 @@ fq_pie_classify_flow(struct mbuf *m, uint16_t fcount, //#endif /* IPv4 */ - ip = mtod(m, struct ip *); *((uint8_t *) &tuple[0]) = ip->ip_p; *((uint32_t *) &tuple[1]) = si->perturbation; *((uint32_t *) &tuple[5]) = ip->ip_src.s_addr; Modified: head/sys/netpfil/ipfw/dn_sched_prio.c ============================================================================== --- head/sys/netpfil/ipfw/dn_sched_prio.c Thu Oct 26 09:29:35 2017 (r325007) +++ head/sys/netpfil/ipfw/dn_sched_prio.c Thu Oct 26 10:11:35 2017 (r325008) @@ -32,13 +32,16 @@ #include #include #include +#include #include #include +#include #include /* IFNAMSIZ */ #include #include /* ipfw_rule_ref */ #include /* flow_id */ #include +#include #include #include #ifdef NEW_AQM Modified: head/sys/netpfil/ipfw/dn_sched_qfq.c ============================================================================== --- head/sys/netpfil/ipfw/dn_sched_qfq.c Thu Oct 26 09:29:35 2017 (r325007) +++ head/sys/netpfil/ipfw/dn_sched_qfq.c Thu Oct 26 10:11:35 2017 (r325008) @@ -33,13 +33,16 @@ #include #include #include +#include #include #include +#include #include /* IFNAMSIZ */ #include #include /* ipfw_rule_ref */ #include /* flow_id */ #include +#include #include #include #ifdef NEW_AQM Modified: head/sys/netpfil/ipfw/dn_sched_rr.c ============================================================================== --- head/sys/netpfil/ipfw/dn_sched_rr.c Thu Oct 26 09:29:35 2017 (r325007) +++ head/sys/netpfil/ipfw/dn_sched_rr.c Thu Oct 26 10:11:35 2017 (r325008) @@ -33,13 +33,16 @@ #include #include #include +#include #include #include +#include #include /* IFNAMSIZ */ #include #include /* ipfw_rule_ref */ #include /* flow_id */ #include +#include #include #include #ifdef NEW_AQM Modified: head/sys/netpfil/ipfw/dn_sched_wf2q.c ============================================================================== --- head/sys/netpfil/ipfw/dn_sched_wf2q.c Thu Oct 26 09:29:35 2017 (r325007) +++ head/sys/netpfil/ipfw/dn_sched_wf2q.c Thu Oct 26 10:11:35 2017 (r325008) @@ -34,13 +34,16 @@ #include #include #include +#include #include #include +#include #include /* IFNAMSIZ */ #include #include /* ipfw_rule_ref */ #include /* flow_id */ #include +#include #include #include #ifdef NEW_AQM Modified: head/sys/netpfil/ipfw/ip_dn_io.c ============================================================================== --- head/sys/netpfil/ipfw/ip_dn_io.c Thu Oct 26 09:29:35 2017 (r325007) +++ head/sys/netpfil/ipfw/ip_dn_io.c Thu Oct 26 10:11:35 2017 (r325008) @@ -237,27 +237,10 @@ SYSEND static void dummynet_send(struct mbuf *); /* - * Packets processed by dummynet have an mbuf tag associated with - * them that carries their dummynet state. - * Outside dummynet, only the 'rule' field is relevant, and it must - * be at the beginning of the structure. - */ -struct dn_pkt_tag { - struct ipfw_rule_ref rule; /* matching rule */ - - /* second part, dummynet specific */ - int dn_dir; /* action when packet comes out.*/ - /* see ip_fw_private.h */ - uint64_t output_time; /* when the pkt is due for delivery*/ - struct ifnet *ifp; /* interface, for ip_output */ - struct _ip6dn_args ip6opt; /* XXX ipv6 options */ -}; - -/* * Return the mbuf tag holding the dummynet state (it should * be the first one on the list). */ -static struct dn_pkt_tag * +struct dn_pkt_tag * dn_tag_get(struct mbuf *m) { struct m_tag *mtag = m_tag_first(m); @@ -448,7 +431,7 @@ int ecn_mark(struct mbuf* m) { struct ip *ip; - ip = mtod(m, struct ip *); + ip = (struct ip *)mtodo(m, dn_tag_get(m)->iphdr_off); switch (ip->ip_v) { case IPVERSION: @@ -472,7 +455,7 @@ ecn_mark(struct mbuf* m) #ifdef INET6 case (IPV6_VERSION >> 4): { - struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); + struct ip6_hdr *ip6 = (struct ip6_hdr *)ip; u_int32_t flowlabel; flowlabel = ntohl(ip6->ip6_flow); @@ -859,6 +842,7 @@ tag_mbuf(struct mbuf *m, int dir, struct ip_fw_args *f dt->ifp = fwa->oif; /* dt->output tame is updated as we move through */ dt->output_time = dn_cfg.curr_time; + dt->iphdr_off = (dir & PROTO_LAYER2) ? ETHER_HDR_LEN : 0; return 0; } Modified: head/sys/netpfil/ipfw/ip_dn_private.h ============================================================================== --- head/sys/netpfil/ipfw/ip_dn_private.h Thu Oct 26 09:29:35 2017 (r325007) +++ head/sys/netpfil/ipfw/ip_dn_private.h Thu Oct 26 10:11:35 2017 (r325008) @@ -367,6 +367,24 @@ enum { DN_QHT_IS_Q = 0x0100, /* in flowset, qht is a single queue */ }; +/* + * Packets processed by dummynet have an mbuf tag associated with + * them that carries their dummynet state. + * Outside dummynet, only the 'rule' field is relevant, and it must + * be at the beginning of the structure. + */ +struct dn_pkt_tag { + struct ipfw_rule_ref rule; /* matching rule */ + + /* second part, dummynet specific */ + int dn_dir; /* action when packet comes out.*/ + /* see ip_fw_private.h */ + uint64_t output_time; /* when the pkt is due for delivery*/ + struct ifnet *ifp; /* interface, for ip_output */ + struct _ip6dn_args ip6opt; /* XXX ipv6 options */ + uint16_t iphdr_off; /* IP header offset for mtodo() */ +}; + extern struct dn_parms dn_cfg; //VNET_DECLARE(struct dn_parms, _base_dn_cfg); //#define dn_cfg VNET(_base_dn_cfg) @@ -374,6 +392,7 @@ extern struct dn_parms dn_cfg; int dummynet_io(struct mbuf **, int , struct ip_fw_args *); void dummynet_task(void *context, int pending); void dn_reschedule(void); +struct dn_pkt_tag * dn_tag_get(struct mbuf *m); struct dn_queue *ipdn_q_find(struct dn_fsk *, struct dn_sch_inst *, struct ipfw_flow_id *);