Module Name:    src
Committed By:   ozaki-r
Date:           Tue Jun 21 03:28:28 UTC 2016

Modified Files:
        src/sys/dist/pf/net: if_pfsync.c
        src/sys/net: if.h
        src/sys/netinet: igmp.c in.c in_pcb.c ip_carp.c ip_mroute.c ip_output.c
            ip_var.h
        src/sys/netinet6: in6_pcb.c in6_src.c ip6_mroute.c ip6_output.c
            ip6_var.h mld6.c nd6_nbr.c

Log Message:
Replace ifp of ip_moptions and ip6_moptions with if_index

The motivation is the same as the mbuf's rcvif case; avoid having a pointer
of an ifnet object in ip_moptions and ip6_moptions, which is not MP-safe.

ip_moptions and ip6_moptions can be stored in a PCB for inet or inet6
that's life time is different from ifnet one and so an ifnet object can be
disappeared anytime we get it via them. Thus we need to look up an ifnet
object by if_index every time for safe.


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/sys/dist/pf/net/if_pfsync.c
cvs rdiff -u -r1.212 -r1.213 src/sys/net/if.h
cvs rdiff -u -r1.58 -r1.59 src/sys/netinet/igmp.c
cvs rdiff -u -r1.166 -r1.167 src/sys/netinet/in.c
cvs rdiff -u -r1.163 -r1.164 src/sys/netinet/in_pcb.c
cvs rdiff -u -r1.70 -r1.71 src/sys/netinet/ip_carp.c
cvs rdiff -u -r1.140 -r1.141 src/sys/netinet/ip_mroute.c
cvs rdiff -u -r1.257 -r1.258 src/sys/netinet/ip_output.c
cvs rdiff -u -r1.113 -r1.114 src/sys/netinet/ip_var.h
cvs rdiff -u -r1.143 -r1.144 src/sys/netinet6/in6_pcb.c
cvs rdiff -u -r1.60 -r1.61 src/sys/netinet6/in6_src.c
cvs rdiff -u -r1.110 -r1.111 src/sys/netinet6/ip6_mroute.c
cvs rdiff -u -r1.167 -r1.168 src/sys/netinet6/ip6_output.c
cvs rdiff -u -r1.65 -r1.66 src/sys/netinet6/ip6_var.h
cvs rdiff -u -r1.67 -r1.68 src/sys/netinet6/mld6.c
cvs rdiff -u -r1.119 -r1.120 src/sys/netinet6/nd6_nbr.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dist/pf/net/if_pfsync.c
diff -u src/sys/dist/pf/net/if_pfsync.c:1.14 src/sys/dist/pf/net/if_pfsync.c:1.15
--- src/sys/dist/pf/net/if_pfsync.c:1.14	Fri Jun 10 13:31:44 2016
+++ src/sys/dist/pf/net/if_pfsync.c	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_pfsync.c,v 1.14 2016/06/10 13:31:44 ozaki-r Exp $	*/
+/*	$NetBSD: if_pfsync.c,v 1.15 2016/06/21 03:28:27 ozaki-r Exp $	*/
 /*	$OpenBSD: if_pfsync.c,v 1.83 2007/06/26 14:44:12 mcbride Exp $	*/
 
 /*
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_pfsync.c,v 1.14 2016/06/10 13:31:44 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_pfsync.c,v 1.15 2016/06/21 03:28:27 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -941,7 +941,7 @@ pfsyncioctl(struct ifnet *ifp, u_long cm
 			}
 			if (imo->imo_num_memberships > 0) {
 				in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
-				imo->imo_multicast_ifp = NULL;
+				imo->imo_multicast_if_index = 0;
 			}
 			break;
 		}
@@ -961,7 +961,7 @@ pfsyncioctl(struct ifnet *ifp, u_long cm
 
 		if (imo->imo_num_memberships > 0) {
 			in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
-			imo->imo_multicast_ifp = NULL;
+			imo->imo_multicast_if_index = 0;
 		}
 
 		if (sc->sc_sync_ifp &&
@@ -983,7 +983,7 @@ pfsyncioctl(struct ifnet *ifp, u_long cm
 				return (ENOBUFS);
 			}
 			imo->imo_num_memberships++;
-			imo->imo_multicast_ifp = sc->sc_sync_ifp;
+			imo->imo_multicast_if_index = if_get_index(sc->sc_sync_ifp);
 			imo->imo_multicast_ttl = PFSYNC_DFLTTL;
 			imo->imo_multicast_loop = 0;
 		}

Index: src/sys/net/if.h
diff -u src/sys/net/if.h:1.212 src/sys/net/if.h:1.213
--- src/sys/net/if.h:1.212	Tue Jun 21 03:07:54 2016
+++ src/sys/net/if.h	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.h,v 1.212 2016/06/21 03:07:54 ozaki-r Exp $	*/
+/*	$NetBSD: if.h,v 1.213 2016/06/21 03:28:27 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -954,6 +954,13 @@ ifnet_t *if_get_byindex(u_int, struct ps
 void	if_put(const struct ifnet *, struct psref *);
 void	if_acquire_unsafe(struct ifnet *, struct psref *);
 
+static inline if_index_t
+if_get_index(const struct ifnet *ifp)
+{
+
+	return ifp != NULL ? ifp->if_index : 0;
+}
+
 bool	if_held(struct ifnet *);
 
 void	if_input(struct ifnet *, struct mbuf *);

Index: src/sys/netinet/igmp.c
diff -u src/sys/netinet/igmp.c:1.58 src/sys/netinet/igmp.c:1.59
--- src/sys/netinet/igmp.c:1.58	Fri Jun 10 13:31:44 2016
+++ src/sys/netinet/igmp.c	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: igmp.c,v 1.58 2016/06/10 13:31:44 ozaki-r Exp $	*/
+/*	$NetBSD: igmp.c,v 1.59 2016/06/21 03:28:27 ozaki-r Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: igmp.c,v 1.58 2016/06/10 13:31:44 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: igmp.c,v 1.59 2016/06/21 03:28:27 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_mrouting.h"
@@ -618,7 +618,7 @@ igmp_sendpkt(struct in_multi *inm, int t
 	m->m_data -= sizeof(struct ip);
 	m->m_len += sizeof(struct ip);
 
-	imo.imo_multicast_ifp = inm->inm_ifp;
+	imo.imo_multicast_if_index = if_get_index(inm->inm_ifp);
 	imo.imo_multicast_ttl = 1;
 #ifdef RSVP_ISI
 	imo.imo_multicast_vif = -1;

Index: src/sys/netinet/in.c
diff -u src/sys/netinet/in.c:1.166 src/sys/netinet/in.c:1.167
--- src/sys/netinet/in.c:1.166	Fri May 27 16:44:15 2016
+++ src/sys/netinet/in.c	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: in.c,v 1.166 2016/05/27 16:44:15 christos Exp $	*/
+/*	$NetBSD: in.c,v 1.167 2016/06/21 03:28:27 ozaki-r Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.166 2016/05/27 16:44:15 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.167 2016/06/21 03:28:27 ozaki-r Exp $");
 
 #include "arp.h"
 
@@ -1508,16 +1508,23 @@ in_selectsrc(struct sockaddr_in *sin, st
 	 */
 	if (IN_MULTICAST(sin->sin_addr.s_addr) && mopts != NULL) {
 		struct ip_moptions *imo;
-		struct ifnet *ifp;
 
 		imo = mopts;
-		if (imo->imo_multicast_ifp != NULL) {
-			ifp = imo->imo_multicast_ifp;
-			IFP_TO_IA(ifp, ia);		/* XXX */
-			if (ia == 0 || ia->ia4_flags & IN_IFF_NOTREADY) {
+		if (imo->imo_multicast_if_index != 0) {
+			struct ifnet *ifp;
+			int s = pserialize_read_enter();
+
+			ifp = if_byindex(imo->imo_multicast_if_index);
+			if (ifp != NULL) {
+				IFP_TO_IA(ifp, ia);		/* XXX */
+			} else
+				ia = NULL;
+			if (ia == NULL || ia->ia4_flags & IN_IFF_NOTREADY) {
+				pserialize_read_exit(s);
 				*errorp = EADDRNOTAVAIL;
 				return NULL;
 			}
+			pserialize_read_exit(s);
 		}
 	}
 	if (ia->ia_ifa.ifa_getifa != NULL) {

Index: src/sys/netinet/in_pcb.c
diff -u src/sys/netinet/in_pcb.c:1.163 src/sys/netinet/in_pcb.c:1.164
--- src/sys/netinet/in_pcb.c:1.163	Mon Feb 15 14:59:03 2016
+++ src/sys/netinet/in_pcb.c	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: in_pcb.c,v 1.163 2016/02/15 14:59:03 rtr Exp $	*/
+/*	$NetBSD: in_pcb.c,v 1.164 2016/06/21 03:28:27 ozaki-r Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -93,7 +93,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.163 2016/02/15 14:59:03 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.164 2016/06/21 03:28:27 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -694,6 +694,8 @@ in_purgeifmcast(struct ip_moptions *imo,
 {
 	int i, gap;
 
+	KASSERT(ifp != NULL);
+
 	if (imo == NULL)
 		return;
 
@@ -701,8 +703,8 @@ in_purgeifmcast(struct ip_moptions *imo,
 	 * Unselect the outgoing interface if it is being
 	 * detached.
 	 */
-	if (imo->imo_multicast_ifp == ifp)
-		imo->imo_multicast_ifp = NULL;
+	if (imo->imo_multicast_if_index == ifp->if_index)
+		imo->imo_multicast_if_index = 0;
 
 	/*
 	 * Drop multicast group membership if we joined

Index: src/sys/netinet/ip_carp.c
diff -u src/sys/netinet/ip_carp.c:1.70 src/sys/netinet/ip_carp.c:1.71
--- src/sys/netinet/ip_carp.c:1.70	Mon Jun 20 08:08:13 2016
+++ src/sys/netinet/ip_carp.c	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_carp.c,v 1.70 2016/06/20 08:08:13 knakahara Exp $	*/
+/*	$NetBSD: ip_carp.c,v 1.71 2016/06/21 03:28:27 ozaki-r Exp $	*/
 /*	$OpenBSD: ip_carp.c,v 1.113 2005/11/04 08:11:54 mcbride Exp $	*/
 
 /*
@@ -33,7 +33,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.70 2016/06/20 08:08:13 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.71 2016/06/21 03:28:27 ozaki-r Exp $");
 
 /*
  * TODO:
@@ -1532,7 +1532,7 @@ carp_multicast_cleanup(struct carp_softc
 		}
 	}
 	imo->imo_num_memberships = 0;
-	imo->imo_multicast_ifp = NULL;
+	imo->imo_multicast_if_index = 0;
 
 #ifdef INET6
 	while (!LIST_EMPTY(&im6o->im6o_memberships)) {
@@ -1542,7 +1542,7 @@ carp_multicast_cleanup(struct carp_softc
 		LIST_REMOVE(imm, i6mm_chain);
 		in6_leavegroup(imm);
 	}
-	im6o->im6o_multicast_ifp = NULL;
+	im6o->im6o_multicast_if_index = 0;
 #endif
 
 	/* And any other multicast memberships */
@@ -1801,7 +1801,7 @@ carp_join_multicast(struct carp_softc *s
 
 	imo->imo_membership[0] = tmpimo.imo_membership[0];
 	imo->imo_num_memberships = 1;
-	imo->imo_multicast_ifp = &sc->sc_if;
+	imo->imo_multicast_if_index = sc->sc_if.if_index;
 	imo->imo_multicast_ttl = CARP_DFLTTL;
 	imo->imo_multicast_loop = 0;
 	return (0);
@@ -1909,7 +1909,7 @@ carp_join_multicast6(struct carp_softc *
 	}
 
 	/* apply v6 multicast membership */
-	im6o->im6o_multicast_ifp = &sc->sc_if;
+	im6o->im6o_multicast_if_index = sc->sc_if.if_index;
 	if (imm)
 		LIST_INSERT_HEAD(&im6o->im6o_memberships, imm,
 		    i6mm_chain);

Index: src/sys/netinet/ip_mroute.c
diff -u src/sys/netinet/ip_mroute.c:1.140 src/sys/netinet/ip_mroute.c:1.141
--- src/sys/netinet/ip_mroute.c:1.140	Fri Jun 10 13:27:16 2016
+++ src/sys/netinet/ip_mroute.c	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_mroute.c,v 1.140 2016/06/10 13:27:16 ozaki-r Exp $	*/
+/*	$NetBSD: ip_mroute.c,v 1.141 2016/06/21 03:28:27 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -93,7 +93,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_mroute.c,v 1.140 2016/06/10 13:27:16 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_mroute.c,v 1.141 2016/06/21 03:28:27 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -2104,7 +2104,7 @@ tbf_send_packet(struct vif *vifp, struct
 		/* if physical interface option, extract the options and then send */
 		struct ip_moptions imo;
 
-		imo.imo_multicast_ifp = vifp->v_ifp;
+		imo.imo_multicast_if_index = if_get_index(vifp->v_ifp);
 		imo.imo_multicast_ttl = mtod(m, struct ip *)->ip_ttl - 1;
 		imo.imo_multicast_loop = 1;
 #ifdef RSVP_ISI

Index: src/sys/netinet/ip_output.c
diff -u src/sys/netinet/ip_output.c:1.257 src/sys/netinet/ip_output.c:1.258
--- src/sys/netinet/ip_output.c:1.257	Mon Jun 20 06:46:38 2016
+++ src/sys/netinet/ip_output.c	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_output.c,v 1.257 2016/06/20 06:46:38 knakahara Exp $	*/
+/*	$NetBSD: ip_output.c,v 1.258 2016/06/21 03:28:27 ozaki-r Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.257 2016/06/20 06:46:38 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.258 2016/06/21 03:28:27 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -229,7 +229,7 @@ ip_output(struct mbuf *m0, struct mbuf *
 {
 	struct rtentry *rt;
 	struct ip *ip;
-	struct ifnet *ifp;
+	struct ifnet *ifp, *mifp = NULL;
 	struct mbuf *m = m0;
 	int hlen = sizeof (struct ip);
 	int len, error = 0;
@@ -251,6 +251,8 @@ ip_output(struct mbuf *m0, struct mbuf *
 	struct sockaddr *rdst = &u.dst;	/* real IP destination, as opposed
 					 * to the nexthop
 					 */
+	struct psref psref;
+	int bound;
 
 	len = 0;
 
@@ -324,8 +326,15 @@ ip_output(struct mbuf *m0, struct mbuf *
 		isbroadcast = in_broadcast(dst->sin_addr, ifp);
 	} else if ((IN_MULTICAST(ip->ip_dst.s_addr) ||
 	    ip->ip_dst.s_addr == INADDR_BROADCAST) &&
-	    imo != NULL && imo->imo_multicast_ifp != NULL) {
-		ifp = imo->imo_multicast_ifp;
+	    imo != NULL && imo->imo_multicast_if_index != 0) {
+		bound = curlwp_bind();
+		ifp = mifp = if_get_byindex(imo->imo_multicast_if_index, &psref);
+		if (ifp == NULL) {
+			curlwp_bindx(bound);
+			IP_STATINC(IP_STAT_NOROUTE);
+			error = ENETUNREACH;
+			goto bad;
+		}
 		mtu = ifp->if_mtu;
 		IFP_TO_IA(ifp, ia);
 		isbroadcast = 0;
@@ -712,6 +721,10 @@ done:
 		KEY_FREESP(&sp);
 	}
 #endif
+	if (mifp != NULL) {
+		if_put(mifp, &psref);
+		curlwp_bindx(bound);
+	}
 	return error;
 bad:
 	m_freem(m);
@@ -1612,7 +1625,7 @@ ip_setmoptions(struct ip_moptions **pimo
 		if (imo == NULL)
 			return ENOBUFS;
 
-		imo->imo_multicast_ifp = NULL;
+		imo->imo_multicast_if_index = 0;
 		imo->imo_multicast_addr.s_addr = INADDR_ANY;
 		imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
 		imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP;
@@ -1635,7 +1648,7 @@ ip_setmoptions(struct ip_moptions **pimo
 		 * chosen every time a multicast packet is sent.
 		 */
 		if (in_nullhost(addr)) {
-			imo->imo_multicast_ifp = NULL;
+			imo->imo_multicast_if_index = 0;
 			break;
 		}
 		/*
@@ -1648,7 +1661,7 @@ ip_setmoptions(struct ip_moptions **pimo
 			error = EADDRNOTAVAIL;
 			break;
 		}
-		imo->imo_multicast_ifp = ifp;
+		imo->imo_multicast_if_index = ifp->if_index;
 		if (ifindex)
 			imo->imo_multicast_addr = addr;
 		else
@@ -1686,7 +1699,7 @@ ip_setmoptions(struct ip_moptions **pimo
 	/*
 	 * If all options have default values, no need to keep the mbuf.
 	 */
-	if (imo->imo_multicast_ifp == NULL &&
+	if (imo->imo_multicast_if_index == 0 &&
 	    imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL &&
 	    imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP &&
 	    imo->imo_num_memberships == 0) {
@@ -1704,20 +1717,27 @@ int
 ip_getmoptions(struct ip_moptions *imo, struct sockopt *sopt)
 {
 	struct in_addr addr;
-	struct in_ifaddr *ia;
 	uint8_t optval;
 	int error = 0;
 
 	switch (sopt->sopt_name) {
 	case IP_MULTICAST_IF:
-		if (imo == NULL || imo->imo_multicast_ifp == NULL)
+		if (imo == NULL || imo->imo_multicast_if_index == 0)
 			addr = zeroin_addr;
 		else if (imo->imo_multicast_addr.s_addr) {
 			/* return the value user has set */
 			addr = imo->imo_multicast_addr;
 		} else {
-			IFP_TO_IA(imo->imo_multicast_ifp, ia);
+			struct ifnet *ifp;
+			struct in_ifaddr *ia = NULL;
+			int s = pserialize_read_enter();
+
+			ifp = if_byindex(imo->imo_multicast_if_index);
+			if (ifp != NULL) {
+				IFP_TO_IA(ifp, ia);
+			}
 			addr = ia ? ia->ia_addr.sin_addr : zeroin_addr;
+			pserialize_read_exit(s);
 		}
 		error = sockopt_set(sopt, &addr, sizeof(addr));
 		break;

Index: src/sys/netinet/ip_var.h
diff -u src/sys/netinet/ip_var.h:1.113 src/sys/netinet/ip_var.h:1.114
--- src/sys/netinet/ip_var.h:1.113	Mon Jun 13 08:29:55 2016
+++ src/sys/netinet/ip_var.h	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_var.h,v 1.113 2016/06/13 08:29:55 knakahara Exp $	*/
+/*	$NetBSD: ip_var.h,v 1.114 2016/06/21 03:28:27 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1993
@@ -114,7 +114,7 @@ struct ipoption {
  * passed to ip_output when IP multicast options are in use.
  */
 struct ip_moptions {
-	struct	  ifnet *imo_multicast_ifp; /* ifp for outgoing multicasts */
+	if_index_t imo_multicast_if_index; /* I/F for outgoing multicasts */
 	struct in_addr imo_multicast_addr; /* ifindex/addr on MULTICAST_IF */
 	u_int8_t  imo_multicast_ttl;	/* TTL for outgoing multicasts */
 	u_int8_t  imo_multicast_loop;	/* 1 => hear sends if a member */

Index: src/sys/netinet6/in6_pcb.c
diff -u src/sys/netinet6/in6_pcb.c:1.143 src/sys/netinet6/in6_pcb.c:1.144
--- src/sys/netinet6/in6_pcb.c:1.143	Mon Aug 24 22:21:27 2015
+++ src/sys/netinet6/in6_pcb.c	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: in6_pcb.c,v 1.143 2015/08/24 22:21:27 pooka Exp $	*/
+/*	$NetBSD: in6_pcb.c,v 1.144 2016/06/21 03:28:27 ozaki-r Exp $	*/
 /*	$KAME: in6_pcb.c,v 1.84 2001/02/08 18:02:08 itojun Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.143 2015/08/24 22:21:27 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.144 2016/06/21 03:28:27 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -812,6 +812,8 @@ in6_pcbpurgeif0(struct inpcbtable *table
 	struct ip6_moptions *im6o;
 	struct in6_multi_mship *imm, *nimm;
 
+	KASSERT(ifp != NULL);
+
 	TAILQ_FOREACH_SAFE(inph, &table->inpt_queue, inph_queue, ninph) {
 		struct in6pcb *in6p = (struct in6pcb *)inph;
 		if (in6p->in6p_af != AF_INET6)
@@ -823,8 +825,8 @@ in6_pcbpurgeif0(struct inpcbtable *table
 			 * Unselect the outgoing interface if it is being
 			 * detached.
 			 */
-			if (im6o->im6o_multicast_ifp == ifp)
-				im6o->im6o_multicast_ifp = NULL;
+			if (im6o->im6o_multicast_if_index == ifp->if_index)
+				im6o->im6o_multicast_if_index = 0;
 
 			/*
 			 * Drop multicast group membership if we joined

Index: src/sys/netinet6/in6_src.c
diff -u src/sys/netinet6/in6_src.c:1.60 src/sys/netinet6/in6_src.c:1.61
--- src/sys/netinet6/in6_src.c:1.60	Wed May 18 09:32:05 2016
+++ src/sys/netinet6/in6_src.c	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: in6_src.c,v 1.60 2016/05/18 09:32:05 ozaki-r Exp $	*/
+/*	$NetBSD: in6_src.c,v 1.61 2016/06/21 03:28:27 ozaki-r Exp $	*/
 /*	$KAME: in6_src.c,v 1.159 2005/10/19 01:40:32 t-momose Exp $	*/
 
 /*
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6_src.c,v 1.60 2016/05/18 09:32:05 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_src.c,v 1.61 2016/06/21 03:28:27 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -600,9 +600,11 @@ selectroute(struct sockaddr_in6 *dstsock
 	 * If the destination address is a multicast address and the outgoing
 	 * interface for the address is specified by the caller, use it.
 	 */
-	if (IN6_IS_ADDR_MULTICAST(dst) &&
-	    mopts != NULL && (ifp = mopts->im6o_multicast_ifp) != NULL) {
-		goto done; /* we do not need a route for multicast. */
+	if (IN6_IS_ADDR_MULTICAST(dst) && mopts != NULL) {
+		/* XXX not MP-safe yet */
+		ifp = if_byindex(mopts->im6o_multicast_if_index);
+		if (ifp != NULL)
+			goto done; /* we do not need a route for multicast. */
 	}
 
   getroute:

Index: src/sys/netinet6/ip6_mroute.c
diff -u src/sys/netinet6/ip6_mroute.c:1.110 src/sys/netinet6/ip6_mroute.c:1.111
--- src/sys/netinet6/ip6_mroute.c:1.110	Fri Jun 10 13:31:44 2016
+++ src/sys/netinet6/ip6_mroute.c	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_mroute.c,v 1.110 2016/06/10 13:31:44 ozaki-r Exp $	*/
+/*	$NetBSD: ip6_mroute.c,v 1.111 2016/06/21 03:28:27 ozaki-r Exp $	*/
 /*	$KAME: ip6_mroute.c,v 1.49 2001/07/25 09:21:18 jinmei Exp $	*/
 
 /*
@@ -117,7 +117,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_mroute.c,v 1.110 2016/06/10 13:31:44 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_mroute.c,v 1.111 2016/06/21 03:28:27 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -1564,7 +1564,7 @@ phyint_send(struct ip6_hdr *ip6, struct 
 	if (m->m_pkthdr.rcvif_index == 0) {
 		struct ip6_moptions im6o;
 
-		im6o.im6o_multicast_ifp = ifp;
+		im6o.im6o_multicast_if_index = if_get_index(ifp);
 		/* XXX: ip6_output will override ip6->ip6_hlim */
 		im6o.im6o_multicast_hlim = ip6->ip6_hlim;
 		im6o.im6o_multicast_loop = 1;

Index: src/sys/netinet6/ip6_output.c
diff -u src/sys/netinet6/ip6_output.c:1.167 src/sys/netinet6/ip6_output.c:1.168
--- src/sys/netinet6/ip6_output.c:1.167	Fri Jun 10 13:27:16 2016
+++ src/sys/netinet6/ip6_output.c	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_output.c,v 1.167 2016/06/10 13:27:16 ozaki-r Exp $	*/
+/*	$NetBSD: ip6_output.c,v 1.168 2016/06/21 03:28:27 ozaki-r Exp $	*/
 /*	$KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.167 2016/06/10 13:27:16 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.168 2016/06/21 03:28:27 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -2377,7 +2377,7 @@ ip6_setmoptions(const struct sockopt *so
 		if (im6o == NULL)
 			return (ENOBUFS);
 		in6p->in6p_moptions = im6o;
-		im6o->im6o_multicast_ifp = NULL;
+		im6o->im6o_multicast_if_index = 0;
 		im6o->im6o_multicast_hlim = ip6_defmcasthlim;
 		im6o->im6o_multicast_loop = IPV6_DEFAULT_MULTICAST_LOOP;
 		LIST_INIT(&im6o->im6o_memberships);
@@ -2404,7 +2404,7 @@ ip6_setmoptions(const struct sockopt *so
 			}
 		} else
 			ifp = NULL;
-		im6o->im6o_multicast_ifp = ifp;
+		im6o->im6o_multicast_if_index = if_get_index(ifp);
 		break;
 
 	case IPV6_MULTICAST_HOPS:
@@ -2585,7 +2585,7 @@ ip6_setmoptions(const struct sockopt *so
 	/*
 	 * If all options have default values, no need to keep the mbuf.
 	 */
-	if (im6o->im6o_multicast_ifp == NULL &&
+	if (im6o->im6o_multicast_if_index == 0 &&
 	    im6o->im6o_multicast_hlim == ip6_defmcasthlim &&
 	    im6o->im6o_multicast_loop == IPV6_DEFAULT_MULTICAST_LOOP &&
 	    im6o->im6o_memberships.lh_first == NULL) {
@@ -2608,10 +2608,10 @@ ip6_getmoptions(struct sockopt *sopt, st
 
 	switch (sopt->sopt_name) {
 	case IPV6_MULTICAST_IF:
-		if (im6o == NULL || im6o->im6o_multicast_ifp == NULL)
+		if (im6o == NULL || im6o->im6o_multicast_if_index == 0)
 			optval = 0;
 		else
-			optval = im6o->im6o_multicast_ifp->if_index;
+			optval = im6o->im6o_multicast_if_index;
 
 		error = sockopt_set(sopt, &optval, sizeof(optval));
 		break;

Index: src/sys/netinet6/ip6_var.h
diff -u src/sys/netinet6/ip6_var.h:1.65 src/sys/netinet6/ip6_var.h:1.66
--- src/sys/netinet6/ip6_var.h:1.65	Fri Jun 10 13:31:44 2016
+++ src/sys/netinet6/ip6_var.h	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_var.h,v 1.65 2016/06/10 13:31:44 ozaki-r Exp $	*/
+/*	$NetBSD: ip6_var.h,v 1.66 2016/06/21 03:28:27 ozaki-r Exp $	*/
 /*	$KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $	*/
 
 /*
@@ -109,7 +109,7 @@ struct	ip6asfrag {
 #define IP6_REASS_MBUF(ip6af) ((ip6af)->ip6af_m)
 
 struct	ip6_moptions {
-	struct	ifnet *im6o_multicast_ifp; /* ifp for outgoing multicasts */
+	if_index_t im6o_multicast_if_index; /* I/F for outgoing multicasts */
 	u_char	im6o_multicast_hlim;	/* hoplimit for outgoing multicasts */
 	u_char	im6o_multicast_loop;	/* 1 >= hear sends if a member */
 	LIST_HEAD(, in6_multi_mship) im6o_memberships;

Index: src/sys/netinet6/mld6.c
diff -u src/sys/netinet6/mld6.c:1.67 src/sys/netinet6/mld6.c:1.68
--- src/sys/netinet6/mld6.c:1.67	Thu Jun 16 03:03:33 2016
+++ src/sys/netinet6/mld6.c	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: mld6.c,v 1.67 2016/06/16 03:03:33 ozaki-r Exp $	*/
+/*	$NetBSD: mld6.c,v 1.68 2016/06/21 03:28:27 ozaki-r Exp $	*/
 /*	$KAME: mld6.c,v 1.25 2001/01/16 14:14:18 itojun Exp $	*/
 
 /*
@@ -102,7 +102,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.67 2016/06/16 03:03:33 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.68 2016/06/21 03:28:27 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -544,7 +544,7 @@ mld_sendpkt(struct in6_multi *in6m, int 
 
 	/* construct multicast option */
 	memset(&im6o, 0, sizeof(im6o));
-	im6o.im6o_multicast_ifp = ifp;
+	im6o.im6o_multicast_if_index = if_get_index(ifp);
 	im6o.im6o_multicast_hlim = 1;
 
 	/*

Index: src/sys/netinet6/nd6_nbr.c
diff -u src/sys/netinet6/nd6_nbr.c:1.119 src/sys/netinet6/nd6_nbr.c:1.120
--- src/sys/netinet6/nd6_nbr.c:1.119	Fri Jun 10 13:31:44 2016
+++ src/sys/netinet6/nd6_nbr.c	Tue Jun 21 03:28:27 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nd6_nbr.c,v 1.119 2016/06/10 13:31:44 ozaki-r Exp $	*/
+/*	$NetBSD: nd6_nbr.c,v 1.120 2016/06/21 03:28:27 ozaki-r Exp $	*/
 /*	$KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.119 2016/06/10 13:31:44 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.120 2016/06/21 03:28:27 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -400,7 +400,7 @@ nd6_ns_output(struct ifnet *ifp, const s
 
 	if (daddr6 == NULL || IN6_IS_ADDR_MULTICAST(daddr6)) {
 		m->m_flags |= M_MCAST;
-		im6o.im6o_multicast_ifp = ifp;
+		im6o.im6o_multicast_if_index = if_get_index(ifp);
 		im6o.im6o_multicast_hlim = 255;
 		im6o.im6o_multicast_loop = 0;
 	}
@@ -907,7 +907,7 @@ nd6_na_output(
 
 	if (IN6_IS_ADDR_MULTICAST(&daddr6)) {
 		m->m_flags |= M_MCAST;
-		im6o.im6o_multicast_ifp = ifp;
+		im6o.im6o_multicast_if_index = if_get_index(ifp);
 		im6o.im6o_multicast_hlim = 255;
 		im6o.im6o_multicast_loop = 0;
 	}

Reply via email to