diff options
| author | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2013-09-30 01:49:47 -0400 |
|---|---|---|
| committer | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2013-09-30 15:33:26 -0400 |
| commit | bd3129fc5e8868df74ffa803c7fec527976bbf1c (patch) | |
| tree | f437934fa8074b889f4cdfd0f3ac3e1a4ebc3a16 | |
| parent | 60b0fe372499f66e0c965dc0594320438a3b711c (diff) | |
netfilter: ipset: order matches and targets separatedly in xt_set.c
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
| -rw-r--r-- | net/netfilter/xt_set.c | 188 |
1 files changed, 96 insertions, 92 deletions
diff --git a/net/netfilter/xt_set.c b/net/netfilter/xt_set.c index 31790e789e22..2095488684ff 100644 --- a/net/netfilter/xt_set.c +++ b/net/netfilter/xt_set.c | |||
| @@ -109,6 +109,101 @@ set_match_v0_destroy(const struct xt_mtdtor_param *par) | |||
| 109 | ip_set_nfnl_put(info->match_set.index); | 109 | ip_set_nfnl_put(info->match_set.index); |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | /* Revision 1 match */ | ||
| 113 | |||
| 114 | static bool | ||
| 115 | set_match_v1(const struct sk_buff *skb, struct xt_action_param *par) | ||
| 116 | { | ||
| 117 | const struct xt_set_info_match_v1 *info = par->matchinfo; | ||
| 118 | ADT_OPT(opt, par->family, info->match_set.dim, | ||
| 119 | info->match_set.flags, 0, UINT_MAX); | ||
| 120 | |||
| 121 | if (opt.flags & IPSET_RETURN_NOMATCH) | ||
| 122 | opt.cmdflags |= IPSET_FLAG_RETURN_NOMATCH; | ||
| 123 | |||
| 124 | return match_set(info->match_set.index, skb, par, &opt, | ||
| 125 | info->match_set.flags & IPSET_INV_MATCH); | ||
| 126 | } | ||
| 127 | |||
| 128 | static int | ||
| 129 | set_match_v1_checkentry(const struct xt_mtchk_param *par) | ||
| 130 | { | ||
| 131 | struct xt_set_info_match_v1 *info = par->matchinfo; | ||
| 132 | ip_set_id_t index; | ||
| 133 | |||
| 134 | index = ip_set_nfnl_get_byindex(info->match_set.index); | ||
| 135 | |||
| 136 | if (index == IPSET_INVALID_ID) { | ||
| 137 | pr_warning("Cannot find set indentified by id %u to match\n", | ||
| 138 | info->match_set.index); | ||
| 139 | return -ENOENT; | ||
| 140 | } | ||
| 141 | if (info->match_set.dim > IPSET_DIM_MAX) { | ||
| 142 | pr_warning("Protocol error: set match dimension " | ||
| 143 | "is over the limit!\n"); | ||
| 144 | ip_set_nfnl_put(info->match_set.index); | ||
| 145 | return -ERANGE; | ||
| 146 | } | ||
| 147 | |||
| 148 | return 0; | ||
| 149 | } | ||
| 150 | |||
| 151 | static void | ||
| 152 | set_match_v1_destroy(const struct xt_mtdtor_param *par) | ||
| 153 | { | ||
| 154 | struct xt_set_info_match_v1 *info = par->matchinfo; | ||
| 155 | |||
| 156 | ip_set_nfnl_put(info->match_set.index); | ||
| 157 | } | ||
| 158 | |||
| 159 | /* Revision 3 match */ | ||
| 160 | |||
| 161 | static bool | ||
| 162 | match_counter(u64 counter, const struct ip_set_counter_match *info) | ||
| 163 | { | ||
| 164 | switch (info->op) { | ||
| 165 | case IPSET_COUNTER_NONE: | ||
| 166 | return true; | ||
| 167 | case IPSET_COUNTER_EQ: | ||
| 168 | return counter == info->value; | ||
| 169 | case IPSET_COUNTER_NE: | ||
| 170 | return counter != info->value; | ||
| 171 | case IPSET_COUNTER_LT: | ||
| 172 | return counter < info->value; | ||
| 173 | case IPSET_COUNTER_GT: | ||
| 174 | return counter > info->value; | ||
| 175 | } | ||
| 176 | return false; | ||
| 177 | } | ||
| 178 | |||
| 179 | static bool | ||
| 180 | set_match_v3(const struct sk_buff *skb, struct xt_action_param *par) | ||
| 181 | { | ||
| 182 | const struct xt_set_info_match_v3 *info = par->matchinfo; | ||
| 183 | ADT_OPT(opt, par->family, info->match_set.dim, | ||
| 184 | info->match_set.flags, info->flags, UINT_MAX); | ||
| 185 | int ret; | ||
| 186 | |||
| 187 | if (info->packets.op != IPSET_COUNTER_NONE || | ||
| 188 | info->bytes.op != IPSET_COUNTER_NONE) | ||
| 189 | opt.cmdflags |= IPSET_FLAG_MATCH_COUNTERS; | ||
| 190 | |||
| 191 | ret = match_set(info->match_set.index, skb, par, &opt, | ||
| 192 | info->match_set.flags & IPSET_INV_MATCH); | ||
| 193 | |||
| 194 | if (!(ret && opt.cmdflags & IPSET_FLAG_MATCH_COUNTERS)) | ||
| 195 | return ret; | ||
| 196 | |||
| 197 | if (!match_counter(opt.ext.packets, &info->packets)) | ||
| 198 | return 0; | ||
| 199 | return match_counter(opt.ext.bytes, &info->bytes); | ||
| 200 | } | ||
| 201 | |||
| 202 | #define set_match_v3_checkentry set_match_v1_checkentry | ||
| 203 | #define set_match_v3_destroy set_match_v1_destroy | ||
| 204 | |||
| 205 | /* Revision 0 interface: backward compatible with netfilter/iptables */ | ||
| 206 | |||
| 112 | static unsigned int | 207 | static unsigned int |
| 113 | set_target_v0(struct sk_buff *skb, const struct xt_action_param *par) | 208 | set_target_v0(struct sk_buff *skb, const struct xt_action_param *par) |
| 114 | { | 209 | { |
| @@ -180,52 +275,7 @@ set_target_v0_destroy(const struct xt_tgdtor_param *par) | |||
| 180 | ip_set_nfnl_put(info->del_set.index); | 275 | ip_set_nfnl_put(info->del_set.index); |
| 181 | } | 276 | } |
| 182 | 277 | ||
| 183 | /* Revision 1 match and target */ | 278 | /* Revision 1 target */ |
| 184 | |||
| 185 | static bool | ||
| 186 | set_match_v1(const struct sk_buff *skb, struct xt_action_param *par) | ||
| 187 | { | ||
| 188 | const struct xt_set_info_match_v1 *info = par->matchinfo; | ||
| 189 | ADT_OPT(opt, par->family, info->match_set.dim, | ||
| 190 | info->match_set.flags, 0, UINT_MAX); | ||
| 191 | |||
| 192 | if (opt.flags & IPSET_RETURN_NOMATCH) | ||
| 193 | opt.cmdflags |= IPSET_FLAG_RETURN_NOMATCH; | ||
| 194 | |||
| 195 | return match_set(info->match_set.index, skb, par, &opt, | ||
| 196 | info->match_set.flags & IPSET_INV_MATCH); | ||
| 197 | } | ||
| 198 | |||
| 199 | static int | ||
| 200 | set_match_v1_checkentry(const struct xt_mtchk_param *par) | ||
| 201 | { | ||
| 202 | struct xt_set_info_match_v1 *info = par->matchinfo; | ||
| 203 | ip_set_id_t index; | ||
| 204 | |||
| 205 | index = ip_set_nfnl_get_byindex(info->match_set.index); | ||
| 206 | |||
| 207 | if (index == IPSET_INVALID_ID) { | ||
| 208 | pr_warning("Cannot find set indentified by id %u to match\n", | ||
| 209 | info->match_set.index); | ||
| 210 | return -ENOENT; | ||
| 211 | } | ||
| 212 | if (info->match_set.dim > IPSET_DIM_MAX) { | ||
| 213 | pr_warning("Protocol error: set match dimension " | ||
| 214 | "is over the limit!\n"); | ||
| 215 | ip_set_nfnl_put(info->match_set.index); | ||
| 216 | return -ERANGE; | ||
| 217 | } | ||
| 218 | |||
| 219 | return 0; | ||
| 220 | } | ||
| 221 | |||
| 222 | static void | ||
| 223 | set_match_v1_destroy(const struct xt_mtdtor_param *par) | ||
| 224 | { | ||
| 225 | struct xt_set_info_match_v1 *info = par->matchinfo; | ||
| 226 | |||
| 227 | ip_set_nfnl_put(info->match_set.index); | ||
| 228 | } | ||
| 229 | 279 | ||
| 230 | static unsigned int | 280 | static unsigned int |
| 231 | set_target_v1(struct sk_buff *skb, const struct xt_action_param *par) | 281 | set_target_v1(struct sk_buff *skb, const struct xt_action_param *par) |
| @@ -320,52 +370,6 @@ set_target_v2(struct sk_buff *skb, const struct xt_action_param *par) | |||
| 320 | #define set_target_v2_checkentry set_target_v1_checkentry | 370 | #define set_target_v2_checkentry set_target_v1_checkentry |
| 321 | #define set_target_v2_destroy set_target_v1_destroy | 371 | #define set_target_v2_destroy set_target_v1_destroy |
| 322 | 372 | ||
| 323 | /* Revision 3 match */ | ||
| 324 | |||
| 325 | static bool | ||
| 326 | match_counter(u64 counter, const struct ip_set_counter_match *info) | ||
| 327 | { | ||
| 328 | switch (info->op) { | ||
| 329 | case IPSET_COUNTER_NONE: | ||
| 330 | return true; | ||
| 331 | case IPSET_COUNTER_EQ: | ||
| 332 | return counter == info->value; | ||
| 333 | case IPSET_COUNTER_NE: | ||
| 334 | return counter != info->value; | ||
| 335 | case IPSET_COUNTER_LT: | ||
| 336 | return counter < info->value; | ||
| 337 | case IPSET_COUNTER_GT: | ||
| 338 | return counter > info->value; | ||
| 339 | } | ||
| 340 | return false; | ||
| 341 | } | ||
| 342 | |||
| 343 | static bool | ||
| 344 | set_match_v3(const struct sk_buff *skb, struct xt_action_param *par) | ||
| 345 | { | ||
| 346 | const struct xt_set_info_match_v3 *info = par->matchinfo; | ||
| 347 | ADT_OPT(opt, par->family, info->match_set.dim, | ||
| 348 | info->match_set.flags, info->flags, UINT_MAX); | ||
| 349 | int ret; | ||
| 350 | |||
| 351 | if (info->packets.op != IPSET_COUNTER_NONE || | ||
| 352 | info->bytes.op != IPSET_COUNTER_NONE) | ||
| 353 | opt.cmdflags |= IPSET_FLAG_MATCH_COUNTERS; | ||
| 354 | |||
| 355 | ret = match_set(info->match_set.index, skb, par, &opt, | ||
| 356 | info->ma | ||
