summaryrefslogtreecommitdiff
path: root/sys/netmpls
diff options
context:
space:
mode:
authorRafael Zalamena <rzalamena@cvs.openbsd.org>2015-07-29 00:04:04 +0000
committerRafael Zalamena <rzalamena@cvs.openbsd.org>2015-07-29 00:04:04 +0000
commitf9452d6600827be8026afad77d2bee42f3f5ec28 (patch)
tree6020f17eaa7adece3613fd99fb745a46a1694e0f /sys/netmpls
parent0570bc829f17be54336aa00b04fdc334d53f2406 (diff)
Don't use mpls_input() as input handler anymore and instead call it
directly. Also protect non mp-safe functions while at it. ok mpi@.
Diffstat (limited to 'sys/netmpls')
-rw-r--r--sys/netmpls/mpls.h5
-rw-r--r--sys/netmpls/mpls_input.c74
2 files changed, 26 insertions, 53 deletions
diff --git a/sys/netmpls/mpls.h b/sys/netmpls/mpls.h
index 07231e0df47..ed71f6cbd18 100644
--- a/sys/netmpls/mpls.h
+++ b/sys/netmpls/mpls.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpls.h,v 1.33 2015/07/20 22:16:41 rzalamena Exp $ */
+/* $OpenBSD: mpls.h,v 1.34 2015/07/29 00:04:03 rzalamena Exp $ */
/*
* Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project.
@@ -191,7 +191,6 @@ struct mbuf *mpls_shim_push(struct mbuf *, struct rt_mpls *);
int mpls_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int mpls_output(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
-int mpls_install_handler(struct ifnet *);
-void mpls_uninstall_handler(struct ifnet *);
+void mpls_input(struct ifnet *, struct mbuf *);
#endif /* _KERNEL */
diff --git a/sys/netmpls/mpls_input.c b/sys/netmpls/mpls_input.c
index d1aa4ca2922..2ae6cb7b9fc 100644
--- a/sys/netmpls/mpls_input.c
+++ b/sys/netmpls/mpls_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpls_input.c,v 1.46 2015/07/20 22:16:41 rzalamena Exp $ */
+/* $OpenBSD: mpls_input.c,v 1.47 2015/07/29 00:04:03 rzalamena Exp $ */
/*
* Copyright (c) 2008 Claudio Jeker <claudio@openbsd.org>
@@ -51,54 +51,13 @@ int mpls_ip6_adjttl(struct mbuf *, u_int8_t);
#endif
struct mbuf *mpls_do_error(struct mbuf *, int, int, int);
-int mpls_input(struct ifnet *, struct mbuf *);
void
mpls_init(void)
{
}
-int
-mpls_install_handler(struct ifnet *ifp)
-{
- struct ifih *ifih, *ifihn;
-
- ifih = malloc(sizeof(*ifih), M_DEVBUF, M_ZERO | M_NOWAIT);
- if (ifih == NULL)
- return (-1);
-
- ifih->ifih_input = mpls_input;
-
- /* We must install mpls_input() after ether_input(). */
- SLIST_FOREACH(ifihn, &ifp->if_inputs, ifih_next)
- if (SLIST_NEXT(ifihn, ifih_next) == NULL)
- break;
-
- if (ifihn == NULL)
- SLIST_INSERT_HEAD(&ifp->if_inputs, ifih, ifih_next);
- else
- SLIST_INSERT_AFTER(ifihn, ifih, ifih_next);
-
- return (0);
-}
-
void
-mpls_uninstall_handler(struct ifnet *ifp)
-{
- struct ifih *ifih;
-
- SLIST_FOREACH(ifih, &ifp->if_inputs, ifih_next) {
- if (ifih->ifih_input != mpls_input)
- continue;
-
- SLIST_REMOVE(&ifp->if_inputs, ifih, ifih, ifih_next);
- break;
- }
-
- free(ifih, M_DEVBUF, sizeof(*ifih));
-}
-
-int
mpls_input(struct ifnet *ifp, struct mbuf *m)
{
struct sockaddr_mpls *smpls;
@@ -111,18 +70,18 @@ mpls_input(struct ifnet *ifp, struct mbuf *m)
if (!ISSET(ifp->if_xflags, IFXF_MPLS)) {
m_freem(m);
- return (1);
+ return;
}
/* drop all broadcast and multicast packets */
if (m->m_flags & (M_BCAST | M_MCAST)) {
m_freem(m);
- return (1);
+ return;
}
if (m->m_len < sizeof(*shim))
if ((m = m_pullup(m, sizeof(*shim))) == NULL)
- return (1);
+ return;
shim = mtod(m, struct shim_hdr *);
@@ -139,7 +98,7 @@ mpls_input(struct ifnet *ifp, struct mbuf *m)
/* TTL exceeded */
m = mpls_do_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0);
if (m == NULL)
- return (1);
+ return;
shim = mtod(m, struct shim_hdr *);
ttl = ntohl(shim->shim_label & MPLS_TTL_MASK);
}
@@ -211,7 +170,9 @@ do_v6:
}
}
+ KERNEL_LOCK();
rt = rtalloc(smplstosa(smpls), RT_REPORT|RT_RESOLVE, 0);
+ KERNEL_UNLOCK();
if (rt == NULL) {
/* no entry for this label */
#ifdef MPLS_DEBUG
@@ -330,7 +291,9 @@ do_v6:
if (ifp != NULL && rt_mpls->mpls_operation != MPLS_OP_LOCAL)
break;
+ KERNEL_LOCK();
rtfree(rt);
+ KERNEL_UNLOCK();
rt = NULL;
}
@@ -357,12 +320,15 @@ do_v6:
goto done;
}
+ KERNEL_LOCK();
(*ifp->if_ll_output)(ifp, m, smplstosa(smpls), rt);
+ KERNEL_UNLOCK();
done:
- if (rt)
+ if (rt) {
+ KERNEL_LOCK();
rtfree(rt);
-
- return (1);
+ KERNEL_UNLOCK();
+ }
}
int
@@ -462,7 +428,9 @@ mpls_do_error(struct mbuf *m, int type, int code, int destmtu)
smpls->smpls_len = sizeof(*smpls);
smpls->smpls_label = shim->shim_label & MPLS_LABEL_MASK;
+ KERNEL_LOCK();
rt = rtalloc(smplstosa(smpls), RT_REPORT|RT_RESOLVE, 0);
+ KERNEL_UNLOCK();
if (rt == NULL) {
/* no entry for this label */
m_freem(m);
@@ -475,14 +443,20 @@ mpls_do_error(struct mbuf *m, int type, int code, int destmtu)
* less interface we need to find some other IP to
* use as source.
*/
+ KERNEL_LOCK();
rtfree(rt);
+ KERNEL_UNLOCK();
m_freem(m);
return (NULL);
}
rt->rt_use++;
+ KERNEL_LOCK();
rtfree(rt);
- if (icmp_reflect(m, NULL, ia))
+ if (icmp_reflect(m, NULL, ia)) {
+ KERNEL_UNLOCK();
return (NULL);
+ }
+ KERNEL_UNLOCK();
ip = mtod(m, struct ip *);
/* stuff to fix up which is normaly done in ip_output */