Hi, As the comment says, icmp6_rip6_input() is mostly duplicated code from rip6_input(). So lets merge these functions together and retire icmp6_rip6_input().
ok? bluhm Index: netinet6/icmp6.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/icmp6.c,v retrieving revision 1.205 diff -u -p -r1.205 icmp6.c --- netinet6/icmp6.c 14 Apr 2017 20:46:31 -0000 1.205 +++ netinet6/icmp6.c 16 Apr 2017 23:23:45 -0000 @@ -135,7 +135,6 @@ static struct rttimer_queue *icmp6_redir static int icmp6_redirect_lowat = -1; void icmp6_errcount(int, int); -int icmp6_rip6_input(struct mbuf **, int); int icmp6_ratelimit(const struct in6_addr *, const int, const int); const char *icmp6_redirect_diag(struct in6_addr *, struct in6_addr *, struct in6_addr *); @@ -761,9 +760,7 @@ badlen: raw: #endif /* deliver the packet to appropriate sockets */ - icmp6_rip6_input(&m, *offp); - - return IPPROTO_DONE; + return rip6_input(mp, offp, proto, af); freeit: m_freem(m); @@ -1039,104 +1036,6 @@ icmp6_mtudisc_update(struct ip6ctlparam */ LIST_FOREACH(mc, &icmp6_mtudisc_callbacks, mc_list) (*mc->mc_func)(&sin6, m->m_pkthdr.ph_rtableid); -} - -/* - * XXX almost dup'ed code with rip6_input. - */ -int -icmp6_rip6_input(struct mbuf **mp, int off) -{ - struct mbuf *m = *mp; - struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); - struct inpcb *in6p; - struct inpcb *last = NULL; - struct sockaddr_in6 rip6src; - struct icmp6_hdr *icmp6; - struct mbuf *opts = NULL; - - IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6)); - if (icmp6 == NULL) { - /* m is already reclaimed */ - return IPPROTO_DONE; - } - - bzero(&rip6src, sizeof(rip6src)); - rip6src.sin6_len = sizeof(struct sockaddr_in6); - rip6src.sin6_family = AF_INET6; - /* KAME hack: recover scopeid */ - in6_recoverscope(&rip6src, &ip6->ip6_src); - - TAILQ_FOREACH(in6p, &rawin6pcbtable.inpt_queue, inp_queue) { - if (!(in6p->inp_flags & INP_IPV6)) - continue; - if (in6p->inp_ipv6.ip6_nxt != IPPROTO_ICMPV6) - continue; -#if NPF > 0 - if (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) { - struct pf_divert *divert; - - /* XXX rdomain support */ - if ((divert = pf_find_divert(m)) == NULL) - continue; - if (IN6_IS_ADDR_UNSPECIFIED(&divert->addr.v6)) - goto divert_reply; - if (!IN6_ARE_ADDR_EQUAL(&in6p->inp_laddr6, - &divert->addr.v6)) - continue; - } else - divert_reply: -#endif - if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->inp_laddr6) && - !IN6_ARE_ADDR_EQUAL(&in6p->inp_laddr6, &ip6->ip6_dst)) - continue; - if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->inp_faddr6) && - !IN6_ARE_ADDR_EQUAL(&in6p->inp_faddr6, &ip6->ip6_src)) - continue; - if (in6p->inp_icmp6filt - && ICMP6_FILTER_WILLBLOCK(icmp6->icmp6_type, - in6p->inp_icmp6filt)) - continue; - if (last) { - struct mbuf *n; - if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) != NULL) { - if (last->inp_flags & IN6P_CONTROLOPTS) - ip6_savecontrol(last, n, &opts); - /* strip intermediate headers */ - m_adj(n, off); - if (sbappendaddr(&last->inp_socket->so_rcv, - sin6tosa(&rip6src), n, opts) == 0) { - /* should notify about lost packet */ - m_freem(n); - m_freem(opts); - } else - sorwakeup(last->inp_socket); - opts = NULL; - } - } - last = in6p; - } - if (last) { - if (last->inp_flags & IN6P_CONTROLOPTS) - ip6_savecontrol(last, m, &opts); - /* strip intermediate headers */ - m_adj(m, off); - if (sbappendaddr(&last->inp_socket->so_rcv, - sin6tosa(&rip6src), m, opts) == 0) { - m_freem(m); - m_freem(opts); - } else - sorwakeup(last->inp_socket); - } else { - struct counters_ref ref; - uint64_t *counters; - - m_freem(m); - counters = counters_enter(&ref, ip6counters); - counters[ip6s_delivered]--; - counters_leave(&ref, ip6counters); - } - return IPPROTO_DONE; } /* Index: netinet6/raw_ip6.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/raw_ip6.c,v retrieving revision 1.109 diff -u -p -r1.109 raw_ip6.c --- netinet6/raw_ip6.c 14 Apr 2017 20:46:31 -0000 1.109 +++ netinet6/raw_ip6.c 16 Apr 2017 23:48:55 -0000 @@ -125,7 +125,8 @@ rip6_input(struct mbuf **mp, int *offp, struct sockaddr_in6 rip6src; struct mbuf *opts = NULL; - rip6stat_inc(rip6s_ipackets); + if (proto != IPPROTO_ICMPV6) + rip6stat_inc(rip6s_ipackets); /* Be proactive about malicious use of IPv4 mapped address */ if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || @@ -146,7 +147,7 @@ rip6_input(struct mbuf **mp, int *offp, continue; if (!(in6p->inp_flags & INP_IPV6)) continue; - if (in6p->inp_ipv6.ip6_nxt && + if ((in6p->inp_ipv6.ip6_nxt || proto == IPPROTO_ICMPV6) && in6p->inp_ipv6.ip6_nxt != proto) continue; #if NPF > 0 @@ -170,7 +171,18 @@ rip6_input(struct mbuf **mp, int *offp, if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->inp_faddr6) && !IN6_ARE_ADDR_EQUAL(&in6p->inp_faddr6, &ip6->ip6_src)) continue; - if (in6p->inp_cksum6 != -1) { + if (proto == IPPROTO_ICMPV6 && in6p->inp_icmp6filt) { + struct icmp6_hdr *icmp6; + + IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, *offp, + sizeof(*icmp6)); + if (icmp6 == NULL) + return IPPROTO_DONE; + if (ICMP6_FILTER_WILLBLOCK(icmp6->icmp6_type, + in6p->inp_icmp6filt)) + continue; + } + if (proto != IPPROTO_ICMPV6 && in6p->inp_cksum6 != -1) { rip6stat_inc(rip6s_isum); if (in6_cksum(m, proto, *offp, m->m_pkthdr.len - *offp)) { @@ -214,12 +226,14 @@ rip6_input(struct mbuf **mp, int *offp, struct counters_ref ref; uint64_t *counters; - rip6stat_inc(rip6s_nosock); - if (m->m_flags & M_MCAST) - rip6stat_inc(rip6s_nosockmcast); - if (proto == IPPROTO_NONE) + if (proto != IPPROTO_ICMPV6) { + rip6stat_inc(rip6s_nosock); + if (m->m_flags & M_MCAST) + rip6stat_inc(rip6s_nosockmcast); + } + if (proto == IPPROTO_NONE || proto == IPPROTO_ICMPV6) { m_freem(m); - else { + } else { u_int8_t *prvnxtp = ip6_get_prevhdr(m, *offp); /* XXX */ icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER,