diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2017-11-29 19:36:04 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2017-11-29 19:36:04 +0000 |
commit | 7b7421b074c872b992ce89edf8b921dddd3a4796 (patch) | |
tree | 66d3591b6dbb171a311422944ad9940cefa46b11 /sys/net/if_mpe.c | |
parent | 272303fcac9605ffced23c4681f61fc329cc97d5 (diff) |
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@
Diffstat (limited to 'sys/net/if_mpe.c')
-rw-r--r-- | sys/net/if_mpe.c | 29 |
1 files 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 <pyr@spootnik.org> @@ -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) { |