| @@ -26,6 +26,7 @@ · 25 unmodified lines |
| 26 | static LIST_HEAD(nf_tables_expressions); | 26 | static LIST_HEAD(nf_tables_expressions); |
| 27 | static LIST_HEAD(nf_tables_objects); | 27 | static LIST_HEAD(nf_tables_objects); |
| 28 | static LIST_HEAD(nf_tables_flowtables); | 28 | static LIST_HEAD(nf_tables_flowtables); |
| | 29 | static u64 table_handle; |
| 29 | | 30 | |
| 30 | static void nft_ctx_init(struct nft_ctx *ctx, | 31 | static 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 | |
| | 336 | static 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 | |
| 335 | static struct nft_table *nf_tables_table_lookup(const struct net *net, | 350 | static 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 | |
| | 366 | static 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 | |
| 351 | static inline u64 nf_tables_alloc_handle(struct nft_table *table) | 382 | static 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 | |
| 399 | static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net, | 431 | static 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 | |
| 2508 | static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = { | 2557 | static 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 | |
| | 2598 | static 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 | |
| 2549 | static struct nft_set *nf_tables_set_lookup_byid(const struct net *net, | 2614 | static 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 | } |
| 4257 | EXPORT_SYMBOL_GPL(nf_tables_obj_lookup); | 4329 | EXPORT_SYMBOL_GPL(nf_tables_obj_lookup); |
| 4258 | | 4330 | |
| | 4331 | struct 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 | |
| 4259 | static const struct nla_policy nft_obj_policy[NFTA_OBJ_MAX + 1] = { | 4346 | static 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 | |
| 4268 | static struct nft_object *nft_obj_init(const struct nft_ctx *ctx, | 4356 | static 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 | |
| 4740 | struct nft_flowtable *nf_tables_flowtable_lookup(const struct nft_table *table, | 4838 | struct 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 | } |
| 4753 | EXPORT_SYMBOL_GPL(nf_tables_flowtable_lookup); | 4851 | EXPORT_SYMBOL_GPL(nf_tables_flowtable_lookup); |
| 4754 | | 4852 | |
| | 4853 | struct nft_flowtable * |
| | 4854 | nf_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 8 | 4867 | #define NFT_FLOWTABLE_DEVICE_MAX 8 |
| 4756 | | 4868 | |
| 4757 | static int nf_tables_parse_devices(const struct nft_ctx *ctx, | 4869 | static 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); |