svn commit: r281155 - in projects/ifnet/sys: net netinet netinet6

Gleb Smirnoff glebius at FreeBSD.org
Mon Apr 6 15:45:48 UTC 2015


Author: glebius
Date: Mon Apr  6 15:45:45 2015
New Revision: 281155
URL: https://svnweb.freebsd.org/changeset/base/281155

Log:
  Provide a working example of if_setsoftc().  Remove if_carp from struct
  ifnet and dynamically allocate IF_CARP softc.
  
  Sponsored by:	Nginx, Inc.
  Sponsored by:	Netflix

Modified:
  projects/ifnet/sys/net/if.c
  projects/ifnet/sys/net/if_ethersubr.c
  projects/ifnet/sys/net/if_var.h
  projects/ifnet/sys/netinet/ip_carp.c
  projects/ifnet/sys/netinet/ip_input.c
  projects/ifnet/sys/netinet6/nd6_nbr.c

Modified: projects/ifnet/sys/net/if.c
==============================================================================
--- projects/ifnet/sys/net/if.c	Mon Apr  6 15:44:09 2015	(r281154)
+++ projects/ifnet/sys/net/if.c	Mon Apr  6 15:45:45 2015	(r281155)
@@ -2276,7 +2276,7 @@ do_link_state_change(void *arg, int pend
 	if ((if_type(ifp) == IFT_ETHER || if_type(ifp) == IFT_L2VLAN) &&
 	    ifp->if_l2com != NULL)
 		(*ng_ether_link_state_p)(ifp, link_state);
-	if (ifp->if_carp)
+	if (if_getsoftc(ifp, IF_CARP) != NULL)
 		(*carp_linkstate_p)(ifp);
 	if (ifp->if_bridge)
 		(*bridge_linkstate_p)(ifp);
@@ -2310,7 +2310,7 @@ if_down(struct ifnet *ifp)
 	TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
 		pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
 	if_qflush(ifp);
-	if (ifp->if_carp)
+	if (if_getsoftc(ifp, IF_CARP) != NULL)
 		(*carp_linkstate_p)(ifp);
 	rt_ifmsg(ifp);
 }
@@ -2328,7 +2328,7 @@ if_up(struct ifnet *ifp)
 	getmicrotime(&ifp->if_lastchange);
 	TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
 		pfctlinput(PRC_IFUP, ifa->ifa_addr);
-	if (ifp->if_carp)
+	if (if_getsoftc(ifp, IF_CARP) != NULL)
 		(*carp_linkstate_p)(ifp);
 	rt_ifmsg(ifp);
 #ifdef INET6

Modified: projects/ifnet/sys/net/if_ethersubr.c
==============================================================================
--- projects/ifnet/sys/net/if_ethersubr.c	Mon Apr  6 15:44:09 2015	(r281154)
+++ projects/ifnet/sys/net/if_ethersubr.c	Mon Apr  6 15:45:45 2015	(r281155)
@@ -318,7 +318,12 @@ ether_output(struct ifnet *ifp, struct m
 	}
 
 #if defined(INET) || defined(INET6)
