| @@ -399,6 +399,8 @@ static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = { · 398 unmodified lines |
| 399 | 399 | [NFTA_TABLE_NAME] = { .type = NLA_STRING, |
| 400 | 400 | .len = NFT_TABLE_MAXNAMELEN - 1 }, |
| 401 | 401 | [NFTA_TABLE_FLAGS] = { .type = NLA_U32 }, |
| 402 | + [NFTA_TABLE_DEV] = { .type = NLA_STRING, |
| 403 | + .len = IFNAMSIZ - 1 }, |
| 402 | 404 | }; |
| 403 | 405 | |
| 404 | 406 | static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net, |
| @@ -423,6 +425,10 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net, · 18 unmodified lines |
| 423 | 425 | nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use))) |
| 424 | 426 | goto nla_put_failure; |
| 425 | 427 | |
| 428 | + if (table->dev && |
| 429 | + nla_put_string(skb, NFTA_TABLE_DEV, table->dev->name)) |
| 430 | + goto nla_put_failure; |
| 431 | + |
| 426 | 432 | nlmsg_end(skb, nlh); |
| 427 | 433 | return 0; |
| 428 | 434 | |
| @@ -608,6 +614,11 @@ static int nf_tables_updtable(struct nft_ctx *ctx) · 179 unmodified lines |
| 608 | 614 | if (flags == ctx->table->flags) |
| 609 | 615 | return 0; |
| 610 | 616 | |
| 617 | + if ((ctx->afi->flags & NFT_AF_NEEDS_DEV) && |
| 618 | + ctx->nla[NFTA_TABLE_DEV] && |
| 619 | + nla_strcmp(ctx->nla[NFTA_TABLE_DEV], ctx->table->dev->name)) |
| 620 | + return -EOPNOTSUPP; |
| 621 | + |
| 611 | 622 | trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE, |
| 612 | 623 | sizeof(struct nft_trans_table)); |
| 613 | 624 | if (trans == NULL) |
| @@ -645,6 +656,7 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb, · 31 unmodified lines |
| 645 | 656 | struct nft_table *table; |
| 646 | 657 | struct net *net = sock_net(skb->sk); |
| 647 | 658 | int family = nfmsg->nfgen_family; |
| 659 | + struct net_device *dev = NULL; |
| 648 | 660 | u32 flags = 0; |
| 649 | 661 | struct nft_ctx ctx; |
| 650 | 662 | int err; |
| @@ -679,30 +691,50 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb, · 28 unmodified lines |
| 679 | 691 | return -EINVAL; |
| 680 | 692 | } |
| 681 | 693 | |
| 694 | + if (afi->flags & NFT_AF_NEEDS_DEV) { |
| 695 | + char ifname[IFNAMSIZ]; |
| 696 | + |
| 697 | + if (!nla[NFTA_TABLE_DEV]) |
| 698 | + return -EOPNOTSUPP; |
| 699 | + |
| 700 | + nla_strlcpy(ifname, nla[NFTA_TABLE_DEV], IFNAMSIZ); |
| 701 | + dev = dev_get_by_name(net, ifname); |
| 702 | + if (!dev) |
| 703 | + return -ENOENT; |
| 704 | + } else if (nla[NFTA_TABLE_DEV]) { |
| 705 | + return -EOPNOTSUPP; |
| 706 | + } |
| 707 | + |
| 708 | + err = -EAFNOSUPPORT; |
| 682 | 709 | if (!try_module_get(afi->owner)) |
| 683 | | − return -EAFNOSUPPORT; |
| 710 | + goto err1; |
| 684 | 711 | |
| 685 | 712 | err = -ENOMEM; |
| 686 | 713 | table = kzalloc(sizeof(*table), GFP_KERNEL); |
| 687 | 714 | if (table == NULL) |
| 688 | | − goto err1; |
| 715 | + goto err2; |
| 689 | 716 | |
| 690 | 717 | nla_strlcpy(table->name, name, NFT_TABLE_MAXNAMELEN); |
| 691 | 718 | INIT_LIST_HEAD(&table->chains); |
| 692 | 719 | INIT_LIST_HEAD(&table->sets); |
| 693 | 720 | table->flags = flags; |
| 721 | + table->dev = dev; |
| 694 | 722 | |
| 695 | 723 | nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla); |
| 696 | 724 | err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE); |
| 697 | 725 | if (err < 0) |
| 698 | | − goto err2; |
| 726 | + goto err3; |
| 699 | 727 | |
| 700 | 728 | list_add_tail_rcu(&table->list, &afi->tables); |
| 701 | 729 | return 0; |
| 702 | | −err2: |
| 730 | +err3: |
| 703 | 731 | kfree(table); |
| 704 | | −err1: |
| 732 | +err2: |
| 705 | 733 | module_put(afi->owner); |
| 734 | +err1: |
| 735 | + if (dev != NULL) |
| 736 | + dev_put(dev); |
| 737 | + |
| 706 | 738 | return err; |
| 707 | 739 | } |
| 708 | 740 | |
| @@ -806,6 +838,9 @@ static void nf_tables_table_destroy(struct nft_ctx *ctx) · 97 unmodified lines |
| 806 | 838 | { |
| 807 | 839 | BUG_ON(ctx->table->use > 0); |
| 808 | 840 | |
| 841 | + if (ctx->table->dev) |
| 842 | + dev_put(ctx->table->dev); |
| 843 | + |
| 809 | 844 | kfree(ctx->table); |
| 810 | 845 | module_put(ctx->afi->owner); |
| 811 | 846 | } |
| @@ -1361,6 +1396,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, · 549 unmodified lines |
| 1361 | 1396 | ops->priority = priority; |
| 1362 | 1397 | ops->priv = chain; |
| 1363 | 1398 | ops->hook = afi->hooks[ops->hooknum]; |
| 1399 | + ops->dev = table->dev; |
| 1364 | 1400 | if (hookfn) |
| 1365 | 1401 | ops->hook = hookfn; |
| 1366 | 1402 | if (afi->hook_ops_init) |