Index: Makefile =================================================================== RCS file: /usr/cvs/src/sys/Makefile,v retrieving revision 1.57 diff -u -p -r1.57 Makefile --- Makefile 11 Dec 2005 12:16:03 -0000 1.57 +++ Makefile 25 May 2006 15:08:08 -0000 @@ -2,7 +2,7 @@ SUBDIR= altq arch compat crypto dev fs miscfs \ net net80211 netatalk netccitt netipsec netinet netinet6 \ - netisdn netiso netkey netnatm netns netsmb \ + netisdn netiso netkey netmpls netnatm netns netsmb \ nfs opencrypto sys ufs uvm .if (${MACHINE} != "evbppc") Index: conf/files =================================================================== RCS file: /usr/cvs/src/sys/conf/files,v retrieving revision 1.775 diff -u -p -r1.775 files --- conf/files 18 May 2006 09:05:51 -0000 1.775 +++ conf/files 25 May 2006 15:08:49 -0000 @@ -149,6 +149,7 @@ include "netiso/files.netiso" include "netnatm/files.netnatm" include "netns/files.netns" include "netsmb/files.netsmb" +include "netmpls/files.netmpls" include "net/files.pf" defflag IPX # IPX network stack Index: kern/uipc_mbuf.c =================================================================== RCS file: /usr/cvs/src/sys/kern/uipc_mbuf.c,v retrieving revision 1.110 diff -u -p -r1.110 uipc_mbuf.c --- kern/uipc_mbuf.c 15 Apr 2006 04:58:14 -0000 1.110 +++ kern/uipc_mbuf.c 25 May 2006 16:11:36 -0000 @@ -1,5 +1,34 @@ /* $NetBSD: uipc_mbuf.c,v 1.110 2006/04/15 04:58:14 christos Exp $ */ +/* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + /*- * Copyright (c) 1999, 2001 The NetBSD Foundation, Inc. * All rights reserved. @@ -939,6 +968,9 @@ m_split0(struct mbuf *m0, int len0, int return (NULL); MCLAIM(m, m0->m_owner); n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif; +#ifdef MPLS + n->m_pkthdr.fecid = m0->m_pkthdr.fecid; +#endif /* MPLS */ n->m_pkthdr.len = m0->m_pkthdr.len - len0; len_save = m0->m_pkthdr.len; m0->m_pkthdr.len = len0; @@ -1009,6 +1041,9 @@ m_devget(char *buf, int totlen, int off0 return (NULL); m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = totlen; +#ifdef MPLS + m->m_pkthdr.fecid = 0; +#endif /* MPLS */ m->m_len = MHLEN; while (totlen > 0) { Index: net/if_atmsubr.c =================================================================== RCS file: /usr/cvs/src/sys/net/if_atmsubr.c,v retrieving revision 1.37 diff -u -p -r1.37 if_atmsubr.c --- net/if_atmsubr.c 11 Dec 2005 23:05:24 -0000 1.37 +++ net/if_atmsubr.c 25 May 2006 16:12:37 -0000 @@ -1,6 +1,35 @@ /* $NetBSD: if_atmsubr.c,v 1.37 2005/12/11 23:05:24 thorpej Exp $ */ /* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* * * Copyright (c) 1996 Charles D. Cranor and Washington University. * All rights reserved. @@ -42,6 +71,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_atmsubr.c #include "opt_inet.h" #include "opt_gateway.h" #include "opt_natm.h" +#include "opt_mpls.h" #include "bpfilter.h" @@ -80,6 +110,11 @@ __KERNEL_RCSID(0, "$NetBSD: if_atmsubr.c #include #endif +#ifdef MPLS +#include +#include +#endif /* MPLS */ + #define senderr(e) { error = (e); goto bad;} /* @@ -181,6 +216,24 @@ atm_output(struct ifnet *ifp, struct mbu break; #endif +#ifdef MPLS + case AF_MPLS: + if (m->m_flags & (M_BCAST | M_MCAST)) + etype = ETHERTYPE_MPLS_MCAST; + else + etype = ETHERTYPE_MPLS; +#ifdef ATM_PVCEXT + if (ifp->if_flags & IFF_POINTOPOINT) { + /* pvc subinterface */ + struct pvcsif *pvcsif = (struct pvcsif *)ifp; + atmdst = pvcsif->sif_aph; + break; + } +#endif + senderr(EHOSTUNREACH); + break; +#endif /* MPLS */ + case AF_UNSPEC: /* * XXX: bpfwrite or output from a pvc shadow if. @@ -301,7 +354,15 @@ atm_input(struct ifnet *ifp, struct atm_ inq = &ip6intrq; break; #endif - default: +#ifdef MPLS + case ETHERTYPE_MPLS: + case ETHERTYPE_MPLS_MCAST: + /* this may be done with a NETISR as well */ + mpls_shim_input(ifp, m); + return; +#endif /* MPLS */ + + default: m_freem(m); return; } Index: net/if_ethersubr.c =================================================================== RCS file: /usr/cvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.133 diff -u -p -r1.133 if_ethersubr.c --- net/if_ethersubr.c 18 May 2006 09:05:51 -0000 1.133 +++ net/if_ethersubr.c 25 May 2006 18:32:10 -0000 @@ -1,6 +1,35 @@ /* $NetBSD: if_ethersubr.c,v 1.133 2006/05/18 09:05:51 liamjfoy Exp $ */ /* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * @@ -69,8 +98,10 @@ __KERNEL_RCSID(0, "$NetBSD: if_ethersubr #include "opt_llc.h" #include "opt_iso.h" #include "opt_ipx.h" +#include "opt_mpls.h" #include "opt_mbuftrace.h" #include "opt_ns.h" +#include "opt_mpls.h" #include "opt_gateway.h" #include "opt_pfil_hooks.h" #include "vlan.h" @@ -189,6 +220,11 @@ extern u_char at_org_code[3]; extern u_char aarp_org_code[3]; #endif /* NETATALK */ +#ifdef MPLS +#include +#include +#endif /* MPLS */ + static struct timeval bigpktppslim_last; static int bigpktppslim = 2; /* XXX */ static int bigpktpps_count; @@ -486,6 +522,42 @@ ether_output(struct ifnet *ifp0, struct #endif /* LLC_DEBUG */ } break; #endif /* LLC */ +#ifdef MPLS + case AF_MPLS: + { + struct sockaddr *sa; + + if (rt && rt->rt_ifa) + sa = (struct sockaddr *)rt->rt_ifa->ifa_dstaddr; + else + senderr(EHOSTUNREACH); + + if (sa == NULL || sa->sa_len < 2) + senderr(EHOSTUNREACH); + + switch (sa->sa_family) { + case AF_LINK: + if (satosdl(sa)->sdl_alen < sizeof(edst)) + senderr(EHOSTUNREACH); + memcpy(edst, LLADDR(satosdl(sa)), + sizeof(edst)); + break; + + case AF_INET: + if (!arpresolve(ifp, 0, m, sa, edst)) + return 0; /* if not yet resolved */ + break; + default: + senderr(EHOSTUNREACH); + } + + if (m->m_flags & (M_BCAST | M_MCAST)) + etype = htons(ETHERTYPE_MPLS_MCAST); + else + etype = htons(ETHERTYPE_MPLS); + } + break; +#endif /* MPLS */ case pseudo_AF_HDRCMPLT: hdrcmplt = 1; @@ -713,6 +785,9 @@ ether_input(struct ifnet *ifp, struct mb /* * Determine if the packet is within its size limits. */ +#ifdef MPLS + if (etype != ETHERTYPE_MPLS && etype != ETHERTYPE_MPLS_MCAST) +#endif if (m->m_pkthdr.len > ETHER_MAX_FRAME(ifp, etype, m->m_flags & M_HASFCS)) { if (ppsratecheck(&bigpktppslim_last, &bigpktpps_count, @@ -984,6 +1059,14 @@ ether_input(struct ifnet *ifp, struct mb aarpinput(ifp, m); /* XXX */ return; #endif /* NETATALK */ +#ifdef MPLS + case ETHERTYPE_MPLS: + case ETHERTYPE_MPLS_MCAST: + /* this may be done with a NETISR as well */ + mpls_shim_input(ifp, m); + return; +#endif /* MPLS */ + default: #if defined (ISO) || defined (LLC) || defined (NETATALK) if (etype > ETHERMTU) Index: net/route.h =================================================================== RCS file: /usr/cvs/src/sys/net/route.h,v retrieving revision 1.43 diff -u -p -r1.43 route.h --- net/route.h 11 Dec 2005 12:24:52 -0000 1.43 +++ net/route.h 25 May 2006 16:13:06 -0000 @@ -1,6 +1,35 @@ /* $NetBSD: route.h,v 1.43 2005/12/11 12:24:52 christos Exp $ */ /* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* * Copyright (c) 1980, 1986, 1993 * The Regents of the University of California. All rights reserved. * @@ -239,6 +268,7 @@ struct route_cb { int ipx_count; int ns_count; int iso_count; + int mpls_count; int any_count; }; Index: net/rtsock.c =================================================================== RCS file: /usr/cvs/src/sys/net/rtsock.c,v retrieving revision 1.84 diff -u -p -r1.84 rtsock.c --- net/rtsock.c 14 May 2006 21:19:33 -0000 1.84 +++ net/rtsock.c 25 May 2006 16:13:23 -0000 @@ -1,6 +1,35 @@ /* $NetBSD: rtsock.c,v 1.84 2006/05/14 21:19:33 elad Exp $ */ /* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * @@ -64,6 +93,7 @@ __KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.84 2006/05/14 21:19:33 elad Exp $"); #include "opt_inet.h" +#include "opt_mpls.h" #include #include @@ -80,6 +110,10 @@ __KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1 #include #include +#ifdef MPLS +#include +#endif /* MPLS */ + #include DOMAIN_DEFINE(routedomain); /* forward declare and add to link set */ @@ -140,6 +174,11 @@ rt_adjustcount(int af, int cnt) case AF_ISO: route_cb.iso_count += cnt; return; +#ifdef MPLS + case AF_MPLS: + route_cb.mpls_count += cnt; + return; +#endif /* MPLS */ } } Index: netinet/ip_input.c =================================================================== RCS file: /usr/cvs/src/sys/netinet/ip_input.c,v retrieving revision 1.226 diff -u -p -r1.226 ip_input.c --- netinet/ip_input.c 8 May 2006 18:50:12 -0000 1.226 +++ netinet/ip_input.c 25 May 2006 15:35:05 -0000 @@ -104,6 +104,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip_input.c,v #include "opt_gateway.h" #include "opt_pfil_hooks.h" #include "opt_ipsec.h" +#include "opt_mpls.h" #include "opt_mrouting.h" #include "opt_mbuftrace.h" #include "opt_inet_csum.h" @@ -619,12 +620,17 @@ ip_input(struct mbuf *m) /* ipflow (IP fast forwarding) is not compatible with IPsec. */ m->m_flags &= ~M_CANFASTFWD; #else +#ifdef MPLS + /* ipflow (IP fast fowarding) is not compatible with MPLS. */ + m->m_flags &= ~M_CANFASTFWD; +#else /* * Assume that we can create a fast-forward IP flow entry * based on this packet. */ m->m_flags |= M_CANFASTFWD; #endif +#endif #ifdef PFIL_HOOKS /* Index: netinet/ip_output.c =================================================================== RCS file: /usr/cvs/src/sys/netinet/ip_output.c,v retrieving revision 1.162 diff -u -p -r1.162 ip_output.c --- netinet/ip_output.c 15 May 2006 00:05:17 -0000 1.162 +++ netinet/ip_output.c 25 May 2006 15:56:52 -0000 @@ -1,6 +1,35 @@ /* $NetBSD: ip_output.c,v 1.162 2006/05/15 00:05:17 christos Exp $ */ /* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * @@ -104,6 +133,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip_output.c, #include "opt_inet.h" #include "opt_ipsec.h" #include "opt_mrouting.h" +#include "opt_mpls.h" #include #include @@ -143,6 +173,11 @@ __KERNEL_RCSID(0, "$NetBSD: ip_output.c, #include #endif /*IPSEC*/ +#ifdef MPLS +#include +#include +#endif /* MPLS */ + #ifdef FAST_IPSEC #include #include @@ -365,6 +400,13 @@ ip_output(struct mbuf *m0, ...) ro->ro_rt->rt_use++; if (ro->ro_rt->rt_flags & RTF_GATEWAY) dst = satosin(ro->ro_rt->rt_gateway); +#ifdef MPLS + /* set fec information by SMART FEC CF */ + if (m->m_pkthdr.fecid == 0) { + if (dst && dst->sin_family == AF_MPLS) + m->m_pkthdr.fecid = satosmpls(dst)->smpls_label; + } +#endif /* MPLS */ } if (IN_MULTICAST(ip->ip_dst.s_addr) || (ip->ip_dst.s_addr == INADDR_BROADCAST)) { @@ -494,7 +536,11 @@ ip_output(struct mbuf *m0, ...) * and verify user is allowed to send * such a packet. */ - if (in_broadcast(dst->sin_addr, ifp)) { + if ( +#ifdef MPLS + dst->sin_family == AF_INET && +#endif /* MPLS */ + in_broadcast(dst->sin_addr, ifp)) { if ((ifp->if_flags & IFF_BROADCAST) == 0) { error = EADDRNOTAVAIL; goto bad; @@ -892,16 +938,25 @@ spd_done: /* clean ipsec history once it goes out of the node */ ipsec_delaux(m); #endif - - if (__predict_true( - (m->m_pkthdr.csum_flags & M_CSUM_TSOv4) == 0 || - (ifp->if_capenable & IFCAP_TSOv4) != 0)) { - error = - (*ifp->if_output)(ifp, m, sintosa(dst), ro->ro_rt); - } else { - error = - ip_tso_output(ifp, m, sintosa(dst), ro->ro_rt); +#ifdef MPLS + if (m->m_pkthdr.fecid) + error = mpls_ip_output(ifp, m, sintosa(dst), ro->ro_rt); + else { +#endif + if (__predict_true( + (m->m_pkthdr.csum_flags & M_CSUM_TSOv4) == 0 || + (ifp->if_capenable & IFCAP_TSOv4) != 0)) { + error = + (*ifp->if_output)(ifp, m, sintosa(dst), + ro->ro_rt); + } else { + error = + ip_tso_output(ifp, m, sintosa(dst), + ro->ro_rt); + } +#ifdef MPLS } +#endif goto done; } @@ -963,7 +1018,17 @@ spd_done: ro, flags, imo, so, mtu_p); } else #endif /* IPSEC_NAT_T */ + +#ifdef MPLS + /* XXX ifp may change in MPLS routing. XXX */ + /* XXX queue length check in upperline maybe bad XXX */ + if (m->m_pkthdr.fecid) + error = mpls_ip_output(ifp, m, sintosa(dst), + ro->ro_rt); + else +#endif /* MPLS */ { + KASSERT((m->m_pkthdr.csum_flags & (M_CSUM_UDPv4 | M_CSUM_TCPv4)) == 0); error = (*ifp->if_output)(ifp, m, sintosa(dst), @@ -1070,6 +1135,9 @@ ip_fragment(struct mbuf *m, struct ifnet } m->m_pkthdr.len = mhlen + len; m->m_pkthdr.rcvif = (struct ifnet *)0; +#ifdef MPLS + m->m_pkthdr.fecid = m0->m_pkthdr.fecid; +#endif mhip->ip_sum = 0; if (sw_csum & M_CSUM_IPv4) { mhip->ip_sum = in_cksum(m, mhlen); Index: netinet6/ip6_forward.c =================================================================== RCS file: /usr/cvs/src/sys/netinet6/ip6_forward.c,v retrieving revision 1.47 diff -u -p -r1.47 ip6_forward.c --- netinet6/ip6_forward.c 21 Jan 2006 00:15:36 -0000 1.47 +++ netinet6/ip6_forward.c 25 May 2006 15:45:50 -0000 @@ -34,6 +34,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_forward.c,v 1.47 2006/01/21 00:15:36 rpaulo Exp $"); #include "opt_ipsec.h" +#include "opt_mpls.h" #include "opt_pfil_hooks.h" #include @@ -69,6 +70,11 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_forward. #include #endif +#ifdef MPLS +#include +#include +#endif /* MPLS */ + #include struct route_in6 ip6_forward_rt; @@ -386,6 +392,16 @@ ip6_forward(m, srcrt) skip_routing:; #endif /* IPSEC */ +#ifdef MPLS + /* set fec information by SMART FEC CF */ + if (m->m_pkthdr.fecid == 0) { + if (rt && rt->rt_flags & RTF_GATEWAY && rt->rt_gateway + && rt->rt_gateway->sa_family == AF_MPLS) + m->m_pkthdr.fecid = + satosmpls(rt->rt_gateway)->smpls_label; + } +#endif /* MPLS */ + /* * Source scope check: if a packet can't be delivered to its * destination for the reason that the destination is beyond the scope @@ -591,6 +607,13 @@ ip6_forward(m, srcrt) ip6 = mtod(m, struct ip6_hdr *); #endif /* PFIL_HOOKS */ +#ifdef MPLS + if (m->m_pkthdr.fecid) + error = mpls_ip6_output(rt->rt_ifp, m, + (struct sockaddr *)dst, + ip6_forward_rt.ro_rt); + else +#endif /* MPLS */ error = nd6_output(rt->rt_ifp, origifp, m, dst, rt); if (error) { in6_ifstat_inc(rt->rt_ifp, ifs6_out_discard); Index: netinet6/ip6_output.c =================================================================== RCS file: /usr/cvs/src/sys/netinet6/ip6_output.c,v retrieving revision 1.98 diff -u -p -r1.98 ip6_output.c --- netinet6/ip6_output.c 14 May 2006 21:19:34 -0000 1.98 +++ netinet6/ip6_output.c 25 May 2006 15:50:20 -0000 @@ -68,6 +68,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_output.c #include "opt_inet6.h" #include "opt_ipsec.h" #include "opt_pfil_hooks.h" +#include "opt_mpls.h" #include #include @@ -102,6 +103,11 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_output.c #include #endif /* IPSEC */ +#ifdef MPLS +#include +#include +#endif /* MPLS */ + #include #ifdef PFIL_HOOKS @@ -546,6 +552,14 @@ skip_ipsec2:; ip6->ip6_hlim = ip6_defmcasthlim; } +#ifdef MPLS + /* set fec information by SMART FEC CF */ + if (m->m_pkthdr.fecid == 0) { + if (dst && dst->sin6_family == AF_MPLS) + m->m_pkthdr.fecid = satosmpls(dst)->smpls_label; + } +#endif /* MPLS */ + #ifdef IPSEC if (needipsec && needipsectun) { struct ipsec_output_state state; @@ -915,16 +929,25 @@ skip_ipsec2:; ipsec_delaux(m); #endif - sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_csum_flags_tx; - if ((sw_csum & (M_CSUM_UDPv6|M_CSUM_TCPv6)) != 0) { - if (IN6_NEED_CHECKSUM(ifp, - sw_csum & (M_CSUM_UDPv6|M_CSUM_TCPv6))) { - in6_delayed_cksum(m); +#ifdef MPLS + if (m->m_pkthdr.fecid) + error = mpls_ip6_output(ifp, m, sin6tosa(dst), + ro->ro_rt); + else +#endif /* MPLS */ + { + sw_csum = m->m_pkthdr.csum_flags + & ~ifp->if_csum_flags_tx; + if ((sw_csum & (M_CSUM_UDPv6|M_CSUM_TCPv6)) != 0) { + if (IN6_NEED_CHECKSUM(ifp, + sw_csum & (M_CSUM_UDPv6|M_CSUM_TCPv6))) { + in6_delayed_cksum(m); + } + m->m_pkthdr.csum_flags &= + ~(M_CSUM_UDPv6|M_CSUM_TCPv6); } - m->m_pkthdr.csum_flags &= ~(M_CSUM_UDPv6|M_CSUM_TCPv6); + error = nd6_output(ifp, origifp, m, dst, rt); } - - error = nd6_output(ifp, origifp, m, dst, rt); goto done; } Index: netmpls/Makefile =================================================================== RCS file: netmpls/Makefile diff -N netmpls/Makefile --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ netmpls/Makefile 25 May 2006 16:14:53 -0000 @@ -0,0 +1,7 @@ +# $NetBSD$ + +INCSDIR= /usr/include/netmpls + +INCS= mpls.h + +.include Index: netmpls/files.netmpls =================================================================== RCS file: netmpls/files.netmpls diff -N netmpls/files.netmpls --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ netmpls/files.netmpls 25 May 2006 15:10:32 -0000 @@ -0,0 +1,11 @@ +# $NetBSD$ + +defflag opt_mpls.h MPLS MPLS_DEBUG MPLS_MCAST + +file netmpls/mpls.c mpls +file netmpls/mpls_ip.c mpls & inet +file netmpls/mpls_ip6.c mpls & inet6 +file netmpls/mpls_lse.c mpls +file netmpls/mpls_proto.c mpls +file netmpls/mpls_raw.c mpls +file netmpls/mpls_shim.c mpls Index: netmpls/mpls.c =================================================================== RCS file: netmpls/mpls.c diff -N netmpls/mpls.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ netmpls/mpls.c 25 May 2006 17:03:15 -0000 @@ -0,0 +1,348 @@ +/* $NetBSD$ */ +/* AYAME Id mpls.c,v 1.3 2002/08/31 19:20:47 zin Exp */ + +/* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +extern void mpls_purgeaddr __P((struct ifaddr *, struct ifnet *)); +extern int mpls_ifinit __P((struct ifnet *, struct mpls_ifaddr *, + struct sockaddr_mpls *, int)); +extern void mpls_ifscrub __P((struct mpls_ifaddr *)); + +struct mpls_ifaddrhead mpls_ifaddr; +struct sockaddr_mpls mpls_scope_sockmask; + +void +mpls_init() +{ + mpls_scope_sockmask.smpls_len = sizeof(struct sockaddr_mpls); + mpls_scope_sockmask.smpls_family = AF_MPLS; + mpls_scope_sockmask.smpls_label = htonl(MPLS_SCOPE_MASK); + TAILQ_INIT(&mpls_ifaddr); +} + +void +mpls_purgeaddr(struct ifaddr *ifa, struct ifnet *ifp) +{ + struct mpls_ifaddr *ia = (void *)ifa; + + mpls_ifscrub(ia); + TAILQ_REMOVE(&ifp->if_addrlist, &ia->ia_ifa, ifa_list); + IFAFREE(&ia->ia_ifa); + TAILQ_REMOVE(&mpls_ifaddr, ia, ia_list); + IFAFREE(&ia->ia_ifa); +} + +void +mpls_purgeif(struct ifnet *ifp) +{ + struct ifaddr *ifa, *nifa; + + for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; ifa = nifa) { + nifa = TAILQ_NEXT(ifa, ifa_list); + if (ifa->ifa_addr->sa_family != AF_MPLS) + continue; + mpls_purgeaddr(ifa, ifp); + } +} + +/* + * Delete any existing route for an interface. + */ +void +mpls_ifscrub(struct mpls_ifaddr *ia) +{ + if ((ia->ia_flags & IFA_ROUTE) == 0) + return; + rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0); + ia->ia_flags &= ~IFA_ROUTE; +} + +/* + * Initialize an interface's MPLS address + * and routing table entry. + */ +int +mpls_ifinit(struct ifnet *ifp, struct mpls_ifaddr *ia, + struct sockaddr_mpls *smpls, int scrub) +{ + struct sockaddr_mpls oldaddr; + int s = splnet(), flags = RTF_UP, error; + + /* + * Set up new addresses. + */ + ia->ia_addr = *smpls; + + /* + * Give the interface a chance to initialize + * if this is its first address, + * and to validate the address if necessary. + */ + if (ifp->if_ioctl && + (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) + goto bad; + + if (ifp->if_type == IFT_ETHER) { + /* + * enable MTU extension on ether interface, if possible. + * + * XXX ToDo: + * XXX now, when last vlan intarface is shutdowned, + * XXX this extension is disabled by if_vlan.c. + */ + struct ethercom *ec = (struct ethercom *)ifp; + + if ((ec->ec_capabilities & ETHERCAP_VLAN_MTU) + && !(ec->ec_capenable & ETHERCAP_VLAN_MTU)) { + ec->ec_capenable |= ETHERCAP_VLAN_MTU; + if (ifp->if_flags & IFF_UP) { + struct ifreq ifr; + + ifr.ifr_flags = ifp->if_flags; + error = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, + (caddr_t)&ifr); + } + } + } + + splx(s); + if (scrub) { + ia->ia_ifa.ifa_addr = smplstosa(&oldaddr); + mpls_ifscrub(ia); + ia->ia_ifa.ifa_addr = smplstosa(&ia->ia_addr); + } + + /* + * Add route for the network. + */ + ia->ia_ifa.ifa_metric = ifp->if_metric; + error = rtinit(&ia->ia_ifa, (int)RTM_ADD, flags); + if (!error) + ia->ia_flags |= IFA_ROUTE; + + return (error); +bad: + splx(s); + ia->ia_addr = oldaddr; + + return error; +} + +/* + * Generic MPLS control operations (ioctl's). + * Ifp is 0 if not an interface-specific ioctl. + */ +/* ARGSUSED */ +int +mpls_control(struct socket *so, unsigned long cmd, caddr_t data, + struct ifnet *ifp, struct lwp *l) +{ + struct ifreq *ifr = (struct ifreq *)data; + struct mpls_ifaddr *ia = 0; + struct mpls_aliasreq *ifra = (struct mpls_aliasreq *)data; + struct sockaddr olddstaddr; + int hostIsNew, dstIsNew, error = 0; + + /* + * Check address family. + */ + switch (cmd) { + + case SIOCAIFADDR: + case SIOCDIFADDR: + case SIOCSIFADDR: + case SIOCGIFALIAS: + if (ifr->ifr_addr.sa_len != sizeof(struct sockaddr_mpls) + || ifr->ifr_addr.sa_family != AF_MPLS) + return (EADDRNOTAVAIL); + break; + + case SIOCSIFDSTADDR: + if (ifr->ifr_addr.sa_len != sizeof(struct sockaddr_dl) + || ifr->ifr_addr.sa_family != AF_LINK) + return (EADDRNOTAVAIL); + break; + + case SIOCSIFNETMASK: + case SIOCGIFBRDADDR: + case SIOCSIFBRDADDR: + return(EOPNOTSUPP); + } + + /* + * Find address for this interface, if it exists. + */ + if (ifp) + for (ia = TAILQ_FIRST(&mpls_ifaddr); ia != NULL; + ia = TAILQ_NEXT(ia, ia_list)) + if (ia->ia_ifp == ifp) + break; + + switch (cmd) { + + case SIOCAIFADDR: + case SIOCDIFADDR: + case SIOCGIFALIAS: + for (ia = TAILQ_FIRST(&mpls_ifaddr); ia != NULL; + ia = TAILQ_NEXT(ia, ia_list)) + if (ia->ia_ifp == ifp && + ia->ia_addr.smpls_label == ifra->ifra_addr.smpls_label) + break; + if (cmd == SIOCDIFADDR && ia == 0) + return (EADDRNOTAVAIL); + /* FALLTHROUGH */ + case SIOCSIFADDR: + case SIOCSIFDSTADDR: + if (ifp == 0) + panic("mpls_control"); + + if (cmd == SIOCGIFALIAS) + break; + + if (kauth_cred_getuid(kauth_cred_get())) + return (EPERM); + + if (ia == 0) { + MALLOC(ia, struct mpls_ifaddr *, sizeof(*ia), + M_IFADDR, M_WAITOK); + if (ia == 0) + return (ENOBUFS); + bzero((caddr_t)ia, sizeof(*ia)); + TAILQ_INSERT_TAIL(&mpls_ifaddr, ia, ia_list); + IFAREF(&ia->ia_ifa); + TAILQ_INSERT_TAIL(&ifp->if_addrlist, &ia->ia_ifa, + ifa_list); + IFAREF(&ia->ia_ifa); + ia->ia_ifa.ifa_refcnt++; /* for 1.4X */ + ia->ia_ifa.ifa_addr = smplstosa(&ia->ia_addr); + ia->ia_ifa.ifa_dstaddr = &ia->ia_dstaddr; + ia->ia_ifa.ifa_netmask = smplstosa(&mpls_scope_sockmask); + ia->ia_ifp = ifp; + } + break; + + case SIOCGIFADDR: + case SIOCGIFNETMASK: + case SIOCGIFDSTADDR: + if (ia == 0) + return (EADDRNOTAVAIL); + break; + } + + switch (cmd) { + + case SIOCGIFADDR: + *satosmpls(&ifr->ifr_addr) = ia->ia_addr; + break; + + case SIOCGIFDSTADDR: + ifr->ifr_dstaddr = ia->ia_dstaddr; + break; + + case SIOCGIFNETMASK: + *satosmpls(&ifr->ifr_addr) = mpls_scope_sockmask; + break; + + case SIOCSIFDSTADDR: + olddstaddr = ia->ia_dstaddr; + ia->ia_dstaddr = ifr->ifr_dstaddr; + + if ((ifp->if_flags & IFF_POINTOPOINT) != 0) + if (ifp->if_ioctl && (error = (*ifp->if_ioctl) + (ifp, SIOCSIFDSTADDR, (caddr_t)ia))) { + ia->ia_dstaddr = olddstaddr; + } + break; + + case SIOCSIFADDR: + error = mpls_ifinit(ifp, ia, satosmpls(&ifr->ifr_addr), 1); + break; + + case SIOCAIFADDR: + hostIsNew = 1; + dstIsNew = 0; + error = 0; + if (ia->ia_addr.smpls_family == AF_MPLS) { + if (ifra->ifra_addr.smpls_len == 0) { + ifra->ifra_addr = ia->ia_addr; + hostIsNew = 0; + } else if (ia->ia_addr.smpls_label == ifra->ifra_addr.smpls_label) + hostIsNew = 0; + } + if (ifra->ifra_dstaddr.sa_len) { + ia->ia_dstaddr = ifra->ifra_dstaddr; + dstIsNew = 1; + } + if (ifra->ifra_addr.smpls_family == AF_MPLS && + (hostIsNew || dstIsNew)) + error = mpls_ifinit(ifp, ia, &ifra->ifra_addr, 0); + break; + + case SIOCGIFALIAS: + ifra->ifra_mask = mpls_scope_sockmask; + if (ia->ia_dstaddr.sa_len) + ifra->ifra_dstaddr = ia->ia_dstaddr; + else + bzero(&ifra->ifra_dstaddr, + sizeof(ifra->ifra_dstaddr)); + break; + + case SIOCDIFADDR: + mpls_purgeaddr(&ia->ia_ifa, ifp); + break; + + default: + if (ifp == 0 || ifp->if_ioctl == 0) + return (EOPNOTSUPP); + error = (*ifp->if_ioctl)(ifp, cmd, data); + break; + } + + return error; +} Index: netmpls/mpls.h =================================================================== RCS file: netmpls/mpls.h diff -N netmpls/mpls.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ netmpls/mpls.h 25 May 2006 17:13:12 -0000 @@ -0,0 +1,169 @@ +/* $NetBSD$ */ +/* AYAME Id mpls.h,v 1.3 2003/04/05 06:09:19 n-ogashi Exp */ + +/* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _NETMPLS_MPLS_H_ +#define _NETMPLS_MPLS_H_ + +#include +#include +#include +#include + +#include +#include + +/* + * Structure of a SHIM header. + */ +struct shim_hdr { + union { + u_int32_t shim_label; /* 20bits of label */ + struct { + u_int8_t shim_un1_pad1; + u_int8_t shim_un1_pad2; + u_int8_t shim_un1_exp; /* 3bits of exp & BoS bit */ + u_int8_t shim_un1_ttl; /* 8bits of ttl */ + } shim_un1; + } shim_ctlun; +}; + +#define shim_label shim_ctlun.shim_label +#define shim_exp shim_ctlun.shim_un1.shim_un1_exp +#define shim_ttl shim_ctlun.shim_un1.shim_un1_ttl + +#if BYTE_ORDER == BIG_ENDIAN +#define SHIM_LABEL_MASK 0xfffff000 /* mpls label (20bits) */ +#else /* LITTLE_ENDIAN */ +#define SHIM_LABEL_MASK 0x00f0ffff /* mpls label (20bits) */ +#endif +#define SHIM_LABEL_OFFSET 12 /* mpls label (20bits) */ + +#define SHIM_EXP_MASK 0x0e /* mpls exp (3bits) */ +#define SHIM_EXP_OFFSET 1 /* mpls exp offset */ +#define SHIM_BOS_MASK 0x01 /* mpls BoS flag (1bit) */ + +#define MPLS_SHIM_LABEL(shimp) (ntohl((shimp)->shim_label & SHIM_LABEL_MASK) \ + >> SHIM_LABEL_OFFSET) +#define MPLS_SHIM_EXP(shimp) (((shimp)->shim_exp & SHIM_EXP_MASK) \ + >> SHIM_EXP_OFFSET) +#define MPLS_SHIM_BOS(shimp) ((shimp)->shim_exp & SHIM_BOS_MASK) +#define MPLS_SHIM_TTL(shimp) ((shimp)->shim_ttl) + +/* Reserved lavel values (draft-ietf-mpls-label-encaps-07) */ +#define MPLS_LABEL_IPV4NULL 0 /* IPv4 Explicit NULL Label */ +#define MPLS_LABEL_RTALERT 1 /* Router Alert Label */ +#define MPLS_LABEL_IPV6NULL 2 /* IPv6 Explicit NULL Label */ +#define MPLS_LABEL_IMPLNULL 3 /* Implicit NULL Label */ +/* MPLS_LABEL_RESERVED 4-15 */ /* Values 4-15 are reserved */ +#define MPLS_LABEL_RESERVED_MAX 15 + +/* + * Socket address + */ + +struct mpls_addr { + u_int32_t s_addr; +} __attribute__((__packed__)); + +struct sockaddr_mpls { + u_int8_t smpls_len; /* length */ + u_int8_t smpls_family; /* AF_MPLS */ + u_int8_t smpls_pad1[2]; /* padding */ +#if 0 + u_int32_t smpls_label; /* MPLS label scope(12) & label(20) */ +#else + struct mpls_addr smpls_addr; +#endif /* if 0 */ + u_int8_t smpls_exp; /* exp value */ +#if MPLS_MCAST + u_int8_t smpls_mcexp; + u_int8_t smpls_pad2[2]; + u_int32_t smpls_mclabel; +#else + u_int8_t smpls_pad2[7]; /* padding */ +#endif +} __attribute__((__packed__)); + +#define smpls_label smpls_addr.s_addr + +#define MPLS_SCOPE_MASK 0xfff00000 /* mpls label scope (12bits) */ +#define MPLS_LABEL_MASK 0x000fffff /* mpls label (20bits) */ +#define MPLS_SCOPE_OFFSET 20 +#define MPLS_EXP_MASK 0x07 /* mpls exp value ( 3bits) */ + +#define MPLS_FECID_SCOPE(fecid) (((fecid) & MPLS_SCOPE_MASK) >> 20) +#define MPLS_FECID_LABEL(fecid) ((fecid) & MPLS_LABEL_MASK) +#define MPLS_FECID_LABEL_MASK 0x000fffff +#define MPLS_FECID_EXP_MASK 0x00700000 + +#define MPLS_RTF_POP 0x4000 +#define MPLS_RTF_PUSH 0x8000 + +#define AYAME_MPLS_SCOPE(addr) ((ntohl((addr).s_addr) & 0xfff00000) >> 20) +#define AYAME_MPLS_LABEL(addr) (ntohl((addr).s_addr) & 0x000fffff) +#define AYAME_MPLS_ADDR_SAME(addr1,addr2) ((addr1).s_addr == (addr2).s_addr) +#define AYAME_IS_MPLS_ADDR_UNSPEC(addr) ((addr).s_addr == 0) + +#define MPLS_INKERNEL_LOOP_MAX 16 + +#define satosmpls(sa) ((struct sockaddr_mpls *)(sa)) +#define smplstosa(smpls) ((struct sockaddr *)(smpls)) +#define satosdl(sa) ((struct sockaddr_dl *)(sa)) +#define sdltosa(sdl) ((struct sockaddr *)(sdl)) + +struct mpls_ifaddr { + struct ifaddr ia_ifa; /* protocol-independent info */ +#define ia_ifp ia_ifa.ifa_ifp +#define ia_flags ia_ifa.ifa_flags + TAILQ_ENTRY(mpls_ifaddr) ia_list; /* list of MPLS addresses */ + struct sockaddr_mpls ia_addr; /* interface address */ + struct sockaddr ia_dstaddr; /* peer dst address */ +}; + +struct mpls_aliasreq { + char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + struct sockaddr_mpls ifra_addr; + struct sockaddr ifra_dstaddr; + struct sockaddr_mpls ifra_mask; /* not used */ +}; + + +#ifdef _KERNEL +TAILQ_HEAD(mpls_ifaddrhead, mpls_ifaddr); /* the actual queue head */ +extern struct mpls_ifaddrhead mpls_ifaddr; + +extern void mpls_init(void); +extern int mpls_control(struct socket *, u_long, caddr_t, + struct ifnet *, struct lwp *); +extern void mpls_purgeif(struct ifnet *); +#endif /* _KERNEL */ +#endif /* _NETMPLS_MPLS_H_ */ Index: netmpls/mpls_ip.c =================================================================== RCS file: netmpls/mpls_ip.c diff -N netmpls/mpls_ip.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ netmpls/mpls_ip.c 25 May 2006 17:04:41 -0000 @@ -0,0 +1,178 @@ +/* $NetBSD$ */ +/* AYAME Id mpls_ip.c,v 1.2 2002/08/23 16:40:30 zin Exp */ + +/* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "opt_mpls.h" +#include "opt_inet.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +int +mpls_ip_input(struct mbuf *m) +{ + int iphlen; + u_int8_t ttl; + struct ip *ip; + struct ifqueue *inq; + int s; + + if (mpls_mapttl_ip) { + /* get ttl */ + mpls_shim_peep(m, NULL, NULL, NULL, &ttl); + + /* adjust shim header */ + m_adj(m, sizeof(struct shim_hdr)); + + /* chatch up ip header */ + if (m->m_len < sizeof (struct ip) && + (m = m_pullup(m, sizeof(struct ip))) == 0) + return ENOBUFS; + ip = mtod(m, struct ip *); + iphlen = ip->ip_hl << 2; + if (m->m_len < iphlen) { + if ((m = m_pullup(m, iphlen)) == 0) + return ENOBUFS; + ip = mtod(m, struct ip *); + } + + ttl++; + if (ttl && ttl < ip->ip_ttl) { + /* check ipsum */ + if (in_cksum(m, iphlen) != 0) + return EINVAL; + + /* set IP ttl from MPLS ttl */ + ip->ip_ttl = ttl; + + /* reexam ipsum */ + ip->ip_sum = 0; + ip->ip_sum = in_cksum(m, iphlen); + } + } else { + /* adjust shim header */ + m_adj(m, sizeof(struct shim_hdr)); + } + + /* clear label */ + m->m_pkthdr.fecid = 0; + + schednetisr(NETISR_IP); + inq = &ipintrq; + + s = splnet(); + if (IF_QFULL(inq)) { + IF_DROP(inq); + m_freem(m); + } else + IF_ENQUEUE(inq, m); + splx(s); + + return 0; +} + +int +mpls_ip_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, + struct rtentry *rt) +{ + struct sockaddr_mpls smpls; + struct ip *iphdr; + u_int32_t ipv4null = MPLS_LABEL_IPV4NULL; + u_int8_t ttl, bosf = 1; + +#if 0 /* It's too old */ + printf("mpls_ip_output:" + " catch a packet to forward (scope=%d,label=%d)\n", + (m->m_pkthdr.fecid & MPLS_SCOPE_MASK) >> 20, + m->m_pkthdr.fecid & MPLS_LABEL_MASK); +#endif /* MPLS_DEBUG */ + + if (mpls_mapttl_ip) { + /* catch-up ip hdr */ + if (m->m_len < sizeof(struct ip)) + if ((m = m_pullup(m, sizeof(struct ip))) == 0) + return(ENOBUFS); + iphdr = mtod(m, struct ip *); + /* map ip ttl to mpls ttl */ + ttl = iphdr->ip_ttl; + } else + ttl = mpls_defttl; + if (ttl < 255) + ttl++; /* XXX */ + + bzero((caddr_t)&smpls, sizeof(smpls)); + smpls.smpls_family = AF_MPLS; + smpls.smpls_len = sizeof(smpls); + smpls.smpls_label = m->m_pkthdr.fecid; + /* XXX E-LSP adhoc support XXX */ + /* XXX where is scope? XXX */ + /* + smpls.smpls_exp |= + ((u_int8_t)((m->m_pkthdr.fecid & MPLS_FECID_EXP_MASK) >> 19)) + & SHIM_EXP_MASK; + */ + + if (mpls_push_expnull_ip) { + if ((m = mpls_shim_push(m, NULL, &ipv4null, &bosf, &ttl)) == 0) + return ENOBUFS; + bosf = 0; + } + + /* Add bottom label by fecid */ + if ((m = mpls_shim_push(m, &smpls, NULL, &bosf, &ttl)) == 0) + return ENOBUFS; + + /* send to mpls_lse */ + return mpls_lse(ifp, m, &smpls, bosf); +} Index: netmpls/mpls_ip6.c =================================================================== RCS file: netmpls/mpls_ip6.c diff -N netmpls/mpls_ip6.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ netmpls/mpls_ip6.c 25 May 2006 17:05:30 -0000 @@ -0,0 +1,159 @@ +/* $NetBSD$ */ +/* AYAME Id mpls_ip6.c,v 1.3 2002/08/23 16:40:30 zin Exp */ + +/* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "opt_mpls.h" +#include "opt_inet.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +int +mpls_ip6_input(struct mbuf *m) +{ + u_int8_t ttl; + struct ip6_hdr *ip6hdr; + struct ifqueue *inq; + int s; + + if (mpls_mapttl_ip6) { /* XXX not supported yet XXX */ + /* get ttl */ + mpls_shim_peep(m, NULL, NULL, NULL, &ttl); + + /* adjust shim header */ + m_adj(m, sizeof(struct shim_hdr)); + + /* chatch up ip header */ + if (m->m_len < sizeof (struct ip6_hdr) && + (m = m_pullup(m, sizeof(struct ip6_hdr))) == 0) + return ENOBUFS; + ip6hdr = mtod(m, struct ip6_hdr *); + + ttl++; + ip6hdr->ip6_hlim = ttl; + } else { + /* adjust shim header */ + m_adj(m, sizeof(struct shim_hdr)); + } + + /* clear label */ + m->m_pkthdr.fecid = 0; + + schednetisr(NETISR_IPV6); + inq = &ip6intrq; + + s = splnet(); + if (IF_QFULL(inq)) { + IF_DROP(inq); + m_freem(m); + } else + IF_ENQUEUE(inq, m); + splx(s); + return(0); +} + +int +mpls_ip6_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, + struct rtentry *rt) +{ + struct sockaddr_mpls smpls; + struct ip6_hdr *ip6hdr; + u_int32_t ipv6null = MPLS_LABEL_IPV6NULL; + u_int8_t ttl, bosf = 1; + +#if 0 /* It's too old */ + printf("mpls_ip6_output:" + " catch a packet to forward (scope=%d,label=%d)\n", + (m->m_pkthdr.fecid & MPLS_SCOPE_MASK) >> 20, + m->m_pkthdr.fecid & MPLS_LABEL_MASK); +#endif /* MPLS_DEBUG */ + + if (mpls_mapttl_ip6) { + /* catch-up ip6 hdr */ + if (m->m_len < sizeof(struct ip6_hdr)) + if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == 0) + return(ENOBUFS); + ip6hdr = mtod(m, struct ip6_hdr *); + /* map ip ttl to mpls ttl */ + ttl = ip6hdr->ip6_hlim; + } else + ttl = mpls_defttl; + if (ttl < 255) + ttl++; /* XXX */ + + bzero((caddr_t)&smpls, sizeof(smpls)); + smpls.smpls_family = AF_MPLS; + smpls.smpls_len = sizeof(smpls); + smpls.smpls_label = m->m_pkthdr.fecid; + /* XXX E-LSP adhoc support XXX */ + /* XXX where is scope? XXX */ + /* + smpls.smpls_exp |= + ((u_int8_t)((m->m_pkthdr.fecid & MPLS_FECID_EXP_MASK) >> 19)) + & SHIM_EXP_MASK; + */ + + if (mpls_push_expnull_ip6) { + if ((m = mpls_shim_push(m, NULL, &ipv6null, &bosf, &ttl)) == 0) + return ENOBUFS; + bosf = 0; + } + + /* Add bottom label by fecid */ + if ((m = mpls_shim_push(m, &smpls, NULL, &bosf, &ttl)) == 0) + return ENOBUFS; + + /* send to mpls_lse */ + return mpls_lse(ifp, m, &smpls, bosf); +} Index: netmpls/mpls_lse.c =================================================================== RCS file: netmpls/mpls_lse.c diff -N netmpls/mpls_lse.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ netmpls/mpls_lse.c 25 May 2006 17:13:41 -0000 @@ -0,0 +1,318 @@ +/* $NetBSD$ */ +/* AYAME Id mpls_lse.c,v 1.5 2003/05/17 09:30:32 n-ogashi Exp */ + +/* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "opt_mpls.h" +#include "opt_inet.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +/* + * MPLS Label Switching Engine. + */ + +/* + * Process a received MPLS packet; + * the packet is in the mbuf chain m from mpls_{ether,...}. + */ +int +mpls_lse(struct ifnet *ifp, struct mbuf *m, struct sockaddr_mpls *dst, + uint8_t bosf) +{ + struct route mplsroute; + struct route *ro = &mplsroute; + struct sockaddr_mpls *rodst = satosmpls(&mplsroute.ro_dst); + struct rtentry *rt = NULL; + struct sockaddr_mpls *dstnew; + struct sockaddr_mpls smpls; /* XXX adhoc XXX */ + u_int8_t exp_bits; /* XXX adhoc XXX */ + int ink_loop, error = 0; + + bzero((caddr_t)ro, sizeof(*ro)); + bcopy((caddr_t)dst, (caddr_t)rodst, dst->smpls_len); + + /* TTL decriment */ + if ((m = mpls_shim_ttl_dec(m)) == NULL) + goto done; + + for (ink_loop = 0; ink_loop < mpls_inkloop; ink_loop++) { + +#ifdef MPLS_DEBUG + printf("MPLS_DEBUG: %s(%d). [label = %08x]\n", + __FILE__, __LINE__, ntohl(rodst->smpls_label)); +#endif /* MPLS_DEBUG */ + + /* + * OPERATIONS for Reserved Labels + */ + if (ntohl(rodst->smpls_label) <= MPLS_LABEL_RESERVED_MAX) { + switch (ntohl(rodst->smpls_label)) { +#ifdef INET + case MPLS_LABEL_IPV4NULL: + if (bosf) { + error = mpls_ip_input(m); + goto done; + } +#ifdef MPLS_DEBUG + printf("MPLS_DEBUG: %s(%d). [bosf = %d]\n", + __FILE__, __LINE__, bosf); +#endif /* MPLS_DEBUG */ + break; +#endif /* INET */ +#ifdef INET6 + case MPLS_LABEL_IPV6NULL: + if (bosf) { + error = mpls_ip6_input(m); + goto done; + } + break; +#endif /* INET6 */ + } + + /* label is reserved, */ + /* but operation is unsupported or invalid */ + error = EINVAL; + printf("MPLS_DEBUG: %s(%d).\n", __FILE__, __LINE__); + goto bad; + } + + /* + * route packet + */ + /* XXX */ + exp_bits = rodst->smpls_exp; + rodst->smpls_exp = 0; + + rtalloc(ro); + rt = ro->ro_rt; + bzero((caddr_t)ro, sizeof(*ro)); + + if (rt == 0) { + /* no entry for this label (silent discard) */ + /* as the scope_id you use is not set interface, etc. */ + /* error = EHOSTUNREACH; */ + error = 0; +#ifdef MPLS_DEBUG + printf("MPLS_DEBUG: %s(%d).\n", __FILE__, __LINE__); +#endif /* MPLS_DEBUG */ + goto bad; + } + + /* + if ((mtu = rt->rt_rmx.rmx_mtu) == 0) + mtu = ifp->if_mtu; + */ + + + /* + * label operations + */ + rt->rt_use++; + if (rt->rt_flags & RTF_GATEWAY) /* XXX */ + dstnew = satosmpls(rt->rt_gateway); + else { + /* XXX silent discard XXX */ + /* error = EHOSTUNREACH; */ + error = 0; +#ifdef MPLS_DEBUG + printf("MPLS_DEBUG: %s(%d).\n", __FILE__, __LINE__); +#endif /* MPLS_DEBUG */ + goto bad; + } + +#ifdef MPLS_MCAST + printf("MPLS_MCAST label=%d mclabel=%d\n", + ntohl(dstnew->smpls_label) & 0x000fffff, + ntohl(dstnew->smpls_mclabel)); + /* + * if gw_entry have next mplsmc entry, + * call mpls_lse again. + */ + if (dstnew->smpls_mclabel != 0) { + struct sockaddr_mpls smpmpls; + struct mbuf *nm; + memset(&smpmpls, 0, sizeof(smpmpls)); + smpmpls.smpls_len = sizeof(smpmpls); + smpmpls.smpls_family = AF_MPLS; + smpmpls.smpls_label = dstnew->smpls_mclabel; +#ifdef MPLS_DEBUG + printf("MPLS_MCAST label=%d mclabel=%d\n", + ntohl(dstnew->smpls_label) & 0x000fffff, + ntohl(dstnew->smpls_mclabel)); +#endif /* MPLS_DEBUG */ + nm = m_copym(m, 0, M_COPYALL, M_DONTWAIT); + if (nm != NULL) { +#ifdef MPLS_DEBUG + printf("MPLS_MCAST dup\n"); +#endif /* MPLS_DEBUG */ + mpls_lse(ifp, nm, &smpmpls, bosf); + m_freem(nm); + } + } +#endif /* MPLS_MCAST */ + + if (dstnew->smpls_family != AF_MPLS) { + if (bosf) { + /* send to L3? */ + switch (dstnew->smpls_family) { +#ifdef INET + case AF_INET: + error = mpls_ip_input(m); + goto done; +#endif /* INET */ +#ifdef INET6 + case AF_INET6: + error = mpls_ip6_input(m); + goto done; +#endif /* INET6 */ + default: + error = EAFNOSUPPORT; +#ifdef MPLS_DEBUG + printf("MPLS_DEBUG: %s(%d).\n", __FILE__, __LINE__); +#endif /* MPLS_DEBUG */ + goto bad; + } + } else { + /* XXX */ + error = EINVAL; +#ifdef MPLS_DEBUG + printf("MPLS_DEBUG: %s(%d).\n", __FILE__, __LINE__); +#endif /* MPLS_DEBUG */ + goto bad; + } + } + + /* XXX */ + smpls = *dstnew; + smpls.smpls_exp = exp_bits; + dstnew = &smpls; + /* XXX */ + + switch(rt->rt_flags & (MPLS_RTF_POP | MPLS_RTF_PUSH)) { + + case MPLS_RTF_POP: /* Label Pop */ + + /* check bos flag */ + if (bosf) { + /* + * XXXXX No ExpNULL XXXXX + * + * I can't know which l3 I shuld send to!! + * now, send to IPv4 stack (XXXXX) + * + * error = EINVAL; + * goto bad; + */ + + error = mpls_ip_input(m); + goto done; + } + /* label pop */ + if ((m = mpls_shim_pop(m, rodst, NULL, &bosf, NULL)) == 0) { + error = ENOBUFS; + goto done; + } + + break; + + case MPLS_RTF_PUSH: /* Label Push */ + + if ((m = mpls_shim_push(m, dstnew, NULL, NULL, NULL)) == 0) { + error = ENOBUFS; + goto done; + } + bosf = 0; + + break; + + case (MPLS_RTF_POP | MPLS_RTF_PUSH): /* Label Swap */ + default: + + if ((m = mpls_shim_swap(m, dstnew, NULL)) == 0) { + error = ENOBUFS; + goto done; + } + } + + ifp = rt->rt_ifp; + /* send to L2 : select outgoing i/f */ + switch (ifp->if_type) { + case IFT_ETHER: + case IFT_ATM: /* now only support scope 0 */ + case IFT_GIF: /* now only support scope 0 */ + error = mpls_shim_output(ifp, m, dstnew, rt); + goto done; + case IFT_LOOP: + break; + default: + /* not supported yet: discard */ +#ifdef MPLS_DEBUG + printf("mpls_lse: interface type not supported yet!\n"); +#endif /* MPLS_DEBUG */ + error = EHOSTUNREACH; + goto bad; + } + + if (rt) { + RTFREE(rt); + rt = 0; + } + } + + /* + * Discard broken packet + */ +bad: +#ifdef MPLS_DEBUG + printf("MPLS_DEBUG: %s(%d) [packet discard!!].\n", __FILE__, __LINE__); +#endif /* MPLS_DEBUG */ + m_freem(m); + +done: + if (rt) + RTFREE(rt); + + return error; +} Index: netmpls/mpls_proto.c =================================================================== RCS file: netmpls/mpls_proto.c diff -N netmpls/mpls_proto.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ netmpls/mpls_proto.c 25 May 2006 17:18:22 -0000 @@ -0,0 +1,77 @@ +/* $NetBSD$ */ +/* AYAME Id mpls_proto.c,v 1.1 2001/10/18 07:27:34 ayame Exp */ + +/* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +/* + * MPLS protocol family: + */ + +extern struct domain mplsdomain; + +struct protosw mplssw[] = { +{ 0, &mplsdomain, 0, 0, + 0, 0, 0, 0, + 0, + mpls_init, 0, 0, 0, NULL +}, +{ SOCK_DGRAM, &mplsdomain, 0, PR_ATOMIC|PR_ADDR, + 0, 0, 0, 0, + mpls_raw_usrreq, + 0, 0, 0, 0, NULL +}, +/* raw wildcard */ +{ SOCK_RAW, &mplsdomain, 0, PR_ATOMIC|PR_ADDR, + 0, 0, 0, 0, + mpls_raw_usrreq, + 0, 0, 0, 0, NULL +}, +}; + +struct domain mplsdomain = { + PF_MPLS, "mpls", /* mpls_init */ 0, 0, 0, + mplssw, + &mplssw[sizeof(mplssw)/sizeof(mplssw[0])], + rn_inithead, + offsetof(struct sockaddr_mpls, smpls_label) << 3, + sizeof(struct sockaddr_mpls) +}; Index: netmpls/mpls_raw.c =================================================================== RCS file: netmpls/mpls_raw.c diff -N netmpls/mpls_raw.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ netmpls/mpls_raw.c 25 May 2006 20:18:29 -0000 @@ -0,0 +1,185 @@ +/* $NetBSD$ */ +/* AYAME Id mpls_raw.c,v 1.2 2002/08/31 18:46:15 zin Exp */ + +/* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "opt_inet.h" +#include "opt_inet6.h" +#include "opt_mpls.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#define MPLS_RAW_SNDQ 8192 +#define MPLS_RAW_RCVQ 8192 + +u_long mpls_raw_sendspace = MPLS_RAW_SNDQ; +u_long mpls_raw_recvspace = MPLS_RAW_RCVQ; + +int mpls_defttl = 255; +int mpls_inkloop = 16; +int mpls_push_expnull_ip = 1; +int mpls_push_expnull_ip6 = 0; +int mpls_mapttl_ip = 1; +int mpls_mapttl_ip6 = 0; + +int +mpls_raw_usrreq(struct socket *so, int req, struct mbuf *m, + struct mbuf *nam, struct mbuf *control, struct lwp *l) +{ + int s; + int error = 0; + +#ifdef MPLS_DEBUG + printf("mpls_raw_usrreq: called! (reqid=%d).\n", req); +#endif /* MPLS_DEBUG */ + + if (req == PRU_CONTROL) + return (mpls_control(so, (long)m, (caddr_t)nam, + (struct ifnet *)control, l)); + + if (req == PRU_PURGEIF) { + mpls_purgeif((struct ifnet *)control); + return (0); + } + + s = splsoftnet(); + + switch (req) { + + case PRU_ATTACH: + if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { + error = soreserve(so, mpls_raw_sendspace, + mpls_raw_recvspace); + if (error) + break; + } + break; + + case PRU_DETACH: + case PRU_BIND: + case PRU_LISTEN: + case PRU_CONNECT: + case PRU_CONNECT2: + case PRU_DISCONNECT: + case PRU_SHUTDOWN: + case PRU_RCVD: + case PRU_SEND: + case PRU_SENSE: + case PRU_RCVOOB: + case PRU_SENDOOB: + case PRU_SOCKADDR: + case PRU_PEERADDR: + error = EOPNOTSUPP; + break; + + default: + panic("rip_usrreq"); + } + +/* release: */ + splx(s); + return (error); +} + +/* + * Sysctl for MPLS variables. + */ +SYSCTL_SETUP(sysctl_net_mpls_setup, "sysctl net.mpls subtree setup") +{ + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_NODE, "net", NULL, + NULL, 0, NULL, 0, + CTL_NET, CTL_EOL); + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_NODE, "mpls", NULL, + NULL, 0, NULL, 0, + CTL_NET, PF_MPLS, CTL_EOL); + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, + CTLTYPE_INT, "ttl", + SYSCTL_DESCR("Default TTL"), + NULL, 0, &mpls_defttl, 0, + CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL); + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, + CTLTYPE_INT, "maxloop_inkernel", + SYSCTL_DESCR("Maximum inkernel loop"), + NULL, 0, &mpls_maxinkloop, 0, + CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL); +#ifdef INET + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, + CTLTYPE_INT, "pushexpnull_ip", + SYSCTL_DESCR("Push ???"), + NULL, 0, &mpls_push_expnull_ip, 0, + CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL); + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, + CTLTYPE_INT, "mapttl_ip", + SYSCTL_DESCR("Map ???"), + NULL, 0, &mpls_mapttl_ip, 0, + CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL); +#endif +#ifdef INET6 + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, + CTLTYPE_INT, "pushexpnull_ip6", + SYSCTL_DESCR("Push ???"), + NULL, 0, &mpls_push_expnull_ip6, 0, + CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL); + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, + CTLTYPE_INT, "mapttl_ip6", + SYSCTL_DESCR("Map ???"), + NULL, 0, &mpls_mapttl_ip6, 0, + CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL); +#endif + +} Index: netmpls/mpls_shim.c =================================================================== RCS file: netmpls/mpls_shim.c diff -N netmpls/mpls_shim.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ netmpls/mpls_shim.c 25 May 2006 17:10:33 -0000 @@ -0,0 +1,234 @@ +/* $NetBSD$ */ +/* AYAME Id mpls_shim.c,v 1.1 2001/10/18 07:27:34 ayame Exp */ + +/* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +/* + * SHIM header exam. + */ + +struct mbuf * +mpls_shim_peep(struct mbuf *m, struct sockaddr_mpls *smplsp, + uint32_t *labelp, uint8_t *bosp, uint8_t *ttlp) +{ + struct shim_hdr *shim; + uint32_t label; + + if (m->m_len < sizeof(struct shim_hdr)) + if ((m = m_pullup(m, sizeof(struct shim_hdr))) == 0) + return(0); + shim = mtod(m, struct shim_hdr *); + + /* set FECid to mbuf */ + label = MPLS_SHIM_LABEL(shim); + if (label > MPLS_LABEL_RESERVED_MAX) + /* scope is always zero */ + m->m_pkthdr.fecid = label; + + /* set sockaddr_mpls structure, if need */ + if (smplsp) { + bzero((caddr_t)smplsp, sizeof(*smplsp)); + smplsp->smpls_family = AF_MPLS; + smplsp->smpls_len = sizeof(*smplsp); + smplsp->smpls_label = htonl(label); /* scope is zero */ + smplsp->smpls_exp = MPLS_SHIM_EXP(shim); + } + + /* set each value, if need */ + if (labelp) + *labelp = label; /* scope is zero */ + if (bosp) + *bosp = MPLS_SHIM_BOS(shim); + if (ttlp) + *ttlp = MPLS_SHIM_TTL(shim); + + /* return mbuf */ + return(m); +} + +struct mbuf * +mpls_shim_pop(struct mbuf *m, struct sockaddr_mpls *smplsp, + uint32_t *labelp, uint8_t *bosp, uint8_t *ttlp) +{ + /* shaves off top shim header from mbuf */ + m_adj(m, sizeof(struct shim_hdr)); + + /* catch-up next shim_hdr */ + if (m->m_len < sizeof(struct shim_hdr)) + if ((m = m_pullup(m, sizeof(struct shim_hdr))) == 0) + return(0); + + /* set each values, if need */ + m = mpls_shim_peep(m, smplsp, labelp, bosp, ttlp); + + /* return mbuf */ + return(m); +} + +struct mbuf * +mpls_shim_swap(struct mbuf *m, struct sockaddr_mpls *smplsp, + uint32_t *labelp) +{ + struct shim_hdr *shim; + + /* pullup shim_hdr */ + if (m->m_len < sizeof(struct shim_hdr)) + if ((m = m_pullup(m, sizeof(struct shim_hdr))) == 0) + return(0); + shim = mtod(m, struct shim_hdr *); + + if (smplsp == NULL && labelp == NULL) + /* can't swap, because no dst label */ + return(m); /* XXX discard? XXX */ + + /* fecid swap */ + if (labelp) { + m->m_pkthdr.fecid = *labelp; + /* + if (smplsp) + smplsp->smpls_label = htonl(*labelp); + */ + } else + m->m_pkthdr.fecid = ntohl(smplsp->smpls_label); + + /* shim swap label */ + shim->shim_label &= ~SHIM_LABEL_MASK; + shim->shim_label |= + htonl((m->m_pkthdr.fecid & MPLS_LABEL_MASK) << SHIM_LABEL_OFFSET); + /* shim swap exp : XXX exp override */ + if (smplsp) { + shim->shim_exp &= ~SHIM_EXP_MASK; /* XXX exp override */ + shim->shim_exp |= + smplsp->smpls_exp << SHIM_EXP_OFFSET & SHIM_EXP_MASK; + } + + return(m); +} + +struct mbuf * +mpls_shim_push(struct mbuf *m, struct sockaddr_mpls *smplsp, + uint32_t *labelp, uint8_t *bosp, uint8_t *ttlp) +{ + struct shim_hdr *shim; + + M_PREPEND(m, sizeof(struct shim_hdr), M_DONTWAIT); + if (m == 0) + return(0); + + shim = mtod(m, struct shim_hdr *); + bzero((caddr_t)shim, sizeof(*shim)); + + if (bosp) + shim->shim_exp = *bosp & SHIM_BOS_MASK; + if (ttlp) + shim->shim_ttl = *ttlp; + else + shim->shim_ttl = 255; /* XXX */ + m = mpls_shim_swap(m, smplsp, labelp); + + return m; +} + +struct mbuf * +mpls_shim_ttl_dec(struct mbuf *m) +{ + struct shim_hdr *shim; + + /* pullup shim_hdr */ + if (m->m_len < sizeof(struct shim_hdr)) + if ((m = m_pullup(m, sizeof(struct shim_hdr))) == 0) + return 0; + shim = mtod(m, struct shim_hdr *); + + if (shim->shim_ttl == 0) { + /* shim ttl exceed */ + m_freem(m); + return 0; + } + shim->shim_ttl--; + + return m; +} + +/* + * MPLS shimed packet exam routine. + * the packet is in the mbuf chain m + */ + +int +mpls_shim_output(struct ifnet *ifp, struct mbuf *m, + struct sockaddr_mpls *smpls, struct rtentry *rt) +{ + int error; + + /* XXX */ + if (ifp->if_type) + m->m_pkthdr.fecid = 0; + + /* no need to exp_exam for output */ + error = (*ifp->if_output)(ifp, m, smplstosa(smpls), rt); + + return error; +} + +void +mpls_shim_input(struct ifnet *ifp, struct mbuf *m) +{ + struct sockaddr_mpls smpls; + u_int8_t bosf; + + if ((m = mpls_shim_peep(m, &smpls, NULL, &bosf, NULL)) == 0) + return; + + /* set interface scope to m->m_pkthdr.fecid */ + /* XXX now only support global(zero) scope */ + +#ifdef MPLS_DEBUG + printf("mpls_ether_input:" + " catch a packet to forward to LSE (scope=%d,label=%d)\n", + (ntohl(smpls.smpls_label) & MPLS_SCOPE_MASK) >> 20, + ntohl(smpls.smpls_label) & MPLS_LABEL_MASK); +#endif /* MPLS_DEBUG */ + + mpls_lse(ifp, m, &smpls, bosf); +} Index: netmpls/mpls_var.h =================================================================== RCS file: netmpls/mpls_var.h diff -N netmpls/mpls_var.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ netmpls/mpls_var.h 25 May 2006 19:48:03 -0000 @@ -0,0 +1,68 @@ +/* $NetBSD$ */ +/* AYAME Id mpls_var.h,v 1.4 2002/08/31 19:20:47 zin Exp */ +/* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef _KERNEL +extern int mpls_defttl; +extern int mpls_inkloop; +extern int mpls_push_expnull_ip; +extern int mpls_push_expnull_ip6; +extern int mpls_mapttl_ip; +extern int mpls_mapttl_ip6; + +extern int mpls_lse(struct ifnet *, struct mbuf *, + struct sockaddr_mpls *, u_int8_t); +extern int mpls_canfwbympls(u_int32_t); +extern struct mbuf *mpls_shim_peep(struct mbuf *, struct sockaddr_mpls *, + u_int32_t *, u_int8_t *, u_int8_t *); +extern struct mbuf *mpls_shim_pop(struct mbuf *, struct sockaddr_mpls *, + u_int32_t *, u_int8_t *, u_int8_t *); +extern struct mbuf *mpls_shim_swap(struct mbuf *, struct sockaddr_mpls *, + u_int32_t *); +extern struct mbuf *mpls_shim_push(struct mbuf *, struct sockaddr_mpls *, + u_int32_t *, u_int8_t *, u_int8_t *); +extern struct mbuf *mpls_shim_ttl_dec(struct mbuf *); + +extern int mpls_raw_usrreq(struct socket *, int, struct mbuf *, + struct mbuf *, struct mbuf *, struct lwp *); +extern int mpls_shim_output(struct ifnet *, struct mbuf *, + struct sockaddr_mpls *, struct rtentry *); +extern void mpls_shim_input(struct ifnet *, struct mbuf *); +/* #ifdef INET / temp comment-out */ +extern int mpls_ip_input(struct mbuf *); +extern int mpls_ip_output(struct ifnet *, struct mbuf *, + struct sockaddr *, struct rtentry *); +/* #endif INET */ +/* #ifdef INET6 / temp comment-out */ +extern int mpls_ip6_input(struct mbuf *); +extern int mpls_ip6_output(struct ifnet *, struct mbuf *, + struct sockaddr *, struct rtentry *); +/* #endif INET6 */ +#endif /* _KERNEL */ Index: sys/mbuf.h =================================================================== RCS file: /usr/cvs/src/sys/sys/mbuf.h,v retrieving revision 1.127 diff -u -p -r1.127 mbuf.h --- sys/mbuf.h 16 Mar 2006 13:41:56 -0000 1.127 +++ sys/mbuf.h 25 May 2006 15:14:41 -0000 @@ -1,5 +1,34 @@ /* $NetBSD: mbuf.h,v 1.127 2006/03/16 13:41:56 yamt Exp $ */ +/* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + /*- * Copyright (c) 1996, 1997, 1999, 2001 The NetBSD Foundation, Inc. * All rights reserved. @@ -159,6 +188,9 @@ struct pkthdr { int csum_flags; /* checksum flags */ uint32_t csum_data; /* checksum data */ u_int segsz; /* segment size */ + uint32_t fecid; /* explicit gw (pointer to rtentry) */ + /* used by sub-l3 (mpls, etc.) */ + }; /* @@ -474,6 +506,7 @@ MBUFLOCK( \ (m)->m_pkthdr.rcvif = NULL; \ (m)->m_pkthdr.csum_flags = 0; \ (m)->m_pkthdr.csum_data = 0; \ + (m)->m_pkthdr.fecid = 0; \ SLIST_INIT(&(m)->m_pkthdr.tags); \ } \ ) Index: sys/socket.h =================================================================== RCS file: /usr/cvs/src/sys/sys/socket.h,v retrieving revision 1.79 diff -u -p -r1.79 socket.h --- sys/socket.h 11 May 2006 15:49:44 -0000 1.79 +++ sys/socket.h 25 May 2006 16:15:02 -0000 @@ -1,6 +1,35 @@ /* $NetBSD: socket.h,v 1.79 2006/05/11 15:49:44 christos Exp $ */ /* + * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * @@ -195,8 +224,9 @@ struct linger { #define pseudo_AF_HDRCMPLT 30 /* Used by BPF to not rewrite hdrs in interface output routine */ #endif +#define AF_MPLS 31 /* Multiprotocol Label Switching */ -#define AF_MAX 31 +#define AF_MAX 32 /* * Structure used by kernel to store most @@ -282,6 +312,7 @@ struct sockaddr_storage { #if defined(_NETBSD_SOURCE) #define PF_KEY pseudo_AF_KEY /* like PF_ROUTE, only for key mgmt */ #endif +#define PF_MPLS AF_MPLS #define PF_MAX AF_MAX @@ -359,6 +390,8 @@ struct sockcred { { "natm", CTLTYPE_NODE }, \ { "arp", CTLTYPE_NODE }, \ { "key", CTLTYPE_NODE }, \ + { 0, 0 }, \ + { "mpls", CTLTYPE_NODE }, \ } struct kinfo_pcb {