/* 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; }
/* 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; }
/* 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; }
/* 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; }