static int ipvs_dests_parse_cb(struct nl_msg *msg, void *arg) { struct nlmsghdr *nlh = nlmsg_hdr(msg); struct nlattr *attrs[IPVS_CMD_ATTR_MAX + 1]; struct nlattr *dest_attrs[IPVS_DEST_ATTR_MAX + 1]; struct nlattr *attr_addr_family = NULL; struct ip_vs_get_dests **dp = (struct ip_vs_get_dests **)arg; struct ip_vs_get_dests *d = (struct ip_vs_get_dests *)*dp; int i = d->num_dests; if (genlmsg_parse(nlh, 0, attrs, IPVS_CMD_ATTR_MAX, ipvs_cmd_policy) != 0) return -1; if (!attrs[IPVS_CMD_ATTR_DEST]) return -1; if (nla_parse_nested(dest_attrs, IPVS_DEST_ATTR_MAX, attrs[IPVS_CMD_ATTR_DEST], ipvs_dest_policy)) return -1; memset(&(d->entrytable[i]), 0, sizeof(d->entrytable[i])); if (!(dest_attrs[IPVS_DEST_ATTR_ADDR] && dest_attrs[IPVS_DEST_ATTR_PORT] && dest_attrs[IPVS_DEST_ATTR_FWD_METHOD] && dest_attrs[IPVS_DEST_ATTR_WEIGHT] && dest_attrs[IPVS_DEST_ATTR_U_THRESH] && dest_attrs[IPVS_DEST_ATTR_L_THRESH] && dest_attrs[IPVS_DEST_ATTR_ACTIVE_CONNS] && dest_attrs[IPVS_DEST_ATTR_INACT_CONNS] && dest_attrs[IPVS_DEST_ATTR_PERSIST_CONNS])) return -1; memcpy(&(d->entrytable[i].addr), nla_data(dest_attrs[IPVS_DEST_ATTR_ADDR]), sizeof(d->entrytable[i].addr)); d->entrytable[i].port = nla_get_u16(dest_attrs[IPVS_DEST_ATTR_PORT]); d->entrytable[i].conn_flags = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_FWD_METHOD]); d->entrytable[i].weight = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_WEIGHT]); d->entrytable[i].u_threshold = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_U_THRESH]); d->entrytable[i].l_threshold = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_L_THRESH]); d->entrytable[i].activeconns = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_ACTIVE_CONNS]); d->entrytable[i].inactconns = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_INACT_CONNS]); d->entrytable[i].persistconns = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_PERSIST_CONNS]); attr_addr_family = dest_attrs[IPVS_DEST_ATTR_ADDR_FAMILY]; if (attr_addr_family) d->entrytable[i].af = nla_get_u16(attr_addr_family); else d->entrytable[i].af = d->af; if (ipvs_parse_stats(&(d->entrytable[i].stats), dest_attrs[IPVS_DEST_ATTR_STATS]) != 0) return -1; i++; d->num_dests = i; d = realloc(d, sizeof(*d) + sizeof(ipvs_dest_entry_t) * (d->num_dests + 1)); *dp = d; return 0; }
static int ipvs_services_parse_cb(struct nl_msg *msg, void *arg) { struct nlmsghdr *nlh = nlmsg_hdr(msg); struct nlattr *attrs[IPVS_CMD_ATTR_MAX + 1]; struct nlattr *svc_attrs[IPVS_SVC_ATTR_MAX + 1]; struct ip_vs_get_services **getp = (struct ip_vs_get_services **)arg; struct ip_vs_get_services *get = (struct ip_vs_get_services *)*getp; struct ip_vs_flags flags; int i = get->num_services; if (genlmsg_parse(nlh, 0, attrs, IPVS_CMD_ATTR_MAX, ipvs_cmd_policy) != 0) return -1; if (!attrs[IPVS_CMD_ATTR_SERVICE]) return -1; if (nla_parse_nested(svc_attrs, IPVS_SVC_ATTR_MAX, attrs[IPVS_CMD_ATTR_SERVICE], ipvs_service_policy)) return -1; memset(&(get->entrytable[i]), 0, sizeof(get->entrytable[i])); if (!(svc_attrs[IPVS_SVC_ATTR_AF] && (svc_attrs[IPVS_SVC_ATTR_FWMARK] || (svc_attrs[IPVS_SVC_ATTR_PROTOCOL] && svc_attrs[IPVS_SVC_ATTR_ADDR] && svc_attrs[IPVS_SVC_ATTR_PORT])) && svc_attrs[IPVS_SVC_ATTR_SCHED_NAME] && svc_attrs[IPVS_SVC_ATTR_NETMASK] && svc_attrs[IPVS_SVC_ATTR_TIMEOUT] && svc_attrs[IPVS_SVC_ATTR_FLAGS])) return -1; get->entrytable[i].af = nla_get_u16(svc_attrs[IPVS_SVC_ATTR_AF]); if (svc_attrs[IPVS_SVC_ATTR_FWMARK]) get->entrytable[i].fwmark = nla_get_u32(svc_attrs[IPVS_SVC_ATTR_FWMARK]); else { get->entrytable[i].protocol = nla_get_u16(svc_attrs[IPVS_SVC_ATTR_PROTOCOL]); memcpy(&(get->entrytable[i].addr), nla_data(svc_attrs[IPVS_SVC_ATTR_ADDR]), sizeof(get->entrytable[i].addr)); get->entrytable[i].port = nla_get_u16(svc_attrs[IPVS_SVC_ATTR_PORT]); } strncpy(get->entrytable[i].sched_name, nla_get_string(svc_attrs[IPVS_SVC_ATTR_SCHED_NAME]), IP_VS_SCHEDNAME_MAXLEN); if (svc_attrs[IPVS_SVC_ATTR_PE_NAME]) strncpy(get->entrytable[i].pe_name, nla_get_string(svc_attrs[IPVS_SVC_ATTR_PE_NAME]), IP_VS_PENAME_MAXLEN); get->entrytable[i].netmask = nla_get_u32(svc_attrs[IPVS_SVC_ATTR_NETMASK]); get->entrytable[i].timeout = nla_get_u32(svc_attrs[IPVS_SVC_ATTR_TIMEOUT]); nla_memcpy(&flags, svc_attrs[IPVS_SVC_ATTR_FLAGS], sizeof(flags)); get->entrytable[i].flags = flags.flags & flags.mask; if (ipvs_parse_stats(&(get->entrytable[i].stats), svc_attrs[IPVS_SVC_ATTR_STATS]) != 0) return -1; get->entrytable[i].num_dests = 0; i++; get->num_services = i; get = realloc(get, sizeof(*get) + sizeof(ipvs_service_entry_t) * (get->num_services + 1)); *getp = get; return 0; }