static int list_set_list(const struct ip_set *set, struct sk_buff *skb, struct netlink_callback *cb) { const struct list_set *map = set->data; struct nlattr *atd, *nested; u32 i, first = cb->args[2]; const struct set_elem *e; atd = ipset_nest_start(skb, IPSET_ATTR_ADT); if (!atd) return -EMSGSIZE; for (; cb->args[2] < map->size; cb->args[2]++) { i = cb->args[2]; e = list_set_elem(map, i); if (e->id == IPSET_INVALID_ID) goto finish; if (with_timeout(map->timeout) && list_set_expired(map, i)) continue; nested = ipset_nest_start(skb, IPSET_ATTR_DATA); if (!nested) { if (i == first) { nla_nest_cancel(skb, atd); return -EMSGSIZE; } else goto nla_put_failure; } if (nla_put_string(skb, IPSET_ATTR_NAME, ip_set_name_byindex(e->id))) goto nla_put_failure; if (with_timeout(map->timeout)) { const struct set_telem *te = (const struct set_telem *) e; __be32 to = htonl(ip_set_timeout_get(te->timeout)); if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT, to)) goto nla_put_failure; } ipset_nest_end(skb, nested); } finish: ipset_nest_end(skb, atd); /* Set listing finished */ cb->args[2] = 0; return 0; nla_put_failure: nla_nest_cancel(skb, nested); ipset_nest_end(skb, atd); if (unlikely(i == first)) { cb->args[2] = 0; return -EMSGSIZE; } return 0; }
static int bitmap_ipmac_tlist(const struct ip_set *set, struct sk_buff *skb, struct netlink_callback *cb) { const struct bitmap_ipmac *map = set->data; const struct ipmac_telem *elem; struct nlattr *atd, *nested; u32 id, first = cb->args[2]; u32 timeout, last = map->last_ip - map->first_ip; atd = ipset_nest_start(skb, IPSET_ATTR_ADT); if (!atd) return -EMSGSIZE; for (; cb->args[2] <= last; cb->args[2]++) { id = cb->args[2]; elem = bitmap_ipmac_elem(map, id); if (!bitmap_ipmac_exist(elem)) continue; nested = ipset_nest_start(skb, IPSET_ATTR_DATA); if (!nested) { if (id == first) { nla_nest_cancel(skb, atd); return -EMSGSIZE; } else goto nla_put_failure; } if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, htonl(map->first_ip + id)) || (elem->match == MAC_FILLED && nla_put(skb, IPSET_ATTR_ETHER, ETH_ALEN, elem->ether))) goto nla_put_failure; timeout = elem->match == MAC_UNSET ? elem->timeout : ip_set_timeout_get(elem->timeout); if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(timeout))) goto nla_put_failure; ipset_nest_end(skb, nested); } ipset_nest_end(skb, atd); /* Set listing finished */ cb->args[2] = 0; return 0; nla_put_failure: nla_nest_cancel(skb, nested); ipset_nest_end(skb, atd); if (unlikely(id == first)) { cb->args[2] = 0; return -EMSGSIZE; } return 0; }
static bool hash_ip6_data_tlist(struct sk_buff *skb, const struct hash_ip6_elem *data) { const struct hash_ip6_telem *e = (const struct hash_ip6_telem *)data; NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip); NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(ip_set_timeout_get(e->timeout))); return 0; nla_put_failure: return 1; }
static bool hash_net4_data_tlist(struct sk_buff *skb, const struct hash_net4_elem *data) { const struct hash_net4_telem *tdata = (const struct hash_net4_telem *)data; NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip); NLA_PUT_U8(skb, IPSET_ATTR_CIDR, tdata->cidr); NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(ip_set_timeout_get(tdata->timeout))); return 0; nla_put_failure: return 1; }
static int bitmap_port_tlist(const struct ip_set *set, struct sk_buff *skb, struct netlink_callback *cb) { const struct bitmap_port *map = set->data; struct nlattr *adt, *nested; u16 id, first = cb->args[2]; u16 last = map->last_port - map->first_port; const unsigned long *members = map->members; adt = ipset_nest_start(skb, IPSET_ATTR_ADT); if (!adt) return -EMSGSIZE; for (; cb->args[2] <= last; cb->args[2]++) { id = cb->args[2]; if (!ip_set_timeout_test(members[id])) continue; nested = ipset_nest_start(skb, IPSET_ATTR_DATA); if (!nested) { if (id == first) { nla_nest_cancel(skb, adt); return -EMSGSIZE; } else goto nla_put_failure; } NLA_PUT_NET16(skb, IPSET_ATTR_PORT, htons(map->first_port + id)); NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(ip_set_timeout_get(members[id]))); ipset_nest_end(skb, nested); } ipset_nest_end(skb, adt); /* Set listing finished */ cb->args[2] = 0; return 0; nla_put_failure: nla_nest_cancel(skb, nested); ipset_nest_end(skb, adt); if (unlikely(id == first)) { cb->args[2] = 0; return -EMSGSIZE; } return 0; }
static bool hash_ipport6_data_tlist(struct sk_buff *skb, const struct hash_ipport6_elem *data) { const struct hash_ipport6_telem *e = (const struct hash_ipport6_telem *)data; if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) || nla_put_net16(skb, IPSET_ATTR_PORT, data->port) || nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) || nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(ip_set_timeout_get(e->timeout)))) goto nla_put_failure; return 0; nla_put_failure: return 1; }
static bool hash_ipport4_data_tlist(struct sk_buff *skb, const struct hash_ipport4_elem *data) { const struct hash_ipport4_telem *tdata = (const struct hash_ipport4_telem *)data; NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip); NLA_PUT_NET16(skb, IPSET_ATTR_PORT, tdata->port); NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto); NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(ip_set_timeout_get(tdata->timeout))); return 0; nla_put_failure: return 1; }
static bool hash_net6_data_tlist(struct sk_buff *skb, const struct hash_net6_elem *data) { const struct hash_net6_telem *e = (const struct hash_net6_telem *)data; u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0; if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) || nla_put_u8(skb, IPSET_ATTR_CIDR, e->cidr) || nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(ip_set_timeout_get(e->timeout))) || (flags && nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags)))) goto nla_put_failure; return 0; nla_put_failure: return 1; }