On Wed, Nov 22, 2017 at 03:48:43PM +0100, Martin Pieuchot wrote:
> Hrvoje Popovski reported the following panic when testing my diff to
> unlock protocol inputs function:
>
> panic() at panic+0x128
> __assert(ffffffff814d1114,ffff800022755d80,ffff8000009ce000,ffff800022755e20)
> carp_ourether(ffffff0003c0c290,ffff8000009ce000) at carp_ourether
> nd6_ns_input(20,0,ffff8000009c9800) at nd6_ns_input+0x4cf
> icmp6_input(18,ffffffff81a95af0,1,3a) at icmp6_input+0x3d4
>
> ip_deliver(ffff800022756020,ffff80002275602c,ffff800000019080,ffffffff817ee880)
> ip6intr() at ip6intr+0x7b
>
> The problem comes from carp_iamatch6() which is not yet MP-safe. Since
> it is now identical to carp_iamatch(), let's use this one instead.
>
> ok?
OK bluhm@
> Index: netinet/ip_carp.h
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_carp.h,v
> retrieving revision 1.43
> diff -u -p -r1.43 ip_carp.h
> --- netinet/ip_carp.h 30 May 2017 12:09:27 -0000 1.43
> +++ netinet/ip_carp.h 22 Nov 2017 14:42:37 -0000
> @@ -199,7 +199,6 @@ void carp_carpdev_state(void *);
> void carp_group_demote_adj(struct ifnet *, int, char *);
> int carp6_proto_input(struct mbuf **, int *, int, int);
> int carp_iamatch(struct ifnet *);
> -int carp_iamatch6(struct ifnet *);
> struct ifnet *carp_ourether(void *, u_int8_t *);
> int carp_output(struct ifnet *, struct mbuf *, struct sockaddr *,
> struct rtentry *);
> Index: netinet/ip_carp.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_carp.c,v
> retrieving revision 1.319
> diff -u -p -r1.319 ip_carp.c
> --- netinet/ip_carp.c 21 Nov 2017 09:08:55 -0000 1.319
> +++ netinet/ip_carp.c 22 Nov 2017 14:42:37 -0000
> @@ -1352,22 +1352,6 @@ carp_iamatch(struct ifnet *ifp)
> return (match);
> }
>
> -#ifdef INET6
> -int
> -carp_iamatch6(struct ifnet *ifp)
> -{
> - struct carp_softc *sc = ifp->if_softc;
> - struct carp_vhost_entry *vhe = SRPL_FIRST_LOCKED(&sc->carp_vhosts);
> -
> - KERNEL_ASSERT_LOCKED(); /* touching carp_vhosts */
> -
> - if (vhe->state == MASTER)
> - return (1);
> -
> - return (0);
> -}
> -#endif /* INET6 */
> -
> struct ifnet *
> carp_ourether(void *v, u_int8_t *ena)
> {
> Index: netinet6/in6.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/in6.c,v
> retrieving revision 1.218
> diff -u -p -r1.218 in6.c
> --- netinet6/in6.c 4 Nov 2017 13:11:54 -0000 1.218
> +++ netinet6/in6.c 22 Nov 2017 14:43:08 -0000
> @@ -1287,7 +1287,7 @@ in6_ifawithscope(struct ifnet *oifp, str
> * Never use a carp address of an interface which is not
> * the master.
> */
> - if (ifp->if_type == IFT_CARP && !carp_iamatch6(ifp))
> + if (ifp->if_type == IFT_CARP && !carp_iamatch(ifp))
> continue;
> #endif
>
> Index: netinet6/nd6_nbr.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/nd6_nbr.c,v
> retrieving revision 1.121
> diff -u -p -r1.121 nd6_nbr.c
> --- netinet6/nd6_nbr.c 11 Aug 2017 21:24:20 -0000 1.121
> +++ netinet6/nd6_nbr.c 22 Nov 2017 14:42:36 -0000
> @@ -218,7 +218,7 @@ nd6_ns_input(struct mbuf *m, int off, in
> /* (1) and (3) check. */
> ifa = &in6ifa_ifpwithaddr(ifp, &taddr6)->ia_ifa;
> #if NCARP > 0
> - if (ifp->if_type == IFT_CARP && ifa && !carp_iamatch6(ifp))
> + if (ifp->if_type == IFT_CARP && ifa && !carp_iamatch(ifp))
> ifa = NULL;
> #endif
>
> @@ -668,7 +668,7 @@ nd6_na_input(struct mbuf *m, int off, in
> * Ignore NAs silently for carp addresses if we're not
> * the CARP master.
> */
> - if (ifp->if_type == IFT_CARP && !carp_iamatch6(ifp))
> + if (ifp->if_type == IFT_CARP && !carp_iamatch(ifp))
> goto freeit;
> #endif
> log(LOG_ERR,
> @@ -1014,7 +1014,7 @@ nd6_na_output(struct ifnet *ifp, struct
>
> #if NCARP > 0
> /* Do not send NAs for carp addresses if we're not the CARP master. */
> - if (ifp->if_type == IFT_CARP && !carp_iamatch6(ifp))
> + if (ifp->if_type == IFT_CARP && !carp_iamatch(ifp))
> goto bad;
> #endif
>