diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2016-04-18 06:43:52 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2016-04-18 06:43:52 +0000 |
commit | 847d1917cd938018847ac6ade829bc8462baa8e7 (patch) | |
tree | 31dbff01cee37c117b58b7ae2f14f929c1f3a99f | |
parent | 515e4913aab9e983e16236fad08921a8a0c6e2f6 (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.c | 4 | ||||
-rw-r--r-- | sys/netinet/ip_input.c | 14 | ||||
-rw-r--r-- | sys/netinet/ip_output.c | 31 |
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 */ |