Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 8 Jul 2008 01:27:58 GMT
From:      Ryan French <rfrench@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 144854 for review
Message-ID:  <200807080127.m681Rw2a047709@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=144854

Change 144854 by rfrench@rfrench_mpls on 2008/07/08 01:27:50

	Initial import from OpenBSDs currently 'in progress' implementation of MPLS, which is based on the original AYAME project for NetBSD. I havent tested it to make sure it works yet.

Affected files ...

.. //depot/projects/soc2008/rfrench_mpls/netmpls/mpls.h#2 edit
.. //depot/projects/soc2008/rfrench_mpls/netmpls/mpls_input.c#2 edit
.. //depot/projects/soc2008/rfrench_mpls/netmpls/mpls_proto.c#2 edit
.. //depot/projects/soc2008/rfrench_mpls/netmpls/mpls_raw.c#2 edit
.. //depot/projects/soc2008/rfrench_mpls/netmpls/mpls_shim.c#2 edit

Differences ...

==== //depot/projects/soc2008/rfrench_mpls/netmpls/mpls.h#2 (text+ko) ====

@@ -1,1 +1,173 @@
- 
+
+/*
+ * 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.
+ */
+#define MPLS_LABEL_MAX          ((1 << 20) - 1)
+
+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))
+
+/*
+ * 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
+
+#ifdef _KERNEL
+
+struct mpe_softc {
+        struct ifnet                sc_if;                /* the interface */
+        int                        sc_unit;
+        struct shim_hdr                sc_shim;
+        LIST_ENTRY(mpe_softc)        sc_list;
+};
+
+#define MPE_HDRLEN      sizeof(struct shim_hdr)
+#define MPE_MTU         1500
+#define MPE_MTU_MIN     256
+#define MPE_MTU_MAX     8192
+
+void    mpe_input(struct mbuf *, struct ifnet *, struct sockaddr_mpls *,
+            u_int32_t);
+
+extern int mpls_raw_usrreq(struct socket *, int, struct mbuf *,
+                        struct mbuf *, struct mbuf *, struct proc *);
+
+extern struct ifqueue   mplsintrq;        /* MPLS input queue */
+extern int              mplsqmaxlen;        /* MPLS input queue length */
+extern int              mpls_enable;
+extern int              mpls_defttl;
+
+void    mpls_init(void);
+void    mplsintr(void);
+
+struct mbuf     *mpls_shim_pop(struct mbuf *);
+struct mbuf     *mpls_shim_swap(struct mbuf *, struct sockaddr_mpls *);
+struct mbuf     *mpls_shim_push(struct mbuf *, struct sockaddr_mpls *);
+
+int     mpls_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+void    mpls_input(struct mbuf *);
+
+#endif /* _KERNEL */

==== //depot/projects/soc2008/rfrench_mpls/netmpls/mpls_input.c#2 (text+ko) ====

@@ -1,23 +1,209 @@
-#include <sys/cdefs.h>
+
+/*
+ * 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 "mpe.h"
 
 #include <sys/param.h>
+#include <sys/mbuf.h>
 #include <sys/systm.h>
-#include <sys/callout.h>
-#include <sys/mbuf.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/route.h>
+
+#include <netmpls/mpls.h>
+
+struct ifqueue  mplsintrq;
+int             mplsqmaxlen = IFQ_MAXLEN;
+extern int      mpls_inkloop;
 
-#include <net/netisr.h>
+#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
 
-struct ifqueue mplsintrq;
+void
+mpls_init(void)
+{
+        mplsintrq.ifq_maxlen = mplsqmaxlen;
+}
 
 void
-mpls_init()
+mplsintr(void)
 {
-	printf("MPLS packet received, netisr_register called");
-	netisr_register(NETISR_MPLS, mpls_input, &mplsintrq, NETISR_MPSAFE);
-} 
+        struct mbuf *m;
+        int s;
+
+        for (;;) {
+                /* 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)
 {
-	printf("MPLS input called");
-} 
+        struct ifnet *ifp = m->m_pkthdr.rcvif;
+        struct sockaddr_mpls *smpls;
+        struct sockaddr_mpls sa_mpls;
+        struct shim_hdr *shim;
+        struct rtentry *rt = NULL;
+        u_int32_t ttl;
+        int i, hasbos;
+
+        if (!mpls_enable) {
+                m_freem(m);
+                return;
+        }
+
+        /* drop all broadcast and multicast packets */
+        if (m->m_flags & (M_BCAST | M_MCAST)) {
+                m_freem(m);
+                return;
+        }
+
+        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++) {
+                bzero(&sa_mpls, sizeof(sa_mpls));
+                smpls = &sa_mpls;
+                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;
+
+#ifdef MPLS_DEBUG
+                printf("smpls 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);
+#endif
+
+                rt = rtalloc1(smplstosa(smpls),1, 0);
+
+                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));
+#ifdef MPLS_DEBUG
+                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);
+#endif
+
+                switch (smpls->smpls_operation) {
+                case MPLS_OP_POP:
+                        hasbos = MPLS_BOS_ISSET(shim->shim_label);
+                        m = mpls_shim_pop(m);
+                        if (hasbos) {
+#if NMPE > 0
+                                if (rt->rt_ifp->if_type == IFT_MPLS) {
+                                        mpe_input(m, rt->rt_ifp, smpls, ttl);
+                                        goto done;
+                                }
+#endif
+                                /* last label but we have no clue so drop */
+                                m_freem(m);
+                                goto done;
+                        }
+                        break;
+                case MPLS_OP_PUSH:
+                        m = mpls_shim_push(m, smpls);
+                        break;
+                case MPLS_OP_SWAP:
+                        m = mpls_shim_swap(m, smpls);
+                        break;
+                default:
+                        m_freem(m);
+                        goto done;
+                }
+
+                if (m == NULL)
+                        goto done;
+
+                /* refetch label */
+                shim = mtod(m, struct shim_hdr *);
+                ifp = rt->rt_ifp;
+
+                if (smpls->smpls_out_ifindex)
+                        break;
+
+                RTFREE(rt);
+                rt = NULL;
+        }
+
+        /* write back TTL */
+        shim->shim_label = (shim->shim_label & ~MPLS_TTL_MASK) | ttl;
+
+#ifdef MPLS_DEBUG
+        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));
+#endif
+
+        (*ifp->if_output)(ifp, m, smplstosa(smpls), rt);
+done:
+        if (rt)
+                RTFREE(rt);
+}

==== //depot/projects/soc2008/rfrench_mpls/netmpls/mpls_proto.c#2 (text+ko) ====

@@ -1,1 +1,74 @@
- 
+
+/*
+ * 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)
+};

==== //depot/projects/soc2008/rfrench_mpls/netmpls/mpls_raw.c#2 (text+ko) ====

@@ -1,1 +1,145 @@
- 
+
+/*
+ * 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, struct proc *p)
+{
+        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);
+        }
+}

==== //depot/projects/soc2008/rfrench_mpls/netmpls/mpls_shim.c#2 (text+ko) ====

@@ -1,1 +1,99 @@
  
+/*
+ * 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;
+        }
+
+        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));
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200807080127.m681Rw2a047709>