diff options
author | glebius <glebius@FreeBSD.org> | 2005-10-10 15:12:59 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2005-10-10 15:12:59 +0000 |
commit | 6fd3442fe2d3ba9a24f475cbeb31e769aa9f0743 (patch) | |
tree | 0d6386935bfb3f1e168283090f968b6527451ff6 /sys/netgraph | |
parent | 633be11491f92c831dd959891dc7a2aa3a6a17cb (diff) | |
download | FreeBSD-src-6fd3442fe2d3ba9a24f475cbeb31e769aa9f0743.zip FreeBSD-src-6fd3442fe2d3ba9a24f475cbeb31e769aa9f0743.tar.gz |
ALTQ support for ng_iface(4). Before turning on please consult manual page.
Diffstat (limited to 'sys/netgraph')
-rw-r--r-- | sys/netgraph/ng_iface.c | 94 |
1 files changed, 68 insertions, 26 deletions
diff --git a/sys/netgraph/ng_iface.c b/sys/netgraph/ng_iface.c index 3452685..d0d27c4 100644 --- a/sys/netgraph/ng_iface.c +++ b/sys/netgraph/ng_iface.c @@ -123,6 +123,8 @@ static int ng_iface_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst, struct rtentry *rt0); static void ng_iface_bpftap(struct ifnet *ifp, struct mbuf *m, sa_family_t family); +static int ng_iface_send(struct ifnet *ifp, struct mbuf *m, + sa_family_t sa); #ifdef DEBUG static void ng_iface_print_ioctl(struct ifnet *ifp, int cmd, caddr_t data); #endif @@ -351,10 +353,8 @@ 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; - u_int32_t af; + uint32_t af; + int error = 0; /* Check interface flags */ if (!((ifp->if_flags & IFF_UP) && @@ -372,36 +372,40 @@ ng_iface_output(struct ifnet *ifp, struct mbuf *m, /* Berkeley packet filter */ ng_iface_bpftap(ifp, m, dst->sa_family); - /* Check address family to determine hook (if known) */ - if (iffam == NULL) { - m_freem(m); - log(LOG_WARNING, "%s: can't handle af%d\n", - ifp->if_xname, (int)dst->sa_family); - return (EAFNOSUPPORT); - } - - /* 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, iffam), m); + if (ALTQ_IS_ENABLED(&ifp->if_snd)) { + M_PREPEND(m, sizeof(sa_family_t), M_DONTWAIT); + if (m == NULL) { + ifp->if_iqdrops++; + ifp->if_oerrors++; + return (ENOBUFS); + } + *(sa_family_t *)m->m_data = dst->sa_family; + IFQ_HANDOFF(ifp, m, error); + } else + error = ng_iface_send(ifp, m, dst->sa_family); - /* Update stats */ - if (error == 0) { - ifp->if_obytes += len; - ifp->if_opackets++; - } return (error); } /* - * This routine should never be called + * Start method is used only when ALTQ is on. */ - static void ng_iface_start(struct ifnet *ifp) { - if_printf(ifp, "%s called?", __func__); + struct mbuf *m; + sa_family_t sa; + + KASSERT(ALTQ_IS_ENABLED(&ifp->if_snd),("ng_iface_start without ALTQ")); + + while (1) { + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; + sa = *mtod(m, sa_family_t *); + m_adj(m, sizeof(sa_family_t)); + ng_iface_send(ifp, m, sa); + } } /* @@ -418,6 +422,42 @@ ng_iface_bpftap(struct ifnet *ifp, struct mbuf *m, sa_family_t family) } } +/* + * This routine does actual delivery of the packet into the + * netgraph(4). It is called from ng_iface_start() and + * nf_iface_output(). + */ +static int +ng_iface_send(struct ifnet *ifp, struct mbuf *m, sa_family_t sa) +{ + const priv_p priv = (priv_p) ifp->if_softc; + const iffam_p iffam = get_iffam_from_af(sa); + int error = 0; + int len; + + /* Check address family to determine hook (if known) */ + if (iffam == NULL) { + m_freem(m); + log(LOG_WARNING, "%s: can't handle af%d\n", ifp->if_xname, sa); + return (EAFNOSUPPORT); + } + + /* 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, iffam), m); + + /* Update stats. */ + if (error == 0) { + ifp->if_obytes += len; + ifp->if_opackets++; + } + + return (error); +} + #ifdef DEBUG /* * Display an ioctl to the virtual interface @@ -493,13 +533,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) |