From b02138dc60b9ef91dfd79917d84d9587b9bd3e0a Mon Sep 17 00:00:00 2001 From: claudio Date: Wed, 29 Nov 2017 19:36:03 +0000 Subject: [PATCH] Make mpe(4) work again by: - Change the way mpe figures out the IP of the MPLS nexthop. Instead of using RTF_GATEWAY and so a valid (and cachable) gateway route just use the gateway IP address of the route (rt->rt_gateway). - Make sure the interface is up when adding a mplslabel. The inserted route is in rtable 0 and so invisible for the link state tracker. Forcing the if_up ensures that the added route is RTF_UP. OK mpi@ --- sys/net/if_mpe.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/sys/net/if_mpe.c b/sys/net/if_mpe.c index 957934b14a7..28cf41e99bb 100644 --- a/sys/net/if_mpe.c +++ b/sys/net/if_mpe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mpe.c,v 1.62 2017/08/14 16:14:02 reyk Exp $ */ +/* $OpenBSD: if_mpe.c,v 1.63 2017/11/29 19:36:03 claudio Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard @@ -178,7 +178,6 @@ mpestart(struct ifnet *ifp0) rtfree(rt); continue; } - #if NBPFILTER > 0 if (ifp0->if_bpf) { /* remove MPLS label before passing packet to bpf */ @@ -191,7 +190,7 @@ mpestart(struct ifnet *ifp0) m->m_pkthdr.len += sizeof(struct shim_hdr); } #endif - /* XXX lie, but mpls_output will only look at sa_family */ + /* XXX lie, but mpls_output looks only at sa_family */ sa->sa_family = AF_MPLS; mpls_output(ifp, m, sa, rt); @@ -207,6 +206,7 @@ mpeoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct shim_hdr shim; int error; int off; + in_addr_t addr; u_int8_t op = 0; #ifdef DIAGNOSTIC @@ -223,12 +223,15 @@ mpeoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, error = 0; switch (dst->sa_family) { case AF_INET: - if (rt && rt->rt_flags & RTF_MPLS) { - shim.shim_label = - ((struct rt_mpls *)rt->rt_llinfo)->mpls_label; - shim.shim_label |= MPLS_BOS_MASK; - op = ((struct rt_mpls *)rt->rt_llinfo)->mpls_operation; + if (!rt || !(rt->rt_flags & RTF_MPLS)) { + m_freem(m); + error = ENETUNREACH; + goto out; } + shim.shim_label = + ((struct rt_mpls *)rt->rt_llinfo)->mpls_label; + shim.shim_label |= MPLS_BOS_MASK; + op = ((struct rt_mpls *)rt->rt_llinfo)->mpls_operation; if (op != MPLS_OP_PUSH) { m_freem(m); error = ENETUNREACH; @@ -247,8 +250,9 @@ mpeoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, goto out; } *mtod(m, sa_family_t *) = AF_INET; + addr = satosin(rt->rt_gateway)->sin_addr.s_addr; m_copyback(m, sizeof(sa_family_t), sizeof(in_addr_t), - (caddr_t)&((satosin(dst)->sin_addr)), M_NOWAIT); + &addr, M_NOWAIT); break; default: m_freem(m); @@ -320,6 +324,12 @@ mpeioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } if (error) break; + /* + * force interface up for now, + * linkstate of MPLS route is not tracked + */ + if (!ISSET(ifp->if_flags, IFF_UP)) + if_up(ifp); ifm = ifp->if_softc; if (ifm->sc_smpls.smpls_label) { /* remove old MPLS route */ @@ -337,6 +347,7 @@ mpeioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; case SIOCSIFRDOMAIN: /* must readd the MPLS "route" for our label */ + /* XXX does not make sense, the MPLS route is on rtable 0 */ ifm = ifp->if_softc; if (ifr->ifr_rdomainid != ifp->if_rdomain) { if (ifm->sc_smpls.smpls_label) { -- 2.20.1