Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netinet/ip_carp.c
Show First 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
* - On module unload we may race (?) with packet processing thread | * - On module unload we may race (?) with packet processing thread | ||||
* dereferencing our function pointers. | * dereferencing our function pointers. | ||||
*/ | */ | ||||
/* Accept incoming CARP packets. */ | /* Accept incoming CARP packets. */ | ||||
static VNET_DEFINE(int, carp_allow) = 1; | static VNET_DEFINE(int, carp_allow) = 1; | ||||
#define V_carp_allow VNET(carp_allow) | #define V_carp_allow VNET(carp_allow) | ||||
/* Set DSCP in outgoing CARP packets. */ | |||||
static VNET_DEFINE(int, carp_dscp) = 56; | |||||
#define V_carp_dscp VNET(carp_dscp) | |||||
/* Preempt slower nodes. */ | /* Preempt slower nodes. */ | ||||
static VNET_DEFINE(int, carp_preempt) = 0; | static VNET_DEFINE(int, carp_preempt) = 0; | ||||
#define V_carp_preempt VNET(carp_preempt) | #define V_carp_preempt VNET(carp_preempt) | ||||
/* Log level. */ | /* Log level. */ | ||||
static VNET_DEFINE(int, carp_log) = 1; | static VNET_DEFINE(int, carp_log) = 1; | ||||
#define V_carp_log VNET(carp_log) | #define V_carp_log VNET(carp_log) | ||||
/* Global advskew demotion. */ | /* Global advskew demotion. */ | ||||
static VNET_DEFINE(int, carp_demotion) = 0; | static VNET_DEFINE(int, carp_demotion) = 0; | ||||
#define V_carp_demotion VNET(carp_demotion) | #define V_carp_demotion VNET(carp_demotion) | ||||
/* Send error demotion factor. */ | /* Send error demotion factor. */ | ||||
static VNET_DEFINE(int, carp_senderr_adj) = CARP_MAXSKEW; | static VNET_DEFINE(int, carp_senderr_adj) = CARP_MAXSKEW; | ||||
#define V_carp_senderr_adj VNET(carp_senderr_adj) | #define V_carp_senderr_adj VNET(carp_senderr_adj) | ||||
/* Iface down demotion factor. */ | /* Iface down demotion factor. */ | ||||
static VNET_DEFINE(int, carp_ifdown_adj) = CARP_MAXSKEW; | static VNET_DEFINE(int, carp_ifdown_adj) = CARP_MAXSKEW; | ||||
#define V_carp_ifdown_adj VNET(carp_ifdown_adj) | #define V_carp_ifdown_adj VNET(carp_ifdown_adj) | ||||
static int carp_allow_sysctl(SYSCTL_HANDLER_ARGS); | static int carp_allow_sysctl(SYSCTL_HANDLER_ARGS); | ||||
static int carp_dscp_sysctl(SYSCTL_HANDLER_ARGS); | |||||
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_PROC(_net_inet_carp, OID_AUTO, allow, | SYSCTL_PROC(_net_inet_carp, OID_AUTO, allow, | ||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW, 0, 0, carp_allow_sysctl, "I", | CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW, 0, 0, carp_allow_sysctl, "I", | ||||
"Accept incoming CARP packets"); | "Accept incoming CARP packets"); | ||||
SYSCTL_PROC(_net_inet_carp, OID_AUTO, dscp, | |||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW, 0, 0, carp_dscp_sysctl, "I", | |||||
"DSCP value for carp packets"); | |||||
SYSCTL_INT(_net_inet_carp, OID_AUTO, preempt, CTLFLAG_VNET | CTLFLAG_RW, | SYSCTL_INT(_net_inet_carp, OID_AUTO, preempt, CTLFLAG_VNET | CTLFLAG_RW, | ||||
&VNET_NAME(carp_preempt), 0, "High-priority backup preemption mode"); | &VNET_NAME(carp_preempt), 0, "High-priority backup preemption mode"); | ||||
SYSCTL_INT(_net_inet_carp, OID_AUTO, log, CTLFLAG_VNET | CTLFLAG_RW, | SYSCTL_INT(_net_inet_carp, OID_AUTO, log, CTLFLAG_VNET | CTLFLAG_RW, | ||||
&VNET_NAME(carp_log), 0, "CARP log level"); | &VNET_NAME(carp_log), 0, "CARP log level"); | ||||
SYSCTL_PROC(_net_inet_carp, OID_AUTO, demotion, | SYSCTL_PROC(_net_inet_carp, OID_AUTO, demotion, | ||||
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW, | CTLFLAG_VNET | 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)"); | ||||
▲ Show 20 Lines • Show All 700 Lines • ▼ Show 20 Lines | if (sc->sc_naddrs) { | ||||
m->m_pkthdr.len = len; | m->m_pkthdr.len = len; | ||||
m->m_pkthdr.rcvif = NULL; | m->m_pkthdr.rcvif = NULL; | ||||
m->m_len = len; | m->m_len = len; | ||||
M_ALIGN(m, m->m_len); | M_ALIGN(m, m->m_len); | ||||
m->m_flags |= M_MCAST; | m->m_flags |= M_MCAST; | ||||
ip = mtod(m, struct ip *); | ip = mtod(m, struct ip *); | ||||
ip->ip_v = IPVERSION; | ip->ip_v = IPVERSION; | ||||
ip->ip_hl = sizeof(*ip) >> 2; | ip->ip_hl = sizeof(*ip) >> 2; | ||||
ip->ip_tos = IPTOS_LOWDELAY; | ip->ip_tos = V_carp_dscp << IPTOS_DSCP_OFFSET; | ||||
ip->ip_len = htons(len); | ip->ip_len = htons(len); | ||||
ip->ip_off = htons(IP_DF); | ip->ip_off = htons(IP_DF); | ||||
ip->ip_ttl = CARP_DFLTTL; | ip->ip_ttl = CARP_DFLTTL; | ||||
ip->ip_p = IPPROTO_CARP; | ip->ip_p = IPPROTO_CARP; | ||||
ip->ip_sum = 0; | ip->ip_sum = 0; | ||||
ip_fillid(ip); | ip_fillid(ip); | ||||
ifa = carp_best_ifa(AF_INET, sc->sc_carpdev); | ifa = carp_best_ifa(AF_INET, sc->sc_carpdev); | ||||
Show All 33 Lines | if (sc->sc_naddrs6) { | ||||
m->m_pkthdr.len = len; | m->m_pkthdr.len = len; | ||||
m->m_pkthdr.rcvif = NULL; | m->m_pkthdr.rcvif = NULL; | ||||
m->m_len = len; | m->m_len = len; | ||||
M_ALIGN(m, m->m_len); | M_ALIGN(m, m->m_len); | ||||
m->m_flags |= M_MCAST; | m->m_flags |= M_MCAST; | ||||
ip6 = mtod(m, struct ip6_hdr *); | ip6 = mtod(m, struct ip6_hdr *); | ||||
bzero(ip6, sizeof(*ip6)); | bzero(ip6, sizeof(*ip6)); | ||||
ip6->ip6_vfc |= IPV6_VERSION; | ip6->ip6_vfc |= IPV6_VERSION; | ||||
/* Traffic class isn't defined in ip6 struct instead | |||||
* it gets offset into flowid field */ | |||||
ip6->ip6_flow |= htonl(V_carp_dscp << (IPV6_FLOWLABEL_LEN + | |||||
IPTOS_DSCP_OFFSET)); | |||||
ip6->ip6_hlim = CARP_DFLTTL; | ip6->ip6_hlim = CARP_DFLTTL; | ||||
ip6->ip6_nxt = IPPROTO_CARP; | ip6->ip6_nxt = IPPROTO_CARP; | ||||
/* set the source address */ | /* set the source address */ | ||||
ifa = carp_best_ifa(AF_INET6, sc->sc_carpdev); | ifa = carp_best_ifa(AF_INET6, sc->sc_carpdev); | ||||
if (ifa != NULL) { | if (ifa != NULL) { | ||||
bcopy(IFA_IN6(ifa), &ip6->ip6_src, | bcopy(IFA_IN6(ifa), &ip6->ip6_src, | ||||
sizeof(struct in6_addr)); | sizeof(struct in6_addr)); | ||||
▲ Show 20 Lines • Show All 1,098 Lines • ▼ Show 20 Lines | if (V_carp_allow != new) { | ||||
LIST_FOREACH(sc, &carp_list, sc_next) { | LIST_FOREACH(sc, &carp_list, sc_next) { | ||||
CARP_LOCK(sc); | CARP_LOCK(sc); | ||||
if (curvnet == sc->sc_carpdev->if_vnet) | if (curvnet == sc->sc_carpdev->if_vnet) | ||||
carp_sc_state(sc); | carp_sc_state(sc); | ||||
CARP_UNLOCK(sc); | CARP_UNLOCK(sc); | ||||
} | } | ||||
mtx_unlock(&carp_mtx); | mtx_unlock(&carp_mtx); | ||||
} | } | ||||
return (0); | |||||
} | |||||
static int | |||||
carp_dscp_sysctl(SYSCTL_HANDLER_ARGS) | |||||
{ | |||||
int new, error; | |||||
new = V_carp_dscp; | |||||
error = sysctl_handle_int(oidp, &new, 0, req); | |||||
if (error || !req->newptr) | |||||
return (error); | |||||
if (new < 0 || new > 63) | |||||
return (EINVAL); | |||||
V_carp_dscp = new; | |||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
carp_demote_adj_sysctl(SYSCTL_HANDLER_ARGS) | carp_demote_adj_sysctl(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
int new, error; | int new, error; | ||||
▲ Show 20 Lines • Show All 160 Lines • Show Last 20 Lines |