Skip to content

Commit

Permalink
different virutal-service may refer to the same address,when the addr…
Browse files Browse the repository at this point in the history
…ess is operated by the script specified by quorum_own var, Add judgment of other virtual-service's quorum_state that refer the same address.
  • Loading branch information
weiyanhua committed Sep 22, 2020
1 parent 6972a0a commit 7e1e159
Showing 1 changed file with 175 additions and 1 deletion.
176 changes: 175 additions & 1 deletion tools/keepalived/keepalived/check/ipwrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,178 @@ notify_fifo_rs(virtual_server_t* vs, real_server_t* rs)
FREE(line);
}

static int vs_addr_cmp(struct sockaddr_storage *addr_a, struct sockaddr_storage *addr_b)
{
int ret = 0;

if (addr_a->ss_family != addr_b->ss_family)
return 0;

if (addr_a->ss_family == AF_INET6) {
ret = inaddr_equal(AF_INET6, &((struct sockaddr_in6 *)addr_a)->sin6_addr,
&((struct sockaddr_in6 *)addr_b)->sin6_addr);
} else {
ret = inaddr_equal(AF_INET, &((struct sockaddr_in *)addr_a)->sin_addr,
&((struct sockaddr_in *)addr_b)->sin_addr);
}

return ret;
}

static int __vs_group_rang_addr_cmp(struct sockaddr_storage *addr,
virtual_server_group_entry_t *vsg_entry)
{
uint32_t addr_ip, ip;
struct sockaddr_storage vip_addr;
int ret = 0;

vip_addr = vsg_entry->addr;
if (vsg_entry->addr.ss_family == AF_INET6) {
//inet_sockaddrip6(&vsg_entry->addr, &addr.in6);
ip = ((struct sockaddr_in6*)&vip_addr)->sin6_addr.s6_addr32[3];
} else {
ip = ((struct sockaddr_in*)&vip_addr)->sin_addr.s_addr;
}

/* Parse the whole range */
for (addr_ip = ip;
((addr_ip >> 24) & 0xFF) <= vsg_entry->range;
addr_ip += 0x01000000) {
if (vsg_entry->addr.ss_family == AF_INET6) {
((struct sockaddr_in6*)&vip_addr)->sin6_addr.s6_addr32[3] = addr_ip;
} else {
((struct sockaddr_in*)&vip_addr)->sin_addr.s_addr = addr_ip;
}

ret |= vs_addr_cmp(addr, &vip_addr);
}
return ret;

}

static int __vs_group_addr_cmp(struct sockaddr_storage *addr, virtual_server_group_t *vsg)
{
virtual_server_group_entry_t *vsg_entry = NULL;
list l;
element e;
int ret = 0;

/* visit range list */
l = vsg->addr_range;
for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
vsg_entry = ELEMENT_DATA(e);
ret |= __vs_group_rang_addr_cmp(addr, vsg_entry);
}

return ret;
}

static int __vs_group_rang_cmp(virtual_server_group_entry_t *vsg_entry,
virtual_server_group_t *vsg)
{
uint32_t addr_ip, ip;
struct sockaddr_storage vip_addr;
int ret = 0;

vip_addr = vsg_entry->addr;
if (vsg_entry->addr.ss_family == AF_INET6) {
//inet_sockaddrip6(&vsg_entry->addr, &addr.in6);
ip = ((struct sockaddr_in6*)&vip_addr)->sin6_addr.s6_addr32[3];
} else {
ip = ((struct sockaddr_in*)&vip_addr)->sin_addr.s_addr;
}

/* Parse the whole range */
for (addr_ip = ip;
((addr_ip >> 24) & 0xFF) <= vsg_entry->range;
addr_ip += 0x01000000) {
if (vsg_entry->addr.ss_family == AF_INET6) {
((struct sockaddr_in6*)&vip_addr)->sin6_addr.s6_addr32[3] = addr_ip;
} else {
((struct sockaddr_in*)&vip_addr)->sin_addr.s_addr = addr_ip;
}
ret |= __vs_group_addr_cmp(&vip_addr, vsg);
}
return ret;
}

static int vs_group_addr_cmp(virtual_server_t *vs_a, virtual_server_t *vs_b)
{
virtual_server_group_t *vsg_a = ipvs_get_group_by_name(vs_a->vsgname, check_data->vs_group);
virtual_server_group_t *vsg_b = ipvs_get_group_by_name(vs_b->vsgname, check_data->vs_group);
virtual_server_group_entry_t *vsg_entry;
list l;
element e;
int ret = 0;

if (vsg_a == NULL || vsg_b == NULL)
return 0;

if (vsg_a == vsg_b)
return 1;

/* visit addr_ip list */
l = vsg_a->addr_ip;
for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
vsg_entry = ELEMENT_DATA(e);
ret |= __vs_group_addr_cmp(&vsg_entry->addr, vsg_b);
}

/* visit range list */
l = vsg_a->addr_range;
for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
vsg_entry = ELEMENT_DATA(e);
ret |= __vs_group_rang_cmp(vsg_entry, vsg_b);
}

return ret;
}

static int all_vs_quorum_down(virtual_server_t *var_vs)
{
element e;
virtual_server_t *tmp_vs = NULL;
virtual_server_group_t *vsg = NULL;
list l;
int ret = 0;

if (NULL == check_data) {
return 1;
}

l = check_data->vs;

if (LIST_ISEMPTY(l)) {
return 1;
}

for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
tmp_vs = ELEMENT_DATA(e);
if (false == tmp_vs->quorum_state_up)
continue;

if (var_vs->vsgname && tmp_vs->vsgname) {
ret = vs_group_addr_cmp(var_vs, tmp_vs);
} else if (var_vs->vsgname && NULL == tmp_vs->vsgname) {
vsg = ipvs_get_group_by_name(var_vs->vsgname, check_data->vs_group);
ret = __vs_group_addr_cmp(&tmp_vs->addr, vsg);
} else if (NULL == var_vs->vsgname && tmp_vs->vsgname) {
vsg = ipvs_get_group_by_name(tmp_vs->vsgname, check_data->vs_group);
ret = __vs_group_addr_cmp(&var_vs->addr, vsg);
} else {
ret = vs_addr_cmp(&var_vs->addr, &tmp_vs->addr);
}

if (ret) {
log_message(LOG_INFO, "VS [%s] have the same vip with VS [%s], and the quorum_state is UP",
(tmp_vs->vsgname) ? tmp_vs->vsgname : FMT_VS(tmp_vs)
,(var_vs->vsgname) ? var_vs->vsgname : FMT_VS(var_vs));
return 0;
}
}
return 1;
}

static void
do_vs_notifies(virtual_server_t* vs, bool init, long threshold, long weight_sum, bool stopping)
{
Expand All @@ -177,8 +349,10 @@ do_vs_notifies(virtual_server_t* vs, bool init, long threshold, long weight_sum,
if (notify_script) {
if (stopping)
system_call_script(master, child_killed_thread, NULL, TIMER_HZ, notify_script);
else
else if (vs->quorum_state_up || ((!vs->quorum_state_up) && all_vs_quorum_down(vs))) {
log_message(LOG_INFO, "Execute script: %s.", cmd_str(notify_script));
notify_exec(notify_script);
}
}

notify_fifo_vs(vs);
Expand Down

0 comments on commit 7e1e159

Please sign in to comment.