-	if (ifp->if_carp &&
+	/*
+	 * XXXGL: the if_getsoftc() lookup might affect performance,
+	 * but the plan is to improve carp to avoid calling
+	 * carp_output() on every packet.
+	 */
+	if (carp_output_p != NULL && if_getsoftc(ifp, IF_CARP) != NULL &&
 	    (error = (*carp_output_p)(ifp, m, dst)))
 		goto bad;
 #endif
@@ -544,7 +549,8 @@ ether_input_internal(struct ifnet *ifp, 
 	 * TODO: Maintain a hash table of ethernet addresses other than
 	 * ether_dhost which may be active on this ifp.
 	 */
-	if (ifp->if_carp && (*carp_forus_p)(ifp, eh->ether_dhost)) {
+	if (carp_forus_p != NULL && if_getsoftc(ifp, IF_CARP) != NULL &&
+	    (*carp_forus_p)(ifp, eh->ether_dhost)) {
 		m->m_flags &= ~M_PROMISC;
 	} else
 #endif

Modified: projects/ifnet/sys/net/if_var.h
==============================================================================
--- projects/ifnet/sys/net/if_var.h	Mon Apr  6 15:44:09 2015	(r281154)
+++ projects/ifnet/sys/net/if_var.h	Mon Apr  6 15:45:45 2015	(r281155)
@@ -36,7 +36,6 @@
 struct	rtentry;		/* ifa_rtrequest */
 struct	rt_addrinfo;		/* ifa_rtrequest */
 struct	socket;
-struct	carp_if;
 struct	carp_softc;
 struct  ifvlantrunk;
 struct	ifmedia;
@@ -171,7 +170,6 @@ struct ifnet {
 	void	*if_bridge;		/* bridge glue */
 	void	*if_lagg;		/* lagg glue */
 	void	*if_pf_kif;		/* pf glue */
-	struct	carp_if *if_carp;	/* carp interface structure */
 	struct	label *if_label;	/* interface MAC label */
 	struct	netmap_adapter *if_netmap; /* netmap(4) softc */
 

Modified: projects/ifnet/sys/netinet/ip_carp.c
==============================================================================
--- projects/ifnet/sys/netinet/ip_carp.c	Mon Apr  6 15:44:09 2015	(r281154)
+++ projects/ifnet/sys/netinet/ip_carp.c	Mon Apr  6 15:45:45 2015	(r281155)
@@ -156,7 +156,7 @@ static int proto_reg[] = {-1, -1};
  * Brief design of carp(4).
  *
  * Any carp-capable ifnet may have a list of carp softcs hanging off
- * its ifp->if_carp pointer. Each softc represents one unique virtual
+ * its IF_CARP softc pointer. Each softc represents one unique virtual
  * host id, or vhid. The softc has a back pointer to the ifnet. All
  * softcs are joined in a global list, which has quite limited use.
  *
@@ -285,9 +285,9 @@ SYSCTL_VNET_PCPUSTAT(_net_inet_carp, OID
 		((ifa) = sc->sc_ifas[_i]) != NULL;			\
 		++_i)
 
-#define	IFNET_FOREACH_CARP(ifp, sc)					\
-	CIF_LOCK_ASSERT(ifp->if_carp);					\
-	TAILQ_FOREACH((sc), &(ifp)->if_carp->cif_vrs, sc_list)
+#define	CIF_FOREACH_CARP(cif, sc)					\
+	CIF_LOCK_ASSERT(cif);						\
+	TAILQ_FOREACH((sc), &(cif)->cif_vrs, sc_list)
 
 #define	DEMOTE_ADVSKEW(sc)					\
     (((sc)->sc_advskew + V_carp_demotion > CARP_MAXSKEW) ?	\
@@ -539,7 +539,7 @@ carp6_input(struct mbuf **mp, int *offp,
 	}
 
 	/* check if received on a valid carp interface */
-	if (m->m_pkthdr.rcvif->if_carp == NULL) {
+	if (if_getsoftc(m->m_pkthdr.rcvif, IF_CARP) == NULL) {
 		CARPSTATS_INC(carps_badif);
 		CARP_DEBUG("%s: packet received on non-carp interface: %s\n",
 		    __func__, m->m_pkthdr.rcvif->if_xname);
@@ -795,6 +795,7 @@ carp_send_ad_locked(struct carp_softc *s
 	struct timeval tv;
 	struct sockaddr sa;
 	struct ifaddr *ifa;
+	struct carp_if *cif;
 	struct carp_header *ch_ptr;
 	struct mbuf *m;
 	int len, advskew;
@@ -814,6 +815,8 @@ carp_send_ad_locked(struct carp_softc *s
 	ch.carp_pad1 = 0;	/* must be zero */
 	ch.carp_cksum = 0;
 
+	cif = if_getsoftc(sc->sc_carpdev, IF_CARP);
+
 	/* XXXGL: OpenBSD picks first ifaddr with needed family. */
 
 #ifdef INET
@@ -865,7 +868,7 @@ carp_send_ad_locked(struct carp_softc *s
 		CARPSTATS_INC(carps_opackets);
 
 		carp_send_ad_error(sc, ip_output(m, NULL, NULL, IP_RAWOUTPUT,
-		    &sc->sc_carpdev->if_carp->cif_imo, NULL));
+		    &cif->cif_imo, NULL));
 	}
 #endif /* INET */
 #ifdef INET6
@@ -922,7 +925,7 @@ carp_send_ad_locked(struct carp_softc *s
 		CARPSTATS_INC(carps_opackets6);
 
 		carp_send_ad_error(sc, ip6_output(m, NULL, NULL, 0,
-		    &sc->sc_carpdev->if_carp->cif_im6o, NULL, NULL));
+		    &cif->cif_im6o, NULL, NULL));
 	}
 #endif /* INET6 */
 
@@ -1111,23 +1114,25 @@ int
 carp_forus(struct ifnet *ifp, u_char *dhost)
 {
 	struct carp_softc *sc;
+	struct carp_if *cif;
 	uint8_t *ena = dhost;
 
 	if (ena[0] || ena[1] || ena[2] != 0x5e || ena[3] || ena[4] != 1)
 		return (0);
 
-	CIF_LOCK(ifp->if_carp);
-	IFNET_FOREACH_CARP(ifp, sc) {
+	cif = if_getsoftc(ifp, IF_CARP);
+	CIF_LOCK(cif);
+	CIF_FOREACH_CARP(cif, sc) {
 		CARP_LOCK(sc);
 		if (sc->sc_state == MASTER && !bcmp(dhost, LLADDR(&sc->sc_addr),
 		    ETHER_ADDR_LEN)) {
 			CARP_UNLOCK(sc);
-			CIF_UNLOCK(ifp->if_carp);
+			CIF_UNLOCK(cif);
 			return (1);
 		}
 		CARP_UNLOCK(sc);
 	}
-	CIF_UNLOCK(ifp->if_carp);
+	CIF_UNLOCK(cif);
 
 	return (0);
 }
@@ -1417,7 +1422,7 @@ carp_output(struct ifnet *ifp, struct mb
 	bcopy(mtag + 1, &sc, sizeof(sc));
 
 	/* Set the source MAC address to the Virtual Router MAC Address. */
-	switch (ifp->if_type) {
+	switch (if_type(ifp)) {
 	case IFT_ETHER:
 	case IFT_BRIDGE:
 	case IFT_L2VLAN: {
@@ -1457,7 +1462,7 @@ carp_output(struct ifnet *ifp, struct mb
 		break;
 	default:
 		printf("%s: carp is not supported for the %d interface type\n",
-		    ifp->if_xname, ifp->if_type);
+		    ifp->if_xname, if_type(ifp));
 		return (EOPNOTSUPP);
 	}
 
@@ -1470,7 +1475,8 @@ carp_alloc(struct ifnet *ifp)
 	struct carp_softc *sc;
 	struct carp_if *cif;
 
-	if ((cif = ifp->if_carp) == NULL)
+	cif = if_getsoftc(ifp, IF_CARP);
+	if (cif == NULL)
 		cif = carp_alloc_if(ifp);
 
 	sc = malloc(sizeof(*sc), M_CARP, M_WAITOK|M_ZERO);
@@ -1526,8 +1532,9 @@ static void
 carp_destroy(struct carp_softc *sc)
 {
 	struct ifnet *ifp = sc->sc_carpdev;
-	struct carp_if *cif = ifp->if_carp;
+	struct carp_if *cif;
 
+	cif = if_getsoftc(ifp, IF_CARP);
 	CIF_LOCK_ASSERT(cif);
 
 	TAILQ_REMOVE(&cif->cif_vrs, sc, sc_list);
@@ -1552,7 +1559,7 @@ carp_destroy(struct carp_softc *sc)
 	free(sc, M_CARP);
 }
 
-static struct carp_if*
+static struct carp_if *
 carp_alloc_if(struct ifnet *ifp)
 {
 	struct carp_if *cif;
@@ -1570,10 +1577,9 @@ carp_alloc_if(struct ifnet *ifp)
 	cif->cif_ifp = ifp;
 	TAILQ_INIT(&cif->cif_vrs);
 
-	IF_ADDR_WLOCK(ifp);
-	ifp->if_carp = cif;
+	error = if_setsoftc(ifp, IF_CARP, cif);
+	KASSERT(error == 0, ("%s: ifp %p has carp softc", __func__, ifp));
 	if_ref(ifp);
-	IF_ADDR_WUNLOCK(ifp);
 
 	return (cif);
 }
@@ -1587,9 +1593,7 @@ carp_free_if(struct carp_if *cif)
 	KASSERT(TAILQ_EMPTY(&cif->cif_vrs), ("%s: softc list not empty",
 	    __func__));
 
-	IF_ADDR_WLOCK(ifp);
-	ifp->if_carp = NULL;
-	IF_ADDR_WUNLOCK(ifp);
+	if_setsoftc(ifp, IF_CARP, NULL);
 
 	CIF_LOCK_DESTROY(cif);
 
@@ -1621,6 +1625,7 @@ carp_ioctl(struct ifreq *ifr, u_long cmd
 {
 	struct carpreq carpr;
 	struct ifnet *ifp;
+	struct carp_if *cif;
 	struct carp_softc *sc = NULL;
 	int error = 0, locked = 0;
 
@@ -1631,7 +1636,7 @@ carp_ioctl(struct ifreq *ifr, u_long cmd
 	if (ifp == NULL)
 		return (ENXIO);
 
-	switch (ifp->if_type) {
+	switch (if_type(ifp)) {
 	case IFT_ETHER:
 	case IFT_L2VLAN:
 	case IFT_BRIDGE:
@@ -1649,6 +1654,7 @@ carp_ioctl(struct ifreq *ifr, u_long cmd
 	}
 
 	sx_xlock(&carp_sx);
+	cif = if_getsoftc(ifp, IF_CARP);
 	switch (cmd) {
 	case SIOCSVH:
 		if ((error = priv_check(td, PRIV_NETINET_CARP)))
@@ -1659,12 +1665,12 @@ carp_ioctl(struct ifreq *ifr, u_long cmd
 			break;
 		}
 
-		if (ifp->if_carp) {
-			CIF_LOCK(ifp->if_carp);
-			IFNET_FOREACH_CARP(ifp, sc)
+		if (cif) {
+			CIF_LOCK(cif);
+			CIF_FOREACH_CARP(cif, sc)
 				if (sc->sc_vhid == carpr.carpr_vhid)
 					break;
-			CIF_UNLOCK(ifp->if_carp);
+			CIF_UNLOCK(cif);
 		}
 		if (sc == NULL) {
 			sc = carp_alloc(ifp);
@@ -1728,18 +1734,18 @@ carp_ioctl(struct ifreq *ifr, u_long cmd
 			error = EMSGSIZE;
 			break;
 		}
-		if (ifp->if_carp == NULL) {
+		if (cif == NULL) {
 			error = ENOENT;
 			break;
 		}
 
 		priveleged = (priv_check(td, PRIV_NETINET_CARP) == 0);
 		if (carpr.carpr_vhid != 0) {
-			CIF_LOCK(ifp->if_carp);
-			IFNET_FOREACH_CARP(ifp, sc)
+			CIF_LOCK(cif);
+			CIF_FOREACH_CARP(cif, sc)
 				if (sc->sc_vhid == carpr.carpr_vhid)
 					break;
-			CIF_UNLOCK(ifp->if_carp);
+			CIF_UNLOCK(cif);
 			if (sc == NULL) {
 				error = ENOENT;
 				break;
@@ -1750,29 +1756,29 @@ carp_ioctl(struct ifreq *ifr, u_long cmd
 			int i, count;
 
 			count = 0;
-			CIF_LOCK(ifp->if_carp);
-			IFNET_FOREACH_CARP(ifp, sc)
+			CIF_LOCK(cif);
+			CIF_FOREACH_CARP(cif, sc)
 				count++;
 
 			if (count > carpr.carpr_count) {
-				CIF_UNLOCK(ifp->if_carp);
+				CIF_UNLOCK(cif);
 				error = EMSGSIZE;
 				break;
 			}
 
 			i = 0;
-			IFNET_FOREACH_CARP(ifp, sc) {
+			CIF_FOREACH_CARP(cif, sc) {
 				carp_carprcp(&carpr, sc, priveleged);
 				carpr.carpr_count = count;
 				error = copyout(&carpr, ifr->ifr_data +
 				    (i * sizeof(carpr)), sizeof(carpr));
 				if (error) {
-					CIF_UNLOCK(ifp->if_carp);
+					CIF_UNLOCK(cif);
 					break;
 				}
 				i++;
 			}
-			CIF_UNLOCK(ifp->if_carp);
+			CIF_UNLOCK(cif);
 		}
 		break;
 	    }
@@ -1803,11 +1809,12 @@ int
 carp_attach(struct ifaddr *ifa, int vhid)
 {
 	struct ifnet *ifp = ifa->ifa_ifp;
-	struct carp_if *cif = ifp->if_carp;
+	struct carp_if *cif;
 	struct carp_softc *sc;
 	int index, error;
 
-	if (ifp->if_carp == NULL)
+	cif = if_getsoftc(ifp, IF_CARP);
+	if (cif == NULL)
 		return (ENOPROTOOPT);
 
 	switch (ifa->ifa_addr->sa_family) {
@@ -1823,7 +1830,7 @@ carp_attach(struct ifaddr *ifa, int vhid
 	}
 
 	CIF_LOCK(cif);
-	IFNET_FOREACH_CARP(ifp, sc)
+	CIF_FOREACH_CARP(cif, sc)
 		if (sc->sc_vhid == vhid)
 			break;
 	if (sc == NULL) {
@@ -1889,8 +1896,9 @@ void
 carp_detach(struct ifaddr *ifa)
 {
 	struct ifnet *ifp = ifa->ifa_ifp;
-	struct carp_if *cif = ifp->if_carp;
+	struct carp_if *cif;
 
+	cif = if_getsoftc(ifp, IF_CARP);
 	CIF_LOCK(cif);
 	carp_detach_locked(ifa);
 	CIF_FREE(cif);
@@ -1900,12 +1908,13 @@ static void
 carp_detach_locked(struct ifaddr *ifa)
 {
 	struct ifnet *ifp = ifa->ifa_ifp;
-	struct carp_if *cif = ifp->if_carp;
+	struct carp_if *cif;
 	struct carp_softc *sc = ifa->ifa_carp;
 	int i, index;
 
 	KASSERT(sc != NULL, ("%s: %p not attached", __func__, ifa));
 
+	cif = if_getsoftc(ifp, IF_CARP);
 	CIF_LOCK_ASSERT(cif);
 	CARP_LOCK(sc);
 
@@ -1976,14 +1985,16 @@ static void
 carp_linkstate(struct ifnet *ifp)
 {
 	struct carp_softc *sc;
+	struct carp_if *cif;
 
-	CIF_LOCK(ifp->if_carp);
-	IFNET_FOREACH_CARP(ifp, sc) {
+	cif = if_getsoftc(ifp, IF_CARP);
+	CIF_LOCK(cif);
+	CIF_FOREACH_CARP(cif, sc) {
 		CARP_LOCK(sc);
 		carp_sc_state(sc);
 		CARP_UNLOCK(sc);
 	}
-	CIF_UNLOCK(ifp->if_carp);
+	CIF_UNLOCK(cif);
 }
 
 static void

Modified: projects/ifnet/sys/netinet/ip_input.c
==============================================================================
--- projects/ifnet/sys/netinet/ip_input.c	Mon Apr  6 15:44:09 2015	(r281154)
+++ projects/ifnet/sys/netinet/ip_input.c	Mon Apr  6 15:45:45 2015	(r281155)
@@ -633,7 +633,7 @@ passin:
 	 */
 	checkif = V_ip_checkinterface && (V_ipforwarding == 0) && 
 	    ifp != NULL && ((ifp->if_flags & IFF_LOOPBACK) == 0) &&
-	    ifp->if_carp == NULL && (dchg == 0);
+	    (dchg == 0) && if_getsoftc(ifp, IF_CARP) == NULL;
 
 	/*
 	 * Check for exact addresses in the hash bucket.

Modified: projects/ifnet/sys/netinet6/nd6_nbr.c
==============================================================================
--- projects/ifnet/sys/netinet6/nd6_nbr.c	Mon Apr  6 15:44:09 2015	(r281154)
+++ projects/ifnet/sys/netinet6/nd6_nbr.c	Mon Apr  6 15:45:45 2015	(r281155)
@@ -242,7 +242,7 @@ nd6_ns_input(struct mbuf *m, int off, in
 	 * (3) "tentative" address on which DAD is being performed.
 	 */
 	/* (1) and (3) check. */
-	if (ifp->if_carp)
+	if (if_getsoftc(ifp, IF_CARP) != NULL)
 		ifa = (*carp_iamatch6_p)(ifp, &taddr6);
 	else
 		ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
@@ -731,7 +731,7 @@ nd6_na_input(struct mbuf *m, int off, in
 	 * This effectively disables the DAD check on a non-master CARP
 	 * address.
 	 */
-	if (ifp->if_carp)
+	if (if_getsoftc(ifp, IF_CARP) != NULL)
 		ifa = (*carp_iamatch6_p)(ifp, &taddr6);
 	else
 		ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
@@ -1077,7 +1077,7 @@ nd6_na_output_fib(struct ifnet *ifp, con
 		 * my address) use lladdr configured for the interface.
 		 */
 		if (sdl0 == NULL) {
-			if (ifp->if_carp)
+			if (if_getsoftc(ifp, IF_CARP) != NULL)
 				mac = (*carp_macmatch6_p)(ifp, m, taddr6);
 			if (mac == NULL)
 				mac = nd6_ifptomac(ifp);


More information about the svn-src-projects mailing list