int ipvs_del_dest(ipvs_service_t *svc, ipvs_dest_t *dest) { ipvs_servicedest_t svcdest; ipvs_func = ipvs_del_dest; #ifdef LIBIPVS_USE_NL if (try_nl) { struct nl_msg *msg = ipvs_nl_message(IPVS_CMD_DEL_DEST, 0); if (!msg) return -1; if (ipvs_nl_fill_service_attr(msg, svc)) goto nla_put_failure; if (ipvs_nl_fill_dest_attr(msg, dest)) goto nla_put_failure; return ipvs_nl_send_message(msg, ipvs_nl_noop_cb, NULL); nla_put_failure: nlmsg_free(msg); return -1; } #endif CHECK_COMPAT_SVC(svc, -1); CHECK_COMPAT_DEST(dest, -1); memcpy(&svcdest.svc, svc, sizeof(svcdest.svc)); memcpy(&svcdest.dest, dest, sizeof(svcdest.dest)); return setsockopt(sockfd, IPPROTO_IP, IP_VS_SO_SET_DELDEST, (char *)&svcdest, sizeof(svcdest)); out_err: return -1; }
int ipvs_zero_service(ipvs_service_t *svc) { ipvs_func = ipvs_zero_service; #ifdef LIBIPVS_USE_NL if (try_nl) { struct nl_msg *msg = ipvs_nl_message(IPVS_CMD_ZERO, 0); if (!msg) return -1; if (svc->fwmark || memcmp(&in6addr_any, &svc->addr.in6, sizeof(struct in6_addr)) || svc->port) { if (ipvs_nl_fill_service_attr(msg, svc)) { nlmsg_free(msg); return -1; } } return ipvs_nl_send_message(msg, ipvs_nl_noop_cb, NULL); } #endif CHECK_COMPAT_SVC(svc, -1); return setsockopt(sockfd, IPPROTO_IP, IP_VS_SO_SET_ZERO, (char *)svc, sizeof(struct ip_vs_service_kern)); out_err: return -1; }
static int ipvs_nl_fill_service_attr(struct nl_msg *msg, ipvs_service_t *svc) { struct nlattr *nl_service; struct ip_vs_flags flags = { .flags = svc->flags, .mask = ~0 }; nl_service = nla_nest_start(msg, IPVS_CMD_ATTR_SERVICE); if (!nl_service) return -1; NLA_PUT_U16(msg, IPVS_SVC_ATTR_AF, svc->af); if (svc->fwmark) { NLA_PUT_U32(msg, IPVS_SVC_ATTR_FWMARK, svc->fwmark); } else { NLA_PUT_U16(msg, IPVS_SVC_ATTR_PROTOCOL, svc->protocol); NLA_PUT(msg, IPVS_SVC_ATTR_ADDR, sizeof(svc->addr), &(svc->addr)); NLA_PUT_U16(msg, IPVS_SVC_ATTR_PORT, svc->port); } NLA_PUT_STRING(msg, IPVS_SVC_ATTR_SCHED_NAME, svc->sched_name); if (svc->pe_name[0]) NLA_PUT_STRING(msg, IPVS_SVC_ATTR_PE_NAME, svc->pe_name); NLA_PUT(msg, IPVS_SVC_ATTR_FLAGS, sizeof(flags), &flags); NLA_PUT_U32(msg, IPVS_SVC_ATTR_TIMEOUT, svc->timeout); NLA_PUT_U32(msg, IPVS_SVC_ATTR_NETMASK, svc->netmask); nla_nest_end(msg, nl_service); return 0; nla_put_failure: return -1; } #endif int ipvs_add_service(ipvs_service_t *svc) { ipvs_func = ipvs_add_service; #ifdef LIBIPVS_USE_NL if (try_nl) { struct nl_msg *msg = ipvs_nl_message(IPVS_CMD_NEW_SERVICE, 0); if (!msg) return -1; if (ipvs_nl_fill_service_attr(msg, svc)) { nlmsg_free(msg); return -1; } return ipvs_nl_send_message(msg, ipvs_nl_noop_cb, NULL); } #endif CHECK_COMPAT_SVC(svc, -1); return setsockopt(sockfd, IPPROTO_IP, IP_VS_SO_SET_ADD, (char *)svc, sizeof(struct ip_vs_service_kern)); out_err: return -1; }
int ipvs_del_service(ipvs_service_t *svc) { ipvs_func = ipvs_del_service; #ifdef LIBIPVS_USE_NL if (try_nl) { struct nl_msg *msg = ipvs_nl_message(IPVS_CMD_DEL_SERVICE, 0); if (!msg) return -1; if (ipvs_nl_fill_service_attr(msg, svc)) { nlmsg_free(msg); return -1; } return ipvs_nl_send_message(msg, ipvs_nl_noop_cb, NULL); } #endif CHECK_COMPAT_SVC(svc, -1); return setsockopt(sockfd, IPPROTO_IP, IP_VS_SO_SET_DEL, (char *)svc, sizeof(struct ip_vs_service_kern)); }
ipvs_service_entry_t * ipvs_get_service(u_int32_t fwmark, u_int16_t af, u_int16_t protocol, union nf_inet_addr addr, u_int16_t port) { ipvs_service_entry_t *svc; socklen_t len; ipvs_func = ipvs_get_service; #ifdef LIBIPVS_USE_NL if (try_nl) { struct ip_vs_get_services *get; struct nl_msg *msg; ipvs_service_t tsvc; svc = malloc(sizeof(*svc)); if (!svc) return NULL; tsvc.fwmark = fwmark; tsvc.af = af; tsvc.protocol= protocol; tsvc.addr = addr; tsvc.port = port; if (!(get = malloc(sizeof(*get) + sizeof(ipvs_service_entry_t)))) goto ipvs_get_service_err2; get->num_services = 0; msg = ipvs_nl_message(IPVS_CMD_GET_SERVICE, 0); if (!msg) goto ipvs_get_service_err; if (ipvs_nl_fill_service_attr(msg, &tsvc)) goto nla_put_failure; if (ipvs_nl_send_message(msg, ipvs_services_parse_cb, &get)) goto ipvs_get_service_err; memcpy(svc, &(get->entrytable[0]), sizeof(*svc)); free(get); return svc; nla_put_failure: nlmsg_free(msg); ipvs_get_service_err: free(get); ipvs_get_service_err2: free(svc); return NULL; } #endif len = sizeof(*svc); svc = calloc(1, len); if (!svc) return NULL; svc->fwmark = fwmark; svc->af = af; svc->protocol = protocol; svc->addr = addr; svc->port = port; CHECK_COMPAT_SVC(svc, NULL); if (getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_SERVICE, (char *)svc, &len)) { free(svc); return NULL; } svc->af = AF_INET; svc->addr.ip = svc->__addr_v4; svc->pe_name[0] = '\0'; return svc; out_err: free(svc); return NULL; }