Hello Rafael,
On 14/09/14(Sun) 23:49, Rafael Zalamena wrote:
> The following patch is just a preparation for the code that is coming to
> implement the wire network interface (the VPLS datapath) to work on OpenBSD.
>
> This code turns the mpe code that handles route and labels into some general
> use functions that will be called by mpe and wire.
Would it be possible to use the new rt_ifa_add() and rt_ifa_del() instead of
keeping what is basically a copy of the old rtinit()?
In your case you want to use the lladdr's ifa and you can check for
RTF_MPLS in the flags to add the corresponding MPLS_OP_POP value.
> diff --git sys/net/if_mpe.c sys/net/if_mpe.c
> index 74039dc..98d69f4 100644
> --- sys/net/if_mpe.c
> +++ sys/net/if_mpe.c
> @@ -61,7 +61,6 @@ int mpeioctl(struct ifnet *, u_long, caddr_t);
> void mpestart(struct ifnet *);
> int mpe_clone_create(struct if_clone *, int);
> int mpe_clone_destroy(struct ifnet *);
> -int mpe_newlabel(struct ifnet *, int, struct shim_hdr *);
>
> LIST_HEAD(, mpe_softc) mpeif_list;
> struct if_clone mpe_cloner =
> @@ -319,36 +318,17 @@ mpeioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
> break;
> }
> 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 (error)
> - break;
> - ifm = ifp->if_softc;
> - if (ifm->sc_shim.shim_label) {
> - /* remove old MPLS route */
> - mpe_newlabel(ifp, RTM_DELETE, &ifm->sc_shim);
> - }
> - /* add new MPLS route */
> - error = mpe_newlabel(ifp, RTM_ADD, &shim);
> - if (error)
> - break;
> - ifm->sc_shim.shim_label = shim.shim_label;
> + error = mpls_shim_set(ifp, &shim, &ifm->sc_shim);
> break;
> case SIOCSIFRDOMAIN:
> /* must readd the MPLS "route" for our label */
> ifm = ifp->if_softc;
> if (ifr->ifr_rdomainid != ifp->if_rdomain) {
> - if (ifm->sc_shim.shim_label) {
> - shim.shim_label = ifm->sc_shim.shim_label;
> - error = mpe_newlabel(ifp, RTM_ADD, &shim);
> - }
> + shim.shim_label = ifm->sc_shim.shim_label;
> +
> + /* XXX trick mpls_shim_set() to reinstall the route */
> + bzero(&ifm->sc_shim, sizeof(ifm->sc_shim));
> + error = mpls_shim_set(ifp, &shim, &ifm->sc_shim);
> }
> /* return with ENOTTY so that the parent handler finishes */
> return (ENOTTY);
> @@ -444,36 +424,13 @@ mpe_input6(struct mbuf *m, struct ifnet *ifp, struct
> sockaddr_mpls *smpls,
> #endif /* INET6 */
>
> int
> -mpe_newlabel(struct ifnet *ifp, int cmd, struct shim_hdr *shim)
> +mpe_label_exists(const struct shim_hdr *shim)
> {
> - struct rtentry *nrt;
> - struct sockaddr_mpls dst;
> - struct rt_addrinfo info;
> - int error;
> -
> - bzero(&dst, sizeof(dst));
> - dst.smpls_len = sizeof(dst);
> - dst.smpls_family = AF_MPLS;
> - dst.smpls_label = shim->shim_label;
> -
> - bzero(&info, sizeof(info));
> - info.rti_flags = RTF_UP | RTF_MPLS;
> - info.rti_mpls = MPLS_OP_POP;
> - info.rti_info[RTAX_DST] = smplstosa(&dst);
> - info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)ifp->if_sadl;
> -
> - error = rtrequest1(cmd, &info, RTP_CONNECTED, &nrt, 0);
> - rt_missmsg(cmd, &info, error ? 0 : nrt->rt_flags, ifp, error, 0);
> - if (cmd == RTM_DELETE) {
> - if (error == 0 && nrt != NULL) {
> - if (nrt->rt_refcnt <= 0) {
> - nrt->rt_refcnt++;
> - rtfree(nrt);
> - }
> - }
> - }
> - if (cmd == RTM_ADD && error == 0 && nrt != NULL) {
> - nrt->rt_refcnt--;
> - }
> - return (error);
> + struct mpe_softc *mpe_sc;
> +
> + LIST_FOREACH(mpe_sc, &mpeif_list, sc_list)
> + if (shim->shim_label == mpe_sc->sc_shim.shim_label)
> + return (1);
> +
> + return (0);
> }
> diff --git sys/netmpls/mpls.h sys/netmpls/mpls.h
> index 2903aa4..0363d86 100644
> --- sys/netmpls/mpls.h
> +++ sys/netmpls/mpls.h
> @@ -176,9 +176,13 @@ extern int mpls_inkloop;
> void mpls_init(void);
> void mplsintr(void);
>
> +int mpe_label_exists(const 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 *);
> +int mpls_shim_set(struct ifnet *, struct shim_hdr *,
> + struct shim_hdr *);
>
> int mpls_sysctl(int *, u_int, void *, size_t *, void *, size_t);
> void mpls_input(struct mbuf *);
> diff --git sys/netmpls/mpls_shim.c sys/netmpls/mpls_shim.c
> index 203f220..3275dfb 100644
> --- sys/netmpls/mpls_shim.c
> +++ sys/netmpls/mpls_shim.c
> @@ -30,6 +30,8 @@
> * SUCH DAMAGE.
> */
>
> +#include "mpe.h"
> +
> #include <sys/param.h>
> #include <sys/mbuf.h>
> #include <sys/errno.h>
> @@ -37,9 +39,13 @@
> #include <sys/systm.h>
>
> #include <net/if.h>
> +#include <net/route.h>
>
> #include <netmpls/mpls.h>
>
> +int mpls_shim_label_exists(const struct shim_hdr *);
> +int mpls_shim_route(struct ifnet *, int, struct shim_hdr *);
> +
> struct mbuf *
> mpls_shim_pop(struct mbuf *m)
> {
> @@ -96,3 +102,78 @@ mpls_shim_push(struct mbuf *m, struct rt_mpls *rt_mpls)
>
> return (mpls_shim_swap(m, rt_mpls));
> }
> +
> +int
> +mpls_shim_label_exists(const struct shim_hdr *shim)
> +{
> +#if NMPE > 0
> + if (mpe_label_exists(shim))
> + return (1);
> +#endif /* NMPE */
> +
> + return (0);
> +}
> +
> +int
> +mpls_shim_route(struct ifnet *ifp, int cmd, struct shim_hdr *shim)
> +{
> + struct rtentry *nrt;
> + struct sockaddr_mpls dst;
> + struct rt_addrinfo info;
> + int error;
> +
> + bzero(&dst, sizeof(dst));
> + dst.smpls_len = sizeof(dst);
> + dst.smpls_family = AF_MPLS;
> + dst.smpls_label = shim->shim_label;
> +
> + bzero(&info, sizeof(info));
> + info.rti_flags = RTF_UP | RTF_MPLS;
> + info.rti_mpls = MPLS_OP_POP;
> + info.rti_info[RTAX_DST] = smplstosa(&dst);
> + info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)ifp->if_sadl;
> +
> + error = rtrequest1(cmd, &info, RTP_CONNECTED, &nrt, 0);
> + rt_missmsg(cmd, &info, error ? 0 : nrt->rt_flags, ifp, error, 0);
> + if (cmd == RTM_DELETE) {
> + if (error == 0 && nrt != NULL) {
> + if (nrt->rt_refcnt <= 0) {
> + nrt->rt_refcnt++;
> + rtfree(nrt);
> + }
> + }
> + }
> + if (cmd == RTM_ADD && error == 0 && nrt != NULL)
> + nrt->rt_refcnt--;
> +
> + return (error);
> +}
> +
> +int
> +mpls_shim_set(struct ifnet *ifp, struct shim_hdr *sshim, struct shim_hdr
> *dshim)
> +{
> + int error;
> +
> + if (sshim->shim_label == dshim->shim_label)
> + return (0);
> +
> + /* There must be only one route to this path */
> + if (mpls_shim_label_exists(sshim))
> + return (EEXIST);
> +
> + /* Remove old MPLS route */
> + if (dshim->shim_label != 0) {
> + mpls_shim_route(ifp, RTM_DELETE, dshim);
> + bzero(dshim, sizeof(*dshim));
> + }
> +
> + if (sshim->shim_label == 0)
> + return (0);
> +
> + /* Add new MPLS route */
> + error = mpls_shim_route(ifp, RTM_ADD, sshim);
> + if (error == 0)
> + dshim->shim_label = sshim->shim_label;
> +
> + return (error);
> +}
>