On 01/02/17(Wed) 20:48, Alexander Bluhm wrote: > Hi, > > I would like to make ip6_input() more like ipv4_input() and introduce > ip6_ours(). > > ok?
This will help making v6 forwarding path un-KERNEL_LOCK()'d, ok mpi@ > Index: netinet6/ip6_input.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_input.c,v > retrieving revision 1.175 > diff -u -p -r1.175 ip6_input.c > --- netinet6/ip6_input.c 29 Jan 2017 19:58:47 -0000 1.175 > +++ netinet6/ip6_input.c 1 Feb 2017 19:42:15 -0000 > @@ -120,9 +120,9 @@ struct niqueue ip6intrq = NIQUEUE_INITIA > struct ip6stat ip6stat; > > 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 *); > +void ip6_ours(struct mbuf *, int, int); > struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int); > > static struct mbuf_queue ip6send_mq; > @@ -179,9 +179,8 @@ ip6_input(struct mbuf *m) > struct ip6_hdr *ip6; > struct sockaddr_in6 sin6; > struct rtentry *rt = NULL; > - int off, nest; > + int off, nxt, ours = 0; > u_int16_t src_scope, dst_scope; > - int nxt, ours = 0; > #if NPF > 0 > struct in6_addr odst; > #endif > @@ -214,8 +213,7 @@ ip6_input(struct mbuf *m) > if (m->m_len < sizeof(struct ip6_hdr)) { > if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { > ip6stat.ip6s_toosmall++; > - if_put(ifp); > - return; > + goto out; > } > } > > @@ -353,9 +351,7 @@ ip6_input(struct mbuf *m) > ip6_check_rh0hdr(m, &off)) { > ip6stat.ip6s_badoptions++; > icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, off); > - /* m is already freed */ > - if_put(ifp); > - return; > + goto out; > } > > if (IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) || > @@ -391,11 +387,8 @@ ip6_input(struct mbuf *m) > > #ifdef MROUTING > if (ip6_mforwarding && ip6_mrouter) { > - if (ip6_hbhchcheck(m, &off, &nxt, &ours)) { > - rtfree(rt); > - if_put(ifp); > - return; /* m have already been freed */ > - } > + if (ip6_hbhchcheck(m, &off, &nxt, &ours)) > + goto out; > > ip6 = mtod(m, struct ip6_hdr *); > > @@ -407,14 +400,15 @@ ip6_input(struct mbuf *m) > * ip6_mforward() returns a non-zero value, the packet > * must be discarded, else it may be accepted below. > */ > - if (ip6_mforward(ip6, ifp, m)) { > + if (ip6_mforward(ip6, ifp, m)) { > ip6stat.ip6s_cantforward++; > goto bad; > } > > if (!ours) > goto bad; > - goto ours; > + ip6_ours(m, off, nxt); > + goto out; > } > #endif > if (!ours) { > @@ -484,36 +478,39 @@ ip6_input(struct mbuf *m) > > hbhcheck: > > - if (ip6_hbhchcheck(m, &off, &nxt, &ours)) { > - rtfree(rt); > - if_put(ifp); > - return; /* m have already been freed */ > - } > + if (ip6_hbhchcheck(m, &off, &nxt, &ours)) > + goto out; > > - /* adjust pointer */ > - ip6 = mtod(m, struct ip6_hdr *); > + if (ours) { > + ip6_ours(m, off, nxt); > + goto out; > + } > > /* > * Forward if desirable. > */ > - if (!ours) { > - ip6_forward(m, rt, srcrt); > - if_put(ifp); > - return; > - } > -#ifdef MROUTING > - ours: > -#endif > + ip6_forward(m, rt, srcrt); > + if_put(ifp); > + return; > + bad: > + m_freem(m); > + out: > + rtfree(rt); > + if_put(ifp); > +} > + > +void > +ip6_ours(struct mbuf *m, int off, int nxt) > +{ > + int nest = 0; > + > /* pf might have changed things */ > in6_proto_cksum_out(m, NULL); > > - ip6 = mtod(m, struct ip6_hdr *); > - > /* > * Tell launch routine the next header > */ > ip6stat.ip6s_delivered++; > - nest = 0; > > while (nxt != IPPROTO_DONE) { > if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { > @@ -543,12 +540,8 @@ ip6_input(struct mbuf *m) > > nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); > } > - rtfree(rt); > - if_put(ifp); > return; > bad: > - rtfree(rt); > - if_put(ifp); > m_freem(m); > } > >