/* 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; }
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); } } } }
static void ipvs_laddr_vsg_cmd(int cmd, list vs_group, virtual_server * vs, local_addr_group *laddr_group) { virtual_server_group *vsg = ipvs_get_group_by_name(vs->vsgname, vs_group); virtual_server_group_entry *vsg_entry; list l; element e; 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); /* reloading may make laddr_set true */ if (vsg_entry->laddr_set && (cmd == IP_VS_SO_SET_ADDLADDR)) continue; vsg_entry->laddr_set = (cmd == IP_VS_SO_SET_ADDLADDR) ? 1:0; 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_laddr_group_cmd(cmd, laddr_group); } /* 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; if (vsg_entry->laddr_set && (cmd == IP_VS_SO_SET_ADDLADDR)) continue; vsg_entry->laddr_set = (cmd == IP_VS_SO_SET_ADDLADDR) ? 1:0; 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_laddr_group_cmd(cmd, laddr_group); } } }
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); } } }
/* 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); } } }