mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-29 16:44:03 +00:00
Virtualize carp(4) variables to have per vnet control.
Reviewed by: ae, glebius
This commit is contained in:
parent
8447b7cddc
commit
c5c392e7ed
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=254292
@ -187,48 +187,59 @@ static int proto_reg[] = {-1, -1};
|
|||||||
* dereferencing our function pointers.
|
* dereferencing our function pointers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int carp_allow = 1; /* Accept incoming CARP packets. */
|
/* Accept incoming CARP packets. */
|
||||||
static int carp_preempt = 0; /* Preempt slower nodes. */
|
static VNET_DEFINE(int, carp_allow) = 1;
|
||||||
static int carp_log = 1; /* Log level. */
|
#define V_carp_allow VNET(carp_allow)
|
||||||
static int carp_demotion = 0; /* Global advskew demotion. */
|
|
||||||
static int carp_senderr_adj = CARP_MAXSKEW; /* Send error demotion factor */
|
/* Preempt slower nodes. */
|
||||||
static int carp_ifdown_adj = CARP_MAXSKEW; /* Iface down demotion factor */
|
static VNET_DEFINE(int, carp_preempt) = 0;
|
||||||
|
#define V_carp_preempt VNET(carp_preempt)
|
||||||
|
|
||||||
|
/* Log level. */
|
||||||
|
static VNET_DEFINE(int, carp_log) = 1;
|
||||||
|
#define V_carp_log VNET(carp_log)
|
||||||
|
|
||||||
|
/* Global advskew demotion. */
|
||||||
|
static VNET_DEFINE(int, carp_demotion) = 0;
|
||||||
|
#define V_carp_demotion VNET(carp_demotion)
|
||||||
|
|
||||||
|
/* Send error demotion factor. */
|
||||||
|
static VNET_DEFINE(int, carp_senderr_adj) = CARP_MAXSKEW;
|
||||||
|
#define V_carp_senderr_adj VNET(carp_senderr_adj)
|
||||||
|
|
||||||
|
/* Iface down demotion factor. */
|
||||||
|
static VNET_DEFINE(int, carp_ifdown_adj) = CARP_MAXSKEW;
|
||||||
|
#define V_carp_ifdown_adj VNET(carp_ifdown_adj)
|
||||||
|
|
||||||
static int carp_demote_adj_sysctl(SYSCTL_HANDLER_ARGS);
|
static int carp_demote_adj_sysctl(SYSCTL_HANDLER_ARGS);
|
||||||
|
|
||||||
SYSCTL_NODE(_net_inet, IPPROTO_CARP, carp, CTLFLAG_RW, 0, "CARP");
|
SYSCTL_NODE(_net_inet, IPPROTO_CARP, carp, CTLFLAG_RW, 0, "CARP");
|
||||||
SYSCTL_INT(_net_inet_carp, OID_AUTO, allow, CTLFLAG_RW, &carp_allow, 0,
|
SYSCTL_VNET_INT(_net_inet_carp, OID_AUTO, allow, CTLFLAG_RW,
|
||||||
"Accept incoming CARP packets");
|
&VNET_NAME(carp_allow), 0, "Accept incoming CARP packets");
|
||||||
SYSCTL_INT(_net_inet_carp, OID_AUTO, preempt, CTLFLAG_RW, &carp_preempt, 0,
|
SYSCTL_VNET_INT(_net_inet_carp, OID_AUTO, preempt, CTLFLAG_RW,
|
||||||
"High-priority backup preemption mode");
|
&VNET_NAME(carp_preempt), 0, "High-priority backup preemption mode");
|
||||||
SYSCTL_INT(_net_inet_carp, OID_AUTO, log, CTLFLAG_RW, &carp_log, 0,
|
SYSCTL_VNET_INT(_net_inet_carp, OID_AUTO, log, CTLFLAG_RW,
|
||||||
"CARP log level");
|
&VNET_NAME(carp_log), 0, "CARP log level");
|
||||||
SYSCTL_PROC(_net_inet_carp, OID_AUTO, demotion, CTLTYPE_INT|CTLFLAG_RW,
|
SYSCTL_VNET_PROC(_net_inet_carp, OID_AUTO, demotion, CTLTYPE_INT|CTLFLAG_RW,
|
||||||
0, 0, carp_demote_adj_sysctl, "I",
|
0, 0, carp_demote_adj_sysctl, "I",
|
||||||
"Adjust demotion factor (skew of advskew)");
|
"Adjust demotion factor (skew of advskew)");
|
||||||
SYSCTL_INT(_net_inet_carp, OID_AUTO, senderr_demotion_factor, CTLFLAG_RW,
|
SYSCTL_VNET_INT(_net_inet_carp, OID_AUTO, senderr_demotion_factor, CTLFLAG_RW,
|
||||||
&carp_senderr_adj, 0, "Send error demotion factor adjustment");
|
&VNET_NAME(carp_senderr_adj), 0, "Send error demotion factor adjustment");
|
||||||
SYSCTL_INT(_net_inet_carp, OID_AUTO, ifdown_demotion_factor, CTLFLAG_RW,
|
SYSCTL_VNET_INT(_net_inet_carp, OID_AUTO, ifdown_demotion_factor, CTLFLAG_RW,
|
||||||
&carp_ifdown_adj, 0, "Interface down demotion factor adjustment");
|
&VNET_NAME(carp_ifdown_adj), 0,
|
||||||
|
"Interface down demotion factor adjustment");
|
||||||
|
|
||||||
|
VNET_PCPUSTAT_DEFINE(struct carpstats, carpstats);
|
||||||
|
VNET_PCPUSTAT_SYSINIT(carpstats);
|
||||||
|
VNET_PCPUSTAT_SYSUNINIT(carpstats);
|
||||||
|
|
||||||
static counter_u64_t carpstats[sizeof(struct carpstats) / sizeof(uint64_t)];
|
|
||||||
#define CARPSTATS_ADD(name, val) \
|
#define CARPSTATS_ADD(name, val) \
|
||||||
counter_u64_add(carpstats[offsetof(struct carpstats, name) / \
|
counter_u64_add(VNET(carpstats)[offsetof(struct carpstats, name) / \
|
||||||
sizeof(uint64_t)], (val))
|
sizeof(uint64_t)], (val))
|
||||||
#define CARPSTATS_INC(name) CARPSTATS_ADD(name, 1)
|
#define CARPSTATS_INC(name) CARPSTATS_ADD(name, 1)
|
||||||
|
|
||||||
static int
|
SYSCTL_VNET_PCPUSTAT(_net_inet_carp, OID_AUTO, stats, struct carpstats,
|
||||||
carpstats_sysctl(SYSCTL_HANDLER_ARGS)
|
carpstats, "CARP statistics (struct carpstats, netinet/ip_carp.h)");
|
||||||
{
|
|
||||||
struct carpstats s;
|
|
||||||
|
|
||||||
COUNTER_ARRAY_COPY(carpstats, &s, sizeof(s) / sizeof(uint64_t));
|
|
||||||
if (req->newptr)
|
|
||||||
COUNTER_ARRAY_ZERO(carpstats, sizeof(s) / sizeof(uint64_t));
|
|
||||||
return (SYSCTL_OUT(req, &s, sizeof(s)));
|
|
||||||
}
|
|
||||||
SYSCTL_PROC(_net_inet_carp, OID_AUTO, stats, CTLTYPE_OPAQUE | CTLFLAG_RW,
|
|
||||||
NULL, 0, carpstats_sysctl, "I",
|
|
||||||
"CARP statistics (struct carpstats, netinet/ip_carp.h)");
|
|
||||||
|
|
||||||
#define CARP_LOCK_INIT(sc) mtx_init(&(sc)->sc_mtx, "carp_softc", \
|
#define CARP_LOCK_INIT(sc) mtx_init(&(sc)->sc_mtx, "carp_softc", \
|
||||||
NULL, MTX_DEF)
|
NULL, MTX_DEF)
|
||||||
@ -251,12 +262,12 @@ SYSCTL_PROC(_net_inet_carp, OID_AUTO, stats, CTLTYPE_OPAQUE | CTLFLAG_RW,
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define CARP_LOG(...) do { \
|
#define CARP_LOG(...) do { \
|
||||||
if (carp_log > 0) \
|
if (V_carp_log > 0) \
|
||||||
log(LOG_INFO, "carp: " __VA_ARGS__); \
|
log(LOG_INFO, "carp: " __VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define CARP_DEBUG(...) do { \
|
#define CARP_DEBUG(...) do { \
|
||||||
if (carp_log > 1) \
|
if (V_carp_log > 1) \
|
||||||
log(LOG_DEBUG, __VA_ARGS__); \
|
log(LOG_DEBUG, __VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
@ -277,8 +288,8 @@ SYSCTL_PROC(_net_inet_carp, OID_AUTO, stats, CTLTYPE_OPAQUE | CTLFLAG_RW,
|
|||||||
TAILQ_FOREACH((sc), &(ifp)->if_carp->cif_vrs, sc_list)
|
TAILQ_FOREACH((sc), &(ifp)->if_carp->cif_vrs, sc_list)
|
||||||
|
|
||||||
#define DEMOTE_ADVSKEW(sc) \
|
#define DEMOTE_ADVSKEW(sc) \
|
||||||
(((sc)->sc_advskew + carp_demotion > CARP_MAXSKEW) ? \
|
(((sc)->sc_advskew + V_carp_demotion > CARP_MAXSKEW) ? \
|
||||||
CARP_MAXSKEW : ((sc)->sc_advskew + carp_demotion))
|
CARP_MAXSKEW : ((sc)->sc_advskew + V_carp_demotion))
|
||||||
|
|
||||||
static void carp_input_c(struct mbuf *, struct carp_header *, sa_family_t);
|
static void carp_input_c(struct mbuf *, struct carp_header *, sa_family_t);
|
||||||
static struct carp_softc
|
static struct carp_softc
|
||||||
@ -430,7 +441,7 @@ carp_input(struct mbuf *m, int hlen)
|
|||||||
|
|
||||||
CARPSTATS_INC(carps_ipackets);
|
CARPSTATS_INC(carps_ipackets);
|
||||||
|
|
||||||
if (!carp_allow) {
|
if (!V_carp_allow) {
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -513,7 +524,7 @@ carp6_input(struct mbuf **mp, int *offp, int proto)
|
|||||||
|
|
||||||
CARPSTATS_INC(carps_ipackets6);
|
CARPSTATS_INC(carps_ipackets6);
|
||||||
|
|
||||||
if (!carp_allow) {
|
if (!V_carp_allow) {
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return (IPPROTO_DONE);
|
return (IPPROTO_DONE);
|
||||||
}
|
}
|
||||||
@ -647,7 +658,7 @@ carp_input_c(struct mbuf *m, struct carp_header *ch, sa_family_t af)
|
|||||||
* If we're pre-empting masters who advertise slower than us,
|
* If we're pre-empting masters who advertise slower than us,
|
||||||
* and this one claims to be slower, treat him as down.
|
* and this one claims to be slower, treat him as down.
|
||||||
*/
|
*/
|
||||||
if (carp_preempt && timevalcmp(&sc_tv, &ch_tv, <)) {
|
if (V_carp_preempt && timevalcmp(&sc_tv, &ch_tv, <)) {
|
||||||
CARP_LOG("VHID %u@%s: BACKUP -> MASTER "
|
CARP_LOG("VHID %u@%s: BACKUP -> MASTER "
|
||||||
"(preempting a slower master)\n",
|
"(preempting a slower master)\n",
|
||||||
sc->sc_vhid,
|
sc->sc_vhid,
|
||||||
@ -830,13 +841,14 @@ carp_send_ad_locked(struct carp_softc *sc)
|
|||||||
if (sc->sc_sendad_errors < INT_MAX)
|
if (sc->sc_sendad_errors < INT_MAX)
|
||||||
sc->sc_sendad_errors++;
|
sc->sc_sendad_errors++;
|
||||||
if (sc->sc_sendad_errors == CARP_SENDAD_MAX_ERRORS)
|
if (sc->sc_sendad_errors == CARP_SENDAD_MAX_ERRORS)
|
||||||
carp_demote_adj(carp_senderr_adj, "send error");
|
carp_demote_adj(V_carp_senderr_adj,
|
||||||
|
"send error");
|
||||||
sc->sc_sendad_success = 0;
|
sc->sc_sendad_success = 0;
|
||||||
} else {
|
} else {
|
||||||
if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS) {
|
if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS) {
|
||||||
if (++sc->sc_sendad_success >=
|
if (++sc->sc_sendad_success >=
|
||||||
CARP_SENDAD_MIN_SUCCESS) {
|
CARP_SENDAD_MIN_SUCCESS) {
|
||||||
carp_demote_adj(-carp_senderr_adj,
|
carp_demote_adj(-V_carp_senderr_adj,
|
||||||
"send ok");
|
"send ok");
|
||||||
sc->sc_sendad_errors = 0;
|
sc->sc_sendad_errors = 0;
|
||||||
}
|
}
|
||||||
@ -903,14 +915,14 @@ carp_send_ad_locked(struct carp_softc *sc)
|
|||||||
if (sc->sc_sendad_errors < INT_MAX)
|
if (sc->sc_sendad_errors < INT_MAX)
|
||||||
sc->sc_sendad_errors++;
|
sc->sc_sendad_errors++;
|
||||||
if (sc->sc_sendad_errors == CARP_SENDAD_MAX_ERRORS)
|
if (sc->sc_sendad_errors == CARP_SENDAD_MAX_ERRORS)
|
||||||
carp_demote_adj(carp_senderr_adj,
|
carp_demote_adj(V_carp_senderr_adj,
|
||||||
"send6 error");
|
"send6 error");
|
||||||
sc->sc_sendad_success = 0;
|
sc->sc_sendad_success = 0;
|
||||||
} else {
|
} else {
|
||||||
if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS) {
|
if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS) {
|
||||||
if (++sc->sc_sendad_success >=
|
if (++sc->sc_sendad_success >=
|
||||||
CARP_SENDAD_MIN_SUCCESS) {
|
CARP_SENDAD_MIN_SUCCESS) {
|
||||||
carp_demote_adj(-carp_senderr_adj,
|
carp_demote_adj(-V_carp_senderr_adj,
|
||||||
"send6 ok");
|
"send6 ok");
|
||||||
sc->sc_sendad_errors = 0;
|
sc->sc_sendad_errors = 0;
|
||||||
}
|
}
|
||||||
@ -1541,7 +1553,7 @@ carp_destroy(struct carp_softc *sc)
|
|||||||
|
|
||||||
CARP_LOCK(sc);
|
CARP_LOCK(sc);
|
||||||
if (sc->sc_suppress)
|
if (sc->sc_suppress)
|
||||||
carp_demote_adj(-carp_ifdown_adj, "vhid removed");
|
carp_demote_adj(-V_carp_ifdown_adj, "vhid removed");
|
||||||
callout_drain(&sc->sc_ad_tmo);
|
callout_drain(&sc->sc_ad_tmo);
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
callout_drain(&sc->sc_md_tmo);
|
callout_drain(&sc->sc_md_tmo);
|
||||||
@ -2006,13 +2018,13 @@ carp_sc_state(struct carp_softc *sc)
|
|||||||
carp_set_state(sc, INIT);
|
carp_set_state(sc, INIT);
|
||||||
carp_setrun(sc, 0);
|
carp_setrun(sc, 0);
|
||||||
if (!sc->sc_suppress)
|
if (!sc->sc_suppress)
|
||||||
carp_demote_adj(carp_ifdown_adj, "interface down");
|
carp_demote_adj(V_carp_ifdown_adj, "interface down");
|
||||||
sc->sc_suppress = 1;
|
sc->sc_suppress = 1;
|
||||||
} else {
|
} else {
|
||||||
carp_set_state(sc, INIT);
|
carp_set_state(sc, INIT);
|
||||||
carp_setrun(sc, 0);
|
carp_setrun(sc, 0);
|
||||||
if (sc->sc_suppress)
|
if (sc->sc_suppress)
|
||||||
carp_demote_adj(-carp_ifdown_adj, "interface up");
|
carp_demote_adj(-V_carp_ifdown_adj, "interface up");
|
||||||
sc->sc_suppress = 0;
|
sc->sc_suppress = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2020,8 +2032,8 @@ carp_sc_state(struct carp_softc *sc)
|
|||||||
static void
|
static void
|
||||||
carp_demote_adj(int adj, char *reason)
|
carp_demote_adj(int adj, char *reason)
|
||||||
{
|
{
|
||||||
atomic_add_int(&carp_demotion, adj);
|
atomic_add_int(&V_carp_demotion, adj);
|
||||||
CARP_LOG("demoted by %d to %d (%s)\n", adj, carp_demotion, reason);
|
CARP_LOG("demoted by %d to %d (%s)\n", adj, V_carp_demotion, reason);
|
||||||
taskqueue_enqueue(taskqueue_swi, &carp_sendall_task);
|
taskqueue_enqueue(taskqueue_swi, &carp_sendall_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2030,7 +2042,7 @@ carp_demote_adj_sysctl(SYSCTL_HANDLER_ARGS)
|
|||||||
{
|
{
|
||||||
int new, error;
|
int new, error;
|
||||||
|
|
||||||
new = carp_demotion;
|
new = V_carp_demotion;
|
||||||
error = sysctl_handle_int(oidp, &new, 0, req);
|
error = sysctl_handle_int(oidp, &new, 0, req);
|
||||||
if (error || !req->newptr)
|
if (error || !req->newptr)
|
||||||
return (error);
|
return (error);
|
||||||
@ -2101,8 +2113,6 @@ carp_mod_cleanup(void)
|
|||||||
mtx_unlock(&carp_mtx);
|
mtx_unlock(&carp_mtx);
|
||||||
taskqueue_drain(taskqueue_swi, &carp_sendall_task);
|
taskqueue_drain(taskqueue_swi, &carp_sendall_task);
|
||||||
mtx_destroy(&carp_mtx);
|
mtx_destroy(&carp_mtx);
|
||||||
COUNTER_ARRAY_FREE(carpstats,
|
|
||||||
sizeof(struct carpstats) / sizeof(uint64_t));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -2112,8 +2122,6 @@ carp_mod_load(void)
|
|||||||
|
|
||||||
mtx_init(&carp_mtx, "carp_mtx", NULL, MTX_DEF);
|
mtx_init(&carp_mtx, "carp_mtx", NULL, MTX_DEF);
|
||||||
LIST_INIT(&carp_list);
|
LIST_INIT(&carp_list);
|
||||||
COUNTER_ARRAY_ALLOC(carpstats,
|
|
||||||
sizeof(struct carpstats) / sizeof(uint64_t), M_WAITOK);
|
|
||||||
carp_get_vhid_p = carp_get_vhid;
|
carp_get_vhid_p = carp_get_vhid;
|
||||||
carp_forus_p = carp_forus;
|
carp_forus_p = carp_forus;
|
||||||
carp_output_p = carp_output;
|
carp_output_p = carp_output;
|
||||||
|
Loading…
Reference in New Issue
Block a user