summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMichele Marchetto <michele@cvs.openbsd.org>2009-01-28 22:18:45 +0000
committerMichele Marchetto <michele@cvs.openbsd.org>2009-01-28 22:18:45 +0000
commit7227a1f7a8d21a364dce2ce2e513c4e0826f0655 (patch)
tree53b778afc500a2b1c3a9d76a056b3dad0f2ef05a /sys
parentcc411b2e1c4c556ba9e319f50cf1c1422f56db9d (diff)
Get rid of the ugly rtentry hack.
We can now act as edge node and allow ipv4 packets to enter a Label Switched Path and not just forwarding MPLS packets. OK claudio@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_ethersubr.c15
-rw-r--r--sys/net/if_mpe.c4
-rw-r--r--sys/net/route.c38
-rw-r--r--sys/net/route.h10
-rw-r--r--sys/net/rtsock.c33
-rw-r--r--sys/netmpls/mpls.h22
-rw-r--r--sys/netmpls/mpls_input.c35
-rw-r--r--sys/netmpls/mpls_output.c125
-rw-r--r--sys/netmpls/mpls_shim.c18
9 files changed, 172 insertions, 128 deletions
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 4e95bdc2796..34e91cedcd5 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ethersubr.c,v 1.130 2008/11/25 12:07:55 claudio Exp $ */
+/* $OpenBSD: if_ethersubr.c,v 1.131 2009/01/28 22:18:43 michele Exp $ */
/* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */
/*
@@ -263,6 +263,12 @@ ether_output(ifp0, m0, dst, rt0)
else
senderr(EHOSTUNREACH);
}
+#ifdef MPLS
+ if (rt->rt_flags & RTF_MPLS) {
+ if ((m = mpls_output(m, rt)) == NULL)
+ senderr(EHOSTUNREACH);
+ }
+#endif
if (rt->rt_flags & RTF_GATEWAY) {
if (rt->rt_gwroute == 0)
goto lookup;
@@ -289,7 +295,12 @@ ether_output(ifp0, m0, dst, rt0)
if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
!m->m_pkthdr.pf.routed)
mcopy = m_copy(m, 0, (int)M_COPYALL);
- etype = htons(ETHERTYPE_IP);
+#ifdef MPLS
+ if (rt0->rt_flags & RTF_MPLS)
+ etype = htons(ETHERTYPE_MPLS);
+ else
+#endif
+ etype = htons(ETHERTYPE_IP);
break;
#endif
#ifdef INET6
diff --git a/sys/net/if_mpe.c b/sys/net/if_mpe.c
index c7fb9253670..1495d8201d7 100644
--- a/sys/net/if_mpe.c
+++ b/sys/net/if_mpe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_mpe.c,v 1.14 2008/11/06 20:53:10 michele Exp $ */
+/* $OpenBSD: if_mpe.c,v 1.15 2009/01/28 22:18:44 michele Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -168,7 +168,7 @@ mpestart(struct ifnet *ifp)
continue;
}
m->m_pkthdr.rcvif = ifp;
- mpls_output(m);
+ mpls_output(m, NULL);
}
}
diff --git a/sys/net/route.c b/sys/net/route.c
index 74c274cb772..3e5ec851890 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.101 2009/01/08 12:47:45 michele Exp $ */
+/* $OpenBSD: route.c,v 1.102 2009/01/28 22:18:44 michele Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -419,6 +419,10 @@ rtfree(struct rtentry *rt)
if (ifa)
IFAFREE(ifa);
rtlabel_unref(rt->rt_labelid);
+#ifdef MPLS
+ if (rt->rt_flags & RTF_MPLS)
+ free(rt->rt_llinfo, M_TEMP);
+#endif
Free(rt_key(rt));
pool_put(&rtentry_pool, rt);
}
@@ -822,7 +826,9 @@ makeroute:
if (rt == NULL)
senderr(ENOBUFS);
Bzero(rt, sizeof(*rt));
+
rt->rt_flags = info->rti_flags;
+
if (prio == 0)
prio = ifa->ifa_ifp->if_priority + RTP_STATIC;
rt->rt_priority = prio; /* init routing priority */
@@ -867,10 +873,36 @@ makeroute:
}
#ifdef MPLS
- if (info->rti_info[RTAX_SRC] != NULL) {
+ /* We have to allocate additional space for MPLS infos */
+ if (info->rti_info[RTAX_SRC] != NULL ||
+ info->rti_info[RTAX_DST]->sa_family == AF_MPLS) {
+ struct rt_mpls *rt_mpls;
+
sa_mpls = (struct sockaddr_mpls *)
info->rti_info[RTAX_SRC];
- rt->rt_mpls = sa_mpls->smpls_label;
+
+ rt->rt_llinfo = (caddr_t)malloc(sizeof(struct rt_mpls),
+ M_TEMP, M_NOWAIT|M_ZERO);
+
+ if (rt->rt_llinfo == NULL) {
+ if (rt->rt_gwroute)
+ rtfree(rt->rt_gwroute);
+ Free(rt_key(rt));
+ pool_put(&rtentry_pool, rt);
+ senderr(ENOMEM);
+ }
+
+ rt_mpls = (struct rt_mpls *)rt->rt_llinfo;
+
+ if (sa_mpls != NULL)
+ rt_mpls->mpls_label = sa_mpls->smpls_label;
+
+ rt_mpls->mpls_operation = rt->rt_flags &
+ (MPLS_OP_PUSH | MPLS_OP_POP | MPLS_OP_SWAP);
+
+ /* XXX: set experimental bits */
+
+ rt->rt_flags |= RTF_MPLS;
}
#endif
diff --git a/sys/net/route.h b/sys/net/route.h
index 45df3f207d2..bce1dfd2534 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.h,v 1.57 2009/01/28 12:34:09 claudio Exp $ */
+/* $OpenBSD: route.h,v 1.58 2009/01/28 22:18:44 michele Exp $ */
/* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */
/*
@@ -114,17 +114,14 @@ struct rtentry {
struct ifnet *rt_ifp; /* the answer: interface to use */
struct ifaddr *rt_ifa; /* the answer: interface addr to use */
struct sockaddr *rt_genmask; /* for generation of cloned routes */
- caddr_t rt_llinfo; /* pointer to link level info cache */
+ caddr_t rt_llinfo; /* pointer to link level info cache or
+ to an MPLS structure */
struct rt_kmetrics rt_rmx; /* metrics used by rx'ing protocols */
struct rtentry *rt_gwroute; /* implied entry for gatewayed routes */
struct rtentry *rt_parent; /* If cloned, parent of this route. */
LIST_HEAD(, rttimer) rt_timer; /* queue of timeouts for misc funcs */
u_int16_t rt_labelid; /* route label ID */
u_int8_t rt_priority; /* routing priority to use */
-#ifdef MPLS
- /* XXX: temporay hack, will be removed soon */
- u_int32_t rt_mpls; /* MPLS outbound label */
-#endif
};
#define rt_use rt_rmx.rmx_pksent
@@ -147,6 +144,7 @@ struct rtentry {
#define RTF_CLONED 0x10000 /* this is a cloned route */
#define RTF_MPATH 0x40000 /* multipath route or operation */
#define RTF_JUMBO 0x80000 /* try to use jumbo frames */
+#define RTF_MPLS 0x100000 /* MPLS additional infos */
/* mask of RTF flags that are allowed to be modified by RTM_CHANGE */
#define RTF_FMASK \
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index e63e31063ea..f86ad767a6e 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.82 2009/01/28 12:34:09 claudio Exp $ */
+/* $OpenBSD: rtsock.c,v 1.83 2009/01/28 22:18:44 michele Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -324,7 +324,6 @@ route_output(struct mbuf *m, ...)
struct sockaddr_rtlabel sa_rt;
#ifdef MPLS
struct sockaddr_mpls sa_mpls;
- struct sockaddr_mpls *psa_mpls;
#endif
const char *label;
va_list ap;
@@ -565,11 +564,12 @@ report:
(struct sockaddr *)&sa_rt;
}
#ifdef MPLS
- if (rt->rt_mpls) {
+ if (rt->rt_flags & RTF_MPLS) {
bzero(&sa_mpls, sizeof(sa_mpls));
sa_mpls.smpls_family = AF_MPLS;
sa_mpls.smpls_len = sizeof(sa_mpls);
- sa_mpls.smpls_label = rt->rt_mpls;
+ sa_mpls.smpls_label = ((struct rt_mpls *)
+ rt->rt_llinfo)->mpls_label;
info.rti_info[RTAX_SRC] =
(struct sockaddr *)&sa_mpls;
}
@@ -661,13 +661,7 @@ report:
rt->rt_labelid =
rtlabel_name2id(rtlabel);
}
-#ifdef MPLS
- if (info.rti_info[RTAX_SRC] != NULL) {
- psa_mpls = (struct sockaddr_mpls *)
- info.rti_info[RTAX_SRC];
- rt->rt_mpls = psa_mpls->smpls_label;
- }
-#endif
+
if_group_routechange(dst, netmask);
/* FALLTHROUGH */
case RTM_LOCK:
@@ -1112,11 +1106,12 @@ sysctl_dumpentry(struct radix_node *rn, void *v)
}
}
#ifdef MPLS
- if (rt->rt_mpls) {
+ if (rt->rt_flags & RTF_MPLS) {
bzero(&sa_mpls, sizeof(sa_mpls));
sa_mpls.smpls_family = AF_MPLS;
sa_mpls.smpls_len = sizeof(sa_mpls);
- sa_mpls.smpls_label = rt->rt_mpls;
+ sa_mpls.smpls_label = ((struct rt_mpls *)
+ rt->rt_llinfo)->mpls_label;
info.rti_info[RTAX_SRC] = (struct sockaddr *)&sa_mpls;
}
#endif
@@ -1126,6 +1121,12 @@ sysctl_dumpentry(struct radix_node *rn, void *v)
struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem;
rtm->rtm_flags = rt->rt_flags;
+#ifdef MPLS
+ if (dst->sa_family == AF_MPLS) {
+ rtm->rtm_flags |=
+ ((struct rt_mpls *)rt->rt_llinfo)->mpls_operation;
+ }
+#endif
rtm->rtm_priority = rt->rt_priority;
rt_getmetrics(&rt->rt_rmx, &rtm->rtm_rmx);
rtm->rtm_rmx.rmx_refcnt = rt->rt_refcnt;
@@ -1142,6 +1143,12 @@ sysctl_dumpentry(struct radix_node *rn, void *v)
struct rt_omsghdr *rtm = (struct rt_omsghdr *)w->w_tmem;
rtm->rtm_flags = rt->rt_flags;
+#ifdef MPLS
+ if (dst->sa_family == AF_MPLS) {
+ rtm->rtm_flags |=
+ ((struct rt_mpls *)rt->rt_llinfo)->mpls_operation;
+ }
+#endif
rtm->rtm_rmx.rmx_locks = rt->rt_rmx.rmx_locks;
rtm->rtm_rmx.rmx_mtu = rt->rt_rmx.rmx_mtu;
rtm->rtm_index = rt->rt_ifp->if_index;
diff --git a/sys/netmpls/mpls.h b/sys/netmpls/mpls.h
index f89151248bb..df287182ee5 100644
--- a/sys/netmpls/mpls.h
+++ b/sys/netmpls/mpls.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpls.h,v 1.16 2009/01/08 12:47:45 michele Exp $ */
+/* $OpenBSD: mpls.h,v 1.17 2009/01/28 22:18:44 michele Exp $ */
/*
* Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project.
@@ -94,9 +94,15 @@ struct sockaddr_mpls {
u_int32_t smpls_pad1[2];
};
-#define MPLS_OP_POP RTF_PROTO1
+struct rt_mpls {
+ u_int32_t mpls_label;
+ u_int8_t mpls_operation;
+ u_int8_t mpls_exp;
+};
+
+#define MPLS_OP_POP RTF_PROTO3
#define MPLS_OP_PUSH RTF_PROTO2
-#define MPLS_OP_SWAP RTF_PROTO3
+#define MPLS_OP_SWAP RTF_PROTO1
#define MPLS_INKERNEL_LOOP_MAX 16
@@ -167,11 +173,11 @@ 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 *);
+struct mbuf *mpls_shim_swap(struct mbuf *, struct rt_mpls *);
+struct mbuf *mpls_shim_push(struct mbuf *, struct rt_mpls *);
-int mpls_sysctl(int *, u_int, void *, size_t *, void *, size_t);
-void mpls_input(struct mbuf *);
-void mpls_output(struct mbuf *);
+int mpls_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+void mpls_input(struct mbuf *);
+struct mbuf *mpls_output(struct mbuf *, struct rtentry *);
#endif /* _KERNEL */
diff --git a/sys/netmpls/mpls_input.c b/sys/netmpls/mpls_input.c
index 9382aa6f9cb..bd7d2a28d62 100644
--- a/sys/netmpls/mpls_input.c
+++ b/sys/netmpls/mpls_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpls_input.c,v 1.17 2009/01/08 12:47:45 michele Exp $ */
+/* $OpenBSD: mpls_input.c,v 1.18 2009/01/28 22:18:44 michele Exp $ */
/*
* Copyright (c) 2008 Claudio Jeker <claudio@openbsd.org>
@@ -70,10 +70,10 @@ mpls_input(struct mbuf *m)
{
struct ifnet *ifp = m->m_pkthdr.rcvif;
struct sockaddr_mpls *smpls;
- struct sockaddr_mpls *newsmpls;
- struct sockaddr_mpls sa_mpls, sa_outmpls;
+ struct sockaddr_mpls sa_mpls;
struct shim_hdr *shim;
struct rtentry *rt = NULL;
+ struct rt_mpls *rt_mpls;
u_int8_t ttl;
int i, hasbos;
@@ -92,11 +92,6 @@ mpls_input(struct mbuf *m)
if ((m = m_pullup(m, sizeof(*shim))) == NULL)
return;
- bzero(&sa_outmpls, sizeof(sa_outmpls));
- newsmpls = &sa_outmpls;
- newsmpls->smpls_family = AF_MPLS;
- newsmpls->smpls_len = sizeof(*smpls);
-
shim = mtod(m, struct shim_hdr *);
#ifdef MPLS_DEBUG
@@ -171,9 +166,18 @@ mpls_input(struct mbuf *m)
rt->rt_use++;
smpls = satosmpls(rt_key(rt));
- newsmpls->smpls_label = rt->rt_mpls;
+ rt_mpls = (struct rt_mpls *)rt->rt_llinfo;
+
+ if (rt_mpls == NULL || (rt->rt_flags & RTF_MPLS) == 0) {
+ /* no MPLS information for this entry */
+#ifdef MPLS_DEBUG
+ printf("MPLS_DEBUG: no MPLS information attached\n");
+#endif
+ m_freem(m);
+ goto done;
+ }
- switch (rt->rt_flags & (MPLS_OP_PUSH | MPLS_OP_POP |
+ switch (rt_mpls->mpls_operation & (MPLS_OP_PUSH | MPLS_OP_POP |
MPLS_OP_SWAP)){
case MPLS_OP_POP:
@@ -192,10 +196,10 @@ mpls_input(struct mbuf *m)
}
break;
case MPLS_OP_PUSH:
- m = mpls_shim_push(m, newsmpls);
+ m = mpls_shim_push(m, rt_mpls);
break;
case MPLS_OP_SWAP:
- m = mpls_shim_swap(m, newsmpls);
+ m = mpls_shim_swap(m, rt_mpls);
break;
default:
m_freem(m);
@@ -216,6 +220,11 @@ mpls_input(struct mbuf *m)
rt = NULL;
}
+ if (rt == NULL) {
+ m_freem(m);
+ goto done;
+ }
+
/* write back TTL */
shim->shim_label = (shim->shim_label & ~MPLS_TTL_MASK) | htonl(ttl);
@@ -223,7 +232,7 @@ mpls_input(struct mbuf *m)
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_label),
- MPLS_LABEL_GET(newsmpls->smpls_label));
+ MPLS_LABEL_GET(rt_mpls->mpls_label));
#endif
(*ifp->if_output)(ifp, m, smplstosa(smpls), rt);
diff --git a/sys/netmpls/mpls_output.c b/sys/netmpls/mpls_output.c
index c8f16019444..a564f28bac8 100644
--- a/sys/netmpls/mpls_output.c
+++ b/sys/netmpls/mpls_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpls_output.c,v 1.4 2009/01/08 12:47:45 michele Exp $ */
+/* $OpenBSD: mpls_output.c,v 1.5 2009/01/28 22:18:44 michele Exp $ */
/*
* Copyright (c) 2008 Claudio Jeker <claudio@openbsd.org>
@@ -33,101 +33,75 @@ extern int mpls_inkloop;
#define MPLS_LABEL_GET(l) ((ntohl((l) & MPLS_LABEL_MASK)) >> MPLS_LABEL_OFFSET)
#endif
-void
-mpls_output(struct mbuf *m)
+struct mbuf *
+mpls_output(struct mbuf *m, struct rtentry *rt0)
{
struct ifnet *ifp = m->m_pkthdr.rcvif;
struct sockaddr_mpls *smpls;
- struct sockaddr_mpls *newsmpls;
- struct sockaddr_mpls sa_mpls, sa_outmpls;
+ struct sockaddr_mpls sa_mpls;
struct shim_hdr *shim;
- struct rtentry *rt = NULL;
- u_int32_t ttl;
+ struct rtentry *rt = rt0;
+ struct rt_mpls *rt_mpls;
+ //u_int32_t ttl;
int i;
if (!mpls_enable) {
m_freem(m);
- return;
+ goto bad;
}
/* reset broadcast and multicast flags, this is a P2P tunnel */
m->m_flags &= ~(M_BCAST | M_MCAST);
- if (m->m_len < sizeof(*shim))
- if ((m = m_pullup(m, sizeof(*shim))) == NULL)
- return;
-
- bzero(&sa_outmpls, sizeof(sa_outmpls));
- newsmpls = &sa_outmpls;
- newsmpls->smpls_family = AF_MPLS;
- newsmpls->smpls_len = sizeof(*smpls);
-
- shim = mtod(m, struct shim_hdr *);
-
- /* extract TTL */
- ttl = shim->shim_label & MPLS_TTL_MASK;
-
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_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_label),
- ifp->if_index);
-#endif
+ if (rt == NULL) {
+ shim = mtod(m, struct shim_hdr *);
- rt = rtalloc1(smplstosa(smpls), 1, 0);
+ bzero(&sa_mpls, sizeof(sa_mpls));
+ smpls = &sa_mpls;
+ smpls->smpls_family = AF_MPLS;
+ smpls->smpls_len = sizeof(*smpls);
+ smpls->smpls_label = shim->shim_label & MPLS_LABEL_MASK;
- if (rt == NULL) {
- /* no entry for this label */
+ rt = rtalloc1(smplstosa(smpls), 1, 0);
+ if (rt == NULL) {
+ /* no entry for this label */
#ifdef MPLS_DEBUG
- printf("MPLS_DEBUG: label not found\n");
+ printf("MPLS_DEBUG: label not found\n");
#endif
- m_freem(m);
- goto done;
+ m_freem(m);
+ goto bad;
+ }
+ rt->rt_use++;
}
- rt->rt_use++;
- smpls = satosmpls(rt_key(rt));
- newsmpls->smpls_label = rt->rt_mpls;
-
+ rt_mpls = (struct rt_mpls *)rt->rt_llinfo;
+ if (rt_mpls == NULL || (rt->rt_flags & RTF_MPLS) == 0) {
+ /* no MPLS information for this entry */
#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_label),
- ifp->if_index);
+ printf("MPLS_DEBUG: no MPLS information attached\n");
#endif
+ m_freem(m);
+ goto bad;
+ }
- switch (rt->rt_flags & (MPLS_OP_PUSH | MPLS_OP_POP |
+ switch (rt_mpls->mpls_operation & (MPLS_OP_PUSH | MPLS_OP_POP |
MPLS_OP_SWAP)) {
- case MPLS_OP_POP:
- if (MPLS_BOS_ISSET(shim->shim_label)) {
- /* drop to avoid loops */
- m_freem(m);
- goto done;
- }
-
- m = mpls_shim_pop(m);
- break;
case MPLS_OP_PUSH:
- m = mpls_shim_push(m, newsmpls);
+ m = mpls_shim_push(m, rt_mpls);
break;
+ case MPLS_OP_POP:
case MPLS_OP_SWAP:
- m = mpls_shim_swap(m, newsmpls);
- break;
+ /* We are entring a LSP. There isn't anything to pop
+ or swap yet. */
default:
m_freem(m);
- goto done;
+ goto bad;
}
if (m == NULL)
- goto done;
+ goto bad;
/* refetch label */
shim = mtod(m, struct shim_hdr *);
@@ -136,22 +110,29 @@ mpls_output(struct mbuf *m)
if (ifp != NULL)
break;
- RTFREE(rt);
+ if (rt0 != rt)
+ RTFREE(rt);
+
rt = NULL;
}
/* write back TTL */
- shim->shim_label = (shim->shim_label & ~MPLS_TTL_MASK) | ttl;
+ shim->shim_label &= ~MPLS_TTL_MASK;
+ shim->shim_label |= MPLS_BOS_MASK | htonl(mpls_defttl);
#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_label),
- MPLS_LABEL_GET(smpls->smpls_label));
+ printf("MPLS: sending on %s outshim %x outlabel %d\n",
+ ifp->if_xname, ntohl(shim->shim_label),
+ MPLS_LABEL_GET(rt_mpls->mpls_label));
#endif
- (*ifp->if_output)(ifp, m, smplstosa(smpls), rt);
-done:
- if (rt)
+ if (rt != rt0)
RTFREE(rt);
+
+ return (m);
+bad:
+ if (rt != rt0)
+ RTFREE(rt);
+
+ return (NULL);
}
diff --git a/sys/netmpls/mpls_shim.c b/sys/netmpls/mpls_shim.c
index 32c27713236..3abe64feb8b 100644
--- a/sys/netmpls/mpls_shim.c
+++ b/sys/netmpls/mpls_shim.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpls_shim.c,v 1.5 2009/01/08 12:47:45 michele Exp $ */
+/* $OpenBSD: mpls_shim.c,v 1.6 2009/01/28 22:18:44 michele Exp $ */
/*
* Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project.
@@ -50,7 +50,7 @@ mpls_shim_pop(struct mbuf *m)
/* catch-up next shim_hdr */
if (m->m_len < sizeof(struct shim_hdr))
- if ((m = m_pullup(m, sizeof(struct shim_hdr))) == 0)
+ if ((m = m_pullup(m, sizeof(struct shim_hdr))) == NULL)
return (NULL);
/* return mbuf */
@@ -58,26 +58,26 @@ mpls_shim_pop(struct mbuf *m)
}
struct mbuf *
-mpls_shim_swap(struct mbuf *m, struct sockaddr_mpls *smplsp)
+mpls_shim_swap(struct mbuf *m, struct rt_mpls *rt_mpls)
{
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)
+ if ((m = m_pullup(m, sizeof(struct shim_hdr))) == NULL)
return (NULL);
shim = mtod(m, struct shim_hdr *);
/* swap label */
shim->shim_label &= ~MPLS_LABEL_MASK;
- shim->shim_label |= smplsp->smpls_label & MPLS_LABEL_MASK;
+ shim->shim_label |= rt_mpls->mpls_label & MPLS_LABEL_MASK;
/* swap exp : XXX exp override */
{
u_int32_t t;
shim->shim_label &= ~MPLS_EXP_MASK;
- t = 0;
+ t = rt_mpls->mpls_exp << MPLS_EXP_OFFSET;
shim->shim_label |= htonl(t) & MPLS_EXP_MASK;
}
@@ -85,16 +85,16 @@ mpls_shim_swap(struct mbuf *m, struct sockaddr_mpls *smplsp)
}
struct mbuf *
-mpls_shim_push(struct mbuf *m, struct sockaddr_mpls *smplsp)
+mpls_shim_push(struct mbuf *m, struct rt_mpls *rt_mpls)
{
struct shim_hdr *shim;
M_PREPEND(m, sizeof(struct shim_hdr), M_DONTWAIT);
- if (m == 0)
+ if (m == NULL)
return (NULL);
shim = mtod(m, struct shim_hdr *);
bzero((caddr_t)shim, sizeof(*shim));
- return (mpls_shim_swap(m, smplsp));
+ return (mpls_shim_swap(m, rt_mpls));
}