/* set IPVS group rules */ static int ipvs_group_cmd(int cmd, list vs_group, real_server * rs, char * vsgname) { virtual_server_group *vsg = ipvs_get_group_by_name(vsgname, vs_group); virtual_server_group_entry *vsg_entry; list l; element e; int err = 1; /* return if jointure fails */ if (!vsg) return -1; /* visit addr_ip list */ l = vsg->addr_ip; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { vsg_entry = ELEMENT_DATA(e); urule->vaddr = SVR_IP(vsg_entry); urule->vport = SVR_PORT(vsg_entry); /* Talk to the IPVS channel */ if (IPVS_ALIVE(cmd, vsg_entry, rs)) { err = ipvs_talk(cmd); IPVS_SET_ALIVE(cmd, vsg_entry); } } /* visit vfwmark list */ l = vsg->vfwmark; urule->vaddr = 0; urule->vport = 0; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { vsg_entry = ELEMENT_DATA(e); urule->vfwmark = vsg_entry->vfwmark; /* Talk to the IPVS channel */ if (IPVS_ALIVE(cmd, vsg_entry, rs)) { err = ipvs_talk(cmd); IPVS_SET_ALIVE(cmd, vsg_entry); } } /* visit range list */ l = vsg->range; urule->vfwmark = 0; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { vsg_entry = ELEMENT_DATA(e); /* Talk to the IPVS channel */ if (IPVS_ALIVE(cmd, vsg_entry, rs)) { err = ipvs_group_range_cmd(cmd, vsg_entry); IPVS_SET_ALIVE(cmd, vsg_entry); } } return err; }
/* Remove a specific vs group entry */ int ipvs_group_remove_entry(virtual_server *vs, virtual_server_group_entry *vsge) { real_server *rs; element e; list l = vs->rs; /* Clean target rules */ memset(srule, 0, sizeof (struct ip_vs_service_user)); memset(drule, 0, sizeof (struct ip_vs_dest_user)); /* Process realserver queue */ for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { rs = ELEMENT_DATA(e); if (rs->alive) { /* Prepare the IPVS rule */ if (!drule->addr) { /* Setting IPVS rule with vs root rs */ ipvs_set_rule(IP_VS_SO_SET_DELDEST, vs, rs); } else { drule->weight = rs->weight; drule->addr = SVR_IP(rs); drule->port = SVR_PORT(rs); } /* Set vs rule */ if (vsge->range) { ipvs_group_range_cmd(IP_VS_SO_SET_DELDEST, vsge); } else { srule->fwmark = vsge->vfwmark; srule->addr = SVR_IP(vsge); srule->port = SVR_PORT(vsge); drule->u_threshold = rs->u_threshold; drule->l_threshold = rs->l_threshold; /* Talk to the IPVS channel */ ipvs_talk(IP_VS_SO_SET_DELDEST); } } } /* Remove VS entry */ if (vsge->range) ipvs_group_range_cmd(IP_VS_SO_SET_DEL, vsge); else ipvs_talk(IP_VS_SO_SET_DEL); return IPVS_SUCCESS; }
/* IPVS group range rule */ static void ipvs_group_range_cmd(int cmd, virtual_server_group_entry *vsg_entry) { uint32_t addr_ip, ip; if (vsg_entry->addr.ss_family == AF_INET6) { inet_sockaddrip6(&vsg_entry->addr, &srule->addr.in6); ip = srule->addr.in6.s6_addr32[3]; } else { ip = inet_sockaddrip4(&vsg_entry->addr); } /* Set Address Family */ srule->af = vsg_entry->addr.ss_family; /* Parse the whole range */ for (addr_ip = ip; ((addr_ip >> 24) & 0xFF) <= vsg_entry->range; addr_ip += 0x01000000) { if (srule->af == AF_INET6) { if (srule->netmask == 0xffffffff) srule->netmask = 128; srule->addr.in6.s6_addr32[3] = addr_ip; } else { srule->addr.ip = addr_ip; } srule->port = inet_sockaddrport(&vsg_entry->addr); /* Talk to the IPVS channel */ ipvs_talk(cmd); } }
int ipvs_laddr_remove_entry(virtual_server *vs, local_addr_entry *laddr_entry) { memset(srule, 0, sizeof(ipvs_service_t)); srule->protocol = vs->service_type; if (vs->vsgname) { ipvs_rm_lentry_from_vsg(laddr_entry, vs->vsgname); } else if (!vs->vfwmark) { srule->af = vs->addr.ss_family; if (vs->addr.ss_family == AF_INET6) { srule->netmask = 128; inet_sockaddrip6(&vs->addr, &srule->addr.in6); } else { srule->netmask = 0xffffffff; srule->addr.ip = inet_sockaddrip4(&vs->addr); } srule->port = inet_sockaddrport(&vs->addr); if (laddr_entry->range) { ipvs_laddr_range_cmd(IP_VS_SO_SET_DELLADDR, laddr_entry); } else { memset(laddr_rule, 0, sizeof(ipvs_laddr_t)); laddr_rule->af = laddr_entry->addr.ss_family; if (laddr_entry->addr.ss_family == AF_INET6) inet_sockaddrip6(&laddr_entry->addr, &laddr_rule->addr.in6); else laddr_rule->addr.ip = inet_sockaddrip4(&laddr_entry->addr); ipvs_talk(IP_VS_SO_SET_DELLADDR); } } return IPVS_SUCCESS; }
static void ipvs_laddr_group_cmd(int cmd, local_addr_group *laddr_group) { local_addr_entry *laddr_entry; list l; element e; if (!laddr_group) return; l = laddr_group->addr_ip; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { laddr_entry = ELEMENT_DATA(e); memset(laddr_rule, 0, sizeof(ipvs_laddr_t)); laddr_rule->af = laddr_entry->addr.ss_family; if (laddr_entry->addr.ss_family == AF_INET6) inet_sockaddrip6(&laddr_entry->addr, &laddr_rule->addr.in6); else laddr_rule->addr.ip = inet_sockaddrip4(&laddr_entry->addr); ipvs_talk(cmd); } l = laddr_group->range; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { laddr_entry = ELEMENT_DATA(e); ipvs_laddr_range_cmd(cmd, laddr_entry); } }
/* Remove a specific vs group entry */ int ipvs_group_remove_entry(virtual_server *vs, virtual_server_group_entry *vsge) { real_server *rs; int err = 0; element e; list l = vs->rs; /* Clean target rules */ memset(urule, 0, sizeof (struct ip_vs_rule_user)); /* Process realserver queue */ for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { rs = ELEMENT_DATA(e); if (rs->alive) { /* Prepare the IPVS rule */ if (urule->daddr) { /* Setting IPVS rule with vs root rs */ ipvs_set_rule(IP_VS_SO_SET_DELDEST, vs, rs); } else { urule->weight = rs->weight; urule->daddr = SVR_IP(rs); urule->dport = SVR_PORT(rs); } /* Set vs rule */ if (vsge->range) { ipvs_group_range_cmd(IP_VS_SO_SET_DELDEST, vsge); } else { urule->vfwmark = vsge->vfwmark; urule->vaddr = SVR_IP(vsge); urule->vport = SVR_PORT(vsge); /* Talk to the IPVS channel */ err = ipvs_talk(IP_VS_SO_SET_DELDEST); } } } /* Remove VS entry */ if (vsge->range) err = ipvs_group_range_cmd(IP_VS_SO_SET_DEL, vsge); else err = ipvs_talk(IP_VS_SO_SET_DEL); return err; }
int ipvs_syncd_cmd(int cmd, char *ifname, int state, int syncid) { memset(daemonrule, 0, sizeof (struct ip_vs_daemon_user)); /* prepare user rule */ daemonrule->state = state; daemonrule->syncid = syncid; if (ifname != NULL) strncpy(daemonrule->mcast_ifn, ifname, IP_VS_IFNAME_MAXLEN); /* Talk to the IPVS channel */ ipvs_talk(cmd); return IPVS_SUCCESS; }
/* IPVS group range rule */ static void ipvs_group_range_cmd(int cmd, virtual_server_group_entry *vsg_entry) { uint32_t addr_ip; /* Parse the whole range */ for (addr_ip = SVR_IP(vsg_entry); ((addr_ip >> 24) & 0xFF) <= vsg_entry->range; addr_ip += 0x01000000) { srule->addr = addr_ip; srule->port = SVR_PORT(vsg_entry); /* Talk to the IPVS channel */ ipvs_talk(cmd); } }
/* Set/Remove a RS or a local address group from a VS */ int ipvs_cmd(int cmd, list vs_group, virtual_server * vs, real_server * rs) { /* Set/Remove local address */ if (cmd == IP_VS_SO_SET_ADDLADDR || cmd == IP_VS_SO_SET_DELLADDR) return ipvs_laddr_cmd(cmd, vs_group, vs); /* Allocate the room */ memset(srule, 0, sizeof(ipvs_service_t)); ipvs_set_rule(cmd, vs, rs); /* Does the service use inhibit flag ? */ if (cmd == IP_VS_SO_SET_DELDEST && rs->inhibit) { drule->weight = 0; cmd = IP_VS_SO_SET_EDITDEST; } if (cmd == IP_VS_SO_SET_ADDDEST && rs->inhibit && rs->set) cmd = IP_VS_SO_SET_EDITDEST; /* Set flag */ if (cmd == IP_VS_SO_SET_ADDDEST && !rs->set) rs->set = 1; if (cmd == IP_VS_SO_SET_DELDEST && rs->set) rs->set = 0; /* Set vs rule and send to kernel */ if (vs->vsgname) { ipvs_group_cmd(cmd, vs_group, rs, vs->vsgname); } else { if (vs->vfwmark) { srule->af = AF_INET; srule->fwmark = vs->vfwmark; } else { srule->af = vs->addr.ss_family; if (vs->addr.ss_family == AF_INET6) inet_sockaddrip6(&vs->addr, &srule->addr.in6); else srule->addr.ip = inet_sockaddrip4(&vs->addr); srule->port = inet_sockaddrport(&vs->addr); } /* Talk to the IPVS channel */ ipvs_talk(cmd); } return IPVS_SUCCESS; }
/* IPVS group range rule */ static int ipvs_group_range_cmd(int cmd, virtual_server_group_entry *vsg_entry) { uint32_t addr_ip; int err = 0; /* Parse the whole range */ for (addr_ip = SVR_IP(vsg_entry); ((addr_ip >> 24) & 0xFF) <= vsg_entry->range; addr_ip += 0x01000000) { urule->vaddr = addr_ip; urule->vport = SVR_PORT(vsg_entry); /* Talk to the IPVS channel */ err = ipvs_talk(cmd); } return err; }
int ipvs_syncd_cmd(int cmd, char *ifname, int state, int syncid) { #ifdef _HAVE_IPVS_SYNCD_ memset(urule, 0, sizeof (struct ip_vs_rule_user)); /* prepare user rule */ urule->state = state; urule->syncid = syncid; if (ifname != NULL) strncpy(urule->mcast_ifn, ifname, IP_VS_IFNAME_MAXLEN); /* Talk to the IPVS channel */ return ipvs_talk(cmd); #else log_message(LOG_INFO, "IPVS : Sync daemon not supported"); return IPVS_ERROR; #endif }
/* Set/Remove a RS from a VS */ int ipvs_cmd(int cmd, list vs_group, virtual_server * vs, real_server * rs) { int err = 0; /* Prepare target rule */ ipvs_set_rule(cmd, vs, rs); /* Does the service use inhibit flag ? */ if (cmd == IP_VS_SO_SET_DELDEST && rs->inhibit) { urule->weight = 0; cmd = IP_VS_SO_SET_EDITDEST; } if (cmd == IP_VS_SO_SET_ADDDEST && rs->inhibit && rs->set) cmd = IP_VS_SO_SET_EDITDEST; /* Set flag */ if (cmd == IP_VS_SO_SET_ADDDEST && !rs->set) rs->set = 1; if (cmd == IP_VS_SO_SET_DELDEST && rs->set) rs->set = 0; /* Set vs rule and send to kernel */ if (vs->vsgname) { err = ipvs_group_cmd(cmd, vs_group, rs, vs->vsgname); } else { if (vs->vfwmark) { urule->vfwmark = vs->vfwmark; } else { urule->vaddr = SVR_IP(vs); urule->vport = SVR_PORT(vs); } /* Talk to the IPVS channel */ err = ipvs_talk(cmd); } return err; }
/* Set/Remove a RS from a VS */ int ipvs_cmd(int cmd, list vs_group, virtual_server * vs, real_server * rs) { /* Allocate the room */ memset(srule, 0, sizeof (struct ip_vs_service_user)); ipvs_set_rule(cmd, vs, rs); /* Does the service use inhibit flag ? */ if (cmd == IP_VS_SO_SET_DELDEST && rs->inhibit) { drule->weight = 0; cmd = IP_VS_SO_SET_EDITDEST; } if (cmd == IP_VS_SO_SET_ADDDEST && rs->inhibit && rs->set) cmd = IP_VS_SO_SET_EDITDEST; /* Set flag */ if (cmd == IP_VS_SO_SET_ADDDEST && !rs->set) rs->set = 1; if (cmd == IP_VS_SO_SET_DELDEST && rs->set) rs->set = 0; /* Set vs rule and send to kernel */ if (vs->vsgname) { ipvs_group_cmd(cmd, vs_group, rs, vs->vsgname); } else { if (vs->vfwmark) { srule->fwmark = vs->vfwmark; } else { srule->addr = SVR_IP(vs); srule->port = SVR_PORT(vs); } /* Talk to the IPVS channel */ ipvs_talk(cmd); } return IPVS_SUCCESS; }
static void ipvs_laddr_range_cmd(int cmd, local_addr_entry *laddr_entry) { uint32_t addr_ip, ip; memset(laddr_rule, 0, sizeof(ipvs_laddr_t)); laddr_rule->af = laddr_entry->addr.ss_family; if (laddr_entry->addr.ss_family == AF_INET6) { inet_sockaddrip6(&laddr_entry->addr, &laddr_rule->addr.in6); ip = laddr_rule->addr.in6.s6_addr32[3]; } else { ip = inet_sockaddrip4(&laddr_entry->addr); } for (addr_ip = ip; ((addr_ip >> 24) & 0xFF) <= laddr_entry->range; addr_ip += 0x01000000) { if (laddr_entry->addr.ss_family == AF_INET6) laddr_rule->addr.in6.s6_addr32[3] = addr_ip; else laddr_rule->addr.ip = addr_ip; ipvs_talk(cmd); } }
static void ipvs_rm_lentry_from_vsg(local_addr_entry *laddr_entry, char *vsgname) { list l; element e; virtual_server_group *vsg; virtual_server_group_entry *vsg_entry; /* it's not old_check_data. help to ISALIVE check later */ vsg = ipvs_get_group_by_name(vsgname, check_data->vs_group); if (!vsg) return; l = vsg->addr_ip; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { vsg_entry = ELEMENT_DATA(e); if (!ISALIVE(vsg_entry)) continue; srule->af = vsg_entry->addr.ss_family; if (vsg_entry->addr.ss_family == AF_INET6) { srule->netmask = 128; inet_sockaddrip6(&vsg_entry->addr, &srule->addr.in6); } else { srule->netmask = 0xffffffff; srule->addr.ip = inet_sockaddrip4(&vsg_entry->addr); } srule->port = inet_sockaddrport(&vsg_entry->addr); if (laddr_entry->range) ipvs_laddr_range_cmd(IP_VS_SO_SET_DELLADDR, laddr_entry); else { memset(laddr_rule, 0, sizeof(ipvs_laddr_t)); laddr_rule->af = laddr_entry->addr.ss_family; if (laddr_entry->addr.ss_family == AF_INET6) inet_sockaddrip6(&laddr_entry->addr, &laddr_rule->addr.in6); else laddr_rule->addr.ip = inet_sockaddrip4(&laddr_entry->addr); ipvs_talk(IP_VS_SO_SET_DELLADDR); } } l = vsg->range; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { vsg_entry = ELEMENT_DATA(e); uint32_t addr_ip, ip; if (!ISALIVE(vsg_entry)) continue; srule->af = vsg_entry->addr.ss_family; srule->netmask = (vsg_entry->addr.ss_family == AF_INET6) ? 128 : ((u_int32_t) 0xffffffff); srule->port = inet_sockaddrport(&vsg_entry->addr); if (vsg_entry->addr.ss_family == AF_INET6) { inet_sockaddrip6(&vsg_entry->addr, &srule->addr.in6); ip = srule->addr.in6.s6_addr32[3]; } else { ip = inet_sockaddrip4(&vsg_entry->addr); } for (addr_ip = ip; ((addr_ip >> 24) & 0xFF) <= vsg_entry->range; addr_ip += 0x01000000) { if (srule->af == AF_INET6) srule->addr.in6.s6_addr32[3] = addr_ip; else srule->addr.ip = addr_ip; if (laddr_entry->range) ipvs_laddr_range_cmd(IP_VS_SO_SET_DELLADDR, laddr_entry); else { memset(laddr_rule, 0, sizeof(ipvs_laddr_t)); laddr_rule->af = laddr_entry->addr.ss_family; if (laddr_entry->addr.ss_family == AF_INET6) inet_sockaddrip6(&laddr_entry->addr, &laddr_rule->addr.in6); else laddr_rule->addr.ip = inet_sockaddrip4(&laddr_entry->addr); ipvs_talk(IP_VS_SO_SET_DELLADDR); } } } }
/* set IPVS group rules */ static void ipvs_group_cmd(int cmd, list vs_group, real_server * rs, char * vsgname) { virtual_server_group *vsg = ipvs_get_group_by_name(vsgname, vs_group); virtual_server_group_entry *vsg_entry; list l; element e; /* return if jointure fails */ if (!vsg) return; /* visit addr_ip list */ l = vsg->addr_ip; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { vsg_entry = ELEMENT_DATA(e); srule->af = vsg_entry->addr.ss_family; if (vsg_entry->addr.ss_family == AF_INET6) { if (srule->netmask == 0xffffffff) srule->netmask = 128; inet_sockaddrip6(&vsg_entry->addr, &srule->addr.in6); } else srule->addr.ip = inet_sockaddrip4(&vsg_entry->addr); srule->port = inet_sockaddrport(&vsg_entry->addr); /* Talk to the IPVS channel */ if (IPVS_ALIVE(cmd, vsg_entry, rs)) { ipvs_talk(cmd); IPVS_SET_ALIVE(cmd, vsg_entry); } } /* visit vfwmark list */ l = vsg->vfwmark; srule->addr.ip = 0; srule->af = 0; srule->port = 0; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { vsg_entry = ELEMENT_DATA(e); srule->af = AF_INET; srule->fwmark = vsg_entry->vfwmark; /* Talk to the IPVS channel */ if (IPVS_ALIVE(cmd, vsg_entry, rs)) { ipvs_talk(cmd); IPVS_SET_ALIVE(cmd, vsg_entry); } } /* visit range list */ l = vsg->range; srule->fwmark = 0; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { vsg_entry = ELEMENT_DATA(e); /* Talk to the IPVS channel */ if (IPVS_ALIVE(cmd, vsg_entry, rs)) { ipvs_group_range_cmd(cmd, vsg_entry); IPVS_SET_ALIVE(cmd, vsg_entry); } } }
/* Remove a specific vs group entry */ int ipvs_group_remove_entry(virtual_server *vs, virtual_server_group_entry *vsge) { real_server *rs; element e; list l = vs->rs; /* Clean target rules */ memset(srule, 0, sizeof(ipvs_service_t)); memset(drule, 0, sizeof(ipvs_dest_t)); /* Process realserver queue */ for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { rs = ELEMENT_DATA(e); if (rs->alive) { /* Prepare the IPVS rule */ if (!drule->addr.ip) { /* Setting IPVS rule with vs root rs */ ipvs_set_rule(IP_VS_SO_SET_DELDEST, vs, rs); } else { drule->af = rs->addr.ss_family; if (rs->addr.ss_family == AF_INET6) inet_sockaddrip6(&rs->addr, &drule->addr.in6); else drule->addr.ip = inet_sockaddrip4(&rs->addr); drule->port = inet_sockaddrport(&rs->addr); drule->weight = rs->weight; } /* Set vs rule */ if (vsge->range) { ipvs_group_range_cmd(IP_VS_SO_SET_DELDEST, vsge); } else { srule->af = vsge->addr.ss_family; if (vsge->addr.ss_family == AF_INET6) inet_sockaddrip6(&vsge->addr, &srule->addr.in6); else srule->addr.ip = inet_sockaddrip4(&vsge->addr); srule->port = inet_sockaddrport(&vsge->addr); srule->fwmark = vsge->vfwmark; drule->u_threshold = rs->u_threshold; drule->l_threshold = rs->l_threshold; /* Talk to the IPVS channel */ ipvs_talk(IP_VS_SO_SET_DELDEST); } } } /* In case of all rs is unalive */ ipvs_set_rule(IP_VS_SO_SET_DEL, vs, NULL); /* Remove VS entry */ if (vsge->range) ipvs_group_range_cmd(IP_VS_SO_SET_DEL, vsge); else { srule->af = vsge->addr.ss_family; if (vsge->addr.ss_family == AF_INET6) inet_sockaddrip6(&vsge->addr, &srule->addr.in6); else srule->addr.ip = inet_sockaddrip4(&vsge->addr); srule->port = inet_sockaddrport(&vsge->addr); srule->fwmark = vsge->vfwmark; ipvs_talk(IP_VS_SO_SET_DEL); } return IPVS_SUCCESS; }
void ipvs_new_laddr_add(virtual_server *vs, local_addr_group *laddr_group) { local_addr_entry *laddr_entry; list l; element e; /* the unalive vs will be set later*/ if (!vs->vsgname && !ISALIVE(vs)) return; memset(srule, 0, sizeof(ipvs_service_t)); srule->netmask = (vs->addr.ss_family == AF_INET6) ? 128 : ((u_int32_t) 0xffffffff); srule->protocol = vs->service_type; l = laddr_group->addr_ip; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { laddr_entry = ELEMENT_DATA(e); if (ISALIVE(laddr_entry)) continue; memset(laddr_rule, 0, sizeof(ipvs_laddr_t)); laddr_rule->af = laddr_entry->addr.ss_family; if (laddr_entry->addr.ss_family == AF_INET6) inet_sockaddrip6(&laddr_entry->addr, &laddr_rule->addr.in6); else laddr_rule->addr.ip = inet_sockaddrip4(&laddr_entry->addr); if (vs->vsgname) { ipvs_new_laddr_vsg(vs); } else { srule->af = vs->addr.ss_family; if (srule->af == AF_INET6) inet_sockaddrip6(&vs->addr, &srule->addr.in6); else srule->addr.ip = inet_sockaddrip4(&vs->addr); srule->port = inet_sockaddrport(&vs->addr); /* local address group channel */ ipvs_talk(IP_VS_SO_SET_ADDLADDR); } } l = laddr_group->range; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { laddr_entry = ELEMENT_DATA(e); uint32_t addr_ip, ip; if (ISALIVE(laddr_entry)) continue; memset(laddr_rule, 0, sizeof(ipvs_laddr_t)); laddr_rule->af = laddr_entry->addr.ss_family; if (laddr_entry->addr.ss_family == AF_INET6) { inet_sockaddrip6(&laddr_entry->addr, &laddr_rule->addr.in6); ip = laddr_rule->addr.in6.s6_addr32[3]; } else { ip = inet_sockaddrip4(&laddr_entry->addr); } for (addr_ip = ip; ((addr_ip >> 24) & 0xFF) <= laddr_entry->range; addr_ip += 0x01000000) { if (laddr_entry->addr.ss_family == AF_INET6) laddr_rule->addr.in6.s6_addr32[3] = addr_ip; else laddr_rule->addr.ip = addr_ip; if (vs->vsgname) { ipvs_new_laddr_vsg(vs); } else { srule->af = vs->addr.ss_family; if (srule->af == AF_INET6) inet_sockaddrip6(&vs->addr, &srule->addr.in6); else srule->addr.ip = inet_sockaddrip4(&vs->addr); srule->port = inet_sockaddrport(&vs->addr); /* local address group channel */ ipvs_talk(IP_VS_SO_SET_ADDLADDR); } } } }
static void ipvs_new_laddr_vsg(virtual_server *vs) { list l; element e; virtual_server_group *vsg; virtual_server_group_entry *vsg_entry; vsg = ipvs_get_group_by_name(vs->vsgname, check_data->vs_group); if (!vsg) return; /* visit addr_ip list */ l = vsg->addr_ip; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { vsg_entry = ELEMENT_DATA(e); /* will be set later */ if (!ISALIVE(vsg_entry)) continue; srule->af = vsg_entry->addr.ss_family; if (srule->af == AF_INET6) { if (srule->netmask == 0xffffffff) srule->netmask = 128; inet_sockaddrip6(&vsg_entry->addr, &srule->addr.in6); } else srule->addr.ip = inet_sockaddrip4(&vsg_entry->addr); srule->port = inet_sockaddrport(&vsg_entry->addr); /* local address group channel */ ipvs_talk(IP_VS_SO_SET_ADDLADDR); } /* visit range list */ l = vsg->range; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { vsg_entry = ELEMENT_DATA(e); uint32_t addr_ip, ip; /* will be set later */ if (!ISALIVE(vsg_entry)) continue; srule->af = vsg_entry->addr.ss_family; if (srule->af == AF_INET6) { inet_sockaddrip6(&vsg_entry->addr, &srule->addr.in6); ip = srule->addr.in6.s6_addr32[3]; } else { ip = inet_sockaddrip4(&vsg_entry->addr); } /* Parse the whole range */ for (addr_ip = ip; ((addr_ip >> 24) & 0xFF) <= vsg_entry->range; addr_ip += 0x01000000) { if (srule->af == AF_INET6) { if (srule->netmask == 0xffffffff) srule->netmask = 128; srule->addr.in6.s6_addr32[3] = addr_ip; } else { srule->addr.ip = addr_ip; } srule->port = inet_sockaddrport(&vsg_entry->addr); ipvs_talk(IP_VS_SO_SET_ADDLADDR); } } }