summaryrefslogtreecommitdiff
path: root/sys/netmpls/mpls_shim.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netmpls/mpls_shim.c')
-rw-r--r--sys/netmpls/mpls_shim.c247
1 files changed, 247 insertions, 0 deletions
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;
+}