History

netfilter: nf_tables: allocate handle and delete objects via handle

This patch allows deletion of objects via unique handle which can be listed via '-a' option.

Harsha Sharma committed 8 years ago

Commit 3ecbfd61 parent cc2d5863 files · +153 −14Browse files

Unified · Split

3 files
  1. include/net/netfilter/nf_tables.h +9 −2
  2. include/uapi/linux/netfilter/nf_tables.h +10 −0
  3. net/netfilter/nf_tables_api.c +134 −12
include/net/netfilter/nf_tables.h+9−2
@@ -374,6 +374,7 @@ void nft_unregister_set(struct nft_set_type *type); · 373 unmodified lines
374 * @list: table set list node374 * @list: table set list node
375 * @bindings: list of set bindings375 * @bindings: list of set bindings
376 * @name: name of the set376 * @name: name of the set
377 * @handle: unique handle of the set
377 * @ktype: key type (numeric type defined by userspace, not used in the kernel)378 * @ktype: key type (numeric type defined by userspace, not used in the kernel)
378 * @dtype: data type (verdict or numeric type defined by userspace)379 * @dtype: data type (verdict or numeric type defined by userspace)
379 * @objtype: object type (see NFT_OBJECT_* definitions)380 * @objtype: object type (see NFT_OBJECT_* definitions)
@@ -396,6 +397,7 @@ struct nft_set { · 16 unmodified lines
396 struct list_head list;397 struct list_head list;
397 struct list_head bindings;398 struct list_head bindings;
398 char *name;399 char *name;
400 u64 handle;
399 u32 ktype;401 u32 ktype;
400 u32 dtype;402 u32 dtype;
401 u32 objtype;403 u32 objtype;
@@ -946,6 +948,7 @@ unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv); · 544 unmodified lines
946 * @objects: stateful objects in the table948 * @objects: stateful objects in the table
947 * @flowtables: flow tables in the table949 * @flowtables: flow tables in the table
948 * @hgenerator: handle generator state950 * @hgenerator: handle generator state
951 * @handle: table handle
949 * @use: number of chain references to this table952 * @use: number of chain references to this table
950 * @flags: table flag (see enum nft_table_flags)953 * @flags: table flag (see enum nft_table_flags)
951 * @genmask: generation mask954 * @genmask: generation mask
@@ -959,6 +962,7 @@ struct nft_table { · 7 unmodified lines
959 struct list_head objects;962 struct list_head objects;
960 struct list_head flowtables;963 struct list_head flowtables;
961 u64 hgenerator;964 u64 hgenerator;
965 u64 handle;
962 u32 use;966 u32 use;
963 u16 family:6,967 u16 family:6,
964 flags:8,968 flags:8,
@@ -983,9 +987,9 @@ int nft_verdict_dump(struct sk_buff *skb, int type, · 18 unmodified lines
983 * @name: name of this stateful object987 * @name: name of this stateful object
984 * @genmask: generation mask988 * @genmask: generation mask
985 * @use: number of references to this stateful object989 * @use: number of references to this stateful object
986 * @data: object data, layout depends on type990 * @handle: unique object handle
987 * @ops: object operations991 * @ops: object operations
988 * @data: pointer to object data992 * @data: object data, layout depends on type
989 */993 */
990struct nft_object {994struct nft_object {
991 struct list_head list;995 struct list_head list;
@@ -993,6 +997,7 @@ struct nft_object { · 1 unmodified line
993 struct nft_table *table;997 struct nft_table *table;
994 u32 genmask:2,998 u32 genmask:2,
995 use:30;999 use:30;
1000 u64 handle;
996 /* runtime data below here */1001 /* runtime data below here */
997 const struct nft_object_ops *ops ____cacheline_aligned;1002 const struct nft_object_ops *ops ____cacheline_aligned;
998 unsigned char data[]1003 unsigned char data[]
@@ -1074,6 +1079,7 @@ void nft_unregister_obj(struct nft_object_type *obj_type); · 75 unmodified lines
1074 * @ops_len: number of hooks in array1079 * @ops_len: number of hooks in array
1075 * @genmask: generation mask1080 * @genmask: generation mask
1076 * @use: number of references to this flow table1081 * @use: number of references to this flow table
1082 * @handle: unique object handle
1077 * @data: rhashtable and garbage collector1083 * @data: rhashtable and garbage collector
1078 * @ops: array of hooks1084 * @ops: array of hooks
1079 */1085 */
@@ -1086,6 +1092,7 @@ struct nft_flowtable { · 6 unmodified lines
1086 int ops_len;1092 int ops_len;
1087 u32 genmask:2,1093 u32 genmask:2,
1088 use:30;1094 use:30;
1095 u64 handle;
1089 /* runtime data below here */1096 /* runtime data below here */
1090 struct nf_hook_ops *ops ____cacheline_aligned;1097 struct nf_hook_ops *ops ____cacheline_aligned;
1091 struct nf_flowtable data;1098 struct nf_flowtable data;
include/uapi/linux/netfilter/nf_tables.h+10−0
@@ -174,6 +174,8 @@ enum nft_table_attributes { · 173 unmodified lines
174 NFTA_TABLE_NAME,174 NFTA_TABLE_NAME,
175 NFTA_TABLE_FLAGS,175 NFTA_TABLE_FLAGS,
176 NFTA_TABLE_USE,176 NFTA_TABLE_USE,
177 NFTA_TABLE_HANDLE,
178 NFTA_TABLE_PAD,
177 __NFTA_TABLE_MAX179 __NFTA_TABLE_MAX
178};180};
179#define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1)181#define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1)
@@ -317,6 +319,7 @@ enum nft_set_desc_attributes { · 137 unmodified lines
317 * @NFTA_SET_GC_INTERVAL: garbage collection interval (NLA_U32)319 * @NFTA_SET_GC_INTERVAL: garbage collection interval (NLA_U32)
318 * @NFTA_SET_USERDATA: user data (NLA_BINARY)320 * @NFTA_SET_USERDATA: user data (NLA_BINARY)
319 * @NFTA_SET_OBJ_TYPE: stateful object type (NLA_U32: NFT_OBJECT_*)321 * @NFTA_SET_OBJ_TYPE: stateful object type (NLA_U32: NFT_OBJECT_*)
322 * @NFTA_SET_HANDLE: set handle (NLA_U64)
320 */323 */
321enum nft_set_attributes {324enum nft_set_attributes {
322 NFTA_SET_UNSPEC,325 NFTA_SET_UNSPEC,
@@ -335,6 +338,7 @@ enum nft_set_attributes { · 12 unmodified lines
335 NFTA_SET_USERDATA,338 NFTA_SET_USERDATA,
336 NFTA_SET_PAD,339 NFTA_SET_PAD,
337 NFTA_SET_OBJ_TYPE,340 NFTA_SET_OBJ_TYPE,
341 NFTA_SET_HANDLE,
338 __NFTA_SET_MAX342 __NFTA_SET_MAX
339};343};
340#define NFTA_SET_MAX (__NFTA_SET_MAX - 1)344#define NFTA_SET_MAX (__NFTA_SET_MAX - 1)
@@ -1314,6 +1318,7 @@ enum nft_ct_helper_attributes { · 973 unmodified lines
1314 * @NFTA_OBJ_TYPE: stateful object type (NLA_U32)1318 * @NFTA_OBJ_TYPE: stateful object type (NLA_U32)
1315 * @NFTA_OBJ_DATA: stateful object data (NLA_NESTED)1319 * @NFTA_OBJ_DATA: stateful object data (NLA_NESTED)
1316 * @NFTA_OBJ_USE: number of references to this expression (NLA_U32)1320 * @NFTA_OBJ_USE: number of references to this expression (NLA_U32)
1321 * @NFTA_OBJ_HANDLE: object handle (NLA_U64)
1317 */1322 */
1318enum nft_object_attributes {1323enum nft_object_attributes {
1319 NFTA_OBJ_UNSPEC,1324 NFTA_OBJ_UNSPEC,
@@ -1322,6 +1327,8 @@ enum nft_object_attributes { · 2 unmodified lines
1322 NFTA_OBJ_TYPE,1327 NFTA_OBJ_TYPE,
1323 NFTA_OBJ_DATA,1328 NFTA_OBJ_DATA,
1324 NFTA_OBJ_USE,1329 NFTA_OBJ_USE,
1330 NFTA_OBJ_HANDLE,
1331 NFTA_OBJ_PAD,
1325 __NFTA_OBJ_MAX1332 __NFTA_OBJ_MAX
1326};1333};
1327#define NFTA_OBJ_MAX (__NFTA_OBJ_MAX - 1)1334#define NFTA_OBJ_MAX (__NFTA_OBJ_MAX - 1)
@@ -1333,6 +1340,7 @@ enum nft_object_attributes { · 5 unmodified lines
1333 * @NFTA_FLOWTABLE_NAME: name of this flow table (NLA_STRING)1340 * @NFTA_FLOWTABLE_NAME: name of this flow table (NLA_STRING)
1334 * @NFTA_FLOWTABLE_HOOK: netfilter hook configuration(NLA_U32)1341 * @NFTA_FLOWTABLE_HOOK: netfilter hook configuration(NLA_U32)
1335 * @NFTA_FLOWTABLE_USE: number of references to this flow table (NLA_U32)1342 * @NFTA_FLOWTABLE_USE: number of references to this flow table (NLA_U32)
1343 * @NFTA_FLOWTABLE_HANDLE: object handle (NLA_U64)
1336 */1344 */
1337enum nft_flowtable_attributes {1345enum nft_flowtable_attributes {
1338 NFTA_FLOWTABLE_UNSPEC,1346 NFTA_FLOWTABLE_UNSPEC,
@@ -1340,6 +1348,8 @@ enum nft_flowtable_attributes { · 1 unmodified line
1340 NFTA_FLOWTABLE_NAME,1348 NFTA_FLOWTABLE_NAME,
1341 NFTA_FLOWTABLE_HOOK,1349 NFTA_FLOWTABLE_HOOK,
1342 NFTA_FLOWTABLE_USE,1350 NFTA_FLOWTABLE_USE,
1351 NFTA_FLOWTABLE_HANDLE,
1352 NFTA_FLOWTABLE_PAD,
1343 __NFTA_FLOWTABLE_MAX1353 __NFTA_FLOWTABLE_MAX
1344};1354};
1345#define NFTA_FLOWTABLE_MAX (__NFTA_FLOWTABLE_MAX - 1)1355#define NFTA_FLOWTABLE_MAX (__NFTA_FLOWTABLE_MAX - 1)
net/netfilter/nf_tables_api.c+134−12
@@ -26,6 +26,7 @@ · 25 unmodified lines
26static LIST_HEAD(nf_tables_expressions);26static LIST_HEAD(nf_tables_expressions);
27static LIST_HEAD(nf_tables_objects);27static LIST_HEAD(nf_tables_objects);
28static LIST_HEAD(nf_tables_flowtables);28static LIST_HEAD(nf_tables_flowtables);
29static u64 table_handle;
29 30
30static void nft_ctx_init(struct nft_ctx *ctx,31static void nft_ctx_init(struct nft_ctx *ctx,
31 struct net *net,32 struct net *net,
@@ -332,6 +333,20 @@ static struct nft_table *nft_table_lookup(const struct net *net, · 300 unmodified lines
332 return NULL;333 return NULL;
333}334}
334 335
336static struct nft_table *nft_table_lookup_byhandle(const struct net *net,
337 const struct nlattr *nla,
338 u8 genmask)
339{
340 struct nft_table *table;
341
342 list_for_each_entry(table, &net->nft.tables, list) {
343 if (be64_to_cpu(nla_get_be64(nla)) == table->handle &&
344 nft_active_genmask(table, genmask))
345 return table;
346 }
347 return NULL;
348}
349
335static struct nft_table *nf_tables_table_lookup(const struct net *net,350static struct nft_table *nf_tables_table_lookup(const struct net *net,
336 const struct nlattr *nla,351 const struct nlattr *nla,
337 u8 family, u8 genmask)352 u8 family, u8 genmask)
@@ -348,6 +363,22 @@ static struct nft_table *nf_tables_table_lookup(const struct net *net, · 10 unmodified lines
348 return ERR_PTR(-ENOENT);363 return ERR_PTR(-ENOENT);
349}364}
350 365
366static struct nft_table *nf_tables_table_lookup_byhandle(const struct net *net,
367 const struct nlattr *nla,
368 u8 genmask)
369{
370 struct nft_table *table;
371
372 if (nla == NULL)
373 return ERR_PTR(-EINVAL);
374
375 table = nft_table_lookup_byhandle(net, nla, genmask);
376 if (table != NULL)
377 return table;
378
379 return ERR_PTR(-ENOENT);
380}
381
351static inline u64 nf_tables_alloc_handle(struct nft_table *table)382static inline u64 nf_tables_alloc_handle(struct nft_table *table)
352{383{
353 return ++table->hgenerator;384 return ++table->hgenerator;
@@ -394,6 +425,7 @@ static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = { · 40 unmodified lines
394 [NFTA_TABLE_NAME] = { .type = NLA_STRING,425 [NFTA_TABLE_NAME] = { .type = NLA_STRING,
395 .len = NFT_TABLE_MAXNAMELEN - 1 },426 .len = NFT_TABLE_MAXNAMELEN - 1 },
396 [NFTA_TABLE_FLAGS] = { .type = NLA_U32 },427 [NFTA_TABLE_FLAGS] = { .type = NLA_U32 },
428 [NFTA_TABLE_HANDLE] = { .type = NLA_U64 },
397};429};
398 430
399static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,431static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
@@ -415,7 +447,9 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net, · 15 unmodified lines
415 447
416 if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) ||448 if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) ||
417 nla_put_be32(skb, NFTA_TABLE_FLAGS, htonl(table->flags)) ||449 nla_put_be32(skb, NFTA_TABLE_FLAGS, htonl(table->flags)) ||
418 nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)))450 nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)) ||
451 nla_put_be64(skb, NFTA_TABLE_HANDLE, cpu_to_be64(table->handle),
452 NFTA_TABLE_PAD))
419 goto nla_put_failure;453 goto nla_put_failure;
420 454
421 nlmsg_end(skb, nlh);455 nlmsg_end(skb, nlh);
@@ -674,6 +708,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk, · 252 unmodified lines
674 INIT_LIST_HEAD(&table->flowtables);708 INIT_LIST_HEAD(&table->flowtables);
675 table->family = family;709 table->family = family;
676 table->flags = flags;710 table->flags = flags;
711 table->handle = ++table_handle;
677 712
678 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);713 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
679 err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE);714 err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE);
@@ -791,11 +826,18 @@ static int nf_tables_deltable(struct net *net, struct sock *nlsk, · 111 unmodified lines
791 struct nft_ctx ctx;826 struct nft_ctx ctx;
792 827
793 nft_ctx_init(&ctx, net, skb, nlh, 0, NULL, NULL, nla);828 nft_ctx_init(&ctx, net, skb, nlh, 0, NULL, NULL, nla);
794 if (family == AF_UNSPEC || nla[NFTA_TABLE_NAME] == NULL)829 if (family == AF_UNSPEC ||
830 (!nla[NFTA_TABLE_NAME] && !nla[NFTA_TABLE_HANDLE]))
795 return nft_flush(&ctx, family);831 return nft_flush(&ctx, family);
796 832
797 table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], family,833 if (nla[NFTA_TABLE_HANDLE])
798 genmask);834 table = nf_tables_table_lookup_byhandle(net,
835 nla[NFTA_TABLE_HANDLE],
836 genmask);
837 else
838 table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME],
839 family, genmask);
840
799 if (IS_ERR(table))841 if (IS_ERR(table))
800 return PTR_ERR(table);842 return PTR_ERR(table);
801 843
@@ -1539,6 +1581,7 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk, · 737 unmodified lines
1539 struct nft_rule *rule;1581 struct nft_rule *rule;
1540 int family = nfmsg->nfgen_family;1582 int family = nfmsg->nfgen_family;
1541 struct nft_ctx ctx;1583 struct nft_ctx ctx;
1584 u64 handle;
1542 u32 use;1585 u32 use;
1543 int err;1586 int err;
1544 1587
@@ -1547,7 +1590,12 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk, · 2 unmodified lines
1547 if (IS_ERR(table))1590 if (IS_ERR(table))
1548 return PTR_ERR(table);1591 return PTR_ERR(table);
1549 1592
1550 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], genmask);1593 if (nla[NFTA_CHAIN_HANDLE]) {
1594 handle = be64_to_cpu(nla_get_be64(nla[NFTA_CHAIN_HANDLE]));
1595 chain = nf_tables_chain_lookup_byhandle(table, handle, genmask);
1596 } else {
1597 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], genmask);
1598 }
1551 if (IS_ERR(chain))1599 if (IS_ERR(chain))
1552 return PTR_ERR(chain);1600 return PTR_ERR(chain);
1553 1601
@@ -2503,6 +2551,7 @@ static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = { · 949 unmodified lines
2503 [NFTA_SET_USERDATA] = { .type = NLA_BINARY,2551 [NFTA_SET_USERDATA] = { .type = NLA_BINARY,
2504 .len = NFT_USERDATA_MAXLEN },2552 .len = NFT_USERDATA_MAXLEN },
2505 [NFTA_SET_OBJ_TYPE] = { .type = NLA_U32 },2553 [NFTA_SET_OBJ_TYPE] = { .type = NLA_U32 },
2554 [NFTA_SET_HANDLE] = { .type = NLA_U64 },
2506};2555};
2507 2556
2508static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {2557static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
@@ -2546,6 +2595,22 @@ static struct nft_set *nf_tables_set_lookup(const struct nft_table *table, · 37 unmodified lines
2546 return ERR_PTR(-ENOENT);2595 return ERR_PTR(-ENOENT);
2547}2596}
2548 2597
2598static struct nft_set *nf_tables_set_lookup_byhandle(const struct nft_table *table,
2599 const struct nlattr *nla, u8 genmask)
2600{
2601 struct nft_set *set;
2602
2603 if (nla == NULL)
2604 return ERR_PTR(-EINVAL);
2605
2606 list_for_each_entry(set, &table->sets, list) {
2607 if (be64_to_cpu(nla_get_be64(nla)) == set->handle &&
2608 nft_active_genmask(set, genmask))
2609 return set;
2610 }
2611 return ERR_PTR(-ENOENT);
2612}
2613
2549static struct nft_set *nf_tables_set_lookup_byid(const struct net *net,2614static struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
2550 const struct nlattr *nla,2615 const struct nlattr *nla,
2551 u8 genmask)2616 u8 genmask)
@@ -2661,6 +2726,9 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx, · 109 unmodified lines
2661 goto nla_put_failure;2726 goto nla_put_failure;
2662 if (nla_put_string(skb, NFTA_SET_NAME, set->name))2727 if (nla_put_string(skb, NFTA_SET_NAME, set->name))
2663 goto nla_put_failure;2728 goto nla_put_failure;
2729 if (nla_put_be64(skb, NFTA_SET_HANDLE, cpu_to_be64(set->handle),
2730 NFTA_SET_PAD))
2731 goto nla_put_failure;
2664 if (set->flags != 0)2732 if (set->flags != 0)
2665 if (nla_put_be32(skb, NFTA_SET_FLAGS, htonl(set->flags)))2733 if (nla_put_be32(skb, NFTA_SET_FLAGS, htonl(set->flags)))
2666 goto nla_put_failure;2734 goto nla_put_failure;
@@ -3069,6 +3137,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, · 402 unmodified lines
3069 set->udata = udata;3137 set->udata = udata;
3070 set->timeout = timeout;3138 set->timeout = timeout;
3071 set->gc_int = gc_int;3139 set->gc_int = gc_int;
3140 set->handle = nf_tables_alloc_handle(table);
3072 3141
3073 err = ops->init(set, &desc, nla);3142 err = ops->init(set, &desc, nla);
3074 if (err < 0)3143 if (err < 0)
@@ -3126,7 +3195,10 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk, · 51 unmodified lines
3126 if (err < 0)3195 if (err < 0)
3127 return err;3196 return err;
3128 3197
3129 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask);3198 if (nla[NFTA_SET_HANDLE])
3199 set = nf_tables_set_lookup_byhandle(ctx.table, nla[NFTA_SET_HANDLE], genmask);
3200 else
3201 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask);
3130 if (IS_ERR(set))3202 if (IS_ERR(set))
3131 return PTR_ERR(set);3203 return PTR_ERR(set);
3132 3204
@@ -4256,6 +4328,21 @@ struct nft_object *nf_tables_obj_lookup(const struct nft_table *table, · 1123 unmodified lines
4256}4328}
4257EXPORT_SYMBOL_GPL(nf_tables_obj_lookup);4329EXPORT_SYMBOL_GPL(nf_tables_obj_lookup);
4258 4330
4331struct nft_object *nf_tables_obj_lookup_byhandle(const struct nft_table *table,
4332 const struct nlattr *nla,
4333 u32 objtype, u8 genmask)
4334{
4335 struct nft_object *obj;
4336
4337 list_for_each_entry(obj, &table->objects, list) {
4338 if (be64_to_cpu(nla_get_be64(nla)) == obj->handle &&
4339 objtype == obj->ops->type->type &&
4340 nft_active_genmask(obj, genmask))
4341 return obj;
4342 }
4343 return ERR_PTR(-ENOENT);
4344}
4345
4259static const struct nla_policy nft_obj_policy[NFTA_OBJ_MAX + 1] = {4346static const struct nla_policy nft_obj_policy[NFTA_OBJ_MAX + 1] = {
4260 [NFTA_OBJ_TABLE] = { .type = NLA_STRING,4347 [NFTA_OBJ_TABLE] = { .type = NLA_STRING,
4261 .len = NFT_TABLE_MAXNAMELEN - 1 },4348 .len = NFT_TABLE_MAXNAMELEN - 1 },
@@ -4263,6 +4350,7 @@ static const struct nla_policy nft_obj_policy[NFTA_OBJ_MAX + 1] = { · 1 unmodified line
4263 .len = NFT_OBJ_MAXNAMELEN - 1 },4350 .len = NFT_OBJ_MAXNAMELEN - 1 },
4264 [NFTA_OBJ_TYPE] = { .type = NLA_U32 },4351 [NFTA_OBJ_TYPE] = { .type = NLA_U32 },
4265 [NFTA_OBJ_DATA] = { .type = NLA_NESTED },4352 [NFTA_OBJ_DATA] = { .type = NLA_NESTED },
4353 [NFTA_OBJ_HANDLE] = { .type = NLA_U64},
4266};4354};
4267 4355
4268static struct nft_object *nft_obj_init(const struct nft_ctx *ctx,4356static struct nft_object *nft_obj_init(const struct nft_ctx *ctx,
@@ -4410,6 +4498,8 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk, · 141 unmodified lines
4410 goto err1;4498 goto err1;
4411 }4499 }
4412 obj->table = table;4500 obj->table = table;
4501 obj->handle = nf_tables_alloc_handle(table);
4502
4413 obj->name = nla_strdup(nla[NFTA_OBJ_NAME], GFP_KERNEL);4503 obj->name = nla_strdup(nla[NFTA_OBJ_NAME], GFP_KERNEL);
4414 if (!obj->name) {4504 if (!obj->name) {
4415 err = -ENOMEM;4505 err = -ENOMEM;
@@ -4456,7 +4546,9 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net, · 40 unmodified lines
4456 nla_put_string(skb, NFTA_OBJ_NAME, obj->name) ||4546 nla_put_string(skb, NFTA_OBJ_NAME, obj->name) ||
4457 nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) ||4547 nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) ||
4458 nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||4548 nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
4459 nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset))4549 nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset) ||
4550 nla_put_be64(skb, NFTA_OBJ_HANDLE, cpu_to_be64(obj->handle),
4551 NFTA_OBJ_PAD))
4460 goto nla_put_failure;4552 goto nla_put_failure;
4461 4553
4462 nlmsg_end(skb, nlh);4554 nlmsg_end(skb, nlh);
@@ -4654,7 +4746,7 @@ static int nf_tables_delobj(struct net *net, struct sock *nlsk, · 191 unmodified lines
4654 u32 objtype;4746 u32 objtype;
4655 4747
4656 if (!nla[NFTA_OBJ_TYPE] ||4748 if (!nla[NFTA_OBJ_TYPE] ||
4657 !nla[NFTA_OBJ_NAME])4749 (!nla[NFTA_OBJ_NAME] && !nla[NFTA_OBJ_HANDLE]))
4658 return -EINVAL;4750 return -EINVAL;
4659 4751
4660 table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], family,4752 table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], family,
@@ -4663,7 +4755,12 @@ static int nf_tables_delobj(struct net *net, struct sock *nlsk, · 2 unmodified lines
4663 return PTR_ERR(table);4755 return PTR_ERR(table);
4664 4756
4665 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));4757 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4666 obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask);4758 if (nla[NFTA_OBJ_HANDLE])
4759 obj = nf_tables_obj_lookup_byhandle(table, nla[NFTA_OBJ_HANDLE],
4760 objtype, genmask);
4761 else
4762 obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME],
4763 objtype, genmask);
4667 if (IS_ERR(obj))4764 if (IS_ERR(obj))
4668 return PTR_ERR(obj);4765 return PTR_ERR(obj);
4669 if (obj->use > 0)4766 if (obj->use > 0)
@@ -4735,6 +4832,7 @@ static const struct nla_policy nft_flowtable_policy[NFTA_FLOWTABLE_MAX + 1] = { · 65 unmodified lines
4735 [NFTA_FLOWTABLE_NAME] = { .type = NLA_STRING,4832 [NFTA_FLOWTABLE_NAME] = { .type = NLA_STRING,
4736 .len = NFT_NAME_MAXLEN - 1 },4833 .len = NFT_NAME_MAXLEN - 1 },
4737 [NFTA_FLOWTABLE_HOOK] = { .type = NLA_NESTED },4834 [NFTA_FLOWTABLE_HOOK] = { .type = NLA_NESTED },
4835 [NFTA_FLOWTABLE_HANDLE] = { .type = NLA_U64 },
4738};4836};
4739 4837
4740struct nft_flowtable *nf_tables_flowtable_lookup(const struct nft_table *table,4838struct nft_flowtable *nf_tables_flowtable_lookup(const struct nft_table *table,
@@ -4752,6 +4850,20 @@ struct nft_flowtable *nf_tables_flowtable_lookup(const struct nft_table *table, · 11 unmodified lines
4752}4850}
4753EXPORT_SYMBOL_GPL(nf_tables_flowtable_lookup);4851EXPORT_SYMBOL_GPL(nf_tables_flowtable_lookup);
4754 4852
4853struct nft_flowtable *
4854nf_tables_flowtable_lookup_byhandle(const struct nft_table *table,
4855 const struct nlattr *nla, u8 genmask)
4856{
4857 struct nft_flowtable *flowtable;
4858
4859 list_for_each_entry(flowtable, &table->flowtables, list) {
4860 if (be64_to_cpu(nla_get_be64(nla)) == flowtable->handle &&
4861 nft_active_genmask(flowtable, genmask))
4862 return flowtable;
4863 }
4864 return ERR_PTR(-ENOENT);
4865}
4866
4755#define NFT_FLOWTABLE_DEVICE_MAX 84867#define NFT_FLOWTABLE_DEVICE_MAX 8
4756 4868
4757static int nf_tables_parse_devices(const struct nft_ctx *ctx,4869static int nf_tables_parse_devices(const struct nft_ctx *ctx,
@@ -4960,6 +5072,8 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk, · 202 unmodified lines
4960 return -ENOMEM;5072 return -ENOMEM;
4961 5073
4962 flowtable->table = table;5074 flowtable->table = table;
5075 flowtable->handle = nf_tables_alloc_handle(table);
5076
4963 flowtable->name = nla_strdup(nla[NFTA_FLOWTABLE_NAME], GFP_KERNEL);5077 flowtable->name = nla_strdup(nla[NFTA_FLOWTABLE_NAME], GFP_KERNEL);
4964 if (!flowtable->name) {5078 if (!flowtable->name) {
4965 err = -ENOMEM;5079 err = -ENOMEM;
@@ -5034,8 +5148,14 @@ static int nf_tables_delflowtable(struct net *net, struct sock *nlsk, · 68 unmodified lines
5034 if (IS_ERR(table))5148 if (IS_ERR(table))
5035 return PTR_ERR(table);5149 return PTR_ERR(table);
5036 5150
5037 flowtable = nf_tables_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME],5151 if (nla[NFTA_FLOWTABLE_HANDLE])
5038 genmask);5152 flowtable = nf_tables_flowtable_lookup_byhandle(table,
5153 nla[NFTA_FLOWTABLE_HANDLE],
5154 genmask);
5155 else
5156 flowtable = nf_tables_flowtable_lookup(table,
5157 nla[NFTA_FLOWTABLE_NAME],
5158 genmask);
5039 if (IS_ERR(flowtable))5159 if (IS_ERR(flowtable))
5040 return PTR_ERR(flowtable);5160 return PTR_ERR(flowtable);
5041 if (flowtable->use > 0)5161 if (flowtable->use > 0)
@@ -5068,7 +5188,9 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net, · 26 unmodified lines
5068 5188
5069 if (nla_put_string(skb, NFTA_FLOWTABLE_TABLE, flowtable->table->name) ||5189 if (nla_put_string(skb, NFTA_FLOWTABLE_TABLE, flowtable->table->name) ||
5070 nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) ||5190 nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) ||
5071 nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)))5191 nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)) ||
5192 nla_put_be64(skb, NFTA_FLOWTABLE_HANDLE, cpu_to_be64(flowtable->handle),
5193 NFTA_FLOWTABLE_PAD))
5072 goto nla_put_failure;5194 goto nla_put_failure;
5073 5195
5074 nest = nla_nest_start(skb, NFTA_FLOWTABLE_HOOK);5196 nest = nla_nest_start(skb, NFTA_FLOWTABLE_HOOK);