Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Oct 2005 18:43:56 -0500
From:      Ryan Rempel <rgrempel@gmail.com>
To:        ovidiue <ovidiue@unixware.ro>
Cc:        freebsd-pf@freebsd.org
Subject:   Re: ALTQ support for MPD (ng_iface patch?) (pf+altq+mpd)
Message-ID:  <fb5ec4230510121643n13ce67b6xc8c3c8c331b71807@mail.gmail.com>
In-Reply-To: <416C4935.304@unixware.ro>
References:  <416C4935.304@unixware.ro>

next in thread | previous in thread | raw e-mail | index | archive | help
------=_Part_15506_11390085.1129160636029
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

On 10/12/04, ovidiue <ovidiue@unixware.ro> wrote:

> Does anybody know of a patch for netgraph to use ALTQ suppport in pf
> with mpd ?
> (I am using 5.4 version)

I have attached a patch which was created by Daniel O'Connor -- I just
modified it slightly to make it apply cleanly to 5.4, and to remove a
logging statement. I've tested it a fair bit on 5.4, and it seems to
work very well indeed, but YMMV.

------=_Part_15506_11390085.1129160636029
Content-Type: application/octet-stream; name=netgraph-altq.diff
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="netgraph-altq.diff"

Index: sys/netgraph/ng_iface.c
===================================================================
RCS file: /usr/CVS-Repository/src/sys/netgraph/ng_iface.c,v
retrieving revision 1.44
diff -u -p -r1.44 ng_iface.c
--- sys/netgraph/ng_iface.c     9 Aug 2005 10:19:59 -0000       1.44
+++ sys/netgraph/ng_iface.c     29 Aug 2005 06:05:19 -0000
@@ -107,6 +107,14 @@
 };
 #define NUM_FAMILIES		(sizeof(gFamilies) / sizeof(*gFamilies))
 
+#define NGM_MTAG_ID_IFFAM      29
+
+/* Tag for mbufs to tell ng_iface_start where to send them */
+struct iffamtag {
+	struct m_tag       tag;
+	iffam_p            iffam_p;
+};
+
 /* Node private data */
 struct ng_iface_private {
 	struct  ifnet *ifp;		/* Our interface */
@@ -118,6 +126,7 @@
 
 /* Interface methods */
 static void	ng_iface_start(struct ifnet *ifp);
+static void	ng_iface_start2(node_p node, hook_p hook, void *arg1, int arg2);
 static int	ng_iface_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
 static int	ng_iface_output(struct ifnet *ifp, struct mbuf *m0,
 			struct sockaddr *dst, struct rtentry *rt0);
@@ -351,10 +360,10 @@
 ng_iface_output(struct ifnet *ifp, struct mbuf *m,
 		struct sockaddr *dst, struct rtentry *rt0)
 {
-	const priv_p priv = (priv_p) ifp->if_softc;
 	const iffam_p iffam = get_iffam_from_af(dst->sa_family);
-	int len, error = 0;
+	int error = 0;
-
+	struct iffamtag *mtag;
+
 	/* Check interface flags */
 	if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
 		m_freem(m);
@@ -380,28 +389,71 @@
 		return (EAFNOSUPPORT);
 	}
 
-	/* Copy length before the mbuf gets invalidated */
-	len = m->m_pkthdr.len;
+	/* Tag mbuf with hook information */
+	/* XXX: kind of dumb that the alloc routine adds the size of
+	 * struct mtag adds to our length, this make it hard to
+	 * allocate the correct size.. */
+	mtag = (struct iffamtag *)m_tag_alloc(NGM_MTAG_ID_IFFAM, NGM_MTAG_ID_IFFAM, 
+						sizeof(struct iffamtag) - sizeof(struct m_tag), M_NOWAIT);
+	if (mtag == NULL)
+		return (ENOBUFS);
+	mtag->iffam_p = iffam;
+	m_tag_prepend(m, (struct m_tag *)mtag);
+	
+	IFQ_HANDOFF(ifp, m, error);
+
+	return (error);
 
-	/* Send packet; if hook is not connected, mbuf will get freed. */
-	NG_SEND_DATA_ONLY(error, *get_hook_from_iffam(priv, iffam), m);
 
-	/* Update stats */
-	if (error == 0) {
-		ifp->if_obytes += len;
-		ifp->if_opackets++;
-	}
-	return (error);
 }
 
 /*
- * This routine should never be called
+ * Called to move queued packets off the interface.
+ *
+ * We wait for netgraph to call us back when we can really move the
+ * data
  */
-
 static void
 ng_iface_start(struct ifnet *ifp)
 {
-	if_printf(ifp, "%s called?", __func__);
+	const priv_p priv = (priv_p)ifp->if_softc;
+
+	ng_send_fn(priv->node, NULL, &ng_iface_start2, ifp, 0);
+}
+
+static void
+ng_iface_start2(node_p node, hook_p hook, void *arg1, int arg2)
+{
+	struct ifnet *ifp = arg1;
+	const priv_p priv = (priv_p) ifp->if_softc;
+	struct iffamtag *mtag;
+	struct mbuf *m;
+	int error = 0, len;
+	
+	// if_printf(ifp, "%s called\n", __func__);
+	while (1) {
+		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
+		if (m == NULL)
+                       break;
+           
+               mtag = (struct iffamtag *)m_tag_locate(m, NGM_MTAG_ID_IFFAM, NGM_MTAG_ID_IFFAM, NULL);
+               if (mtag == NULL) { /* mbuf with no tag? shouldn't be possible */
+                       if_printf(ifp, "mbuf found without a tag, discarding\n");
+                       m_freem(m); /* XXX: does this free tags too? */
+               }
+               
+               /* Copy length before the mbuf gets invalidated */
+               len = m->m_pkthdr.len;
+
+               /* Send packet; if hook is not connected, mbuf will get freed. */
+               NG_SEND_DATA_ONLY(error, *get_hook_from_iffam(priv, mtag->iffam_p), m);
+
+               /* Update stats */
+               if (error == 0) {
+                       ifp->if_obytes += len;
+                       ifp->if_opackets++;
+               }
+       }
 }
 
 /*
@@ -493,13 +545,15 @@
 	ifp->if_start = ng_iface_start;
 	ifp->if_ioctl = ng_iface_ioctl;
 	ifp->if_watchdog = NULL;
-	ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
 	ifp->if_mtu = NG_IFACE_MTU_DEFAULT;
 	ifp->if_flags = (IFF_SIMPLEX|IFF_POINTOPOINT|IFF_NOARP|IFF_MULTICAST);
 	ifp->if_type = IFT_PROPVIRTUAL;		/* XXX */
 	ifp->if_addrlen = 0;			/* XXX */
 	ifp->if_hdrlen = 0;			/* XXX */
 	ifp->if_baudrate = 64000;		/* XXX */
 	TAILQ_INIT(&ifp->if_addrhead);
+	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
+	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
+	IFQ_SET_READY(&ifp->if_snd);
 
 	/* Give this node the same name as the interface (if possible) */
 	if (ng_name_node(node, ifp->if_xname) != 0)

------=_Part_15506_11390085.1129160636029--



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