Index: sys/netgraph/ng_iface.c =================================================================== RCS file: /usr/CVS-Repository/src/sys/netgraph/ng_iface.c,v retrieving revision 1.43 diff -u -p -r1.43 ng_iface.c --- sys/netgraph/ng_iface.c 26 Jun 2005 18:11:10 -0000 1.43 +++ sys/netgraph/ng_iface.c 30 Jul 2005 11:56:53 -0000 @@ -107,6 +107,14 @@ const static struct iffam gFamilies[] = }; #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 */ @@ -349,11 +357,11 @@ static int 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; u_int32_t af; - + struct iffamtag *mtag; + /* Check interface flags */ if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) { m_freem(m); @@ -377,18 +385,22 @@ ng_iface_output(struct ifnet *ifp, struc 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); } /* @@ -398,7 +410,35 @@ ng_iface_output(struct ifnet *ifp, struc static void ng_iface_start(struct ifnet *ifp) { - if_printf(ifp, "%s called?", __func__); + struct mbuf *m = NULL; + const priv_p priv = (priv_p) ifp->if_softc; + struct iffamtag *mtag; + 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++; + } + } } /* @@ -490,13 +530,15 @@ ng_iface_constructor(node_p node) 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 */ + 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)