diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2019-02-15 01:06:39 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2019-02-15 01:06:39 +0000 |
commit | 2123b9e382ebf7e59538d92745ff9c9417a53403 (patch) | |
tree | 3fa3624f1f7f8a992f4618f10155e63a0b341894 /sys | |
parent | a2ba4cc48d47c6b9099a51b953c006ad5eaa820b (diff) |
allow configuration of the rdomain that mpls operates in
this is based on the changes to mpe i made yesterday. unfortunately
mpw has a monstor ioctl that configures all the things, which makes
the kernel side complicated. hopefully i can split them up.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if_mpw.c | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/sys/net/if_mpw.c b/sys/net/if_mpw.c index 53f5803932c..edde0672b66 100644 --- a/sys/net/if_mpw.c +++ b/sys/net/if_mpw.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mpw.c,v 1.36 2019/02/14 03:29:46 dlg Exp $ */ +/* $OpenBSD: if_mpw.c,v 1.37 2019/02/15 01:06:38 dlg Exp $ */ /* * Copyright (c) 2015 Rafael Zalamena <rzalamena@openbsd.org> @@ -48,6 +48,7 @@ struct mpw_softc { struct arpcom sc_ac; #define sc_if sc_ac.ac_if + unsigned int sc_rdomain; struct ifaddr sc_ifa; struct sockaddr_mpls sc_smpls; /* Local label */ @@ -103,6 +104,7 @@ mpw_clone_create(struct if_clone *ifc, int unit) if_attach(ifp); ether_ifattach(ifp); + 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); @@ -120,7 +122,7 @@ mpw_clone_destroy(struct ifnet *ifp) if (sc->sc_smpls.smpls_label) { rt_ifa_del(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL, - smplstosa(&sc->sc_smpls), 0); + smplstosa(&sc->sc_smpls), sc->sc_rdomain); } ether_ifdetach(ifp); @@ -132,6 +134,27 @@ mpw_clone_destroy(struct ifnet *ifp) } int +mpw_set_label(struct mpw_softc *sc, uint32_t label, unsigned int rdomain) +{ + int error; + + if (sc->sc_smpls.smpls_label) { + rt_ifa_del(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL, + smplstosa(&sc->sc_smpls), sc->sc_rdomain); + } + + 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 != 0) + sc->sc_smpls.smpls_label = 0; + + return (0); +} + +int mpw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct ifreq *ifr = (struct ifreq *) data; @@ -193,17 +216,10 @@ mpw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) MPLS_LABEL2SHIM(imr.imr_rshim.shim_label); if (sc->sc_smpls.smpls_label != imr.imr_lshim.shim_label) { - if (sc->sc_smpls.smpls_label) - rt_ifa_del(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL, - smplstosa(&sc->sc_smpls), 0); - - sc->sc_smpls.smpls_label = imr.imr_lshim.shim_label; - error = rt_ifa_add(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL, - smplstosa(&sc->sc_smpls), 0); - if (error != 0) { - sc->sc_smpls.smpls_label = 0; + error = mpw_set_label(sc, imr.imr_lshim.shim_label, + sc->sc_rdomain); + if (error != 0) break; - } } /* Apply configuration */ @@ -232,6 +248,24 @@ mpw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) error = copyout(&imr, ifr->ifr_data, sizeof(imr)); 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) { + error = mpw_set_label(sc, sc->sc_smpls.smpls_label, + ifr->ifr_rdomainid); + } + break; + case SIOCGLIFPHYRTABLE: + ifr->ifr_rdomainid = sc->sc_rdomain; + break; + + case SIOCADDMULTI: case SIOCDELMULTI: break; @@ -311,7 +345,7 @@ mpw_input(struct mpw_softc *sc, struct mbuf *m) if (n == NULL) return; m = n; - } + } ml_enqueue(&ml, m); if_input(ifp, &ml); @@ -355,7 +389,7 @@ mpw_start(struct ifnet *ifp) return; } - rt = rtalloc(sstosa(&sc->sc_nexthop), RT_RESOLVE, 0); + rt = rtalloc(sstosa(&sc->sc_nexthop), RT_RESOLVE, sc->sc_rdomain); if (!rtisvalid(rt)) { IFQ_PURGE(&ifp->if_snd); goto rtfree; |