diff --git a/sys/net/if_mpls.c b/sys/net/if_mpls.c index 6eb9f66affc8..f62a6fb6d53e 100644 --- a/sys/net/if_mpls.c +++ b/sys/net/if_mpls.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_mpls.c,v 1.9 2013/07/15 12:10:34 kefren Exp $ */ +/* $NetBSD: if_mpls.c,v 1.10 2013/07/23 11:11:55 kefren Exp $ */ /* * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_mpls.c,v 1.9 2013/07/15 12:10:34 kefren Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_mpls.c,v 1.10 2013/07/23 11:11:55 kefren Exp $"); #include "opt_inet.h" #include "opt_mpls.h" @@ -95,7 +95,8 @@ static struct mbuf *mpls_label_inet6(struct mbuf *, union mpls_shim *, uint); static struct mbuf *mpls_prepend_shim(struct mbuf *, union mpls_shim *); extern int mpls_defttl, mpls_mapttl_inet, mpls_mapttl_inet6, mpls_icmp_respond, - mpls_forwarding, mpls_accept, mpls_mapprec_inet, mpls_mapclass_inet6; + mpls_forwarding, mpls_accept, mpls_mapprec_inet, mpls_mapclass_inet6, + mpls_rfc4182; /* ARGSUSED */ void @@ -325,6 +326,19 @@ mpls_lse(struct mbuf *m) if ((m = mpls_ttl_dec(m)) == NULL) goto done; + /* RFC 4182 */ + if (mpls_rfc4182 != 0) + while((dst.smpls_addr.shim.label == MPLS_LABEL_IPV4NULL || + dst.smpls_addr.shim.label == MPLS_LABEL_IPV6NULL) && + __predict_false(dst.smpls_addr.shim.bos == 0)) { + m_adj(m, sizeof(union mpls_shim)); + if (m->m_len < sizeof(union mpls_shim) && + (m = m_pullup(m, sizeof(union mpls_shim))) == NULL) + goto done; + dst.smpls_addr.s_addr = + ntohl(mtod(m, union mpls_shim *)->s_addr); + } + if (dst.smpls_addr.shim.label <= MPLS_LABEL_RESMAX) { /* Don't swap reserved labels */ switch (dst.smpls_addr.shim.label) { diff --git a/sys/netmpls/mpls_proto.c b/sys/netmpls/mpls_proto.c index 2c316d9accc3..609ba324b39c 100644 --- a/sys/netmpls/mpls_proto.c +++ b/sys/netmpls/mpls_proto.c @@ -1,4 +1,4 @@ -/* $NetBSD: mpls_proto.c,v 1.4 2013/07/18 06:23:07 kefren Exp $ */ +/* $NetBSD: mpls_proto.c,v 1.5 2013/07/23 11:11:55 kefren Exp $ */ /* * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mpls_proto.c,v 1.4 2013/07/18 06:23:07 kefren Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mpls_proto.c,v 1.5 2013/07/23 11:11:55 kefren Exp $"); #include "opt_inet.h" #include "opt_mbuftrace.h" @@ -65,6 +65,7 @@ int mpls_forwarding = 0; int mpls_accept = 0; int mpls_mapprec_inet = 1; int mpls_mapclass_inet6 = 1; +int mpls_rfc4182 = 1; void mpls_init(void) { @@ -176,6 +177,12 @@ sysctl_net_mpls_setup(struct sysctllog **clog) SYSCTL_DESCR("MPLS queue length"), NULL, 0, &mplsintrq.ifq_maxlen, 0, CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL); + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, + CTLTYPE_INT, "rfc4182", + SYSCTL_DESCR("RFC 4182 conformance"), + NULL, 0, &mpls_rfc4182, 0, + CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL); #ifdef INET sysctl_createv(clog, 0, NULL, NULL, CTLFLAG_PERMANENT|CTLFLAG_READWRITE,