On Monday 29 August 2005 16:10, Gleb Smirnoff wrote: > D> (I'll try it later but a definitive answer would be nice :) > > If you have put smth into ng_iface_start(), then you should do this > stuff via ng_send_fn().
OK. > Sorry, that I haven't yet feedbacked on your patches. I'll probably look > at them after 6.0-RELEASE. No problem :) I have attached an updated (untested - but it compiles! version) -- Daniel O'Connor software and network engineer for Genesis Software - http://www.gsoft.com.au "The nice thing about standards is that there are so many of them to choose from." -- Andrew Tanenbaum GPG Fingerprint - 5596 B766 97C0 0E94 4347 295E E593 DC20 7B3F CE8C
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 @@ 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 */ @@ -118,6 +126,7 @@ typedef struct ng_iface_private *priv_p; /* 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,11 +360,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) && (ifp->if_drv_flags & IFF_DRV_RUNNING))) { @@ -380,28 +389,71 @@ 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); } /* - * 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 @@ 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)
pgpTjI65mh4pS.pgp
Description: PGP signature