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