On 22/02/17(Wed) 18:10, Alexander Bluhm wrote:
> On Wed, Feb 22, 2017 at 05:06:34PM +0100, Martin Pieuchot wrote:
> [...]
> > -ip6_ours(struct mbuf *m, int off, int nxt)
> > +ip6_ours(struct mbuf *m)
> > +{
> > + int off, nxt;
> > +
> > + KERNEL_ASSERT_LOCKED();
> > +
> > + if (ip6_hbhchcheck(m, &off, &nxt, NULL))
> > + return;
> > +
> > + ip6_local(m, off, nxt);
> > +}
>
> When you unlock the forwarding path, there must be a KERNEL_LOCK()
> around ip6_local(). Or do you plan to rewrite this function anyway?
I plan to rewrite the function to enqueue mbufs on ip6intrq. See my
diff "IPv4 forwarding w/o KERNEL_LOCK()", it's the same but for legacy
IP.
Here's an updated diff that should address all your points.
Index: netinet/ipsec_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ipsec_input.c,v
retrieving revision 1.144
diff -u -p -r1.144 ipsec_input.c
--- netinet/ipsec_input.c 8 Feb 2017 12:37:43 -0000 1.144
+++ netinet/ipsec_input.c 22 Feb 2017 17:23:06 -0000
@@ -592,7 +592,7 @@ ipsec_common_input_cb(struct mbuf *m, st
return;
#ifdef INET6
case AF_INET6:
- ip6_ours(m, skip, prot);
+ ip6_local(m, skip, prot);
return;
#endif /* INET6 */
default:
Index: netinet6/ip6_input.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.179
diff -u -p -r1.179 ip6_input.c
--- netinet6/ip6_input.c 8 Feb 2017 12:37:43 -0000 1.179
+++ netinet6/ip6_input.c 22 Feb 2017 17:27:36 -0000
@@ -119,6 +119,7 @@ struct niqueue ip6intrq = NIQUEUE_INITIA
struct cpumem *ip6counters;
+void ip6_ours(struct mbuf *);
int ip6_check_rh0hdr(struct mbuf *, int *);
int ip6_hbhchcheck(struct mbuf *, int *, int *, int *);
int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
@@ -180,8 +181,8 @@ ip6_input(struct mbuf *m)
struct ip6_hdr *ip6;
struct sockaddr_in6 sin6;
struct rtentry *rt = NULL;
- int off, nxt, ours = 0;
u_int16_t src_scope, dst_scope;
+ int off, nxt, ours = 0;
#if NPF > 0
struct in6_addr odst;
#endif
@@ -339,14 +340,14 @@ ip6_input(struct mbuf *m)
if (IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) ||
IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) {
- ours = 1;
- goto hbhcheck;
+ ip6_ours(m);
+ goto out;
}
#if NPF > 0
if (pf_ouraddr(m) == 1) {
- ours = 1;
- goto hbhcheck;
+ ip6_ours(m);
+ goto out;
}
#endif
@@ -383,14 +384,16 @@ ip6_input(struct mbuf *m)
* ip6_mforward() returns a non-zero value, the packet
* must be discarded, else it may be accepted below.
*/
+ KERNEL_LOCK();
if (ip6_mforward(ip6, ifp, m)) {
ip6stat_inc(ip6s_cantforward);
- goto bad;
+ m_freem(m);
+ } else if (ours) {
+ ip6_local(m, off, nxt);
+ } else {
+ m_freem(m);
}
-
- if (!ours)
- goto bad;
- ip6_ours(m, off, nxt);
+ KERNEL_UNLOCK();
goto out;
}
#endif
@@ -400,7 +403,8 @@ ip6_input(struct mbuf *m)
ip6stat_inc(ip6s_cantforward);
goto bad;
}
- goto hbhcheck;
+ ip6_ours(m);
+ goto out;
}
@@ -438,9 +442,8 @@ ip6_input(struct mbuf *m)
goto bad;
} else {
- /* this address is ready */
- ours = 1;
- goto hbhcheck;
+ ip6_ours(m);
+ goto out;
}
}
@@ -459,19 +462,16 @@ ip6_input(struct mbuf *m)
goto bad;
}
- hbhcheck:
-
if (ip6_hbhchcheck(m, &off, &nxt, &ours))
goto out;
if (ours) {
- ip6_ours(m, off, nxt);
+ KERNEL_LOCK();
+ ip6_local(m, off, nxt);
+ KERNEL_UNLOCK();
goto out;
}
- /*
- * Forward if desirable.
- */
ip6_forward(m, rt, srcrt);
if_put(ifp);
return;
@@ -483,10 +483,23 @@ ip6_input(struct mbuf *m)
}
void
-ip6_ours(struct mbuf *m, int off, int nxt)
+ip6_ours(struct mbuf *m)
+{
+ int off, nxt;
+
+ if (ip6_hbhchcheck(m, &off, &nxt, NULL))
+ return;
+
+ ip6_local(m, off, nxt);
+}
+
+void
+ip6_local(struct mbuf *m, int off, int nxt)
{
int nest = 0;
+ KERNEL_ASSERT_LOCKED();
+
/* pf might have changed things */
in6_proto_cksum_out(m, NULL);
@@ -582,7 +595,7 @@ ip6_hbhchcheck(struct mbuf *m, int *offp
* accept the packet if a router alert option is included
* and we act as an IPv6 router.
*/
- if (rtalert != ~0 && ip6_forwarding)
+ if (rtalert != ~0 && ip6_forwarding && oursp != NULL)
*oursp = 1;
} else
*nxtp = ip6->ip6_nxt;
Index: netinet6/ip6_var.h
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_var.h,v
retrieving revision 1.68
diff -u -p -r1.68 ip6_var.h
--- netinet6/ip6_var.h 8 Feb 2017 12:37:43 -0000 1.68
+++ netinet6/ip6_var.h 22 Feb 2017 17:25:35 -0000
@@ -304,7 +304,7 @@ int icmp6_ctloutput(int, struct socket *
void ip6_init(void);
void ip6intr(void);
void ip6_input(struct mbuf *);
-void ip6_ours(struct mbuf *, int, int);
+void ip6_local(struct mbuf *, int, int);
void ip6_freepcbopts(struct ip6_pktopts *);
void ip6_freemoptions(struct ip6_moptions *);
int ip6_unknown_opt(u_int8_t *, struct mbuf *, int);