summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/netmpls/mpls.c111
-rw-r--r--sys/netmpls/mpls.h296
-rw-r--r--sys/netmpls/mpls_input.c337
-rw-r--r--sys/netmpls/mpls_lse.c333
-rw-r--r--sys/netmpls/mpls_proto.c155
-rw-r--r--sys/netmpls/mpls_raw.c301
-rw-r--r--sys/netmpls/mpls_shim.c247
-rw-r--r--sys/netmpls/mpls_var.h65
8 files changed, 1845 insertions, 0 deletions
diff --git a/sys/netmpls/mpls.c b/sys/netmpls/mpls.c
new file mode 100644
index 00000000000..ac683aa135e
--- /dev/null
+++ b/sys/netmpls/mpls.c
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+/*
+ *
+ * $Id: mpls.c,v 1.1 2008/04/23 11:00:35 norby Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/errno.h>
+#include <sys/protosw.h>
+#include <sys/sockio.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/systm.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <netmpls/mpls.h>
+#include <netmpls/mpls_var.h>
+
+extern void mpls_purgeaddr(struct ifaddr *, struct ifnet *);
+extern int mpls_ifinit(struct ifnet *, struct mpls_ifaddr *,
+ struct sockaddr_mpls *, int);
+extern void mpls_ifscrub(struct mpls_ifaddr *);
+
+struct mpls_ifaddrhead mpls_ifaddr;
+struct sockaddr_mpls mpls_scope_sockmask;
+
+void
+mpls_init()
+{
+ mplsintrq.ifq_maxlen = 50;
+}
+
+void
+mpls_purgeaddr(struct ifaddr *ifa, struct ifnet *ifp)
+{
+}
+
+void
+mpls_purgeif(struct ifnet *ifp)
+{
+}
+
+/*
+ * Delete any existing route for an interface.
+ */
+void
+mpls_ifscrub(struct mpls_ifaddr *ia)
+{
+}
+
+/*
+ * 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)
+{
+#ifdef MPLS_DEBUG
+ panic("mpls_ifinit\n");
+#endif
+ return (EAFNOSUPPORT);
+}
+
+/*
+ * Generic MPLS control operations (ioctl's).
+ * Ifp is 0 if not an interface-specific ioctl.
+ */
+/* ARGSUSED */
+int
+mpls_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
+{
+ return (EOPNOTSUPP);
+}
diff --git a/sys/netmpls/mpls.h b/sys/netmpls/mpls.h
new file mode 100644
index 00000000000..969795208f2
--- /dev/null
+++ b/sys/netmpls/mpls.h
@@ -0,0 +1,296 @@
+/* $OpenBSD: mpls.h,v 1.1 2008/04/23 11:00:35 norby 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 PARTICULARPURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, ORCONSEQUENTIAL
+ * 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 <sys/param.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <sys/queue.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+
+/*
+ * Structure of a SHIM header.
+ */
+struct shim_hdr {
+ u_int32_t shim_label; /* 20 bit label, 4 bit exp & BoS, 8 bit TTL */
+};
+
+/*
+ * By byte-swapping the constants, we avoid ever having to byte-swap IP
+ * addresses inside the kernel. Unfortunately, user-level programs rely
+ * on these macros not doing byte-swapping.
+ */
+
+#ifdef _KERNEL
+#define __MADDR(x) ((u_int32_t)htonl((u_int32_t)(x)))
+#else
+#define __MADDR(x) ((u_int32_t)(x))
+#endif
+
+#define MPLS_LABEL_MASK __MADDR(0xfffff000U)
+#define MPLS_LABEL_OFFSET 12
+#define MPLS_EXP_MASK __MADDR(0x00000e00U)
+#define MPLS_EXP_OFFSET 9
+#define MPLS_BOS_MASK __MADDR(0x00000100U)
+#define MPLS_BOS_OFFSET 8
+#define MPLS_TTL_MASK __MADDR(0x000000ffU)
+
+#define MPLS_BOS_ISSET(l) (((l) & MPLS_BOS_MASK) == MPLS_BOS_MASK)
+
+/* Reserved lavel values (RFC3032) */
+#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 sockaddr_mpls {
+ u_int8_t smpls_len; /* length */
+ u_int8_t smpls_family; /* AF_MPLS */
+ u_int8_t smpls_operation;
+ u_int8_t smpls_out_exp; /* outgoing exp value */
+ u_int32_t smpls_out_label; /* outgoing MPLS label */
+ u_int16_t smpls_out_ifindex;
+ u_int16_t smpls_in_ifindex;
+ u_int32_t smpls_in_label; /* MPLS label 20 bits*/
+#if MPLS_MCAST
+ u_int8_t smpls_mcexp;
+ u_int8_t smpls_pad2[2];
+ u_int32_t smpls_mclabel;
+#endif
+};
+
+#define MPLS_OP_POP 1
+#define MPLS_OP_PUSH 2
+#define MPLS_OP_SWAP 3
+
+#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))
+
+/*
+ * Names for MPLS sysctl objects
+ */
+#define MPLSCTL_ENABLE 1
+#define MPLSCTL_DEFTTL 2
+#define MPLSCTL_IFQUEUE 3
+#define MPLSCTL_MAXINKLOOP 4
+#define MPLSCTL_MAXID 5
+
+#define MPLSCTL_NAMES { \
+ { 0, 0 }, \
+ { "enable", CTLTYPE_INT }, \
+ { "ttl", CTLTYPE_INT }, \
+ { "ifq", CTLTYPE_NODE },\
+ { "maxloop_inkernel", CTLTYPE_INT }, \
+}
+
+#define MPLSCTL_VARS { \
+ 0, \
+ &mpls_enable, \
+ &mpls_defttl, \
+ 0, \
+ &mpls_inkloop, \
+}
+
+#endif
+/*
+ * 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 PARTICULARPURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, ORCONSEQUENTIAL
+ * 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.
+ */
+
+/*
+ *
+ * $Id: mpls.h,v 1.1 2008/04/23 11:00:35 norby Exp $
+ */
+
+#ifndef _NETMPLS_MPLS_H_
+#define _NETMPLS_MPLS_H_
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <sys/queue.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+
+/*
+ * Structure of a SHIM header.
+ */
+struct shim_hdr {
+ u_int32_t shim_label; /* 20bit label, 4bit exp & BOS, 8bit ttl */
+};
+
+/*
+ * By byte-swapping the constants, we avoid ever having to byte-swap IP
+ * addresses inside the kernel. Unfortunately, user-level programs rely
+ * on these macros not doing byte-swapping.
+ */
+#define SHIM_LABEL_MASK 0xfffff000U
+#define SHIM_LABEL_OFFSET 12
+#define SHIM_EXP_MASK 0x00000e00U
+#define SHIM_EXP_OFFSET 9
+#define SHIM_BOS_MASK 0x00000100U
+#define SHIM_BOS_OFFSET 8
+#define SHIM_TTL_MASK 0x000000ffU
+
+#define MPLS_SHIM_LABEL_GET(l) (((l) & SHIM_LABEL_MASK) >> SHIM_LABEL_OFFSET)
+#define MPLS_SHIM_EXP_GET(l) (((l) & SHIM_EXP_MASK) >> SHIM_EXP_OFFSET)
+#define MPLS_SHIM_BOS_ISSET(l) (((l) & SHIM_BOS_MASK) == SHIM_BOS_MASK)
+#define MPLS_SHIM_TTL_GET(l) ((l) & SHIM_TTL_MASK)
+#define MPLS_SHIM_TTL_SET(l, t) (((l) & ~SHIM_TTL_MASK) | ((t) & SHIM_TTL_MASK))
+
+/* Reserved lavel values (rfc3032) */
+#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 sockaddr_mpls {
+ u_int8_t smpls_len; /* length */
+ u_int8_t smpls_family; /* AF_MPLS */
+ u_int8_t smpls_operation;
+ u_int8_t smpls_out_exp; /* outgoing exp value */
+ u_int32_t smpls_out_label; /* outgoing MPLS label */
+ u_int16_t smpls_out_ifindex;
+ u_int16_t smpls_in_ifindex;
+ u_int32_t smpls_in_label; /* MPLS label 20 bits*/
+#if MPLS_MCAST
+ u_int8_t smpls_mcexp;
+ u_int8_t smpls_pad2[2];
+ u_int32_t smpls_mclabel;
+#endif
+};
+
+#define MPLS_EXP_MASK 0x07 /* mpls exp value ( 3bits) */
+
+#define MPLS_OP_POP 1
+#define MPLS_OP_PUSH 2
+#define MPLS_OP_SWAP 3
+
+#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 */
+};
+
+
+/*
+ * Names for IP sysctl objects
+ */
+#define MPLSCTL_DEFTTL 1
+#define MPLSCTL_MAXINKLOOP 2
+#define MPLSCTL_PUSHEXPNULL_IP 3
+#define MPLSCTL_PUSHEXPNULL_IP6 4
+#define MPLSCTL_MAPTTL_IP 5
+#define MPLSCTL_MAPTTL_IP6 6
+#define MPLSCTL_MAXID 7
+
+#define MPLSCTL_NAMES { \
+ { 0, 0 }, \
+ { "ttl", CTLTYPE_INT }, \
+ { "maxloop_inkernel", CTLTYPE_INT }, \
+ { "pushexpnull_ip", CTLTYPE_INT }, \
+ { "pushexpnull_ip6", CTLTYPE_INT }, \
+ { "mapttl_ip", CTLTYPE_INT }, \
+ { "mapttl_ip6", CTLTYPE_INT }, \
+}
+
+#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 *);
+extern void mpls_purgeif(struct ifnet *);
+#endif /* _KERNEL */
+#endif /* _NETMPLS_MPLS_H_ */
diff --git a/sys/netmpls/mpls_input.c b/sys/netmpls/mpls_input.c
new file mode 100644
index 00000000000..2e5681b3848
--- /dev/null
+++ b/sys/netmpls/mpls_input.c
@@ -0,0 +1,337 @@
+/* $OpenBSD: mpls_input.c,v 1.1 2008/04/23 11:00:35 norby Exp $ */
+
+/*
+ * Copyright (c) 2008 Claudio Jeker <claudio@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/systm.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netmpls/mpls.h>
+
+struct ifqueue mplsintrq;
+int mplsqmaxlen = IFQ_MAXLEN;
+extern int mpls_inkloop;
+
+void mpls_input(struct mbuf *);
+
+#ifdef MPLS_DEBUG
+#define MPLS_LABEL_GET(l) ((ntohl((l) & MPLS_LABEL_MASK)) >> MPLS_LABEL_OFFSET)
+#define MPLS_TTL_GET(l) (ntohl((l) & MPLS_TTL_MASK))
+#endif
+
+void
+mpls_init(void)
+{
+ mplsintrq.ifq_maxlen = mplsqmaxlen;
+}
+
+void
+mplsintr(void)
+{
+ struct mbuf *m;
+ int s;
+
+ while (mplsintrq.ifq_head) {
+ /* Get next datagram of input queue */
+ s = splnet();
+ IF_DEQUEUE(&mplsintrq, m);
+ splx(s);
+ if (m == NULL)
+ return;
+#ifdef DIAGNOSTIC
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("ipintr no HDR");
+#endif
+ mpls_input(m);
+ }
+}
+
+void
+mpls_input(struct mbuf *m)
+{
+ struct route ro;
+ struct ifnet *ifp = m->m_pkthdr.rcvif;
+ struct sockaddr_mpls *smpls;
+ struct shim_hdr *shim;
+ struct rtentry *rt = NULL;
+ u_int32_t ttl;
+ int i;
+
+ if (m->m_len < sizeof(*shim))
+ if ((m = m_pullup(m, sizeof(*shim))) == NULL)
+ return;
+
+ shim = mtod(m, struct shim_hdr *);
+
+#ifdef MPLS_DEBUG
+ printf("mpls_input: iface %s label=%d, ttl=%d BoS %d\n",
+ ifp->if_xname, MPLS_LABEL_GET(shim->shim_label),
+ MPLS_TTL_GET(shim->shim_label),
+ MPLS_BOS_ISSET(shim->shim_label));
+#endif /* MPLS_DEBUG */
+
+ /* check and decrement TTL */
+ ttl = ntohl(shim->shim_label & MPLS_TTL_MASK);
+ if (ttl <= 1) {
+ /* TTL exceeded */
+ /*
+ * XXX if possible hand packet up to network layer so that an
+ * ICMP TTL exceeded can be sent back.
+ */
+ m_freem(m);
+ return;
+ }
+ ttl = htonl(ttl - 1);
+
+ for (i = 0; i < mpls_inkloop; i++) {
+ /* XXX maybe this should be done later */
+ if (MPLS_BOS_ISSET(shim->shim_label)) {
+ /* no LER until now */
+ m_freem(m);
+ goto done;
+ }
+
+ bzero(&ro, sizeof(ro));
+ smpls = satosmpls(&ro.ro_dst);
+ smpls->smpls_family = AF_MPLS;
+ smpls->smpls_len = sizeof(*smpls);
+ smpls->smpls_in_ifindex = ifp->if_index;
+ smpls->smpls_in_label = shim->shim_label & MPLS_LABEL_MASK;
+
+printf("smpls af %d len %d in_label %d in_ifindex %d\n", smpls->smpls_family,
+ smpls->smpls_len, smpls->smpls_in_label, smpls->smpls_in_ifindex);
+
+ rtalloc(&ro); /* XXX switch to rtalloc1() */
+ rt = ro.ro_rt;
+
+ if (rt == NULL) {
+ /* no entry for this label */
+#ifdef MPLS_DEBUG
+ printf("MPLS_DEBUG: label not found\n");
+#endif
+ m_freem(m);
+ goto done;
+ }
+
+ rt->rt_use++;
+ smpls = satosmpls(rt_key(rt));
+printf("route af %d len %d in_label %d in_ifindex %d\n", smpls->smpls_family,
+ smpls->smpls_len, MPLS_LABEL_GET(smpls->smpls_in_label),
+ smpls->smpls_in_ifindex);
+printf("\top %d out_label %d out_ifindex %d\n", smpls->smpls_operation,
+ MPLS_LABEL_GET(smpls->smpls_out_label), smpls->smpls_out_ifindex);
+
+ switch (smpls->smpls_operation) {
+ case MPLS_OP_POP:
+ m = mpls_shim_pop(m);
+ break;
+ case MPLS_OP_PUSH:
+ m = mpls_shim_push(m, smpls);
+ break;
+ case MPLS_OP_SWAP:
+ m = mpls_shim_swap(m, smpls);
+ break;
+ default:
+ break;
+ }
+
+ break;
+ /* not yet done with packet */
+ if (rt) {
+ RTFREE(rt);
+ rt = NULL;
+ }
+ }
+
+ /* write back TTL */
+ shim->shim_label = (shim->shim_label & ~MPLS_TTL_MASK) | ttl;
+
+printf("MPLS: sending on %s outlabel %x dst af %d in %d out %d\n",
+ ifp->if_xname, ntohl(shim->shim_label), smpls->smpls_family,
+ MPLS_LABEL_GET(smpls->smpls_in_label),
+ MPLS_LABEL_GET(smpls->smpls_out_label));
+
+ (*ifp->if_output)(ifp, m, smplstosa(smpls), rt);
+done:
+ if (rt)
+ RTFREE(rt);
+}
+/* $OpenBSD: mpls_input.c,v 1.1 2008/04/23 11:00:35 norby Exp $ */
+/*
+ * Copyright (c) 2008 Claudio Jeker <claudio@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/systm.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netmpls/mpls.h>
+#include <netmpls/mpls_var.h>
+
+struct ifqueue mplsintrq;
+
+void mpls_input(struct mbuf *);
+
+void
+mplsintr(void)
+{
+ struct mbuf *m;
+ int s;
+
+ while (mplsintrq.ifq_head) {
+ /* Get next datagram of input queue */
+ s = splnet();
+ IF_DEQUEUE(&mplsintrq, m);
+ splx(s);
+ if (m == NULL)
+ return;
+#ifdef DIAGNOSTIC
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("ipintr no HDR");
+#endif
+ mpls_input(m);
+ }
+}
+
+void
+mpls_input(struct mbuf *m)
+{
+ struct route ro;
+ struct ifnet *ifp = m->m_pkthdr.rcvif;
+ struct sockaddr_mpls *smpls;
+ struct shim_hdr *shim;
+ struct rtentry *rt = NULL;
+ u_int32_t label, ttl;
+ int i, error;
+
+ printf("mpls_input: !! \n");
+
+ if (m->m_len < sizeof(label))
+ if ((m = m_pullup(m, sizeof(label))) == NULL)
+ return;
+
+ shim = mtod(m, struct shim_hdr *);
+ /* swap label to host byte order. */
+ label = ntohl(shim->shim_label);
+
+#ifdef MPLS_DEBUG
+ printf("mpls_input: iface %s label=%d, ttl=%d BoS %d\n",
+ ifp->if_xname, MPLS_SHIM_LABEL_GET(label),
+ MPLS_SHIM_TTL_GET(label), MPLS_SHIM_BOS_ISSET(label));
+#endif /* MPLS_DEBUG */
+
+ /* check and decrement TTL */
+ ttl = MPLS_SHIM_TTL_GET(label);
+ if (ttl <= 1) {
+ /* ttl exceeded */
+ /*
+ * XXX if possible hand packet up to network layer so that an
+ * ICMP TTL exceeded can be sent back.
+ */
+ m_freem(m);
+ return;
+ }
+ ttl--;
+
+ for (i = 0; i < MPLS_INKERNEL_LOOP_MAX; i++) {
+ /* XXX maybe this should be done later */
+ if (MPLS_SHIM_BOS_ISSET(label)) {
+ /* no LER until now */
+ error = EHOSTUNREACH;
+ goto done;
+ }
+
+ bzero(&ro, sizeof(ro));
+ smpls = satosmpls(&ro.ro_dst);
+ smpls->smpls_family = AF_MPLS;
+ smpls->smpls_len = sizeof(*smpls);
+ smpls->smpls_in_ifindex = ifp->if_index;
+ smpls->smpls_in_label = MPLS_SHIM_LABEL_GET(label);
+
+ rtalloc(&ro); /* XXX switch to rtalloc1() */
+ rt = ro.ro_rt;
+
+ if (rt == NULL) {
+ /* no entry for this label */
+ error = EHOSTUNREACH;
+#ifdef MPLS_DEBUG
+ printf("MPLS_DEBUG: label not found\n");
+#endif
+ goto done;
+ }
+
+ rt->rt_use++;
+ smpls = satosmpls(rt_key(rt));
+
+ switch (smpls->smpls_operation) {
+ case MPLS_OP_POP:
+ printf("mpls_input: POP\n");
+ /* mpls_shim_pop() */
+ break;
+ case MPLS_OP_PUSH:
+ printf("mpls_input: PUSH\n");
+ /* mpls_shim_push() */
+ break;
+ case MPLS_OP_SWAP:
+ printf("mpls_input: SWAP\n");
+ /* mpls_shim_swap() */
+ break;
+ default:
+ break;
+ }
+
+ /* not yet done with packet */
+ /* reget current label */
+ shim = mtod(m, struct shim_hdr *);
+ label = ntohl(shim->shim_label);
+
+ if (rt) {
+ RTFREE(rt);
+ rt = NULL;
+ }
+ }
+
+ /* write back modified label */
+ shim->shim_label = htonl(MPLS_SHIM_TTL_SET(label, ttl));
+
+ error = (*ifp->if_output)(ifp, m, smplstosa(&smpls), rt);
+done:
+ if (error)
+ m_freem(m);
+ if (rt)
+ RTFREE(rt);
+}
diff --git a/sys/netmpls/mpls_lse.c b/sys/netmpls/mpls_lse.c
new file mode 100644
index 00000000000..92ec6386d37
--- /dev/null
+++ b/sys/netmpls/mpls_lse.c
@@ -0,0 +1,333 @@
+/*
+ * 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.
+ */
+
+/*
+ *
+ * $Id: mpls_lse.c,v 1.1 2008/04/23 11:00:35 norby Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/errno.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/systm.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/route.h>
+
+#include <netmpls/mpls.h>
+#include <netmpls/mpls_var.h>
+
+/*
+ * 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,
+ u_int8_t bosf)
+{
+ struct route mplsroute;
+ struct route *ro = &mplsroute;
+ struct sockaddr_mpls *rodst = satosmpls(&mplsroute.ro_dst); /* Actual labeland stuff */
+ 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, bad = 0;
+
+ bzero((caddr_t)ro, sizeof(*ro));
+ bcopy((caddr_t)dst, (caddr_t)rodst, dst->smpls_len);
+
+/* XXX: Kefren: I don't understand this inkloop so I've replaced it with asingle
+ loop for easy break */
+ for (ink_loop = 0; ink_loop < mpls_inkloop; ink_loop++) {
+/* for (ink_loop = 0; ink_loop < 1; ink_loop++) { */
+
+#ifdef MPLS_DEBUG
+ printf("MPLS_DEBUG: %s(%d). [label=%d]\n",
+ __FILE__, __LINE__, ntohl(rodst->smpls_in_label));
+#endif /* MPLS_DEBUG */
+
+ /*
+ * OPERATIONS for Reserved Labels
+ */
+ if (ntohl(rodst->smpls_in_label) <= MPLS_LABEL_RESERVED_MAX) {
+ printf("MPLS_DEBUG: %s(%d). [bosf = %d label = %s]\n",
+ __FILE__, __LINE__, bosf,
+ ntohl(rodst->smpls_in_label));
+ switch (ntohl(rodst->smpls_in_label)) {
+#ifdef INET
+ case MPLS_LABEL_IPV4NULL:
+#if 0 /* claudio@ */
+ if (bosf) {
+ error = mpls_ip_input(m);
+ goto done;
+ }
+#endif
+#ifdef MPLS_DEBUG
+#endif /* MPLS_DEBUG */
+ break;
+#endif /* INET */
+#ifdef INET6
+ case MPLS_LABEL_IPV6NULL:
+#if 0 /* claudio@ */
+ if (bosf) {
+ error = mpls_ip6_input(m);
+ goto done;
+ }
+#endif
+ break;
+#endif /* INET6 */
+ }
+
+ /* label is reserved, */
+ /* but operation is unsupported or invalid */
+ error = EINVAL;
+ printf("MPLS_DEBUG: %s(%d).\n", __FILE__, __LINE__);
+ bad = 1;
+ break;
+ } /* MPLS RESERVED label */
+
+ /*
+ * switch packet
+ *
+ * XXX: no really, this is fun. AYAME sucks so much. */
+ exp_bits = rodst->smpls_out_exp;
+ rodst->smpls_out_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 */
+ bad = 1;
+ break;
+ }
+
+ /*
+ 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 */
+ bad = 1;
+ break;
+ }
+
+#ifdef MPLS_MCAST
+ printf("MPLS_MCAST label=%d mclabel=%d\n",
+ ntohl(dstnew->smpls_in_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_in_label = dstnew->smpls_mclabel;
+#ifdef MPLS_DEBUG
+ printf("MPLS_MCAST label=%d mclabel=%d\n",
+ ntohl(dstnew->smpls_in_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) {
+#if 0 /* claudio@ */
+#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 */
+#endif
+ default:
+ error = EAFNOSUPPORT;
+#ifdef MPLS_DEBUG
+ printf("MPLS_DEBUG: %s(%d).\n", __FILE__, __LINE__);
+#endif /* MPLS_DEBUG */
+ bad = 1;
+ }
+ break;
+ } else {
+ /* XXX */
+ error = EINVAL;
+#ifdef MPLS_DEBUG
+ printf("MPLS_DEBUG: %s(%d).\n", __FILE__, __LINE__);
+#endif /* MPLS_DEBUG */
+ bad = 1;
+ break;
+ }
+ }
+
+ /* XXX */
+ smpls = *dstnew;
+ smpls.smpls_out_exp = exp_bits;
+ dstnew = &smpls;
+ /* XXX Kefren */
+/* dstnew->smpls_exp = exp_bits;*/
+
+ switch(dstnew->smpls_operation) {
+
+ case MPLS_OP_POP: /* Label Pop */
+
+ /* check bos flag */
+#if 0 /* claudio@ */
+ if (bosf) {
+ /*
+ * XXXXX No ExpNULL XXXXX
+ *
+ * I can't know which l3 I shuld send to!!
+ * now, send to IPv4 stack (XXXXX)
+ * We have to 'look' into the packet
+ * and clasify it
+ *
+ * error = EINVAL;
+ * goto bad;
+ */
+
+ error = mpls_ip_input(m);
+ goto done;
+ }
+#endif
+ /* label pop */
+ if ((m = mpls_shim_pop(m, rodst, NULL, &bosf, NULL)) == 0) {
+ error = ENOBUFS;
+ goto done;
+ }
+
+ break;
+
+ case MPLS_OP_PUSH: /* Label Push */
+
+ if ((m = mpls_shim_push(m, dstnew, NULL, NULL, NULL)) == 0) {
+ error = ENOBUFS;
+ goto done;
+ }
+ bosf = 0;
+
+ break;
+
+ case MPLS_OP_SWAP: /* 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 = (*ifp->if_output)(ifp, m, smplstosa(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;
+ bad=1;
+ }
+ if (bad) break;
+ if (rt) {
+ RTFREE(rt);
+ rt = 0;
+ }
+ } /* The big inkloop for */
+
+ /*
+ * Discard broken packet
+ */
+if (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);
+}
diff --git a/sys/netmpls/mpls_proto.c b/sys/netmpls/mpls_proto.c
new file mode 100644
index 00000000000..3984208fdd3
--- /dev/null
+++ b/sys/netmpls/mpls_proto.c
@@ -0,0 +1,155 @@
+/* $OpenBSD: mpls_proto.c,v 1.1 2008/04/23 11:00:35 norby 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 <sys/param.h>
+#include <sys/socket.h>
+#include <sys/protosw.h>
+#include <sys/domain.h>
+#include <sys/mbuf.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netmpls/mpls.h>
+
+/*
+ * MPLS protocol family:
+ */
+
+extern struct domain mplsdomain;
+
+struct protosw mplssw[] = {
+{ 0, &mplsdomain, 0, 0,
+ 0, 0, 0, 0,
+ 0,
+ mpls_init, 0, 0, 0, mpls_sysctl
+},
+{ SOCK_DGRAM, &mplsdomain, 0, PR_ATOMIC|PR_ADDR,
+ 0, 0, 0, 0,
+ mpls_raw_usrreq,
+ 0, 0, 0, 0, mpls_sysctl,
+},
+/* raw wildcard */
+{ SOCK_RAW, &mplsdomain, 0, PR_ATOMIC|PR_ADDR,
+ 0, 0, 0, 0,
+ mpls_raw_usrreq,
+ 0, 0, 0, 0, mpls_sysctl,
+},
+};
+
+struct domain mplsdomain = {
+ AF_MPLS, "mpls", mpls_init, 0, 0,
+ mplssw,
+ &mplssw[sizeof(mplssw)/sizeof(mplssw[0])], 0,
+ rn_inithead,
+ offsetof(struct sockaddr_mpls, smpls_in_ifindex) << 3,
+ sizeof(struct sockaddr_mpls)
+};
+/*
+ * 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.
+ */
+
+/*
+ *
+ * $Id: mpls_proto.c,v 1.1 2008/04/23 11:00:35 norby Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/protosw.h>
+#include <sys/domain.h>
+#include <sys/mbuf.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netmpls/mpls.h>
+#include <netmpls/mpls_var.h>
+
+/*
+ * MPLS protocol family:
+ */
+
+extern struct domain mplsdomain;
+
+struct protosw mplssw[] = {
+{ 0, &mplsdomain, 0, 0,
+ 0, 0, 0, 0,
+ 0,
+ mpls_init, 0, 0, 0, mpls_sysctl
+},
+{ SOCK_DGRAM, &mplsdomain, 0, PR_ATOMIC|PR_ADDR,
+ 0, 0, 0, 0,
+ mpls_raw_usrreq,
+ 0, 0, 0, 0, mpls_sysctl,
+},
+/* raw wildcard */
+{ SOCK_RAW, &mplsdomain, 0, PR_ATOMIC|PR_ADDR,
+ 0, 0, 0, 0,
+ mpls_raw_usrreq,
+ 0, 0, 0, 0, mpls_sysctl,
+},
+};
+
+struct domain mplsdomain = {
+ AF_MPLS, "mpls", /*mpls_init */ 0 , 0, 0,
+ mplssw,
+ &mplssw[sizeof(mplssw)/sizeof(mplssw[0])], 0,
+ rn_inithead,
+ offsetof(struct sockaddr_mpls, smpls_in_ifindex) << 3,
+ sizeof(struct sockaddr_mpls)
+};
diff --git a/sys/netmpls/mpls_raw.c b/sys/netmpls/mpls_raw.c
new file mode 100644
index 00000000000..b084f879dcc
--- /dev/null
+++ b/sys/netmpls/mpls_raw.c
@@ -0,0 +1,301 @@
+/* $OpenBSD: mpls_raw.c,v 1.1 2008/04/23 11:00:35 norby 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 <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/errno.h>
+#include <sys/protosw.h>
+#include <sys/sockio.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/systm.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/route.h>
+
+#include <netmpls/mpls.h>
+
+#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_enable = 0;
+int mpls_defttl = 255;
+int mpls_inkloop = 16;
+int mpls_push_expnull_ip = 0;
+int mpls_push_expnull_ip6 = 0;
+int mpls_mapttl_ip = 1;
+int mpls_mapttl_ip6 = 0;
+
+int *mplsctl_vars[MPLSCTL_MAXID] = MPLSCTL_VARS;
+
+int mpls_control(struct socket *, u_long, caddr_t, struct ifnet *);
+
+/*
+ * Generic MPLS control operations (ioctl's).
+ * Ifp is 0 if not an interface-specific ioctl.
+ */
+/* ARGSUSED */
+int
+mpls_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
+{
+ return (EOPNOTSUPP);
+}
+
+int
+mpls_raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control)
+{
+ 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, (u_long)m, (caddr_t)nam,
+ (struct ifnet *)control));
+
+ 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");
+ }
+
+ return (error);
+}
+
+int
+mpls_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
+ size_t newlen)
+{
+ if (name[0] >= MPLSCTL_MAXID)
+ return EOPNOTSUPP;
+
+ /* Almost all sysctl names at this level are terminal. */
+ if (namelen != 1 && name[0] != MPLSCTL_IFQUEUE)
+ return (ENOTDIR);
+
+ switch (name[0]) {
+ case MPLSCTL_IFQUEUE:
+ return (sysctl_ifq(name + 1, namelen - 1,
+ oldp, oldlenp, newp, newlen, &mplsintrq));
+ default:
+ return sysctl_int_arr(mplsctl_vars, name, namelen,
+ oldp, oldlenp, newp, newlen);
+ }
+}
+/*
+ * 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.
+ */
+
+/*
+ *
+ * $Id: mpls_raw.c,v 1.1 2008/04/23 11:00:35 norby Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/errno.h>
+#include <sys/protosw.h>
+#include <sys/sockio.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/systm.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/route.h>
+
+#include <netmpls/mpls.h>
+#include <netmpls/mpls_var.h>
+
+#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 = 0;
+int mpls_push_expnull_ip6 = 0;
+int mpls_mapttl_ip = 1;
+int mpls_mapttl_ip6 = 0;
+
+#define MPLSCTL_VARS { \
+ 0, \
+ &mpls_defttl, \
+ &mpls_inkloop, \
+ &mpls_push_expnull_ip, \
+ &mpls_push_expnull_ip6, \
+ &mpls_mapttl_ip, \
+ &mpls_mapttl_ip6, \
+}
+
+int
+mpls_raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control)
+{
+ 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));
+/* XXX norby
+ 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);
+}
+
+static int *mpls_sysvars[] = MPLSCTL_VARS;
+
+int
+mpls_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
+ size_t newlen)
+{
+ if (name[0] >= MPLSCTL_MAXID)
+ return EOPNOTSUPP;
+ if (!mpls_sysvars[name[0]])
+ return EOPNOTSUPP;
+
+#ifdef MPLS_DEBUG
+ printf("mpls_sysctl\n");
+#endif /* MPLS_DEBUG */
+
+ switch (name[0]) {
+ default:
+ return sysctl_int(oldp, oldlenp, newp, newlen,
+ mpls_sysvars[name[0]]);
+ }
+}
+
diff --git a/sys/netmpls/mpls_shim.c b/sys/netmpls/mpls_shim.c
new file mode 100644
index 00000000000..57df3b4f1ce
--- /dev/null
+++ b/sys/netmpls/mpls_shim.c
@@ -0,0 +1,247 @@
+/* $OpenBSD: mpls_shim.c,v 1.1 2008/04/23 11:00:35 norby 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 <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/errno.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netmpls/mpls.h>
+
+struct mbuf *
+mpls_shim_pop(struct mbuf *m)
+{
+ /* 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 (NULL);
+
+ /* return mbuf */
+ return (m);
+}
+
+struct mbuf *
+mpls_shim_swap(struct mbuf *m, struct sockaddr_mpls *smplsp)
+{
+ 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 (NULL);
+ shim = mtod(m, struct shim_hdr *);
+
+ /* swap label */
+ shim->shim_label &= ~MPLS_LABEL_MASK;
+ shim->shim_label |= smplsp->smpls_out_label & MPLS_LABEL_MASK;
+
+ /* swap exp : XXX exp override */
+ {
+ u_int32_t t;
+
+ shim->shim_label &= ~MPLS_EXP_MASK;
+ t = smplsp->smpls_out_exp << MPLS_EXP_OFFSET;
+ shim->shim_label |= htonl(t) & MPLS_EXP_MASK;
+ }
+ shim->shim_label = htonl(shim->shim_label);
+
+ return (m);
+}
+
+struct mbuf *
+mpls_shim_push(struct mbuf *m, struct sockaddr_mpls *smplsp)
+{
+ struct shim_hdr *shim;
+
+ M_PREPEND(m, sizeof(struct shim_hdr), M_DONTWAIT);
+ if (m == 0)
+ return (NULL);
+
+ shim = mtod(m, struct shim_hdr *);
+ bzero((caddr_t)shim, sizeof(*shim));
+
+ return (mpls_shim_swap(m, smplsp));
+}
+/*
+ * 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.
+ */
+
+/*
+ *
+ * $Id: mpls_shim.c,v 1.1 2008/04/23 11:00:35 norby Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/errno.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netmpls/mpls.h>
+#include <netmpls/mpls_var.h>
+
+struct mbuf *
+mpls_shim_pop(struct mbuf *m, struct sockaddr_mpls *smplsp, u_int32_t *labelp,
+ u_int8_t *bosp, u_int8_t *ttlp)
+{
+ u_int32_t label;
+
+ /* 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);
+
+ label = ntohl(*mtod(m, u_int32_t *));
+
+ /* set each values, if need */
+ if (bosp)
+ *bosp = MPLS_SHIM_BOS_ISSET(label);
+ if (ttlp)
+ *ttlp = MPLS_SHIM_TTL_GET(label);
+ if (labelp)
+ *labelp = MPLS_SHIM_LABEL_GET(label);
+ if (smplsp) {
+ bzero(smplsp, sizeof(*smplsp));
+ smplsp->smpls_family = AF_MPLS;
+ smplsp->smpls_len = sizeof(*smplsp);
+ smplsp->smpls_in_label = MPLS_SHIM_LABEL_GET(label);
+ }
+
+ /* return mbuf */
+ return(m);
+}
+
+struct mbuf *
+mpls_shim_swap(struct mbuf *m, struct sockaddr_mpls *smplsp, u_int32_t *labelp)
+{
+ struct shim_hdr *shim;
+ u_int32_t label;
+
+ /* pullup shim_hdr */
+ if (m->m_len < sizeof(struct shim_hdr)) /* XXX isn't this
+ already checked by mpls_shim_peep ? */
+ if ((m = m_pullup(m, sizeof(struct shim_hdr))) == 0)
+ return(0);
+ shim = mtod(m, struct shim_hdr *);
+ shim->shim_label = ntohl(shim->shim_label);
+
+ if (smplsp == NULL && labelp == NULL)
+ /* can't swap, because no dst label */
+ return(m); /* XXX discard? XXX */
+
+ if (labelp) {
+ label = *labelp;
+ /*
+ if (smplsp)
+ smplsp->smpls_in_label = htonl(*labelp);
+ */
+ } else
+ label = ntohl(smplsp->smpls_in_label);
+
+ /* shim swap label */
+ shim->shim_label &= ~SHIM_LABEL_MASK;
+ shim->shim_label |= MPLS_SHIM_LABEL_GET(label) << SHIM_LABEL_OFFSET;
+
+ /* shim swap exp : XXX exp override */
+ if (smplsp) {
+ shim->shim_label &= ~SHIM_EXP_MASK;
+ shim->shim_label |=
+ smplsp->smpls_out_exp << SHIM_EXP_OFFSET & SHIM_EXP_MASK;
+ }
+ shim->shim_label = htonl(shim->shim_label);
+
+ return(m);
+}
+
+struct mbuf *
+mpls_shim_push(struct mbuf *m, struct sockaddr_mpls *smplsp, u_int32_t *labelp,
+ u_int8_t *bosp, u_int8_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 && *bosp)
+ shim->shim_label |= SHIM_BOS_MASK;
+ if (ttlp)
+ shim->shim_label |= *ttlp & SHIM_TTL_MASK;
+ else
+ shim->shim_label |= 255; /* XXX */
+ m = mpls_shim_swap(m, smplsp, labelp);
+
+ return m;
+}
diff --git a/sys/netmpls/mpls_var.h b/sys/netmpls/mpls_var.h
new file mode 100644
index 00000000000..4d1e2e62437
--- /dev/null
+++ b/sys/netmpls/mpls_var.h
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+/*
+ *
+ * $Id: mpls_var.h,v 1.1 2008/04/23 11:00:35 norby Exp $
+ */
+
+#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 int mpls_raw_usrreq(struct socket *, int, struct mbuf *,
+ struct mbuf *, struct mbuf *);
+
+extern int mpls_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+
+
+
+extern struct ifqueue mplsintrq; /* MPLS input queue */
+
+void mplsintr(void);
+#endif /* _KERNEL */