Commit 0b0dc0f1 authored by David S. Miller's avatar David S. Miller
parents 0553c891 a8a8a093
...@@ -343,6 +343,10 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -343,6 +343,10 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct ipmac data; struct ipmac data;
/* MAC can be src only */
if (!(flags & IPSET_DIM_TWO_SRC))
return 0;
data.id = ntohl(ip4addr(skb, flags & IPSET_DIM_ONE_SRC)); data.id = ntohl(ip4addr(skb, flags & IPSET_DIM_ONE_SRC));
if (data.id < map->first_ip || data.id > map->last_ip) if (data.id < map->first_ip || data.id > map->last_ip)
return -IPSET_ERR_BITMAP_RANGE; return -IPSET_ERR_BITMAP_RANGE;
......
...@@ -1022,8 +1022,9 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -1022,8 +1022,9 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
if (cb->args[1] >= ip_set_max) if (cb->args[1] >= ip_set_max)
goto out; goto out;
pr_debug("args[0]: %ld args[1]: %ld\n", cb->args[0], cb->args[1]);
max = cb->args[0] == DUMP_ONE ? cb->args[1] + 1 : ip_set_max; max = cb->args[0] == DUMP_ONE ? cb->args[1] + 1 : ip_set_max;
dump_last:
pr_debug("args[0]: %ld args[1]: %ld\n", cb->args[0], cb->args[1]);
for (; cb->args[1] < max; cb->args[1]++) { for (; cb->args[1] < max; cb->args[1]++) {
index = (ip_set_id_t) cb->args[1]; index = (ip_set_id_t) cb->args[1];
set = ip_set_list[index]; set = ip_set_list[index];
...@@ -1038,8 +1039,8 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -1038,8 +1039,8 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
* so that lists (unions of sets) are dumped last. * so that lists (unions of sets) are dumped last.
*/ */
if (cb->args[0] != DUMP_ONE && if (cb->args[0] != DUMP_ONE &&
!((cb->args[0] == DUMP_ALL) ^ ((cb->args[0] == DUMP_ALL) ==
(set->type->features & IPSET_DUMP_LAST))) !!(set->type->features & IPSET_DUMP_LAST)))
continue; continue;
pr_debug("List set: %s\n", set->name); pr_debug("List set: %s\n", set->name);
if (!cb->args[2]) { if (!cb->args[2]) {
...@@ -1083,6 +1084,12 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -1083,6 +1084,12 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
goto release_refcount; goto release_refcount;
} }
} }
/* If we dump all sets, continue with dumping last ones */
if (cb->args[0] == DUMP_ALL) {
cb->args[0] = DUMP_LAST;
cb->args[1] = 0;
goto dump_last;
}
goto out; goto out;
nla_put_failure: nla_put_failure:
...@@ -1093,11 +1100,6 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -1093,11 +1100,6 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
pr_debug("release set %s\n", ip_set_list[index]->name); pr_debug("release set %s\n", ip_set_list[index]->name);
ip_set_put_byindex(index); ip_set_put_byindex(index);
} }
/* If we dump all sets, continue with dumping last ones */
if (cb->args[0] == DUMP_ALL && cb->args[1] >= max && !cb->args[2])
cb->args[0] = DUMP_LAST;
out: out:
if (nlh) { if (nlh) {
nlmsg_end(skb, nlh); nlmsg_end(skb, nlh);
......
...@@ -81,6 +81,7 @@ set_match_v0_checkentry(const struct xt_mtchk_param *par) ...@@ -81,6 +81,7 @@ set_match_v0_checkentry(const struct xt_mtchk_param *par)
if (info->match_set.u.flags[IPSET_DIM_MAX-1] != 0) { if (info->match_set.u.flags[IPSET_DIM_MAX-1] != 0) {
pr_warning("Protocol error: set match dimension " pr_warning("Protocol error: set match dimension "
"is over the limit!\n"); "is over the limit!\n");
ip_set_nfnl_put(info->match_set.index);
return -ERANGE; return -ERANGE;
} }
...@@ -135,6 +136,8 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par) ...@@ -135,6 +136,8 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par)
if (index == IPSET_INVALID_ID) { if (index == IPSET_INVALID_ID) {
pr_warning("Cannot find del_set index %u as target\n", pr_warning("Cannot find del_set index %u as target\n",
info->del_set.index); info->del_set.index);
if (info->add_set.index != IPSET_INVALID_ID)
ip_set_nfnl_put(info->add_set.index);
return -ENOENT; return -ENOENT;
} }
} }
...@@ -142,6 +145,10 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par) ...@@ -142,6 +145,10 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par)
info->del_set.u.flags[IPSET_DIM_MAX-1] != 0) { info->del_set.u.flags[IPSET_DIM_MAX-1] != 0) {
pr_warning("Protocol error: SET target dimension " pr_warning("Protocol error: SET target dimension "
"is over the limit!\n"); "is over the limit!\n");
if (info->add_set.index != IPSET_INVALID_ID)
ip_set_nfnl_put(info->add_set.index);
if (info->del_set.index != IPSET_INVALID_ID)
ip_set_nfnl_put(info->del_set.index);
return -ERANGE; return -ERANGE;
} }
...@@ -192,6 +199,7 @@ set_match_checkentry(const struct xt_mtchk_param *par) ...@@ -192,6 +199,7 @@ set_match_checkentry(const struct xt_mtchk_param *par)
if (info->match_set.dim > IPSET_DIM_MAX) { if (info->match_set.dim > IPSET_DIM_MAX) {
pr_warning("Protocol error: set match dimension " pr_warning("Protocol error: set match dimension "
"is over the limit!\n"); "is over the limit!\n");
ip_set_nfnl_put(info->match_set.index);
return -ERANGE; return -ERANGE;
} }
...@@ -219,7 +227,7 @@ set_target(struct sk_buff *skb, const struct xt_action_param *par) ...@@ -219,7 +227,7 @@ set_target(struct sk_buff *skb, const struct xt_action_param *par)
if (info->del_set.index != IPSET_INVALID_ID) if (info->del_set.index != IPSET_INVALID_ID)
ip_set_del(info->del_set.index, ip_set_del(info->del_set.index,
skb, par->family, skb, par->family,
info->add_set.dim, info->del_set.dim,
info->del_set.flags); info->del_set.flags);
return XT_CONTINUE; return XT_CONTINUE;
...@@ -245,13 +253,19 @@ set_target_checkentry(const struct xt_tgchk_param *par) ...@@ -245,13 +253,19 @@ set_target_checkentry(const struct xt_tgchk_param *par)
if (index == IPSET_INVALID_ID) { if (index == IPSET_INVALID_ID) {
pr_warning("Cannot find del_set index %u as target\n", pr_warning("Cannot find del_set index %u as target\n",
info->del_set.index); info->del_set.index);
if (info->add_set.index != IPSET_INVALID_ID)
ip_set_nfnl_put(info->add_set.index);
return -ENOENT; return -ENOENT;
} }
} }
if (info->add_set.dim > IPSET_DIM_MAX || if (info->add_set.dim > IPSET_DIM_MAX ||
info->del_set.flags > IPSET_DIM_MAX) { info->del_set.dim > IPSET_DIM_MAX) {
pr_warning("Protocol error: SET target dimension " pr_warning("Protocol error: SET target dimension "
"is over the limit!\n"); "is over the limit!\n");
if (info->add_set.index != IPSET_INVALID_ID)
ip_set_nfnl_put(info->add_set.index);
if (info->del_set.index != IPSET_INVALID_ID)
ip_set_nfnl_put(info->del_set.index);
return -ERANGE; return -ERANGE;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment