From owner-svn-src-projects@FreeBSD.ORG Tue Jan 13 09:05:50 2015 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 523AFD45; Tue, 13 Jan 2015 09:05:50 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 338E1D7F; Tue, 13 Jan 2015 09:05:50 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t0D95oFD077496; Tue, 13 Jan 2015 09:05:50 GMT (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t0D95otm077495; Tue, 13 Jan 2015 09:05:50 GMT (envelope-from glebius@FreeBSD.org) Message-Id: <201501130905.t0D95otm077495@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: glebius set sender to glebius@FreeBSD.org using -f From: Gleb Smirnoff Date: Tue, 13 Jan 2015 09:05:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r277123 - projects/ifnet/sys/netgraph X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Jan 2015 09:05:50 -0000 Author: glebius Date: Tue Jan 13 09:05:49 2015 New Revision: 277123 URL: https://svnweb.freebsd.org/changeset/base/277123 Log: Convert ng_iface(4) to new ifnet API. Since this interface type is somewhat special, it still includes if_var.h. All what ng_iface needs to know is if_transmit() macro and access to if_index, which normal drivers shouldn't need. It is lesser evil to make ng_iface(4) aware of ifnet structure, rather than provide access to these fields to all drivers. Might be rethought however. Committed via: ng0 Sponsored by: Nginx, Inc. Modified: projects/ifnet/sys/netgraph/ng_iface.c Modified: projects/ifnet/sys/netgraph/ng_iface.c ============================================================================== --- projects/ifnet/sys/netgraph/ng_iface.c Tue Jan 13 09:02:06 2015 (r277122) +++ projects/ifnet/sys/netgraph/ng_iface.c Tue Jan 13 09:05:49 2015 (r277123) @@ -69,10 +69,10 @@ #include #include +#include #include -#include +#include /* XXXGL: for if_transmit() and if_index. */ #include -#include #include #include #include @@ -116,16 +116,13 @@ struct ng_iface_private { typedef struct ng_iface_private *priv_p; /* Interface methods */ -static void ng_iface_start(struct ifnet *ifp); -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, +static int ng_iface_transmit(if_t, struct mbuf *); +static int ng_iface_ioctl(if_t, u_long cmd, caddr_t data); +static int ng_iface_output(if_t, struct mbuf *m0, const struct sockaddr *dst, struct route *ro); -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); +static int ng_iface_send(if_t, struct mbuf *m, sa_family_t sa); #ifdef DEBUG -static void ng_iface_print_ioctl(struct ifnet *ifp, int cmd, caddr_t data); +static void ng_iface_print_ioctl(if_t, int cmd, caddr_t data); #endif /* Netgraph methods */ @@ -194,6 +191,19 @@ NETGRAPH_INIT(iface, &typestruct); static VNET_DEFINE(struct unrhdr *, ng_iface_unit); #define V_ng_iface_unit VNET(ng_iface_unit) +static struct ifdriver ng_ifdrv = { + .ifdrv_ops = { + .ifop_origin = IFOP_ORIGIN_DRIVER, + .ifop_output = ng_iface_output, + .ifop_transmit = ng_iface_transmit, + .ifop_ioctl = ng_iface_ioctl, + }, + .ifdrv_name = NG_IFACE_IFACE_NAME, + .ifdrv_type = IFT_PROPVIRTUAL, + .ifdrv_dlt = DLT_NULL, + .ifdrv_dlt_hdrlen = sizeof(uint32_t), +}; + /************************************************************************ HELPER STUFF ************************************************************************/ @@ -264,7 +274,7 @@ get_iffam_from_name(const char *name) * Process an ioctl for the virtual interface */ static int -ng_iface_ioctl(struct ifnet *ifp, u_long command, caddr_t data) +ng_iface_ioctl(if_t ifp, u_long command, caddr_t data) { struct ifreq *const ifr = (struct ifreq *) data; int error = 0; @@ -276,29 +286,11 @@ ng_iface_ioctl(struct ifnet *ifp, u_long /* These two are mostly handled at a higher layer */ case SIOCSIFADDR: - ifp->if_flags |= IFF_UP; - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE); + if_addflags(ifp, IF_FLAGS, IFF_UP); break; case SIOCGIFADDR: break; - - /* Set flags */ case SIOCSIFFLAGS: - /* - * If the interface is marked up and stopped, then start it. - * If it is marked down and running, then stop it. - */ - if (ifr->ifr_flags & IFF_UP) { - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE); - ifp->if_drv_flags |= IFF_DRV_RUNNING; - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | - IFF_DRV_OACTIVE); - } break; /* Set the interface MTU */ @@ -307,7 +299,7 @@ ng_iface_ioctl(struct ifnet *ifp, u_long || ifr->ifr_mtu < NG_IFACE_MTU_MIN) error = EINVAL; else - ifp->if_mtu = ifr->ifr_mtu; + if_set(ifp, IF_MTU, ifr->ifr_mtu); break; /* Stuff that's not supported */ @@ -333,16 +325,14 @@ ng_iface_ioctl(struct ifnet *ifp, u_long */ static int -ng_iface_output(struct ifnet *ifp, struct mbuf *m, - const struct sockaddr *dst, struct route *ro) +ng_iface_output(if_t ifp, struct mbuf *m, const struct sockaddr *dst, + struct route *ro) { struct m_tag *mtag; uint32_t af; - int error; /* Check interface flags */ - if (!((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING))) { + if ((if_get(ifp, IF_FLAGS) & IFF_UP) == 0) { m_freem(m); return (ENETDOWN); } @@ -350,19 +340,18 @@ ng_iface_output(struct ifnet *ifp, struc /* Protect from deadly infinite recursion. */ mtag = NULL; while ((mtag = m_tag_locate(m, MTAG_NGIF, MTAG_NGIF_CALLED, mtag))) { - if (*(struct ifnet **)(mtag + 1) == ifp) { - log(LOG_NOTICE, "Loop detected on %s\n", ifp->if_xname); + if (*(if_t *)(mtag + 1) == ifp) { + log(LOG_NOTICE, "Loop detected on %s\n", if_name(ifp)); m_freem(m); return (EDEADLK); } } - mtag = m_tag_alloc(MTAG_NGIF, MTAG_NGIF_CALLED, sizeof(struct ifnet *), - M_NOWAIT); + mtag = m_tag_alloc(MTAG_NGIF, MTAG_NGIF_CALLED, sizeof(if_t), M_NOWAIT); if (mtag == NULL) { m_freem(m); return (ENOMEM); } - *(struct ifnet **)(mtag + 1) = ifp; + *(if_t *)(mtag + 1) = ifp; m_tag_prepend(m, mtag); /* BPF writes need to be handled specially. */ @@ -371,56 +360,31 @@ ng_iface_output(struct ifnet *ifp, struc else af = dst->sa_family; - /* Berkeley packet filter */ - ng_iface_bpftap(ifp, m, af); - - if (ALTQ_IS_ENABLED(&ifp->if_snd)) { - M_PREPEND(m, sizeof(sa_family_t), M_NOWAIT); - if (m == NULL) { - if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1); - return (ENOBUFS); - } - *(sa_family_t *)m->m_data = af; - error = (ifp->if_transmit)(ifp, m); - } else - error = ng_iface_send(ifp, m, af); + M_PREPEND(m, sizeof(sa_family_t), M_NOWAIT); + if (m == NULL) { + if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1); + return (ENOBUFS); + } + *(sa_family_t *)m->m_data = af; - return (error); + return (if_transmit(ifp, m)); } /* * Start method is used only when ALTQ is enabled. */ -static void -ng_iface_start(struct ifnet *ifp) +static int +ng_iface_transmit(if_t ifp, struct mbuf *m) { - struct mbuf *m; - sa_family_t sa; + sa_family_t af; - KASSERT(ALTQ_IS_ENABLED(&ifp->if_snd), ("%s without ALTQ", __func__)); + af = *mtod(m, sa_family_t *); + KASSERT(af != AF_UNSPEC, ("%s: af = AF_UNSPEC", __func__)); + m_adj(m, sizeof(sa_family_t)); - for(;;) { - 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); - } -} + if_mtap(ifp, m, &af, sizeof(af)); -/* - * Flash a packet by the BPF (requires prepending 4 byte AF header) - * Note the phoney mbuf; this is OK because BPF treats it read-only. - */ -static void -ng_iface_bpftap(struct ifnet *ifp, struct mbuf *m, sa_family_t family) -{ - KASSERT(family != AF_UNSPEC, ("%s: family=AF_UNSPEC", __func__)); - if (bpf_peers_present(ifp->if_bpf)) { - int32_t family4 = (int32_t)family; - bpf_mtap2(ifp->if_bpf, &family4, sizeof(family4), m); - } + return (ng_iface_send(ifp, m, af)); } /* @@ -429,9 +393,9 @@ ng_iface_bpftap(struct ifnet *ifp, struc * ng_iface_output(). */ static int -ng_iface_send(struct ifnet *ifp, struct mbuf *m, sa_family_t sa) +ng_iface_send(if_t ifp, struct mbuf *m, sa_family_t sa) { - const priv_p priv = (priv_p) ifp->if_softc; + const priv_p priv = if_getsoftc(ifp, IF_DRIVER_SOFTC); const iffam_p iffam = get_iffam_from_af(sa); int error; int len; @@ -439,7 +403,7 @@ ng_iface_send(struct ifnet *ifp, struct /* 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); + log(LOG_WARNING, "%s: can't handle af%d\n", if_name(ifp), sa); return (EAFNOSUPPORT); } @@ -455,7 +419,8 @@ ng_iface_send(struct ifnet *ifp, struct if (error == 0) { if_inc_counter(ifp, IFCOUNTER_OBYTES, len); if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - } + } else + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); return (error); } @@ -466,7 +431,7 @@ ng_iface_send(struct ifnet *ifp, struct */ static void -ng_iface_print_ioctl(struct ifnet *ifp, int command, caddr_t data) +ng_iface_print_ioctl(if_t ifp, int command, caddr_t data) { char *str; @@ -487,7 +452,7 @@ ng_iface_print_ioctl(struct ifnet *ifp, str = "IO??"; } log(LOG_DEBUG, "%s: %s('%c', %d, char[%d])\n", - ifp->if_xname, + if_name(ifp), str, IOCGROUP(command), command & 0xff, @@ -505,53 +470,28 @@ ng_iface_print_ioctl(struct ifnet *ifp, static int ng_iface_constructor(node_p node) { - struct ifnet *ifp; + struct if_attach_args ifat = { + .ifat_version = IF_ATTACH_VERSION, + .ifat_drv = &ng_ifdrv, + .ifat_mtu = NG_IFACE_MTU_DEFAULT, + .ifat_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_NOARP | + IFF_MULTICAST, + .ifat_baudrate = 64000, /* XXX */ + }; priv_p priv; - /* Allocate node and interface private structures */ priv = malloc(sizeof(*priv), M_NETGRAPH_IFACE, M_WAITOK | M_ZERO); - ifp = if_alloc(IFT_PROPVIRTUAL); - if (ifp == NULL) { - free(priv, M_NETGRAPH_IFACE); - return (ENOMEM); - } - - /* Link them together */ - ifp->if_softc = priv; - priv->ifp = ifp; - - /* Get an interface unit number */ - priv->unit = alloc_unr(V_ng_iface_unit); - - /* Link together node and private info */ NG_NODE_SET_PRIVATE(node, priv); priv->node = node; - - /* Initialize interface structure */ - if_initname(ifp, NG_IFACE_IFACE_NAME, priv->unit); - ifp->if_output = ng_iface_output; - ifp->if_start = ng_iface_start; - ifp->if_ioctl = ng_iface_ioctl; - 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, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); + ifat.ifat_softc = priv; + ifat.ifat_dunit = priv->unit = alloc_unr(V_ng_iface_unit); + priv->ifp = if_attach(&ifat); /* Give this node the same name as the interface (if possible) */ - if (ng_name_node(node, ifp->if_xname) != 0) + if (ng_name_node(node, if_name(priv->ifp)) != 0) log(LOG_WARNING, "%s: can't acquire netgraph name\n", - ifp->if_xname); - - /* Attach the interface */ - if_attach(ifp); - bpfattach(ifp, DLT_NULL, sizeof(u_int32_t)); + if_name(priv->ifp)); - /* Done */ return (0); } @@ -582,7 +522,7 @@ static int ng_iface_rcvmsg(node_p node, item_p item, hook_p lasthook) { const priv_p priv = NG_NODE_PRIVATE(node); - struct ifnet *const ifp = priv->ifp; + const if_t ifp = priv->ifp; struct ng_mesg *resp = NULL; int error = 0; struct ng_mesg *msg; @@ -597,7 +537,7 @@ ng_iface_rcvmsg(node_p node, item_p item error = ENOMEM; break; } - strlcpy(resp->data, ifp->if_xname, IFNAMSIZ); + strlcpy(resp->data, if_name(ifp), IFNAMSIZ); break; case NGM_IFACE_POINT2POINT: @@ -605,18 +545,18 @@ ng_iface_rcvmsg(node_p node, item_p item { /* Deny request if interface is UP */ - if ((ifp->if_flags & IFF_UP) != 0) + if ((if_get(ifp, IF_FLAGS) & IFF_UP) != 0) return (EBUSY); /* Change flags */ switch (msg->header.cmd) { case NGM_IFACE_POINT2POINT: - ifp->if_flags |= IFF_POINTOPOINT; - ifp->if_flags &= ~IFF_BROADCAST; + if_addflags(ifp, IF_FLAGS, IFF_POINTOPOINT); + if_clrflags(ifp, IF_FLAGS, IFF_BROADCAST); break; case NGM_IFACE_BROADCAST: - ifp->if_flags &= ~IFF_POINTOPOINT; - ifp->if_flags |= IFF_BROADCAST; + if_clrflags(ifp, IF_FLAGS, IFF_POINTOPOINT); + if_addflags(ifp, IF_FLAGS, IFF_BROADCAST); break; } break; @@ -628,7 +568,7 @@ ng_iface_rcvmsg(node_p node, item_p item error = ENOMEM; break; } - *((uint32_t *)resp->data) = priv->ifp->if_index; + *((uint32_t *)resp->data) = ifp->if_index; break; default: @@ -665,8 +605,9 @@ ng_iface_rcvdata(hook_p hook, item_p ite { const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); const iffam_p iffam = get_iffam_from_hook(priv, hook); - struct ifnet *const ifp = priv->ifp; + const if_t ifp = priv->ifp; struct mbuf *m; + sa_family_t af; int isr; NGI_GET_M(item, m); @@ -674,7 +615,7 @@ ng_iface_rcvdata(hook_p hook, item_p ite /* Sanity checks */ KASSERT(iffam != NULL, ("%s: iffam", __func__)); M_ASSERTPKTHDR(m); - if ((ifp->if_flags & IFF_UP) == 0) { + if ((if_get(ifp, IF_FLAGS) & IFF_UP) == 0) { NG_FREE_M(m); return (ENETDOWN); } @@ -687,7 +628,8 @@ ng_iface_rcvdata(hook_p hook, item_p ite m->m_pkthdr.rcvif = ifp; /* Berkeley packet filter */ - ng_iface_bpftap(ifp, m, iffam->family); + af = iffam->family; + if_mtap(ifp, m, &af, sizeof(af)); /* Send packet */ switch (iffam->family) { @@ -706,7 +648,7 @@ ng_iface_rcvdata(hook_p hook, item_p ite return (EAFNOSUPPORT); } random_harvest(&(m->m_data), 12, 2, RANDOM_NET_NG); - M_SETFIB(m, ifp->if_fib); + M_SETFIB(m, if_get(ifp, IF_FIB)); netisr_dispatch(isr, m); return (0); } @@ -724,9 +666,7 @@ ng_iface_shutdown(node_p node) * hence we have to change the current vnet context here. */ CURVNET_SET_QUIET(priv->ifp->if_vnet); - bpfdetach(priv->ifp); if_detach(priv->ifp); - if_free(priv->ifp); CURVNET_RESTORE(); priv->ifp = NULL; free_unr(V_ng_iface_unit, priv->unit);