diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2019-02-14 00:49:05 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2019-02-14 00:49:05 +0000 |
commit | 5f5f02f92cfa29c2ac02549129e8c92f87899dd9 (patch) | |
tree | 8b84bbbc5bbe14a144a78519eb52f3aae1673946 /sys/net | |
parent | 493d832ea3cc4182790b215901a5b52609548b25 (diff) |
allow configuration of the rdomain the mpls encap operates in
this borrows the SIOCSLIFPHYRTABLE and SIOCGLIFPHYRTABLE that tunnel
interfaces implement to set the rdomain mpls operates in.
ifconfig tunneldomain X lets you set it, and you can see the effect
with netstat -nr -f mpls -TX, but ifconfig currently doesnt show
the tunneldomain. yet.
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if_mpe.c | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/sys/net/if_mpe.c b/sys/net/if_mpe.c index d2a9d5448ed..a516415de3d 100644 --- a/sys/net/if_mpe.c +++ b/sys/net/if_mpe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mpe.c,v 1.82 2019/02/13 23:55:56 dlg Exp $ */ +/* $OpenBSD: if_mpe.c,v 1.83 2019/02/14 00:49:04 dlg Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@spootnik.org> @@ -55,6 +55,7 @@ struct mpe_softc { struct ifnet sc_if; /* the interface */ + unsigned int sc_rdomain; struct ifaddr sc_ifa; struct sockaddr_mpls sc_smpls; }; @@ -115,6 +116,7 @@ mpe_clone_create(struct if_clone *ifc, int unit) bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t)); #endif + sc->sc_rdomain = 0; sc->sc_ifa.ifa_ifp = ifp; sc->sc_ifa.ifa_addr = sdltosa(ifp->if_sadl); sc->sc_smpls.smpls_len = sizeof(sc->sc_smpls); @@ -129,8 +131,8 @@ mpe_clone_destroy(struct ifnet *ifp) struct mpe_softc *sc = ifp->if_softc; if (sc->sc_smpls.smpls_label) { - rt_ifa_del(&sc->sc_ifa, RTF_MPLS, - smplstosa(&sc->sc_smpls), 0); + rt_ifa_del(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL, + smplstosa(&sc->sc_smpls), sc->sc_rdomain); } if_detach(ifp); @@ -274,6 +276,29 @@ out: } int +mpe_set_label(struct mpe_softc *sc, uint32_t label, unsigned int rdomain) +{ + int error; + + if (sc->sc_smpls.smpls_label) { + /* remove old MPLS route */ + rt_ifa_del(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL, + smplstosa(&sc->sc_smpls), sc->sc_rdomain); + } + + /* add new MPLS route */ + sc->sc_smpls.smpls_label = label; + sc->sc_rdomain = rdomain; + + error = rt_ifa_add(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL, + smplstosa(&sc->sc_smpls), sc->sc_rdomain); + if (error) + sc->sc_smpls.smpls_label = 0; + + return (error); +} + +int mpe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct mpe_softc *sc = ifp->if_softc; @@ -313,20 +338,26 @@ mpe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) shim.shim_label = MPLS_LABEL2SHIM(shim.shim_label); if (sc->sc_smpls.smpls_label == shim.shim_label) break; - if (sc->sc_smpls.smpls_label) { - /* remove old MPLS route */ - rt_ifa_del(&sc->sc_ifa, RTF_MPLS, - smplstosa(&sc->sc_smpls), 0); - } - /* add new MPLS route */ - sc->sc_smpls.smpls_label = shim.shim_label; - error = rt_ifa_add(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL, - smplstosa(&sc->sc_smpls), 0); - if (error) { - sc->sc_smpls.smpls_label = 0; + error = mpe_set_label(sc, shim.shim_label, sc->sc_rdomain); + break; + case SIOCSLIFPHYRTABLE: + if (ifr->ifr_rdomainid < 0 || + ifr->ifr_rdomainid > RT_TABLEID_MAX || + !rtable_exists(ifr->ifr_rdomainid) || + ifr->ifr_rdomainid != rtable_l2(ifr->ifr_rdomainid)) { + error = EINVAL; break; } + if (sc->sc_rdomain == ifr->ifr_rdomainid) + break; + + error = mpe_set_label(sc, sc->sc_smpls.smpls_label, + ifr->ifr_rdomainid); break; + case SIOCGLIFPHYRTABLE: + ifr->ifr_rdomainid = sc->sc_rdomain; + break; + default: return (ENOTTY); } |