On Wed, Aug 22, 2012 at 12:20:19AM -0300, Rafael Zalamena wrote: > I've being working on a project that involves MPLS and OpenBSD, I > recently started coding and I would really love to get some > comments/advices about it. > > This thread will contain code about the wire(4) pseudo device (RFC4448), > it will be used in the future by ldpd(8) or ifconfig(8) to configure > pseudowires (RFC4447). This device will allow us to develop VPLS support > in LDPd later (RFC4762). > > Since I'm quite new to this expect rough edges. >
Updated v1 patch: * Cleaned up code - removed code at if_output() and if_start() that didn't make sense. * Setting and getting labels works (fixed setlabel) * Moved wire_input() call to its propper place at ether_input() * Creating wire and associating it with ethernet + mpe interface works - needs custom program that calls the appropriated ioctl() --- /dev/null Mon Aug 27 00:22:40 2012 +++ net/if_mpe.h Tue Aug 21 23:50:31 2012 @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2012 Rafael F. Zalamena <rzalam...@gmail.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +struct mpe_softc { + struct ifnet sc_if; /* the interface */ + int sc_unit; + struct shim_hdr sc_shim; + LIST_ENTRY(mpe_softc) sc_list; +}; + +int mpe_newlabel(struct ifnet *, int, struct shim_hdr *); --- /dev/null Mon Aug 27 00:30:25 2012 +++ net/if_wire.c Mon Aug 27 00:29:49 2012 @@ -0,0 +1,418 @@ +/* + * Copyright (c) 2012 Rafael F. Zalamena <rzalam...@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "bpfilter.h" +#include "vlan.h" + +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <sys/errno.h> +#include <sys/kernel.h> +#include <machine/cpu.h> + +#include <net/if.h> +#include <net/if_types.h> +#include <net/if_llc.h> +#include <net/route.h> +#include <net/netisr.h> + +#ifdef INET +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/in_var.h> +#include <netinet/ip.h> +#include <netinet/ip_var.h> +#include <netinet/if_ether.h> +#endif + +#if NBPFILTER > 0 +#include <net/bpf.h> +#endif + +#include <netmpls/mpls.h> + +#include <net/if_mpe.h> +#include <net/if_wire.h> + +#ifdef WIRE_DEBUG +#define DPRINTF(fmt, args...) printf("wire: " fmt "\n", ## args) +#else +#define DPRINTF(fmt, args...) +#endif + + +void wireattach(int); +int wire_clone_create(struct if_clone *, int); +int wire_clone_destroy(struct ifnet *); +int wire_ioctl(struct ifnet *, u_long, caddr_t); +void wire_init(struct wire_softc *); +void wire_stop(struct wire_softc *); +int wire_output(struct ifnet *, struct mbuf *, + struct sockaddr *, struct rtentry *); +void wire_start(struct ifnet *); +void wire_input(struct mbuf *, struct ether_header *, struct wire_softc *); + +LIST_HEAD(, wire_softc) wire_list; + +struct if_clone wire_cloner = + IF_CLONE_INITIALIZER("wire", wire_clone_create, wire_clone_destroy); + +/* ARGSUSED */ +void +wireattach(int n) +{ + LIST_INIT(&wire_list); + if_clone_attach(&wire_cloner); +} + +int +wire_clone_create(struct if_clone *ifc, int unit) +{ + struct wire_softc *sc; + struct ifnet *ifp; + int s; + + sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT|M_ZERO); + if (sc == NULL) + return (ENOMEM); + + ifp = &sc->sc_if; + snprintf(ifp->if_xname, sizeof(ifp->if_xname), "%s%d", + ifc->ifc_name, unit); + ifp->if_softc = sc; + ifp->if_mtu = ETHERMTU; + ifp->if_flags = IFF_POINTOPOINT; + ifp->if_ioctl = wire_ioctl; + ifp->if_output = wire_output; + ifp->if_start = wire_start; + ifp->if_type = IFT_MPLSTUNNEL; + ifp->if_hdrlen = ETHER_HDR_LEN; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + IFQ_SET_READY(&ifp->if_snd); + + if_attach(ifp); + if_alloc_sadl(ifp); + +#if NBPFILTER > 0 + bpfattach(&sc->sc_if.if_bpf, ifp, + DLT_EN10MB, ETHER_HDR_LEN); +#endif + + s = splnet(); + LIST_INSERT_HEAD(&wire_list, sc, sc_list); + splx(s); + + return (0); +} + +int +wire_clone_destroy(struct ifnet *ifp) +{ + struct wire_softc *sc = ifp->if_softc; + int s; + + wire_stop(sc); + + s = splnet(); + LIST_REMOVE(sc, sc_list); + splx(s); + + if_detach(ifp); + + free(sc, M_DEVBUF); + return (0); +} + +int +wire_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +{ + struct ifwreq *req = (struct ifwreq *) data; + struct ifnet *ifs, *ifm; + struct ifreq *ifreq = (struct ifreq *) data; + struct wire_softc *sc; + int error = 0, s; + struct shim_hdr shim; + struct ifreq ifreq_aux; + + sc = ifp->if_softc; + s = splnet(); + switch (cmd) { + case SIOCSETLABEL: + if ((error = copyin(ifreq->ifr_data, &shim, sizeof(shim)))) + break; + if (shim.shim_label > MPLS_LABEL_MAX || + shim.shim_label <= MPLS_LABEL_RESERVED_MAX) { + error = EINVAL; + break; + } + shim.shim_label = htonl(shim.shim_label << MPLS_LABEL_OFFSET); + if (sc->sc_shim.shim_label == shim.shim_label) + break; + if (mpls_shim_label_exists(&shim)) { + error = EEXIST; + break; + } + if (sc->sc_shim.shim_label) { + /* remove old MPLS route */ + mpe_newlabel(ifp, RTM_DELETE, &sc->sc_shim); + } + /* add new MPLS route */ + error = mpe_newlabel(ifp, RTM_ADD, &shim); + if (error) + break; + sc->sc_shim.shim_label = shim.shim_label; + break; + + case SIOCGETLABEL: + bzero(&shim, sizeof(struct shim_hdr)); + shim.shim_label = + ((ntohl(sc->sc_shim.shim_label & MPLS_LABEL_MASK)) >> + MPLS_LABEL_OFFSET); + error = copyout(&shim, ifreq->ifr_data, sizeof(shim)); + break; + + case SIOCWIREADD: + if ((error = suser(curproc, 0)) != 0) + break; + + /* Get mpe output interface */ + ifs = ifunit(req->ifwr_ifsname); + ifm = ifunit(req->ifwr_mpename); + if (ifs == NULL || ifm == NULL) { + error = ENOENT; + break; + } + if (ifs->if_type != IFT_ETHER || + ifm->if_type != IFT_MPLS) { + error = EINVAL; + break; + } + + /* Set input interface to promiscuos mode */ + if ((ifs->if_flags & IFF_UP) == 0) { + /* + * Bring interface up long enough to set + * promiscuous flag, then shut it down again. + */ + strlcpy(ifreq_aux.ifr_name, req->ifwr_ifsname, + IFNAMSIZ); + ifs->if_flags |= IFF_UP; + ifreq_aux.ifr_flags = ifs->if_flags; + error = (*ifs->if_ioctl)(ifs, SIOCSIFFLAGS, + (caddr_t) &ifreq_aux); + if (error != 0) + break; + + error = ifpromisc(ifs, 1); + if (error != 0) + break; + + strlcpy(ifreq_aux.ifr_name, req->ifwr_ifsname, + IFNAMSIZ); + ifs->if_flags &= ~IFF_UP; + ifreq_aux.ifr_flags = ifs->if_flags; + error = (*ifs->if_ioctl)(ifs, SIOCSIFFLAGS, + (caddr_t) &ifreq_aux); + if (error != 0) { + ifpromisc(ifs, 0); + break; + } + } else { + error = ifpromisc(ifs, 1); + if (error != 0) + break; + } + + sc->sc_ifmpe = ifm; + sc->sc_ifs = ifs; + ifs->if_wire = (caddr_t) sc; + ifm->if_wire = (caddr_t) sc; + break; + + case SIOCWIREDEL: + if ((error = suser(curproc, 0)) != 0) + break; + + ifs = ifunit(req->ifwr_ifsname); + ifm = ifunit(req->ifwr_mpename); + if (ifs == NULL || ifm == NULL) { + error = ENOENT; + break; + } + if (ifs->if_wire == NULL || ifm->if_wire == NULL) { + error = ENXIO; + break; + } + wire_stop(sc); + ifs->if_wire = NULL; + ifm->if_wire = NULL; + sc->sc_ifs = NULL; + sc->sc_ifmpe = NULL; + break; + + case SIOCSIFFLAGS: + if ((ifp->if_flags & IFF_UP)) + wire_init(sc); + else + wire_stop(sc); + break; + + default: + error = ENOTTY; + break; + } + splx(s); + return (error); +} + +void +wire_ifdetach(struct ifnet *ifp) +{ + struct wire_softc *sc; + + sc = (struct wire_softc *) ifp->if_wire; + if (sc->sc_ifs) { + sc->sc_ifs->if_wire = NULL; + sc->sc_ifs = NULL; + } + if (sc->sc_ifmpe) { + sc->sc_ifmpe->if_wire = NULL; + sc->sc_ifmpe = NULL; + } + + wire_stop(sc); + ifpromisc(ifp, 0); +} + +void +wire_init(struct wire_softc *sc) +{ + struct ifnet *ifp = &sc->sc_if; + + if ((ifp->if_flags & IFF_RUNNING) == IFF_RUNNING) + return; + + ifp->if_flags |= IFF_RUNNING; +} + +void +wire_stop(struct wire_softc *sc) +{ + struct ifnet *ifp = &sc->sc_if; + + if ((ifp->if_flags & IFF_RUNNING) == 0) + return; + + ifp->if_flags &= ~IFF_RUNNING; +} + +int +wire_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa, + struct rtentry *rt) +{ + if ((ifp->if_flags & IFF_RUNNING) == 0) { + m_freem(m); + return (0); + } + + /* TODO */ + + m_freem(m); + return (EPFNOSUPPORT); +} + +void +wire_start(struct ifnet *ifp) +{ + struct mbuf *m; + int s; + + if ((ifp->if_flags & IFF_RUNNING) == 0) + return; + + for (;;) { + s = splnet(); + IFQ_DEQUEUE(&ifp->if_snd, m); + splx(s); + + if (m == NULL) + return; + + /* TODO */ + + m_freem(m); + } +} + +void +wire_input(struct mbuf *m, struct ether_header *eh, struct wire_softc *sc) +{ + struct ether_header *aux; + struct shim_hdr shim, *sptr; + int s; + + if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) + return; + + /* Don't accept packets if there is no way to output them later */ + if (sc->sc_ifmpe == NULL) { + sc->sc_if.if_ierrors++; + m_freem(m); + return; + } + + /* Copy the encapsulated ethernet header */ + M_PREPEND(m, sizeof(struct ether_header), M_NOWAIT); + if (m == NULL) + return; + + aux = mtod(m, struct ether_header *); + bcopy(eh, aux, sizeof(struct ether_header)); + + /* Add our MPLS shim */ + M_PREPEND(m, sizeof(struct shim_hdr), M_NOWAIT); + if (m == NULL) + return; + + /* Set our protection against last time modifications and + * enqueue packet to ourselves, to send later through mpe(4). + */ + bzero(&shim, sizeof(shim)); + shim.shim_label |= htonl(mpls_defttl) & MPLS_TTL_MASK; + shim.shim_label |= sc->sc_shim.shim_label; + + sptr = mtod(m, struct shim_hdr *); + bcopy(&shim, sptr, sizeof(struct shim_hdr)); + s = splnet(); + IF_ENQUEUE(&sc->sc_ifmpe->if_snd, m); + splx(s); + + return; +} --- /dev/null Mon Aug 27 00:22:43 2012 +++ net/if_wire.h Tue Aug 21 21:10:19 2012 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2012 Rafael F. Zalamena <rzalam...@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _NET_IF_WIRE_H_ +#define _NET_IF_WIRE_H_ + +struct ifwreq { + char ifwr_name[IFNAMSIZ]; + char ifwr_ifsname[IFNAMSIZ]; + char ifwr_mpename[IFNAMSIZ]; +}; + +struct wire_softc { + struct ifnet sc_if; /* the interface */ + struct ifnet *sc_ifmpe; /* Interfaces to exchange packets */ + struct ifnet *sc_ifs; + struct shim_hdr sc_shim; + + LIST_ENTRY(wire_softc) sc_list; /* linked wire list */ +}; + +void wire_ifdetach(struct ifnet *); + +#endif /* _NET_IF_WIRE_H_ */ Index: conf/GENERIC =================================================================== RCS file: /backup/obsd_cvs//src/sys/conf/GENERIC,v retrieving revision 1.190 diff -u -r1.190 GENERIC --- conf/GENERIC 23 Aug 2012 06:12:49 -0000 1.190 +++ conf/GENERIC 27 Aug 2012 03:24:30 -0000 @@ -65,6 +65,7 @@ option MROUTING # Multicast router #option PIM # Protocol Independent Multicast option MPLS # Multi-Protocol Label Switching +option WIRE_DEBUG # Wire debugging messages #mpath0 at root # SCSI Multipathing #scsibus* at mpath? @@ -92,6 +93,7 @@ # clonable devices pseudo-device bpfilter # packet filter pseudo-device bridge # network bridging support +pseudo-device wire # pseudowire support pseudo-device carp # CARP protocol support pseudo-device gif # IPv[46] over IPv[46] tunnel (RFC1933) pseudo-device gre # GRE encapsulation interface Index: conf/files =================================================================== RCS file: /backup/obsd_cvs//src/sys/conf/files,v retrieving revision 1.538 diff -u -r1.538 files --- conf/files 23 Aug 2012 06:12:49 -0000 1.538 +++ conf/files 27 Aug 2012 03:24:30 -0000 @@ -518,6 +518,7 @@ pseudo-device bpfilter: ifnet pseudo-device enc: ifnet pseudo-device bridge: ifnet, ether +pseudo-device wire: ifnet, ether pseudo-device vlan: ifnet, ether pseudo-device carp: ifnet, ether pseudo-device sppp: ifnet @@ -758,6 +759,7 @@ file net/if_bridge.c bridge needs-count file net/bridgestp.c bridge file net/if_vlan.c vlan needs-count +file net/if_wire.c wire needs-count file net/pipex.c pipex file net/radix.c file net/radix_mpath.c !small_kernel Index: net/if.c =================================================================== RCS file: /backup/obsd_cvs//src/sys/net/if.c,v retrieving revision 1.241 diff -u -r1.241 if.c --- net/if.c 3 Jan 2012 23:41:51 -0000 1.241 +++ net/if.c 27 Aug 2012 03:24:30 -0000 @@ -124,6 +124,10 @@ #include <net/if_bridge.h> #endif +#if NWIRE > 0 +#include <net/if_wire.h> +#endif + #if NCARP > 0 #include <netinet/ip_carp.h> #endif @@ -533,6 +537,10 @@ /* Remove the interface from any bridge it is part of. */ if (ifp->if_bridge) bridge_ifdetach(ifp); +#endif +#if NWIRE > 0 + if (ifp->if_wire) + wire_ifdetach(ifp); #endif #if NCARP > 0 Index: net/if.h =================================================================== RCS file: /backup/obsd_cvs//src/sys/net/if.h,v retrieving revision 1.132 diff -u -r1.132 if.h --- net/if.h 21 Aug 2012 19:50:39 -0000 1.132 +++ net/if.h 27 Aug 2012 03:24:30 -0000 @@ -251,6 +251,7 @@ int if_pcount; /* number of promiscuous listeners */ caddr_t if_bpf; /* packet filter structure */ caddr_t if_bridge; /* bridge structure */ + caddr_t if_wire; /* wire structure */ caddr_t if_tp; /* used by trunk ports */ caddr_t if_pf_kif; /* pf interface abstraction */ union { Index: net/if_ethersubr.c =================================================================== RCS file: /backup/obsd_cvs//src/sys/net/if_ethersubr.c,v retrieving revision 1.151 diff -u -r1.151 if_ethersubr.c --- net/if_ethersubr.c 9 Jul 2011 00:47:18 -0000 1.151 +++ net/if_ethersubr.c 27 Aug 2012 03:24:30 -0000 @@ -500,6 +500,14 @@ m_freem(m); return; } + +#if NWIRE > 0 + if (ifp->if_wire) { + wire_input(m, eh, ifp->if_wire); + return; + } +#endif + if (ETHER_IS_MULTICAST(eh->ether_dhost)) { if ((ifp->if_flags & IFF_SIMPLEX) == 0) { struct ifaddr *ifa; Index: net/if_mpe.c =================================================================== RCS file: /backup/obsd_cvs//src/sys/net/if_mpe.c,v retrieving revision 1.27 diff -u -r1.27 if_mpe.c --- net/if_mpe.c 14 Apr 2012 09:39:47 -0000 1.27 +++ net/if_mpe.c 27 Aug 2012 03:24:30 -0000 @@ -51,6 +51,8 @@ #include <netmpls/mpls.h> +#include <net/if_mpe.h> + #ifdef MPLS_DEBUG #define DPRINTF(x) do { if (mpedebug) printf x ; } while (0) #else @@ -324,12 +326,9 @@ shim.shim_label = htonl(shim.shim_label << MPLS_LABEL_OFFSET); if (ifm->sc_shim.shim_label == shim.shim_label) break; - LIST_FOREACH(ifm, &mpeif_list, sc_list) { - if (ifm != ifp->if_softc && - ifm->sc_shim.shim_label == shim.shim_label) { - error = EEXIST; - break; - } + if (mpls_shim_label_exists(&shim)) { + error = EEXIST; + break; } if (error) break; Index: netmpls/mpls.h =================================================================== RCS file: /backup/obsd_cvs//src/sys/netmpls/mpls.h,v retrieving revision 1.25 diff -u -r1.25 mpls.h --- netmpls/mpls.h 8 Sep 2010 08:00:56 -0000 1.25 +++ netmpls/mpls.h 27 Aug 2012 03:24:30 -0000 @@ -145,13 +145,6 @@ #ifdef _KERNEL -struct mpe_softc { - struct ifnet sc_if; /* the interface */ - int sc_unit; - struct shim_hdr sc_shim; - LIST_ENTRY(mpe_softc) sc_list; -}; - #define MPE_HDRLEN sizeof(struct shim_hdr) #define MPE_MTU 1500 #define MPE_MTU_MIN 256 @@ -175,6 +168,7 @@ void mpls_init(void); void mplsintr(void); +int mpls_shim_label_exists(struct shim_hdr *); struct mbuf *mpls_shim_pop(struct mbuf *); struct mbuf *mpls_shim_swap(struct mbuf *, struct rt_mpls *); struct mbuf *mpls_shim_push(struct mbuf *, struct rt_mpls *); Index: netmpls/mpls_shim.c =================================================================== RCS file: /backup/obsd_cvs//src/sys/netmpls/mpls_shim.c,v retrieving revision 1.6 diff -u -r1.6 mpls_shim.c --- netmpls/mpls_shim.c 28 Jan 2009 22:18:44 -0000 1.6 +++ netmpls/mpls_shim.c 27 Aug 2012 03:24:30 -0000 @@ -42,6 +42,30 @@ #include <netmpls/mpls.h> +#include <net/if_mpe.h> +#include <net/if_wire.h> + +int +mpls_shim_label_exists(struct shim_hdr *shim) +{ + extern LIST_HEAD(, mpe_softc) mpeif_list; + extern LIST_HEAD(, wire_softc) wire_list; + + struct mpe_softc *mpe_sc; + struct wire_softc *wr_sc; + + LIST_FOREACH(mpe_sc, &mpeif_list, sc_list) { + if (shim->shim_label == mpe_sc->sc_shim.shim_label) + return (1); + } + + LIST_FOREACH(wr_sc, &wire_list, sc_list) { + if (shim->shim_label == wr_sc->sc_shim.shim_label) + return (1); + } + return (0); +} + struct mbuf * mpls_shim_pop(struct mbuf *m) { Index: sys/sockio.h =================================================================== RCS file: /backup/obsd_cvs//src/sys/sys/sockio.h,v retrieving revision 1.49 diff -u -r1.49 sockio.h --- sys/sockio.h 26 Nov 2011 23:38:18 -0000 1.49 +++ sys/sockio.h 27 Aug 2012 03:24:30 -0000 @@ -181,6 +181,9 @@ #define SIOCSETKALIVE _IOW('i', 163, struct ifkalivereq) #define SIOCGETKALIVE _IOWR('i', 164, struct ifkalivereq) +#define SIOCWIREADD _IOW('i', 165, struct ifwreq) /* add wire ifs */ +#define SIOCWIREDEL _IOW('i', 166, struct ifwreq) /* del wire ifs */ + #define SIOCSVH _IOWR('i', 245, struct ifreq) /* set carp param */ #define SIOCGVH _IOWR('i', 246, struct ifreq) /* get carp param */