Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 26 Oct 2017 10:11:35 +0000 (UTC)
From:      Don Lewis <truckman@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r325008 - head/sys/netpfil/ipfw
Message-ID:  <201710261011.v9QABZDk085463@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/mbuf.h>
 #include <sys/module.h>
+#include <sys/rwlock.h>
 #include <net/if.h>	/* IFNAMSIZ */
 #include <netinet/in.h>
 #include <netinet/ip_var.h>		/* ipfw_rule_ref */
 #include <netinet/ip_fw.h>	/* flow_id */
 #include <netinet/ip_dummynet.h>
+#include <netpfil/ipfw/ip_fw_private.h>
 #include <netpfil/ipfw/dn_heap.h>
 #include <netpfil/ipfw/ip_dn_private.h>
 #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 <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/mbuf.h>
 #include <sys/module.h>
+#include <sys/rwlock.h>
 #include <net/if.h>	/* IFNAMSIZ */
 #include <netinet/in.h>
 #include <netinet/ip_var.h>		/* ipfw_rule_ref */
 #include <netinet/ip_fw.h>	/* flow_id */
 #include <netinet/ip_dummynet.h>
+#include <netpfil/ipfw/ip_fw_private.h>
 #include <netpfil/ipfw/dn_heap.h>
 #include <netpfil/ipfw/ip_dn_private.h>
 #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 <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/mbuf.h>
 #include <sys/module.h>
+#include <sys/rwlock.h>
 #include <net/if.h>	/* IFNAMSIZ */
 #include <netinet/in.h>
 #include <netinet/ip_var.h>		/* ipfw_rule_ref */
 #include <netinet/ip_fw.h>	/* flow_id */
 #include <netinet/ip_dummynet.h>
+#include <netpfil/ipfw/ip_fw_private.h>
 #include <netpfil/ipfw/dn_heap.h>
 #include <netpfil/ipfw/ip_dn_private.h>
 #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 <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/mbuf.h>
 #include <sys/module.h>
+#include <sys/rwlock.h>
 #include <net/if.h>	/* IFNAMSIZ */
 #include <netinet/in.h>
 #include <netinet/ip_var.h>		/* ipfw_rule_ref */
 #include <netinet/ip_fw.h>	/* flow_id */
 #include <netinet/ip_dummynet.h>
+#include <netpfil/ipfw/ip_fw_private.h>
 #include <netpfil/ipfw/dn_heap.h>
 #include <netpfil/ipfw/ip_dn_private.h>
 #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 <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/mbuf.h>
 #include <sys/module.h>
+#include <sys/rwlock.h>
 #include <net/if.h>	/* IFNAMSIZ */
 #include <netinet/in.h>
 #include <netinet/ip_var.h>		/* ipfw_rule_ref */
 #include <netinet/ip_fw.h>	/* flow_id */
 #include <netinet/ip_dummynet.h>
+#include <netpfil/ipfw/ip_fw_private.h>
 #include <netpfil/ipfw/dn_heap.h>
 #include <netpfil/ipfw/ip_dn_private.h>
 #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 *);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201710261011.v9QABZDk085463>