summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2016-04-18 06:43:52 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2016-04-18 06:43:52 +0000
commit847d1917cd938018847ac6ade829bc8462baa8e7 (patch)
tree31dbff01cee37c117b58b7ae2f14f929c1f3a99f
parent515e4913aab9e983e16236fad08921a8a0c6e2f6 (diff)
Put a KERNEL_LOCK/UNLOCK dance around sections that still need some
work in the forwarding path. Tested by Hrvoje Popovski, ok dlg@
-rw-r--r--sys/netinet/in.c4
-rw-r--r--sys/netinet/ip_input.c14
-rw-r--r--sys/netinet/ip_output.c31
3 files changed, 34 insertions, 15 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 40f21d279e4..790c988e3f3 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in.c,v 1.126 2016/01/21 11:23:48 mpi Exp $ */
+/* $OpenBSD: in.c,v 1.127 2016/04/18 06:43:51 mpi Exp $ */
/* $NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $ */
/*
@@ -890,8 +890,10 @@ in_hasmulti(struct in_addr *ap, struct ifnet *ifp)
struct in_multi *inm;
int joined;
+ KERNEL_LOCK();
IN_LOOKUP_MULTI(*ap, ifp, inm);
joined = (inm != NULL);
+ KERNEL_UNLOCK();
return (joined);
}
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 993e05e77b0..071c3acc488 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.270 2016/04/15 11:18:40 mpi Exp $ */
+/* $OpenBSD: ip_input.c,v 1.271 2016/04/18 06:43:51 mpi Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -227,7 +227,7 @@ ipv4_input(struct mbuf *m)
{
struct ifnet *ifp;
struct ip *ip;
- int hlen, len;
+ int rv, hlen, len;
in_addr_t pfrdr = 0;
ifp = if_get(m->m_pkthdr.ph_ifidx);
@@ -355,8 +355,6 @@ ipv4_input(struct mbuf *m)
#ifdef MROUTING
if (ipmforwarding && ip_mrouter) {
- int rv;
-
if (m->m_flags & M_EXT) {
if ((m = m_pullup(m, hlen)) == NULL) {
ipstat.ips_toosmall++;
@@ -430,7 +428,10 @@ ipv4_input(struct mbuf *m)
}
#ifdef IPSEC
if (ipsec_in_use) {
- if (ip_input_ipsec_fwd_check(m, hlen) != 0) {
+ KERNEL_LOCK();
+ rv = ip_input_ipsec_fwd_check(m, hlen);
+ KERNEL_UNLOCK();
+ if (rv != 0) {
ipstat.ips_cantforward++;
goto bad;
}
@@ -1027,6 +1028,7 @@ ip_dooptions(struct mbuf *m, struct ifnet *ifp)
cp = (u_char *)(ip + 1);
cnt = (ip->ip_hl << 2) - sizeof (struct ip);
+ KERNEL_LOCK();
for (; cnt > 0; cnt -= optlen, cp += optlen) {
opt = cp[IPOPT_OPTVAL];
if (opt == IPOPT_EOL)
@@ -1240,12 +1242,14 @@ ip_dooptions(struct mbuf *m, struct ifnet *ifp)
ipt.ipt_ptr += sizeof(u_int32_t);
}
}
+ KERNEL_UNLOCK();
if (forward && ipforwarding) {
ip_forward(m, ifp, 1);
return (1);
}
return (0);
bad:
+ KERNEL_UNLOCK();
icmp_error(m, type, code, 0, 0);
ipstat.ips_badoptions++;
return (1);
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index eaf45fef8c7..d3f85647ac5 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.318 2016/02/11 12:56:08 jca Exp $ */
+/* $OpenBSD: ip_output.c,v 1.319 2016/04/18 06:43:51 mpi Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -100,10 +100,9 @@ ip_output(struct mbuf *m0, struct mbuf *opt, struct route *ro, int flags,
struct ifnet *ifp = NULL;
struct mbuf *m = m0;
int hlen = sizeof (struct ip);
- int len, error = 0;
+ int rv, len, error = 0;
struct route iproute;
struct sockaddr_in *dst;
- struct in_ifaddr *ia;
struct tdb *tdb = NULL;
u_long mtu;
@@ -183,9 +182,17 @@ reroute:
if ((IN_MULTICAST(ip->ip_dst.s_addr) ||
(ip->ip_dst.s_addr == INADDR_BROADCAST)) &&
imo != NULL && (ifp = if_get(imo->imo_ifidx)) != NULL) {
+ struct in_ifaddr *ia;
+
mtu = ifp->if_mtu;
+ KERNEL_LOCK();
IFP_TO_IA(ifp, ia);
+ if (ip->ip_src.s_addr == INADDR_ANY && ia)
+ ip->ip_src = ia->ia_addr.sin_addr;
+ KERNEL_UNLOCK();
} else {
+ struct in_ifaddr *ia;
+
if (ro->ro_rt == NULL)
ro->ro_rt = rtalloc_mpath(&ro->ro_dst,
&ip->ip_src.s_addr, ro->ro_tableid);
@@ -206,17 +213,19 @@ reroute:
if (ro->ro_rt->rt_flags & RTF_GATEWAY)
dst = satosin(ro->ro_rt->rt_gateway);
- }
- /* Set the source IP address */
- if (ip->ip_src.s_addr == INADDR_ANY && ia)
- ip->ip_src = ia->ia_addr.sin_addr;
+ /* Set the source IP address */
+ if (ip->ip_src.s_addr == INADDR_ANY && ia)
+ ip->ip_src = ia->ia_addr.sin_addr;
+ }
#ifdef IPSEC
if (ipsec_in_use || inp != NULL) {
+ KERNEL_LOCK();
/* Do we have any pending SAs to apply ? */
tdb = ip_output_ipsec_lookup(m, hlen, &error, inp,
ipsecflowinfo);
+ KERNEL_UNLOCK();
if (error != 0) {
/* Should silently drop packet */
if (error == -EINVAL)
@@ -289,9 +298,13 @@ reroute:
* of outgoing interface.
*/
if (ip->ip_src.s_addr == INADDR_ANY) {
+ struct in_ifaddr *ia;
+
+ KERNEL_LOCK();
IFP_TO_IA(ifp, ia);
if (ia != NULL)
ip->ip_src = ia->ia_addr.sin_addr;
+ KERNEL_UNLOCK();
}
if ((imo == NULL || imo->imo_loop) &&
@@ -322,8 +335,6 @@ reroute:
*/
if (ipmforwarding && ip_mrouter &&
(flags & IP_FORWARDING) == 0) {
- int rv;
-
KERNEL_LOCK();
rv = ip_mforward(m, ifp);
KERNEL_UNLOCK();
@@ -389,8 +400,10 @@ sendit:
* Check if the packet needs encapsulation.
*/
if (tdb != NULL) {
+ KERNEL_LOCK();
/* Callee frees mbuf */
error = ip_output_ipsec_send(tdb, m, ifp, ro);
+ KERNEL_UNLOCK();
goto done;
}
#endif /* IPSEC */