1d956798dSJozsef Kadlecsik /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu> 2d956798dSJozsef Kadlecsik * Patrick Schaaf <bof@bof.de> 3d956798dSJozsef Kadlecsik * Martin Josefsson <gandalf@wlug.westbo.se> 4075e64c0SJozsef Kadlecsik * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 5d956798dSJozsef Kadlecsik * 6d956798dSJozsef Kadlecsik * This program is free software; you can redistribute it and/or modify 7d956798dSJozsef Kadlecsik * it under the terms of the GNU General Public License version 2 as 8d956798dSJozsef Kadlecsik * published by the Free Software Foundation. 9d956798dSJozsef Kadlecsik */ 10d956798dSJozsef Kadlecsik 11d956798dSJozsef Kadlecsik /* Kernel module which implements the set match and SET target 12ca0f6a5cSJozsef Kadlecsik * for netfilter/iptables. 13ca0f6a5cSJozsef Kadlecsik */ 14d956798dSJozsef Kadlecsik 15d956798dSJozsef Kadlecsik #include <linux/module.h> 16d956798dSJozsef Kadlecsik #include <linux/skbuff.h> 17d956798dSJozsef Kadlecsik 18d956798dSJozsef Kadlecsik #include <linux/netfilter/x_tables.h> 19a9756e6fSJozsef Kadlecsik #include <linux/netfilter/ipset/ip_set.h> 20a73f89a6SJozsef Kadlecsik #include <linux/netfilter/ipset/ip_set_timeout.h> 21a9756e6fSJozsef Kadlecsik #include <uapi/linux/netfilter/xt_set.h> 22d956798dSJozsef Kadlecsik 23d956798dSJozsef Kadlecsik MODULE_LICENSE("GPL"); 24d956798dSJozsef Kadlecsik MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 25d956798dSJozsef Kadlecsik MODULE_DESCRIPTION("Xtables: IP set match and target module"); 26d956798dSJozsef Kadlecsik MODULE_ALIAS("xt_SET"); 27d956798dSJozsef Kadlecsik MODULE_ALIAS("ipt_set"); 28d956798dSJozsef Kadlecsik MODULE_ALIAS("ip6t_set"); 29d956798dSJozsef Kadlecsik MODULE_ALIAS("ipt_SET"); 30d956798dSJozsef Kadlecsik MODULE_ALIAS("ip6t_SET"); 31d956798dSJozsef Kadlecsik 32d956798dSJozsef Kadlecsik static inline int 33d956798dSJozsef Kadlecsik match_set(ip_set_id_t index, const struct sk_buff *skb, 34b66554cfSJozsef Kadlecsik const struct xt_action_param *par, 35075e64c0SJozsef Kadlecsik struct ip_set_adt_opt *opt, int inv) 36d956798dSJozsef Kadlecsik { 37b66554cfSJozsef Kadlecsik if (ip_set_test(index, skb, par, opt)) 38d956798dSJozsef Kadlecsik inv = !inv; 39d956798dSJozsef Kadlecsik return inv; 40d956798dSJozsef Kadlecsik } 41d956798dSJozsef Kadlecsik 424750005aSJozsef Kadlecsik #define ADT_OPT(n, f, d, fs, cfs, t, p, b, po, bo) \ 43127f5591SJozsef Kadlecsik struct ip_set_adt_opt n = { \ 44127f5591SJozsef Kadlecsik .family = f, \ 45127f5591SJozsef Kadlecsik .dim = d, \ 46127f5591SJozsef Kadlecsik .flags = fs, \ 47127f5591SJozsef Kadlecsik .cmdflags = cfs, \ 48075e64c0SJozsef Kadlecsik .ext.timeout = t, \ 494750005aSJozsef Kadlecsik .ext.packets = p, \ 504750005aSJozsef Kadlecsik .ext.bytes = b, \ 514750005aSJozsef Kadlecsik .ext.packets_op = po, \ 524750005aSJozsef Kadlecsik .ext.bytes_op = bo, \ 53127f5591SJozsef Kadlecsik } 54ac8cc925SJozsef Kadlecsik 55d956798dSJozsef Kadlecsik /* Revision 0 interface: backward compatible with netfilter/iptables */ 56d956798dSJozsef Kadlecsik 57d956798dSJozsef Kadlecsik static bool 58d956798dSJozsef Kadlecsik set_match_v0(const struct sk_buff *skb, struct xt_action_param *par) 59d956798dSJozsef Kadlecsik { 60d956798dSJozsef Kadlecsik const struct xt_set_info_match_v0 *info = par->matchinfo; 61ca0f6a5cSJozsef Kadlecsik 62613dbd95SPablo Neira Ayuso ADT_OPT(opt, xt_family(par), info->match_set.u.compat.dim, 634750005aSJozsef Kadlecsik info->match_set.u.compat.flags, 0, UINT_MAX, 644750005aSJozsef Kadlecsik 0, 0, 0, 0); 65d956798dSJozsef Kadlecsik 66b66554cfSJozsef Kadlecsik return match_set(info->match_set.index, skb, par, &opt, 67d956798dSJozsef Kadlecsik info->match_set.u.compat.flags & IPSET_INV_MATCH); 68d956798dSJozsef Kadlecsik } 69d956798dSJozsef Kadlecsik 70d956798dSJozsef Kadlecsik static void 71d956798dSJozsef Kadlecsik compat_flags(struct xt_set_info_v0 *info) 72d956798dSJozsef Kadlecsik { 73d956798dSJozsef Kadlecsik u_int8_t i; 74d956798dSJozsef Kadlecsik 75d956798dSJozsef Kadlecsik /* Fill out compatibility data according to enum ip_set_kopt */ 76d956798dSJozsef Kadlecsik info->u.compat.dim = IPSET_DIM_ZERO; 77d956798dSJozsef Kadlecsik if (info->u.flags[0] & IPSET_MATCH_INV) 78d956798dSJozsef Kadlecsik info->u.compat.flags |= IPSET_INV_MATCH; 79d956798dSJozsef Kadlecsik for (i = 0; i < IPSET_DIM_MAX - 1 && info->u.flags[i]; i++) { 80d956798dSJozsef Kadlecsik info->u.compat.dim++; 81d956798dSJozsef Kadlecsik if (info->u.flags[i] & IPSET_SRC) 82d956798dSJozsef Kadlecsik info->u.compat.flags |= (1 << info->u.compat.dim); 83d956798dSJozsef Kadlecsik } 84d956798dSJozsef Kadlecsik } 85d956798dSJozsef Kadlecsik 86d956798dSJozsef Kadlecsik static int 87d956798dSJozsef Kadlecsik set_match_v0_checkentry(const struct xt_mtchk_param *par) 88d956798dSJozsef Kadlecsik { 89d956798dSJozsef Kadlecsik struct xt_set_info_match_v0 *info = par->matchinfo; 90d956798dSJozsef Kadlecsik ip_set_id_t index; 91d956798dSJozsef Kadlecsik 921785e8f4SVitaly Lavrov index = ip_set_nfnl_get_byindex(par->net, info->match_set.index); 93d956798dSJozsef Kadlecsik 94d956798dSJozsef Kadlecsik if (index == IPSET_INVALID_ID) { 95c82b31c5SFlorian Westphal pr_info_ratelimited("Cannot find set identified by id %u to match\n", 96d956798dSJozsef Kadlecsik info->match_set.index); 97d956798dSJozsef Kadlecsik return -ENOENT; 98d956798dSJozsef Kadlecsik } 99d956798dSJozsef Kadlecsik if (info->match_set.u.flags[IPSET_DIM_MAX - 1] != 0) { 100c82b31c5SFlorian Westphal pr_info_ratelimited("set match dimension is over the limit!\n"); 1011785e8f4SVitaly Lavrov ip_set_nfnl_put(par->net, info->match_set.index); 102d956798dSJozsef Kadlecsik return -ERANGE; 103d956798dSJozsef Kadlecsik } 104d956798dSJozsef Kadlecsik 105d956798dSJozsef Kadlecsik /* Fill out compatibility data */ 106d956798dSJozsef Kadlecsik compat_flags(&info->match_set); 107d956798dSJozsef Kadlecsik 108d956798dSJozsef Kadlecsik return 0; 109d956798dSJozsef Kadlecsik } 110d956798dSJozsef Kadlecsik 111d956798dSJozsef Kadlecsik static void 112d956798dSJozsef Kadlecsik set_match_v0_destroy(const struct xt_mtdtor_param *par) 113d956798dSJozsef Kadlecsik { 114d956798dSJozsef Kadlecsik struct xt_set_info_match_v0 *info = par->matchinfo; 115d956798dSJozsef Kadlecsik 1161785e8f4SVitaly Lavrov ip_set_nfnl_put(par->net, info->match_set.index); 117d956798dSJozsef Kadlecsik } 118d956798dSJozsef Kadlecsik 119bd3129fcSJozsef Kadlecsik /* Revision 1 match */ 120bd3129fcSJozsef Kadlecsik 121bd3129fcSJozsef Kadlecsik static bool 122bd3129fcSJozsef Kadlecsik set_match_v1(const struct sk_buff *skb, struct xt_action_param *par) 123bd3129fcSJozsef Kadlecsik { 124bd3129fcSJozsef Kadlecsik const struct xt_set_info_match_v1 *info = par->matchinfo; 125ca0f6a5cSJozsef Kadlecsik 126613dbd95SPablo Neira Ayuso ADT_OPT(opt, xt_family(par), info->match_set.dim, 1274750005aSJozsef Kadlecsik info->match_set.flags, 0, UINT_MAX, 1284750005aSJozsef Kadlecsik 0, 0, 0, 0); 129bd3129fcSJozsef Kadlecsik 130bd3129fcSJozsef Kadlecsik if (opt.flags & IPSET_RETURN_NOMATCH) 131bd3129fcSJozsef Kadlecsik opt.cmdflags |= IPSET_FLAG_RETURN_NOMATCH; 132bd3129fcSJozsef Kadlecsik 133bd3129fcSJozsef Kadlecsik return match_set(info->match_set.index, skb, par, &opt, 134bd3129fcSJozsef Kadlecsik info->match_set.flags & IPSET_INV_MATCH); 135bd3129fcSJozsef Kadlecsik } 136bd3129fcSJozsef Kadlecsik 137bd3129fcSJozsef Kadlecsik static int 138bd3129fcSJozsef Kadlecsik set_match_v1_checkentry(const struct xt_mtchk_param *par) 139bd3129fcSJozsef Kadlecsik { 140bd3129fcSJozsef Kadlecsik struct xt_set_info_match_v1 *info = par->matchinfo; 141bd3129fcSJozsef Kadlecsik ip_set_id_t index; 142bd3129fcSJozsef Kadlecsik 1431785e8f4SVitaly Lavrov index = ip_set_nfnl_get_byindex(par->net, info->match_set.index); 144bd3129fcSJozsef Kadlecsik 145bd3129fcSJozsef Kadlecsik if (index == IPSET_INVALID_ID) { 146c82b31c5SFlorian Westphal pr_info_ratelimited("Cannot find set identified by id %u to match\n", 147bd3129fcSJozsef Kadlecsik info->match_set.index); 148bd3129fcSJozsef Kadlecsik return -ENOENT; 149bd3129fcSJozsef Kadlecsik } 150bd3129fcSJozsef Kadlecsik if (info->match_set.dim > IPSET_DIM_MAX) { 151c82b31c5SFlorian Westphal pr_info_ratelimited("set match dimension is over the limit!\n"); 1521785e8f4SVitaly Lavrov ip_set_nfnl_put(par->net, info->match_set.index); 153bd3129fcSJozsef Kadlecsik return -ERANGE; 154bd3129fcSJozsef Kadlecsik } 155bd3129fcSJozsef Kadlecsik 156bd3129fcSJozsef Kadlecsik return 0; 157bd3129fcSJozsef Kadlecsik } 158bd3129fcSJozsef Kadlecsik 159bd3129fcSJozsef Kadlecsik static void 160bd3129fcSJozsef Kadlecsik set_match_v1_destroy(const struct xt_mtdtor_param *par) 161bd3129fcSJozsef Kadlecsik { 162bd3129fcSJozsef Kadlecsik struct xt_set_info_match_v1 *info = par->matchinfo; 163bd3129fcSJozsef Kadlecsik 1641785e8f4SVitaly Lavrov ip_set_nfnl_put(par->net, info->match_set.index); 165bd3129fcSJozsef Kadlecsik } 166bd3129fcSJozsef Kadlecsik 167bd3129fcSJozsef Kadlecsik /* Revision 3 match */ 168bd3129fcSJozsef Kadlecsik 169bd3129fcSJozsef Kadlecsik static bool 170bd3129fcSJozsef Kadlecsik set_match_v3(const struct sk_buff *skb, struct xt_action_param *par) 171bd3129fcSJozsef Kadlecsik { 172bd3129fcSJozsef Kadlecsik const struct xt_set_info_match_v3 *info = par->matchinfo; 173ca0f6a5cSJozsef Kadlecsik 174613dbd95SPablo Neira Ayuso ADT_OPT(opt, xt_family(par), info->match_set.dim, 1754750005aSJozsef Kadlecsik info->match_set.flags, info->flags, UINT_MAX, 1764750005aSJozsef Kadlecsik info->packets.value, info->bytes.value, 1774750005aSJozsef Kadlecsik info->packets.op, info->bytes.op); 178bd3129fcSJozsef Kadlecsik 179bd3129fcSJozsef Kadlecsik if (info->packets.op != IPSET_COUNTER_NONE || 180bd3129fcSJozsef Kadlecsik info->bytes.op != IPSET_COUNTER_NONE) 181bd3129fcSJozsef Kadlecsik opt.cmdflags |= IPSET_FLAG_MATCH_COUNTERS; 182bd3129fcSJozsef Kadlecsik 1834750005aSJozsef Kadlecsik return match_set(info->match_set.index, skb, par, &opt, 184bd3129fcSJozsef Kadlecsik info->match_set.flags & IPSET_INV_MATCH); 185a51b9199SJozsef Kadlecsik } 186a51b9199SJozsef Kadlecsik 187a51b9199SJozsef Kadlecsik #define set_match_v3_checkentry set_match_v1_checkentry 188a51b9199SJozsef Kadlecsik #define set_match_v3_destroy set_match_v1_destroy 189a51b9199SJozsef Kadlecsik 190a51b9199SJozsef Kadlecsik /* Revision 4 match */ 191a51b9199SJozsef Kadlecsik 192a51b9199SJozsef Kadlecsik static bool 193a51b9199SJozsef Kadlecsik set_match_v4(const struct sk_buff *skb, struct xt_action_param *par) 194a51b9199SJozsef Kadlecsik { 195a51b9199SJozsef Kadlecsik const struct xt_set_info_match_v4 *info = par->matchinfo; 196ca0f6a5cSJozsef Kadlecsik 197613dbd95SPablo Neira Ayuso ADT_OPT(opt, xt_family(par), info->match_set.dim, 1984750005aSJozsef Kadlecsik info->match_set.flags, info->flags, UINT_MAX, 1994750005aSJozsef Kadlecsik info->packets.value, info->bytes.value, 2004750005aSJozsef Kadlecsik info->packets.op, info->bytes.op); 201a51b9199SJozsef Kadlecsik 202a51b9199SJozsef Kadlecsik if (info->packets.op != IPSET_COUNTER_NONE || 203a51b9199SJozsef Kadlecsik info->bytes.op != IPSET_COUNTER_NONE) 204a51b9199SJozsef Kadlecsik opt.cmdflags |= IPSET_FLAG_MATCH_COUNTERS; 205a51b9199SJozsef Kadlecsik 2064750005aSJozsef Kadlecsik return match_set(info->match_set.index, skb, par, &opt, 207a51b9199SJozsef Kadlecsik info->match_set.flags & IPSET_INV_MATCH); 208bd3129fcSJozsef Kadlecsik } 209bd3129fcSJozsef Kadlecsik 210a51b9199SJozsef Kadlecsik #define set_match_v4_checkentry set_match_v1_checkentry 211a51b9199SJozsef Kadlecsik #define set_match_v4_destroy set_match_v1_destroy 212bd3129fcSJozsef Kadlecsik 213bd3129fcSJozsef Kadlecsik /* Revision 0 interface: backward compatible with netfilter/iptables */ 214bd3129fcSJozsef Kadlecsik 215d956798dSJozsef Kadlecsik static unsigned int 216d956798dSJozsef Kadlecsik set_target_v0(struct sk_buff *skb, const struct xt_action_param *par) 217d956798dSJozsef Kadlecsik { 218d956798dSJozsef Kadlecsik const struct xt_set_info_target_v0 *info = par->targinfo; 219ca0f6a5cSJozsef Kadlecsik 220613dbd95SPablo Neira Ayuso ADT_OPT(add_opt, xt_family(par), info->add_set.u.compat.dim, 2214750005aSJozsef Kadlecsik info->add_set.u.compat.flags, 0, UINT_MAX, 2224750005aSJozsef Kadlecsik 0, 0, 0, 0); 223613dbd95SPablo Neira Ayuso ADT_OPT(del_opt, xt_family(par), info->del_set.u.compat.dim, 2244750005aSJozsef Kadlecsik info->del_set.u.compat.flags, 0, UINT_MAX, 2254750005aSJozsef Kadlecsik 0, 0, 0, 0); 226d956798dSJozsef Kadlecsik 227d956798dSJozsef Kadlecsik if (info->add_set.index != IPSET_INVALID_ID) 228b66554cfSJozsef Kadlecsik ip_set_add(info->add_set.index, skb, par, &add_opt); 229d956798dSJozsef Kadlecsik if (info->del_set.index != IPSET_INVALID_ID) 230b66554cfSJozsef Kadlecsik ip_set_del(info->del_set.index, skb, par, &del_opt); 231d956798dSJozsef Kadlecsik 232d956798dSJozsef Kadlecsik return XT_CONTINUE; 233d956798dSJozsef Kadlecsik } 234d956798dSJozsef Kadlecsik 235d956798dSJozsef Kadlecsik static int 236d956798dSJozsef Kadlecsik set_target_v0_checkentry(const struct xt_tgchk_param *par) 237d956798dSJozsef Kadlecsik { 238d956798dSJozsef Kadlecsik struct xt_set_info_target_v0 *info = par->targinfo; 239d956798dSJozsef Kadlecsik ip_set_id_t index; 240d956798dSJozsef Kadlecsik 241d956798dSJozsef Kadlecsik if (info->add_set.index != IPSET_INVALID_ID) { 2421785e8f4SVitaly Lavrov index = ip_set_nfnl_get_byindex(par->net, info->add_set.index); 243d956798dSJozsef Kadlecsik if (index == IPSET_INVALID_ID) { 244c82b31c5SFlorian Westphal pr_info_ratelimited("Cannot find add_set index %u as target\n", 245d956798dSJozsef Kadlecsik info->add_set.index); 246d956798dSJozsef Kadlecsik return -ENOENT; 247d956798dSJozsef Kadlecsik } 248d956798dSJozsef Kadlecsik } 249d956798dSJozsef Kadlecsik 250d956798dSJozsef Kadlecsik if (info->del_set.index != IPSET_INVALID_ID) { 2511785e8f4SVitaly Lavrov index = ip_set_nfnl_get_byindex(par->net, info->del_set.index); 252d956798dSJozsef Kadlecsik if (index == IPSET_INVALID_ID) { 253c82b31c5SFlorian Westphal pr_info_ratelimited("Cannot find del_set index %u as target\n", 254d956798dSJozsef Kadlecsik info->del_set.index); 255eafbd3fdSJozsef Kadlecsik if (info->add_set.index != IPSET_INVALID_ID) 2561785e8f4SVitaly Lavrov ip_set_nfnl_put(par->net, info->add_set.index); 257d956798dSJozsef Kadlecsik return -ENOENT; 258d956798dSJozsef Kadlecsik } 259d956798dSJozsef Kadlecsik } 260d956798dSJozsef Kadlecsik if (info->add_set.u.flags[IPSET_DIM_MAX - 1] != 0 || 261d956798dSJozsef Kadlecsik info->del_set.u.flags[IPSET_DIM_MAX - 1] != 0) { 262c82b31c5SFlorian Westphal pr_info_ratelimited("SET target dimension over the limit!\n"); 263eafbd3fdSJozsef Kadlecsik if (info->add_set.index != IPSET_INVALID_ID) 2641785e8f4SVitaly Lavrov ip_set_nfnl_put(par->net, info->add_set.index); 265eafbd3fdSJozsef Kadlecsik if (info->del_set.index != IPSET_INVALID_ID) 2661785e8f4SVitaly Lavrov ip_set_nfnl_put(par->net, info->del_set.index); 267d956798dSJozsef Kadlecsik return -ERANGE; 268d956798dSJozsef Kadlecsik } 269d956798dSJozsef Kadlecsik 270d956798dSJozsef Kadlecsik /* Fill out compatibility data */ 271d956798dSJozsef Kadlecsik compat_flags(&info->add_set); 272d956798dSJozsef Kadlecsik compat_flags(&info->del_set); 273d956798dSJozsef Kadlecsik 274d956798dSJozsef Kadlecsik return 0; 275d956798dSJozsef Kadlecsik } 276d956798dSJozsef Kadlecsik 277d956798dSJozsef Kadlecsik static void 278d956798dSJozsef Kadlecsik set_target_v0_destroy(const struct xt_tgdtor_param *par) 279d956798dSJozsef Kadlecsik { 280d956798dSJozsef Kadlecsik const struct xt_set_info_target_v0 *info = par->targinfo; 281d956798dSJozsef Kadlecsik 282d956798dSJozsef Kadlecsik if (info->add_set.index != IPSET_INVALID_ID) 2831785e8f4SVitaly Lavrov ip_set_nfnl_put(par->net, info->add_set.index); 284d956798dSJozsef Kadlecsik if (info->del_set.index != IPSET_INVALID_ID) 2851785e8f4SVitaly Lavrov ip_set_nfnl_put(par->net, info->del_set.index); 286d956798dSJozsef Kadlecsik } 287d956798dSJozsef Kadlecsik 288bd3129fcSJozsef Kadlecsik /* Revision 1 target */ 289d956798dSJozsef Kadlecsik 290d956798dSJozsef Kadlecsik static unsigned int 291ac8cc925SJozsef Kadlecsik set_target_v1(struct sk_buff *skb, const struct xt_action_param *par) 292d956798dSJozsef Kadlecsik { 293ac8cc925SJozsef Kadlecsik const struct xt_set_info_target_v1 *info = par->targinfo; 294ca0f6a5cSJozsef Kadlecsik 295613dbd95SPablo Neira Ayuso ADT_OPT(add_opt, xt_family(par), info->add_set.dim, 2964750005aSJozsef Kadlecsik info->add_set.flags, 0, UINT_MAX, 2974750005aSJozsef Kadlecsik 0, 0, 0, 0); 298613dbd95SPablo Neira Ayuso ADT_OPT(del_opt, xt_family(par), info->del_set.dim, 2994750005aSJozsef Kadlecsik info->del_set.flags, 0, UINT_MAX, 3004750005aSJozsef Kadlecsik 0, 0, 0, 0); 301d956798dSJozsef Kadlecsik 302d956798dSJozsef Kadlecsik if (info->add_set.index != IPSET_INVALID_ID) 303b66554cfSJozsef Kadlecsik ip_set_add(info->add_set.index, skb, par, &add_opt); 304d956798dSJozsef Kadlecsik if (info->del_set.index != IPSET_INVALID_ID) 305b66554cfSJozsef Kadlecsik ip_set_del(info->del_set.index, skb, par, &del_opt); 306d956798dSJozsef Kadlecsik 307d956798dSJozsef Kadlecsik return XT_CONTINUE; 308d956798dSJozsef Kadlecsik } 309d956798dSJozsef Kadlecsik 310d956798dSJozsef Kadlecsik static int 311ac8cc925SJozsef Kadlecsik set_target_v1_checkentry(const struct xt_tgchk_param *par) 312d956798dSJozsef Kadlecsik { 313ac8cc925SJozsef Kadlecsik const struct xt_set_info_target_v1 *info = par->targinfo; 314d956798dSJozsef Kadlecsik ip_set_id_t index; 315d956798dSJozsef Kadlecsik 316d956798dSJozsef Kadlecsik if (info->add_set.index != IPSET_INVALID_ID) { 3171785e8f4SVitaly Lavrov index = ip_set_nfnl_get_byindex(par->net, info->add_set.index); 318d956798dSJozsef Kadlecsik if (index == IPSET_INVALID_ID) { 319c82b31c5SFlorian Westphal pr_info_ratelimited("Cannot find add_set index %u as target\n", 320d956798dSJozsef Kadlecsik info->add_set.index); 321d956798dSJozsef Kadlecsik return -ENOENT; 322d956798dSJozsef Kadlecsik } 323d956798dSJozsef Kadlecsik } 324d956798dSJozsef Kadlecsik 325d956798dSJozsef Kadlecsik if (info->del_set.index != IPSET_INVALID_ID) { 3261785e8f4SVitaly Lavrov index = ip_set_nfnl_get_byindex(par->net, info->del_set.index); 327d956798dSJozsef Kadlecsik if (index == IPSET_INVALID_ID) { 328c82b31c5SFlorian Westphal pr_info_ratelimited("Cannot find del_set index %u as target\n", 329d956798dSJozsef Kadlecsik info->del_set.index); 330eafbd3fdSJozsef Kadlecsik if (info->add_set.index != IPSET_INVALID_ID) 3311785e8f4SVitaly Lavrov ip_set_nfnl_put(par->net, info->add_set.index); 332d956798dSJozsef Kadlecsik return -ENOENT; 333d956798dSJozsef Kadlecsik } 334d956798dSJozsef Kadlecsik } 335d956798dSJozsef Kadlecsik if (info->add_set.dim > IPSET_DIM_MAX || 336eafbd3fdSJozsef Kadlecsik info->del_set.dim > IPSET_DIM_MAX) { 337c82b31c5SFlorian Westphal pr_info_ratelimited("SET target dimension over the limit!\n"); 338eafbd3fdSJozsef Kadlecsik if (info->add_set.index != IPSET_INVALID_ID) 3391785e8f4SVitaly Lavrov ip_set_nfnl_put(par->net, info->add_set.index); 340eafbd3fdSJozsef Kadlecsik if (info->del_set.index != IPSET_INVALID_ID) 3411785e8f4SVitaly Lavrov ip_set_nfnl_put(par->net, info->del_set.index); 342d956798dSJozsef Kadlecsik return -ERANGE; 343d956798dSJozsef Kadlecsik } 344d956798dSJozsef Kadlecsik 345d956798dSJozsef Kadlecsik return 0; 346d956798dSJozsef Kadlecsik } 347d956798dSJozsef Kadlecsik 348d956798dSJozsef Kadlecsik static void 349ac8cc925SJozsef Kadlecsik set_target_v1_destroy(const struct xt_tgdtor_param *par) 350d956798dSJozsef Kadlecsik { 351ac8cc925SJozsef Kadlecsik const struct xt_set_info_target_v1 *info = par->targinfo; 352d956798dSJozsef Kadlecsik 353d956798dSJozsef Kadlecsik if (info->add_set.index != IPSET_INVALID_ID) 3541785e8f4SVitaly Lavrov ip_set_nfnl_put(par->net, info->add_set.index); 355d956798dSJozsef Kadlecsik if (info->del_set.index != IPSET_INVALID_ID) 3561785e8f4SVitaly Lavrov ip_set_nfnl_put(par->net, info->del_set.index); 357d956798dSJozsef Kadlecsik } 358d956798dSJozsef Kadlecsik 359ac8cc925SJozsef Kadlecsik /* Revision 2 target */ 360ac8cc925SJozsef Kadlecsik 361ac8cc925SJozsef Kadlecsik static unsigned int 362ac8cc925SJozsef Kadlecsik set_target_v2(struct sk_buff *skb, const struct xt_action_param *par) 363ac8cc925SJozsef Kadlecsik { 364ac8cc925SJozsef Kadlecsik const struct xt_set_info_target_v2 *info = par->targinfo; 365ca0f6a5cSJozsef Kadlecsik 366613dbd95SPablo Neira Ayuso ADT_OPT(add_opt, xt_family(par), info->add_set.dim, 3674750005aSJozsef Kadlecsik info->add_set.flags, info->flags, info->timeout, 3684750005aSJozsef Kadlecsik 0, 0, 0, 0); 369613dbd95SPablo Neira Ayuso ADT_OPT(del_opt, xt_family(par), info->del_set.dim, 3704750005aSJozsef Kadlecsik info->del_set.flags, 0, UINT_MAX, 3714750005aSJozsef Kadlecsik 0, 0, 0, 0); 372ac8cc925SJozsef Kadlecsik 373127f5591SJozsef Kadlecsik /* Normalize to fit into jiffies */ 374075e64c0SJozsef Kadlecsik if (add_opt.ext.timeout != IPSET_NO_TIMEOUT && 37530a2e107SJozsef Kadlecsik add_opt.ext.timeout > IPSET_MAX_TIMEOUT) 37630a2e107SJozsef Kadlecsik add_opt.ext.timeout = IPSET_MAX_TIMEOUT; 377ac8cc925SJozsef Kadlecsik if (info->add_set.index != IPSET_INVALID_ID) 378b66554cfSJozsef Kadlecsik ip_set_add(info->add_set.index, skb, par, &add_opt); 379ac8cc925SJozsef Kadlecsik if (info->del_set.index != IPSET_INVALID_ID) 380b66554cfSJozsef Kadlecsik ip_set_del(info->del_set.index, skb, par, &del_opt); 381ac8cc925SJozsef Kadlecsik 382ac8cc925SJozsef Kadlecsik return XT_CONTINUE; 383ac8cc925SJozsef Kadlecsik } 384ac8cc925SJozsef Kadlecsik 385ac8cc925SJozsef Kadlecsik #define set_target_v2_checkentry set_target_v1_checkentry 386ac8cc925SJozsef Kadlecsik #define set_target_v2_destroy set_target_v1_destroy 387ac8cc925SJozsef Kadlecsik 38876cea410SAnton Danilov /* Revision 3 target */ 38976cea410SAnton Danilov 390bec810d9SJozsef Kadlecsik #define MOPT(opt, member) ((opt).ext.skbinfo.member) 391bec810d9SJozsef Kadlecsik 39276cea410SAnton Danilov static unsigned int 39376cea410SAnton Danilov set_target_v3(struct sk_buff *skb, const struct xt_action_param *par) 39476cea410SAnton Danilov { 39576cea410SAnton Danilov const struct xt_set_info_target_v3 *info = par->targinfo; 396ca0f6a5cSJozsef Kadlecsik int ret; 397ca0f6a5cSJozsef Kadlecsik 398613dbd95SPablo Neira Ayuso ADT_OPT(add_opt, xt_family(par), info->add_set.dim, 3994750005aSJozsef Kadlecsik info->add_set.flags, info->flags, info->timeout, 4004750005aSJozsef Kadlecsik 0, 0, 0, 0); 401613dbd95SPablo Neira Ayuso ADT_OPT(del_opt, xt_family(par), info->del_set.dim, 4024750005aSJozsef Kadlecsik info->del_set.flags, 0, UINT_MAX, 4034750005aSJozsef Kadlecsik 0, 0, 0, 0); 404613dbd95SPablo Neira Ayuso ADT_OPT(map_opt, xt_family(par), info->map_set.dim, 4054750005aSJozsef Kadlecsik info->map_set.flags, 0, UINT_MAX, 4064750005aSJozsef Kadlecsik 0, 0, 0, 0); 40776cea410SAnton Danilov 40876cea410SAnton Danilov /* Normalize to fit into jiffies */ 40976cea410SAnton Danilov if (add_opt.ext.timeout != IPSET_NO_TIMEOUT && 41030a2e107SJozsef Kadlecsik add_opt.ext.timeout > IPSET_MAX_TIMEOUT) 41130a2e107SJozsef Kadlecsik add_opt.ext.timeout = IPSET_MAX_TIMEOUT; 41276cea410SAnton Danilov if (info->add_set.index != IPSET_INVALID_ID) 41376cea410SAnton Danilov ip_set_add(info->add_set.index, skb, par, &add_opt); 41476cea410SAnton Danilov if (info->del_set.index != IPSET_INVALID_ID) 41576cea410SAnton Danilov ip_set_del(info->del_set.index, skb, par, &del_opt); 41676cea410SAnton Danilov if (info->map_set.index != IPSET_INVALID_ID) { 41776cea410SAnton Danilov map_opt.cmdflags |= info->flags & (IPSET_FLAG_MAP_SKBMARK | 41876cea410SAnton Danilov IPSET_FLAG_MAP_SKBPRIO | 41976cea410SAnton Danilov IPSET_FLAG_MAP_SKBQUEUE); 42076cea410SAnton Danilov ret = match_set(info->map_set.index, skb, par, &map_opt, 42176cea410SAnton Danilov info->map_set.flags & IPSET_INV_MATCH); 42276cea410SAnton Danilov if (!ret) 42376cea410SAnton Danilov return XT_CONTINUE; 42476cea410SAnton Danilov if (map_opt.cmdflags & IPSET_FLAG_MAP_SKBMARK) 425bec810d9SJozsef Kadlecsik skb->mark = (skb->mark & ~MOPT(map_opt,skbmarkmask)) 426bec810d9SJozsef Kadlecsik ^ MOPT(map_opt, skbmark); 42776cea410SAnton Danilov if (map_opt.cmdflags & IPSET_FLAG_MAP_SKBPRIO) 428bec810d9SJozsef Kadlecsik skb->priority = MOPT(map_opt, skbprio); 42976cea410SAnton Danilov if ((map_opt.cmdflags & IPSET_FLAG_MAP_SKBQUEUE) && 43076cea410SAnton Danilov skb->dev && 431bec810d9SJozsef Kadlecsik skb->dev->real_num_tx_queues > MOPT(map_opt, skbqueue)) 432bec810d9SJozsef Kadlecsik skb_set_queue_mapping(skb, MOPT(map_opt, skbqueue)); 43376cea410SAnton Danilov } 43476cea410SAnton Danilov return XT_CONTINUE; 43576cea410SAnton Danilov } 43676cea410SAnton Danilov 43776cea410SAnton Danilov static int 43876cea410SAnton Danilov set_target_v3_checkentry(const struct xt_tgchk_param *par) 43976cea410SAnton Danilov { 44076cea410SAnton Danilov const struct xt_set_info_target_v3 *info = par->targinfo; 44176cea410SAnton Danilov ip_set_id_t index; 44276cea410SAnton Danilov 44376cea410SAnton Danilov if (info->add_set.index != IPSET_INVALID_ID) { 44476cea410SAnton Danilov index = ip_set_nfnl_get_byindex(par->net, 44576cea410SAnton Danilov info->add_set.index); 44676cea410SAnton Danilov if (index == IPSET_INVALID_ID) { 447c82b31c5SFlorian Westphal pr_info_ratelimited("Cannot find add_set index %u as target\n", 44876cea410SAnton Danilov info->add_set.index); 44976cea410SAnton Danilov return -ENOENT; 45076cea410SAnton Danilov } 45176cea410SAnton Danilov } 45276cea410SAnton Danilov 45376cea410SAnton Danilov if (info->del_set.index != IPSET_INVALID_ID) { 45476cea410SAnton Danilov index = ip_set_nfnl_get_byindex(par->net, 45576cea410SAnton Danilov info->del_set.index); 45676cea410SAnton Danilov if (index == IPSET_INVALID_ID) { 457c82b31c5SFlorian Westphal pr_info_ratelimited("Cannot find del_set index %u as target\n", 45876cea410SAnton Danilov info->del_set.index); 45976cea410SAnton Danilov if (info->add_set.index != IPSET_INVALID_ID) 46076cea410SAnton Danilov ip_set_nfnl_put(par->net, 46176cea410SAnton Danilov info->add_set.index); 46276cea410SAnton Danilov return -ENOENT; 46376cea410SAnton Danilov } 46476cea410SAnton Danilov } 46576cea410SAnton Danilov 46676cea410SAnton Danilov if (info->map_set.index != IPSET_INVALID_ID) { 46776cea410SAnton Danilov if (strncmp(par->table, "mangle", 7)) { 468c82b31c5SFlorian Westphal pr_info_ratelimited("--map-set only usable from mangle table\n"); 46976cea410SAnton Danilov return -EINVAL; 47076cea410SAnton Danilov } 47176cea410SAnton Danilov if (((info->flags & IPSET_FLAG_MAP_SKBPRIO) | 47276cea410SAnton Danilov (info->flags & IPSET_FLAG_MAP_SKBQUEUE)) && 4739dcceb13SSerhey Popovych (par->hook_mask & ~(1 << NF_INET_FORWARD | 47476cea410SAnton Danilov 1 << NF_INET_LOCAL_OUT | 47576cea410SAnton Danilov 1 << NF_INET_POST_ROUTING))) { 476c82b31c5SFlorian Westphal pr_info_ratelimited("mapping of prio or/and queue is allowed only from OUTPUT/FORWARD/POSTROUTING chains\n"); 47776cea410SAnton Danilov return -EINVAL; 47876cea410SAnton Danilov } 47976cea410SAnton Danilov index = ip_set_nfnl_get_byindex(par->net, 48076cea410SAnton Danilov info->map_set.index); 48176cea410SAnton Danilov if (index == IPSET_INVALID_ID) { 482c82b31c5SFlorian Westphal pr_info_ratelimited("Cannot find map_set index %u as target\n", 48376cea410SAnton Danilov info->map_set.index); 48476cea410SAnton Danilov if (info->add_set.index != IPSET_INVALID_ID) 48576cea410SAnton Danilov ip_set_nfnl_put(par->net, 48676cea410SAnton Danilov info->add_set.index); 48776cea410SAnton Danilov if (info->del_set.index != IPSET_INVALID_ID) 48876cea410SAnton Danilov ip_set_nfnl_put(par->net, 48976cea410SAnton Danilov info->del_set.index); 49076cea410SAnton Danilov return -ENOENT; 49176cea410SAnton Danilov } 49276cea410SAnton Danilov } 49376cea410SAnton Danilov 49476cea410SAnton Danilov if (info->add_set.dim > IPSET_DIM_MAX || 49576cea410SAnton Danilov info->del_set.dim > IPSET_DIM_MAX || 49676cea410SAnton Danilov info->map_set.dim > IPSET_DIM_MAX) { 497c82b31c5SFlorian Westphal pr_info_ratelimited("SET target dimension over the limit!\n"); 49876cea410SAnton Danilov if (info->add_set.index != IPSET_INVALID_ID) 49976cea410SAnton Danilov ip_set_nfnl_put(par->net, info->add_set.index); 50076cea410SAnton Danilov if (info->del_set.index != IPSET_INVALID_ID) 50176cea410SAnton Danilov ip_set_nfnl_put(par->net, info->del_set.index); 50276cea410SAnton Danilov if (info->map_set.index != IPSET_INVALID_ID) 50376cea410SAnton Danilov ip_set_nfnl_put(par->net, info->map_set.index); 50476cea410SAnton Danilov return -ERANGE; 50576cea410SAnton Danilov } 50676cea410SAnton Danilov 50776cea410SAnton Danilov return 0; 50876cea410SAnton Danilov } 50976cea410SAnton Danilov 51076cea410SAnton Danilov static void 51176cea410SAnton Danilov set_target_v3_destroy(const struct xt_tgdtor_param *par) 51276cea410SAnton Danilov { 51376cea410SAnton Danilov const struct xt_set_info_target_v3 *info = par->targinfo; 51476cea410SAnton Danilov 51576cea410SAnton Danilov if (info->add_set.index != IPSET_INVALID_ID) 51676cea410SAnton Danilov ip_set_nfnl_put(par->net, info->add_set.index); 51776cea410SAnton Danilov if (info->del_set.index != IPSET_INVALID_ID) 51876cea410SAnton Danilov ip_set_nfnl_put(par->net, info->del_set.index); 51976cea410SAnton Danilov if (info->map_set.index != IPSET_INVALID_ID) 52076cea410SAnton Danilov ip_set_nfnl_put(par->net, info->map_set.index); 52176cea410SAnton Danilov } 52276cea410SAnton Danilov 523d956798dSJozsef Kadlecsik static struct xt_match set_matches[] __read_mostly = { 524d956798dSJozsef Kadlecsik { 525d956798dSJozsef Kadlecsik .name = "set", 526d956798dSJozsef Kadlecsik .family = NFPROTO_IPV4, 527d956798dSJozsef Kadlecsik .revision = 0, 528d956798dSJozsef Kadlecsik .match = set_match_v0, 529d956798dSJozsef Kadlecsik .matchsize = sizeof(struct xt_set_info_match_v0), 530d956798dSJozsef Kadlecsik .checkentry = set_match_v0_checkentry, 531d956798dSJozsef Kadlecsik .destroy = set_match_v0_destroy, 532d956798dSJozsef Kadlecsik .me = THIS_MODULE 533d956798dSJozsef Kadlecsik }, 534d956798dSJozsef Kadlecsik { 535d956798dSJozsef Kadlecsik .name = "set", 536d956798dSJozsef Kadlecsik .family = NFPROTO_IPV4, 537d956798dSJozsef Kadlecsik .revision = 1, 538ac8cc925SJozsef Kadlecsik .match = set_match_v1, 539ac8cc925SJozsef Kadlecsik .matchsize = sizeof(struct xt_set_info_match_v1), 540ac8cc925SJozsef Kadlecsik .checkentry = set_match_v1_checkentry, 541ac8cc925SJozsef Kadlecsik .destroy = set_match_v1_destroy, 542d956798dSJozsef Kadlecsik .me = THIS_MODULE 543d956798dSJozsef Kadlecsik }, 544d956798dSJozsef Kadlecsik { 545d956798dSJozsef Kadlecsik .name = "set", 546d956798dSJozsef Kadlecsik .family = NFPROTO_IPV6, 547d956798dSJozsef Kadlecsik .revision = 1, 548ac8cc925SJozsef Kadlecsik .match = set_match_v1, 549ac8cc925SJozsef Kadlecsik .matchsize = sizeof(struct xt_set_info_match_v1), 550ac8cc925SJozsef Kadlecsik .checkentry = set_match_v1_checkentry, 551ac8cc925SJozsef Kadlecsik .destroy = set_match_v1_destroy, 552d956798dSJozsef Kadlecsik .me = THIS_MODULE 553d956798dSJozsef Kadlecsik }, 5543e0304a5SJozsef Kadlecsik /* --return-nomatch flag support */ 5553e0304a5SJozsef Kadlecsik { 5563e0304a5SJozsef Kadlecsik .name = "set", 5573e0304a5SJozsef Kadlecsik .family = NFPROTO_IPV4, 5583e0304a5SJozsef Kadlecsik .revision = 2, 5593e0304a5SJozsef Kadlecsik .match = set_match_v1, 5603e0304a5SJozsef Kadlecsik .matchsize = sizeof(struct xt_set_info_match_v1), 5613e0304a5SJozsef Kadlecsik .checkentry = set_match_v1_checkentry, 5623e0304a5SJozsef Kadlecsik .destroy = set_match_v1_destroy, 5633e0304a5SJozsef Kadlecsik .me = THIS_MODULE 5643e0304a5SJozsef Kadlecsik }, 5653e0304a5SJozsef Kadlecsik { 5663e0304a5SJozsef Kadlecsik .name = "set", 5673e0304a5SJozsef Kadlecsik .family = NFPROTO_IPV6, 5683e0304a5SJozsef Kadlecsik .revision = 2, 5693e0304a5SJozsef Kadlecsik .match = set_match_v1, 5703e0304a5SJozsef Kadlecsik .matchsize = sizeof(struct xt_set_info_match_v1), 5713e0304a5SJozsef Kadlecsik .checkentry = set_match_v1_checkentry, 5723e0304a5SJozsef Kadlecsik .destroy = set_match_v1_destroy, 5733e0304a5SJozsef Kadlecsik .me = THIS_MODULE 5743e0304a5SJozsef Kadlecsik }, 5756e01781dSJozsef Kadlecsik /* counters support: update, match */ 5766e01781dSJozsef Kadlecsik { 5776e01781dSJozsef Kadlecsik .name = "set", 5786e01781dSJozsef Kadlecsik .family = NFPROTO_IPV4, 5796e01781dSJozsef Kadlecsik .revision = 3, 5806e01781dSJozsef Kadlecsik .match = set_match_v3, 5816e01781dSJozsef Kadlecsik .matchsize = sizeof(struct xt_set_info_match_v3), 5826e01781dSJozsef Kadlecsik .checkentry = set_match_v3_checkentry, 5836e01781dSJozsef Kadlecsik .destroy = set_match_v3_destroy, 5846e01781dSJozsef Kadlecsik .me = THIS_MODULE 5856e01781dSJozsef Kadlecsik }, 5866e01781dSJozsef Kadlecsik { 5876e01781dSJozsef Kadlecsik .name = "set", 5886e01781dSJozsef Kadlecsik .family = NFPROTO_IPV6, 5896e01781dSJozsef Kadlecsik .revision = 3, 5906e01781dSJozsef Kadlecsik .match = set_match_v3, 5916e01781dSJozsef Kadlecsik .matchsize = sizeof(struct xt_set_info_match_v3), 5926e01781dSJozsef Kadlecsik .checkentry = set_match_v3_checkentry, 5936e01781dSJozsef Kadlecsik .destroy = set_match_v3_destroy, 5946e01781dSJozsef Kadlecsik .me = THIS_MODULE 5956e01781dSJozsef Kadlecsik }, 596a51b9199SJozsef Kadlecsik /* new revision for counters support: update, match */ 597a51b9199SJozsef Kadlecsik { 598a51b9199SJozsef Kadlecsik .name = "set", 599a51b9199SJozsef Kadlecsik .family = NFPROTO_IPV4, 600a51b9199SJozsef Kadlecsik .revision = 4, 601a51b9199SJozsef Kadlecsik .match = set_match_v4, 602a51b9199SJozsef Kadlecsik .matchsize = sizeof(struct xt_set_info_match_v4), 603a51b9199SJozsef Kadlecsik .checkentry = set_match_v4_checkentry, 604a51b9199SJozsef Kadlecsik .destroy = set_match_v4_destroy, 605a51b9199SJozsef Kadlecsik .me = THIS_MODULE 606a51b9199SJozsef Kadlecsik }, 607a51b9199SJozsef Kadlecsik { 608a51b9199SJozsef Kadlecsik .name = "set", 609a51b9199SJozsef Kadlecsik .family = NFPROTO_IPV6, 610a51b9199SJozsef Kadlecsik .revision = 4, 611a51b9199SJozsef Kadlecsik .match = set_match_v4, 612a51b9199SJozsef Kadlecsik .matchsize = sizeof(struct xt_set_info_match_v4), 613a51b9199SJozsef Kadlecsik .checkentry = set_match_v4_checkentry, 614a51b9199SJozsef Kadlecsik .destroy = set_match_v4_destroy, 615a51b9199SJozsef Kadlecsik .me = THIS_MODULE 616a51b9199SJozsef Kadlecsik }, 617d956798dSJozsef Kadlecsik }; 618d956798dSJozsef Kadlecsik 619d956798dSJozsef Kadlecsik static struct xt_target set_targets[] __read_mostly = { 620d956798dSJozsef Kadlecsik { 621d956798dSJozsef Kadlecsik .name = "SET", 622d956798dSJozsef Kadlecsik .revision = 0, 623d956798dSJozsef Kadlecsik .family = NFPROTO_IPV4, 624d956798dSJozsef Kadlecsik .target = set_target_v0, 625d956798dSJozsef Kadlecsik .targetsize = sizeof(struct xt_set_info_target_v0), 626d956798dSJozsef Kadlecsik .checkentry = set_target_v0_checkentry, 627d956798dSJozsef Kadlecsik .destroy = set_target_v0_destroy, 628d956798dSJozsef Kadlecsik .me = THIS_MODULE 629d956798dSJozsef Kadlecsik }, 630d956798dSJozsef Kadlecsik { 631d956798dSJozsef Kadlecsik .name = "SET", 632d956798dSJozsef Kadlecsik .revision = 1, 633d956798dSJozsef Kadlecsik .family = NFPROTO_IPV4, 634ac8cc925SJozsef Kadlecsik .target = set_target_v1, 635ac8cc925SJozsef Kadlecsik .targetsize = sizeof(struct xt_set_info_target_v1), 636ac8cc925SJozsef Kadlecsik .checkentry = set_target_v1_checkentry, 637ac8cc925SJozsef Kadlecsik .destroy = set_target_v1_destroy, 638d956798dSJozsef Kadlecsik .me = THIS_MODULE 639d956798dSJozsef Kadlecsik }, 640d956798dSJozsef Kadlecsik { 641d956798dSJozsef Kadlecsik .name = "SET", 642d956798dSJozsef Kadlecsik .revision = 1, 643d956798dSJozsef Kadlecsik .family = NFPROTO_IPV6, 644ac8cc925SJozsef Kadlecsik .target = set_target_v1, 645ac8cc925SJozsef Kadlecsik .targetsize = sizeof(struct xt_set_info_target_v1), 646ac8cc925SJozsef Kadlecsik .checkentry = set_target_v1_checkentry, 647ac8cc925SJozsef Kadlecsik .destroy = set_target_v1_destroy, 648ac8cc925SJozsef Kadlecsik .me = THIS_MODULE 649ac8cc925SJozsef Kadlecsik }, 6503e0304a5SJozsef Kadlecsik /* --timeout and --exist flags support */ 651ac8cc925SJozsef Kadlecsik { 652ac8cc925SJozsef Kadlecsik .name = "SET", 653ac8cc925SJozsef Kadlecsik .revision = 2, 654ac8cc925SJozsef Kadlecsik .family = NFPROTO_IPV4, 655ac8cc925SJozsef Kadlecsik .target = set_target_v2, 656ac8cc925SJozsef Kadlecsik .targetsize = sizeof(struct xt_set_info_target_v2), 657ac8cc925SJozsef Kadlecsik .checkentry = set_target_v2_checkentry, 658ac8cc925SJozsef Kadlecsik .destroy = set_target_v2_destroy, 659ac8cc925SJozsef Kadlecsik .me = THIS_MODULE 660ac8cc925SJozsef Kadlecsik }, 661ac8cc925SJozsef Kadlecsik { 662ac8cc925SJozsef Kadlecsik .name = "SET", 663ac8cc925SJozsef Kadlecsik .revision = 2, 664ac8cc925SJozsef Kadlecsik .family = NFPROTO_IPV6, 665ac8cc925SJozsef Kadlecsik .target = set_target_v2, 666ac8cc925SJozsef Kadlecsik .targetsize = sizeof(struct xt_set_info_target_v2), 667ac8cc925SJozsef Kadlecsik .checkentry = set_target_v2_checkentry, 668ac8cc925SJozsef Kadlecsik .destroy = set_target_v2_destroy, 669d956798dSJozsef Kadlecsik .me = THIS_MODULE 670d956798dSJozsef Kadlecsik }, 67176cea410SAnton Danilov /* --map-set support */ 67276cea410SAnton Danilov { 67376cea410SAnton Danilov .name = "SET", 67476cea410SAnton Danilov .revision = 3, 67576cea410SAnton Danilov .family = NFPROTO_IPV4, 67676cea410SAnton Danilov .target = set_target_v3, 67776cea410SAnton Danilov .targetsize = sizeof(struct xt_set_info_target_v3), 67876cea410SAnton Danilov .checkentry = set_target_v3_checkentry, 67976cea410SAnton Danilov .destroy = set_target_v3_destroy, 68076cea410SAnton Danilov .me = THIS_MODULE 68176cea410SAnton Danilov }, 68276cea410SAnton Danilov { 68376cea410SAnton Danilov .name = "SET", 68476cea410SAnton Danilov .revision = 3, 68576cea410SAnton Danilov .family = NFPROTO_IPV6, 68676cea410SAnton Danilov .target = set_target_v3, 68776cea410SAnton Danilov .targetsize = sizeof(struct xt_set_info_target_v3), 68876cea410SAnton Danilov .checkentry = set_target_v3_checkentry, 68976cea410SAnton Danilov .destroy = set_target_v3_destroy, 69076cea410SAnton Danilov .me = THIS_MODULE 69176cea410SAnton Danilov }, 692d956798dSJozsef Kadlecsik }; 693d956798dSJozsef Kadlecsik 694d956798dSJozsef Kadlecsik static int __init xt_set_init(void) 695d956798dSJozsef Kadlecsik { 696d956798dSJozsef Kadlecsik int ret = xt_register_matches(set_matches, ARRAY_SIZE(set_matches)); 697d956798dSJozsef Kadlecsik 698d956798dSJozsef Kadlecsik if (!ret) { 699d956798dSJozsef Kadlecsik ret = xt_register_targets(set_targets, 700d956798dSJozsef Kadlecsik ARRAY_SIZE(set_targets)); 701d956798dSJozsef Kadlecsik if (ret) 702d956798dSJozsef Kadlecsik xt_unregister_matches(set_matches, 703d956798dSJozsef Kadlecsik ARRAY_SIZE(set_matches)); 704d956798dSJozsef Kadlecsik } 705d956798dSJozsef Kadlecsik return ret; 706d956798dSJozsef Kadlecsik } 707d956798dSJozsef Kadlecsik 708d956798dSJozsef Kadlecsik static void __exit xt_set_fini(void) 709d956798dSJozsef Kadlecsik { 710d956798dSJozsef Kadlecsik xt_unregister_matches(set_matches, ARRAY_SIZE(set_matches)); 711d956798dSJozsef Kadlecsik xt_unregister_targets(set_targets, ARRAY_SIZE(set_targets)); 712d956798dSJozsef Kadlecsik } 713d956798dSJozsef Kadlecsik 714d956798dSJozsef Kadlecsik module_init(xt_set_init); 715d956798dSJozsef Kadlecsik module_exit(xt_set_fini); 716