|
Lines 142-148
struct carp_if {
Link Here
|
| 142 |
struct ip6_moptions cif_im6o; |
142 |
struct ip6_moptions cif_im6o; |
| 143 |
#endif |
143 |
#endif |
| 144 |
struct ifnet *cif_ifp; |
144 |
struct ifnet *cif_ifp; |
| 145 |
struct mtx cif_mtx; |
145 |
struct rwlock cif_mtx; |
| 146 |
}; |
146 |
}; |
| 147 |
|
147 |
|
| 148 |
#define CARP_INET 0 |
148 |
#define CARP_INET 0 |
|
Lines 246-263
SYSCTL_VNET_PCPUSTAT(_net_inet_carp, OID_AUTO, stats, struct carpstats,
Link Here
|
| 246 |
#define CARP_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) |
246 |
#define CARP_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) |
| 247 |
#define CARP_LOCK(sc) mtx_lock(&(sc)->sc_mtx) |
247 |
#define CARP_LOCK(sc) mtx_lock(&(sc)->sc_mtx) |
| 248 |
#define CARP_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) |
248 |
#define CARP_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) |
| 249 |
#define CIF_LOCK_INIT(cif) mtx_init(&(cif)->cif_mtx, "carp_if", \ |
249 |
#define CIF_LOCK_INIT(cif) rw_init(&(cif)->cif_mtx, "carp_if") |
| 250 |
NULL, MTX_DEF) |
250 |
#define CIF_LOCK_DESTROY(cif) rw_destroy(&(cif)->cif_mtx) |
| 251 |
#define CIF_LOCK_DESTROY(cif) mtx_destroy(&(cif)->cif_mtx) |
251 |
#define CIF_LOCK_ASSERT(cif) rw_assert(&(cif)->cif_mtx, MA_OWNED) |
| 252 |
#define CIF_LOCK_ASSERT(cif) mtx_assert(&(cif)->cif_mtx, MA_OWNED) |
252 |
#define CIF_RLOCK(cif) rw_rlock(&(cif)->cif_mtx) |
| 253 |
#define CIF_LOCK(cif) mtx_lock(&(cif)->cif_mtx) |
253 |
#define CIF_RUNLOCK(cif) rw_runlock(&(cif)->cif_mtx) |
| 254 |
#define CIF_UNLOCK(cif) mtx_unlock(&(cif)->cif_mtx) |
254 |
#define CIF_WLOCK(cif) rw_wlock(&(cif)->cif_mtx) |
|
|
255 |
#define CIF_WUNLOCK(cif) rw_wunlock(&(cif)->cif_mtx) |
| 255 |
#define CIF_FREE(cif) do { \ |
256 |
#define CIF_FREE(cif) do { \ |
| 256 |
CIF_LOCK_ASSERT(cif); \ |
257 |
CIF_LOCK_ASSERT(cif); \ |
| 257 |
if (TAILQ_EMPTY(&(cif)->cif_vrs)) \ |
258 |
if (TAILQ_EMPTY(&(cif)->cif_vrs)) \ |
| 258 |
carp_free_if(cif); \ |
259 |
carp_free_if(cif); \ |
| 259 |
else \ |
260 |
else \ |
| 260 |
CIF_UNLOCK(cif); \ |
261 |
CIF_WUNLOCK(cif); \ |
| 261 |
} while (0) |
262 |
} while (0) |
| 262 |
|
263 |
|
| 263 |
#define CARP_LOG(...) do { \ |
264 |
#define CARP_LOG(...) do { \ |
|
Lines 1122-1139
carp_forus(struct ifnet *ifp, u_char *dhost)
Link Here
|
| 1122 |
if (ena[0] || ena[1] || ena[2] != 0x5e || ena[3] || ena[4] != 1) |
1123 |
if (ena[0] || ena[1] || ena[2] != 0x5e || ena[3] || ena[4] != 1) |
| 1123 |
return (0); |
1124 |
return (0); |
| 1124 |
|
1125 |
|
| 1125 |
CIF_LOCK(ifp->if_carp); |
1126 |
CIF_RLOCK(ifp->if_carp); |
| 1126 |
IFNET_FOREACH_CARP(ifp, sc) { |
1127 |
IFNET_FOREACH_CARP(ifp, sc) { |
| 1127 |
CARP_LOCK(sc); |
1128 |
//CARP_LOCK(sc); |
| 1128 |
if (sc->sc_state == MASTER && !bcmp(dhost, LLADDR(&sc->sc_addr), |
1129 |
if (sc->sc_state == MASTER && ena[5] == sc->sc_vhid) { |
| 1129 |
ETHER_ADDR_LEN)) { |
1130 |
//CARP_UNLOCK(sc); |
| 1130 |
CARP_UNLOCK(sc); |
1131 |
CIF_RUNLOCK(ifp->if_carp); |
| 1131 |
CIF_UNLOCK(ifp->if_carp); |
|
|
| 1132 |
return (1); |
1132 |
return (1); |
| 1133 |
} |
1133 |
} |
| 1134 |
CARP_UNLOCK(sc); |
1134 |
//CARP_UNLOCK(sc); |
| 1135 |
} |
1135 |
} |
| 1136 |
CIF_UNLOCK(ifp->if_carp); |
1136 |
CIF_RUNLOCK(ifp->if_carp); |
| 1137 |
|
1137 |
|
| 1138 |
return (0); |
1138 |
return (0); |
| 1139 |
} |
1139 |
} |
|
Lines 1508-1516
carp_alloc(struct ifnet *ifp)
Link Here
|
| 1508 |
#endif |
1508 |
#endif |
| 1509 |
callout_init_mtx(&sc->sc_ad_tmo, &sc->sc_mtx, CALLOUT_RETURNUNLOCKED); |
1509 |
callout_init_mtx(&sc->sc_ad_tmo, &sc->sc_mtx, CALLOUT_RETURNUNLOCKED); |
| 1510 |
|
1510 |
|
| 1511 |
CIF_LOCK(cif); |
1511 |
CIF_WLOCK(cif); |
| 1512 |
TAILQ_INSERT_TAIL(&cif->cif_vrs, sc, sc_list); |
1512 |
TAILQ_INSERT_TAIL(&cif->cif_vrs, sc, sc_list); |
| 1513 |
CIF_UNLOCK(cif); |
1513 |
CIF_WUNLOCK(cif); |
| 1514 |
|
1514 |
|
| 1515 |
mtx_lock(&carp_mtx); |
1515 |
mtx_lock(&carp_mtx); |
| 1516 |
LIST_INSERT_HEAD(&carp_list, sc, sc_next); |
1516 |
LIST_INSERT_HEAD(&carp_list, sc, sc_next); |
|
Lines 1674-1684
carp_ioctl(struct ifreq *ifr, u_long cmd, struct thread *td)
Link Here
|
| 1674 |
} |
1674 |
} |
| 1675 |
|
1675 |
|
| 1676 |
if (ifp->if_carp) { |
1676 |
if (ifp->if_carp) { |
| 1677 |
CIF_LOCK(ifp->if_carp); |
1677 |
CIF_RLOCK(ifp->if_carp); |
| 1678 |
IFNET_FOREACH_CARP(ifp, sc) |
1678 |
IFNET_FOREACH_CARP(ifp, sc) |
| 1679 |
if (sc->sc_vhid == carpr.carpr_vhid) |
1679 |
if (sc->sc_vhid == carpr.carpr_vhid) |
| 1680 |
break; |
1680 |
break; |
| 1681 |
CIF_UNLOCK(ifp->if_carp); |
1681 |
CIF_RUNLOCK(ifp->if_carp); |
| 1682 |
} |
1682 |
} |
| 1683 |
if (sc == NULL) { |
1683 |
if (sc == NULL) { |
| 1684 |
sc = carp_alloc(ifp); |
1684 |
sc = carp_alloc(ifp); |
|
Lines 1752-1762
carp_ioctl(struct ifreq *ifr, u_long cmd, struct thread *td)
Link Here
|
| 1752 |
|
1752 |
|
| 1753 |
priveleged = (priv_check(td, PRIV_NETINET_CARP) == 0); |
1753 |
priveleged = (priv_check(td, PRIV_NETINET_CARP) == 0); |
| 1754 |
if (carpr.carpr_vhid != 0) { |
1754 |
if (carpr.carpr_vhid != 0) { |
| 1755 |
CIF_LOCK(ifp->if_carp); |
1755 |
CIF_RLOCK(ifp->if_carp); |
| 1756 |
IFNET_FOREACH_CARP(ifp, sc) |
1756 |
IFNET_FOREACH_CARP(ifp, sc) |
| 1757 |
if (sc->sc_vhid == carpr.carpr_vhid) |
1757 |
if (sc->sc_vhid == carpr.carpr_vhid) |
| 1758 |
break; |
1758 |
break; |
| 1759 |
CIF_UNLOCK(ifp->if_carp); |
1759 |
CIF_RUNLOCK(ifp->if_carp); |
| 1760 |
if (sc == NULL) { |
1760 |
if (sc == NULL) { |
| 1761 |
error = ENOENT; |
1761 |
error = ENOENT; |
| 1762 |
break; |
1762 |
break; |
|
Lines 1767-1778
carp_ioctl(struct ifreq *ifr, u_long cmd, struct thread *td)
Link Here
|
| 1767 |
int i, count; |
1767 |
int i, count; |
| 1768 |
|
1768 |
|
| 1769 |
count = 0; |
1769 |
count = 0; |
| 1770 |
CIF_LOCK(ifp->if_carp); |
1770 |
CIF_RLOCK(ifp->if_carp); |
| 1771 |
IFNET_FOREACH_CARP(ifp, sc) |
1771 |
IFNET_FOREACH_CARP(ifp, sc) |
| 1772 |
count++; |
1772 |
count++; |
| 1773 |
|
1773 |
|
| 1774 |
if (count > carpr.carpr_count) { |
1774 |
if (count > carpr.carpr_count) { |
| 1775 |
CIF_UNLOCK(ifp->if_carp); |
1775 |
CIF_RUNLOCK(ifp->if_carp); |
| 1776 |
error = EMSGSIZE; |
1776 |
error = EMSGSIZE; |
| 1777 |
break; |
1777 |
break; |
| 1778 |
} |
1778 |
} |
|
Lines 1784-1795
carp_ioctl(struct ifreq *ifr, u_long cmd, struct thread *td)
Link Here
|
| 1784 |
error = copyout(&carpr, ifr->ifr_data + |
1784 |
error = copyout(&carpr, ifr->ifr_data + |
| 1785 |
(i * sizeof(carpr)), sizeof(carpr)); |
1785 |
(i * sizeof(carpr)), sizeof(carpr)); |
| 1786 |
if (error) { |
1786 |
if (error) { |
| 1787 |
CIF_UNLOCK(ifp->if_carp); |
1787 |
CIF_RUNLOCK(ifp->if_carp); |
| 1788 |
break; |
1788 |
break; |
| 1789 |
} |
1789 |
} |
| 1790 |
i++; |
1790 |
i++; |
| 1791 |
} |
1791 |
} |
| 1792 |
CIF_UNLOCK(ifp->if_carp); |
1792 |
CIF_RUNLOCK(ifp->if_carp); |
| 1793 |
} |
1793 |
} |
| 1794 |
break; |
1794 |
break; |
| 1795 |
} |
1795 |
} |
|
Lines 1838-1849
carp_attach(struct ifaddr *ifa, int vhid)
Link Here
|
| 1838 |
return (EPROTOTYPE); |
1838 |
return (EPROTOTYPE); |
| 1839 |
} |
1839 |
} |
| 1840 |
|
1840 |
|
| 1841 |
CIF_LOCK(cif); |
1841 |
CIF_WLOCK(cif); |
| 1842 |
IFNET_FOREACH_CARP(ifp, sc) |
1842 |
IFNET_FOREACH_CARP(ifp, sc) |
| 1843 |
if (sc->sc_vhid == vhid) |
1843 |
if (sc->sc_vhid == vhid) |
| 1844 |
break; |
1844 |
break; |
| 1845 |
if (sc == NULL) { |
1845 |
if (sc == NULL) { |
| 1846 |
CIF_UNLOCK(cif); |
1846 |
CIF_WUNLOCK(cif); |
| 1847 |
return (ENOENT); |
1847 |
return (ENOENT); |
| 1848 |
} |
1848 |
} |
| 1849 |
|
1849 |
|
|
Lines 1851-1857
carp_attach(struct ifaddr *ifa, int vhid)
Link Here
|
| 1851 |
if (ifa->ifa_carp->sc_vhid != vhid) |
1851 |
if (ifa->ifa_carp->sc_vhid != vhid) |
| 1852 |
carp_detach_locked(ifa); |
1852 |
carp_detach_locked(ifa); |
| 1853 |
else { |
1853 |
else { |
| 1854 |
CIF_UNLOCK(cif); |
1854 |
CIF_WUNLOCK(cif); |
| 1855 |
return (0); |
1855 |
return (0); |
| 1856 |
} |
1856 |
} |
| 1857 |
} |
1857 |
} |
|
Lines 1896-1902
carp_attach(struct ifaddr *ifa, int vhid)
Link Here
|
| 1896 |
carp_sc_state(sc); |
1896 |
carp_sc_state(sc); |
| 1897 |
|
1897 |
|
| 1898 |
CARP_UNLOCK(sc); |
1898 |
CARP_UNLOCK(sc); |
| 1899 |
CIF_UNLOCK(cif); |
1899 |
CIF_WUNLOCK(cif); |
| 1900 |
|
1900 |
|
| 1901 |
return (0); |
1901 |
return (0); |
| 1902 |
} |
1902 |
} |
|
Lines 1907-1913
carp_detach(struct ifaddr *ifa)
Link Here
|
| 1907 |
struct ifnet *ifp = ifa->ifa_ifp; |
1907 |
struct ifnet *ifp = ifa->ifa_ifp; |
| 1908 |
struct carp_if *cif = ifp->if_carp; |
1908 |
struct carp_if *cif = ifp->if_carp; |
| 1909 |
|
1909 |
|
| 1910 |
CIF_LOCK(cif); |
1910 |
CIF_WLOCK(cif); |
| 1911 |
carp_detach_locked(ifa); |
1911 |
carp_detach_locked(ifa); |
| 1912 |
CIF_FREE(cif); |
1912 |
CIF_FREE(cif); |
| 1913 |
} |
1913 |
} |
|
Lines 1989-2001
carp_linkstate(struct ifnet *ifp)
Link Here
|
| 1989 |
{ |
1989 |
{ |
| 1990 |
struct carp_softc *sc; |
1990 |
struct carp_softc *sc; |
| 1991 |
|
1991 |
|
| 1992 |
CIF_LOCK(ifp->if_carp); |
1992 |
CIF_RLOCK(ifp->if_carp); |
| 1993 |
IFNET_FOREACH_CARP(ifp, sc) { |
1993 |
IFNET_FOREACH_CARP(ifp, sc) { |
| 1994 |
CARP_LOCK(sc); |
1994 |
CARP_LOCK(sc); |
| 1995 |
carp_sc_state(sc); |
1995 |
carp_sc_state(sc); |
| 1996 |
CARP_UNLOCK(sc); |
1996 |
CARP_UNLOCK(sc); |
| 1997 |
} |
1997 |
} |
| 1998 |
CIF_UNLOCK(ifp->if_carp); |
1998 |
CIF_RUNLOCK(ifp->if_carp); |
| 1999 |
} |
1999 |
} |
| 2000 |
|
2000 |
|
| 2001 |
static void |
2001 |
static void |
|
Lines 2030-2038
carp_sc_state(struct carp_softc *sc)
Link Here
|
| 2030 |
static void |
2030 |
static void |
| 2031 |
carp_demote_adj(int adj, char *reason) |
2031 |
carp_demote_adj(int adj, char *reason) |
| 2032 |
{ |
2032 |
{ |
|
|
2033 |
if (adj == 0) |
| 2034 |
return; |
| 2033 |
atomic_add_int(&V_carp_demotion, adj); |
2035 |
atomic_add_int(&V_carp_demotion, adj); |
| 2034 |
CARP_LOG("demoted by %d to %d (%s)\n", adj, V_carp_demotion, reason); |
2036 |
CARP_LOG("demoted by %d to %d (%s)\n", adj, V_carp_demotion, reason); |
| 2035 |
taskqueue_enqueue(taskqueue_swi, &carp_sendall_task); |
2037 |
taskqueue_enqueue(taskqueue_thread, &carp_sendall_task); |
| 2036 |
} |
2038 |
} |
| 2037 |
|
2039 |
|
| 2038 |
static int |
2040 |
static int |