> On 23 Oct 2015, at 09:00, Reyk Floeter <r...@openbsd.org> wrote: > > Hi, > > this diff allows to interconnect routing domains. > > It is very useful to route traffic from one routing domain to another, > without using the pf "rtable" hack (tested in production for a long > time). > > eg., > # ifconfig vether0 10.0.1.1/24 > # ifconfig vether1 rdomain 1 10.0.1.2/24 > # ping 10.1.1.2 > # route -T 1 add default 10.0.1.1 > # ifconfig bridge0 add vether0 add em0 > > for hacking/testing, you can do thing like: > # dhcpd vether0 > # dhclient vether1 > > It has been discussed in much detail if this is possible with > bridge(4). It is not. The bridge is not designed for it and explain > on request.
the diff implements a crossover option, but the example above doesnt use them. does that mean you can use a bridge to build crossovers without the extra code, or the example is wrong? > > OK? > > Reyk > > Index: sbin/ifconfig/ifconfig.8 > =================================================================== > RCS file: /cvs/src/sbin/ifconfig/ifconfig.8,v > retrieving revision 1.257 > diff -u -p -u -p -r1.257 ifconfig.8 > --- sbin/ifconfig/ifconfig.8 6 Oct 2015 17:23:21 -0000 1.257 > +++ sbin/ifconfig/ifconfig.8 22 Oct 2015 22:33:40 -0000 > @@ -1560,6 +1560,33 @@ The accepted size of the number depends > it is a 24-bit number for > .Xr vxlan 4 . > .El > +.\" VETHER > +.Sh VETHER > +.nr nS 1 > +.Bk -words > +.Nm ifconfig > +.Ar vether-interface > +.Op Oo Fl Oc Ns Cm crossover Ar interface > +.Ek > +.nr nS 0 > +.Pp > +The following options are available for a > +.Xr vether 4 > +interface: > +.Bl -tag -width Ds > +.It Cm crossover Ar interface > +Create a virtual crossover link with another > +.Xr vether 4 > +interface. > +Any outgoing packets from the > +.Ar vether-interface > +will be received by the crossover > +.Ar interface > +and vice versa. > +This link allows to interconnect two routing domains locally. > +.It Fl crossover > +If configured, disconnect the virtual crossover link. > +.El > .\" VLAN > .Sh VLAN > .nr nS 1 > Index: sbin/ifconfig/ifconfig.c > =================================================================== > RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v > retrieving revision 1.302 > diff -u -p -u -p -r1.302 ifconfig.c > --- sbin/ifconfig/ifconfig.c 3 Oct 2015 10:44:23 -0000 1.302 > +++ sbin/ifconfig/ifconfig.c 22 Oct 2015 22:33:41 -0000 > @@ -275,6 +275,8 @@ void setifipdst(const char *, int); > void setifdesc(const char *, int); > void unsetifdesc(const char *, int); > void printifhwfeatures(const char *, int); > +void setxover(const char *, int); > +void unsetxover(const char *, int); > #else > void setignore(const char *, int); > #endif > @@ -490,6 +492,8 @@ const struct cmd { > { "-descr", 1, 0, unsetifdesc }, > { "wol", IFXF_WOL, 0, setifxflags }, > { "-wol", -IFXF_WOL, 0, setifxflags }, > + { "crossover", NEXTARG, 0, setxover }, > + { "-crossover", 1, 0, unsetxover }, > #else /* SMALL */ > { "powersave", NEXTARG0, 0, setignore }, > { "priority", NEXTARG, 0, setignore }, > @@ -2917,6 +2921,7 @@ status(int link, struct sockaddr_dl *sdl > struct ifreq ifrdesc; > struct ifkalivereq ikardesc; > char ifdescr[IFDESCRSIZE]; > + char ifname[IF_NAMESIZE]; > #endif > uint64_t *media_list; > int i; > @@ -2955,6 +2960,9 @@ status(int link, struct sockaddr_dl *sdl > (ikardesc.ikar_timeo != 0 || ikardesc.ikar_cnt != 0)) > printf("\tkeepalive: timeout %d count %d\n", > ikardesc.ikar_timeo, ikardesc.ikar_cnt); > + if (ioctl(s, SIOCGXOVER, &ifrdesc) == 0 && ifrdesc.ifr_index != 0 && > + if_indextoname(ifrdesc.ifr_index, ifname) != NULL) > + printf("\tcrossover: %s\n", ifname); > #endif > vlan_status(); > #ifndef SMALL > @@ -5199,6 +5207,29 @@ setinstance(const char *id, int param) > ifr.ifr_rdomainid = rdomainid; > if (ioctl(s, SIOCSIFRDOMAIN, (caddr_t)&ifr) < 0) > warn("SIOCSIFRDOMAIN"); > +} > +#endif > + > +#ifndef SMALL > +void > +setxover(const char *val, int d) > +{ > + strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); > + if ((ifr.ifr_index = if_nametoindex(val)) == 0) { > + errno = ENOENT; > + err(1, "crossover %s", val); > + } > + if (ioctl(s, SIOCSXOVER, (caddr_t)&ifr) < 0) > + warn("SIOCSXOVER"); > +} > + > +void > +unsetxover(const char *val, int d) > +{ > + ifr.ifr_index = 0; > + strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); > + if (ioctl(s, SIOCSXOVER, (caddr_t)&ifr) < 0) > + warn("SIOCSXOVER"); > } > #endif > > Index: sys/net/if.c > =================================================================== > RCS file: /cvs/src/sys/net/if.c,v > retrieving revision 1.391 > diff -u -p -u -p -r1.391 if.c > --- sys/net/if.c 22 Oct 2015 15:37:47 -0000 1.391 > +++ sys/net/if.c 22 Oct 2015 22:33:42 -0000 > @@ -1794,6 +1794,7 @@ ifioctl(struct socket *so, u_long cmd, c > case SIOCDELMULTI: > case SIOCSIFMEDIA: > case SIOCSVNETID: > + case SIOCSXOVER: > if ((error = suser(p, 0)) != 0) > return (error); > /* FALLTHROUGH */ > @@ -1804,6 +1805,7 @@ ifioctl(struct socket *so, u_long cmd, c > case SIOCGLIFPHYTTL: > case SIOCGIFMEDIA: > case SIOCGVNETID: > + case SIOCGXOVER: > if (ifp->if_ioctl == 0) > return (EOPNOTSUPP); > error = (*ifp->if_ioctl)(ifp, cmd, data); > Index: sys/net/if.h > =================================================================== > RCS file: /cvs/src/sys/net/if.h,v > retrieving revision 1.169 > diff -u -p -u -p -r1.169 if.h > --- sys/net/if.h 5 Oct 2015 15:19:29 -0000 1.169 > +++ sys/net/if.h 22 Oct 2015 22:33:42 -0000 > @@ -356,6 +356,7 @@ struct ifreq { > int ifru_metric; > uint64_t ifru_media; > caddr_t ifru_data; > + unsigned int ifru_index; > } ifr_ifru; > #define ifr_addr ifr_ifru.ifru_addr /* address */ > #define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p > link */ > @@ -369,6 +370,7 @@ struct ifreq { > #define ifr_vnetid ifr_ifru.ifru_metric /* Virtual Net Id (overload) */ > #define ifr_ttl ifr_ifru.ifru_metric /* tunnel TTL > (overload) */ > #define ifr_data ifr_ifru.ifru_data /* for use by interface > */ > +#define ifr_index ifr_ifru.ifru_index /* interface index */ > }; > > struct ifaliasreq { > Index: sys/net/if_var.h > =================================================================== > RCS file: /cvs/src/sys/net/if_var.h,v > retrieving revision 1.48 > diff -u -p -u -p -r1.48 if_var.h > --- sys/net/if_var.h 12 Oct 2015 13:17:58 -0000 1.48 > +++ sys/net/if_var.h 22 Oct 2015 22:33:42 -0000 > @@ -431,6 +431,9 @@ void if_clone_detach(struct if_clone *); > int if_clone_create(const char *); > int if_clone_destroy(const char *); > > +struct if_clone * > + if_clone_lookup(const char *, int *); > + > int sysctl_mq(int *, u_int, void *, size_t *, void *, size_t, > struct mbuf_queue *); > > Index: sys/net/if_vether.c > =================================================================== > RCS file: /cvs/src/sys/net/if_vether.c,v > retrieving revision 1.24 > diff -u -p -u -p -r1.24 if_vether.c > --- sys/net/if_vether.c 23 May 2015 08:31:05 -0000 1.24 > +++ sys/net/if_vether.c 22 Oct 2015 22:33:42 -0000 > @@ -45,6 +45,7 @@ void vether_media_status(struct ifnet *, > struct vether_softc { > struct arpcom sc_ac; > struct ifmedia sc_media; > + unsigned int sc_crossover; > }; > > struct if_clone vether_cloner = > @@ -106,11 +107,20 @@ int > vether_clone_destroy(struct ifnet *ifp) > { > struct vether_softc *sc = ifp->if_softc; > + struct ifnet *dstifp; > + struct vether_softc *dstsc = ifp->if_softc; > + > + if ((dstifp = if_get(sc->sc_crossover)) != NULL) { > + dstsc = dstifp->if_softc; > + dstsc->sc_crossover = 0; > + if_put(dstifp); > + } > > ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY); > ether_ifdetach(ifp); > if_detach(ifp); > free(sc, M_DEVBUF, sizeof(*sc)); > + > return (0); > } > > @@ -121,12 +131,17 @@ vether_clone_destroy(struct ifnet *ifp) > void > vetherstart(struct ifnet *ifp) > { > + struct vether_softc *sc = (struct vether_softc *)ifp->if_softc; > + struct mbuf_list ml = MBUF_LIST_INITIALIZER(); > + struct ifnet *dstifp; > struct mbuf *m; > > + dstifp = if_get(sc->sc_crossover); > + > for (;;) { > IFQ_DEQUEUE(&ifp->if_snd, m); > if (m == NULL) > - return; > + break; > > #if NBPFILTER > 0 > if (ifp->if_bpf) > @@ -134,7 +149,15 @@ vetherstart(struct ifnet *ifp) > #endif /* NBPFILTER > 0 */ > > ifp->if_opackets++; > - m_freem(m); > + if (dstifp != NULL) > + ml_enqueue(&ml, m); > + else > + m_freem(m); > + } > + > + if (dstifp != NULL) { > + if_input(dstifp, &ml); > + if_put(dstifp); > } > } > > @@ -145,7 +168,10 @@ vetherioctl(struct ifnet *ifp, u_long cm > struct vether_softc *sc = (struct vether_softc *)ifp->if_softc; > struct ifaddr *ifa = (struct ifaddr *)data; > struct ifreq *ifr = (struct ifreq *)data; > - int error = 0, link_state; > + struct if_clone *ifc; > + struct vether_softc *dstsc = ifp->if_softc; > + struct ifnet *dstifp; > + int error = 0, link_state, unit; > > switch (cmd) { > case SIOCSIFADDR: > @@ -175,6 +201,45 @@ vetherioctl(struct ifnet *ifp, u_long cm > case SIOCGIFMEDIA: > case SIOCSIFMEDIA: > error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); > + break; > + > + case SIOCSXOVER: > + /* First disconnect the connected interface */ > + if ((dstifp = if_get(sc->sc_crossover)) != NULL) { > + dstsc = dstifp->if_softc; > + dstsc->sc_crossover = 0; > + if_put(dstifp); > + dstifp = NULL; > + } > + > + /* Now disconnect the local interface */ > + if (ifr->ifr_index == 0) { > + sc->sc_crossover = 0; > + break; > + } > + > + /* And find the new interface */ > + if ((dstifp = if_get(ifr->ifr_index)) == NULL) { > + error = ENOENT; > + break; > + } > + > + /* Only allow vether(4) interfaces for the crossover */ > + if ((ifc = if_clone_lookup(dstifp->if_xname, &unit)) == NULL || > + strcmp("vether", ifc->ifc_name) != 0) { > + if_put(dstifp); > + error = ENODEV; > + break; > + } > + > + sc->sc_crossover = ifr->ifr_index; > + dstsc = dstifp->if_softc; > + dstsc->sc_crossover = ifp->if_index; > + if_put(dstifp); > + break; > + > + case SIOCGXOVER: > + ifr->ifr_index = sc->sc_crossover; > break; > > default: > Index: sys/sys/sockio.h > =================================================================== > RCS file: /cvs/src/sys/sys/sockio.h,v > retrieving revision 1.60 > diff -u -p -u -p -r1.60 sockio.h > --- sys/sys/sockio.h 11 Sep 2015 13:02:28 -0000 1.60 > +++ sys/sys/sockio.h 22 Oct 2015 22:33:42 -0000 > @@ -194,6 +194,9 @@ > #define SIOCSETMPWCFG _IOW('i', 173, struct ifreq) /* set mpw config */ > #define SIOCGETMPWCFG _IOWR('i', 174, struct ifreq) /* get mpw config */ > > +#define SIOCSXOVER _IOW('i', 175, struct ifreq) /* set crossover if */ > +#define SIOCGXOVER _IOWR('i', 176, struct ifreq) /* get crossover if */ > + > #define SIOCSVH _IOWR('i', 245, struct ifreq) /* set carp > param */ > #define SIOCGVH _IOWR('i', 246, struct ifreq) /* get carp > param */ > >