Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nfnetlink: pass struct nfnl_info to rcu callbacks

Update rcu callbacks to use the nfnl_info structure.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

+109 -122
+2 -4
include/linux/netfilter/nfnetlink.h
··· 17 17 struct nfnl_callback { 18 18 int (*call)(struct sk_buff *skb, const struct nfnl_info *info, 19 19 const struct nlattr * const cda[]); 20 - int (*call_rcu)(struct net *net, struct sock *nl, struct sk_buff *skb, 21 - const struct nlmsghdr *nlh, 22 - const struct nlattr * const cda[], 23 - struct netlink_ext_ack *extack); 20 + int (*call_rcu)(struct sk_buff *skb, const struct nfnl_info *info, 21 + const struct nlattr * const cda[]); 24 22 int (*call_batch)(struct net *net, struct sock *nl, struct sk_buff *skb, 25 23 const struct nlmsghdr *nlh, 26 24 const struct nlattr * const cda[],
+76 -78
net/netfilter/nf_tables_api.c
··· 858 858 } 859 859 860 860 /* called with rcu_read_lock held */ 861 - static int nf_tables_gettable(struct net *net, struct sock *nlsk, 862 - struct sk_buff *skb, const struct nlmsghdr *nlh, 863 - const struct nlattr * const nla[], 864 - struct netlink_ext_ack *extack) 861 + static int nf_tables_gettable(struct sk_buff *skb, const struct nfnl_info *info, 862 + const struct nlattr * const nla[]) 865 863 { 866 - const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 867 - u8 genmask = nft_genmask_cur(net); 868 - const struct nft_table *table; 869 - struct sk_buff *skb2; 864 + const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 865 + struct netlink_ext_ack *extack = info->extack; 866 + u8 genmask = nft_genmask_cur(info->net); 870 867 int family = nfmsg->nfgen_family; 868 + const struct nft_table *table; 869 + struct net *net = info->net; 870 + struct sk_buff *skb2; 871 871 int err; 872 872 873 - if (nlh->nlmsg_flags & NLM_F_DUMP) { 873 + if (info->nlh->nlmsg_flags & NLM_F_DUMP) { 874 874 struct netlink_dump_control c = { 875 875 .dump = nf_tables_dump_tables, 876 876 .module = THIS_MODULE, 877 877 }; 878 878 879 - return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c); 879 + return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); 880 880 } 881 881 882 882 table = nft_table_lookup(net, nla[NFTA_TABLE_NAME], family, genmask, 0); ··· 890 890 return -ENOMEM; 891 891 892 892 err = nf_tables_fill_table_info(skb2, net, NETLINK_CB(skb).portid, 893 - nlh->nlmsg_seq, NFT_MSG_NEWTABLE, 0, 894 - family, table); 893 + info->nlh->nlmsg_seq, NFT_MSG_NEWTABLE, 894 + 0, family, table); 895 895 if (err < 0) 896 896 goto err_fill_table_info; 897 897 ··· 1623 1623 } 1624 1624 1625 1625 /* called with rcu_read_lock held */ 1626 - static int nf_tables_getchain(struct net *net, struct sock *nlsk, 1627 - struct sk_buff *skb, const struct nlmsghdr *nlh, 1628 - const struct nlattr * const nla[], 1629 - struct netlink_ext_ack *extack) 1626 + static int nf_tables_getchain(struct sk_buff *skb, const struct nfnl_info *info, 1627 + const struct nlattr * const nla[]) 1630 1628 { 1631 - const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1632 - u8 genmask = nft_genmask_cur(net); 1629 + const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 1630 + struct netlink_ext_ack *extack = info->extack; 1631 + u8 genmask = nft_genmask_cur(info->net); 1632 + int family = nfmsg->nfgen_family; 1633 1633 const struct nft_chain *chain; 1634 + struct net *net = info->net; 1634 1635 struct nft_table *table; 1635 1636 struct sk_buff *skb2; 1636 - int family = nfmsg->nfgen_family; 1637 1637 int err; 1638 1638 1639 - if (nlh->nlmsg_flags & NLM_F_DUMP) { 1639 + if (info->nlh->nlmsg_flags & NLM_F_DUMP) { 1640 1640 struct netlink_dump_control c = { 1641 1641 .dump = nf_tables_dump_chains, 1642 1642 .module = THIS_MODULE, 1643 1643 }; 1644 1644 1645 - return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c); 1645 + return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); 1646 1646 } 1647 1647 1648 1648 table = nft_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, genmask, 0); ··· 1662 1662 return -ENOMEM; 1663 1663 1664 1664 err = nf_tables_fill_chain_info(skb2, net, NETLINK_CB(skb).portid, 1665 - nlh->nlmsg_seq, NFT_MSG_NEWCHAIN, 0, 1666 - family, table, chain); 1665 + info->nlh->nlmsg_seq, NFT_MSG_NEWCHAIN, 1666 + 0, family, table, chain); 1667 1667 if (err < 0) 1668 1668 goto err_fill_chain_info; 1669 1669 ··· 3076 3076 } 3077 3077 3078 3078 /* called with rcu_read_lock held */ 3079 - static int nf_tables_getrule(struct net *net, struct sock *nlsk, 3080 - struct sk_buff *skb, const struct nlmsghdr *nlh, 3081 - const struct nlattr * const nla[], 3082 - struct netlink_ext_ack *extack) 3079 + static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info, 3080 + const struct nlattr * const nla[]) 3083 3081 { 3084 - const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 3085 - u8 genmask = nft_genmask_cur(net); 3082 + const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 3083 + struct netlink_ext_ack *extack = info->extack; 3084 + u8 genmask = nft_genmask_cur(info->net); 3085 + int family = nfmsg->nfgen_family; 3086 3086 const struct nft_chain *chain; 3087 3087 const struct nft_rule *rule; 3088 + struct net *net = info->net; 3088 3089 struct nft_table *table; 3089 3090 struct sk_buff *skb2; 3090 - int family = nfmsg->nfgen_family; 3091 3091 int err; 3092 3092 3093 - if (nlh->nlmsg_flags & NLM_F_DUMP) { 3093 + if (info->nlh->nlmsg_flags & NLM_F_DUMP) { 3094 3094 struct netlink_dump_control c = { 3095 3095 .start= nf_tables_dump_rules_start, 3096 3096 .dump = nf_tables_dump_rules, ··· 3099 3099 .data = (void *)nla, 3100 3100 }; 3101 3101 3102 - return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c); 3102 + return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); 3103 3103 } 3104 3104 3105 3105 table = nft_table_lookup(net, nla[NFTA_RULE_TABLE], family, genmask, 0); ··· 3125 3125 return -ENOMEM; 3126 3126 3127 3127 err = nf_tables_fill_rule_info(skb2, net, NETLINK_CB(skb).portid, 3128 - nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0, 3128 + info->nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0, 3129 3129 family, table, chain, rule, NULL); 3130 3130 if (err < 0) 3131 3131 goto err_fill_rule_info; ··· 4045 4045 } 4046 4046 4047 4047 /* called with rcu_read_lock held */ 4048 - static int nf_tables_getset(struct net *net, struct sock *nlsk, 4049 - struct sk_buff *skb, const struct nlmsghdr *nlh, 4050 - const struct nlattr * const nla[], 4051 - struct netlink_ext_ack *extack) 4048 + static int nf_tables_getset(struct sk_buff *skb, const struct nfnl_info *info, 4049 + const struct nlattr * const nla[]) 4052 4050 { 4053 - u8 genmask = nft_genmask_cur(net); 4051 + const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 4052 + struct netlink_ext_ack *extack = info->extack; 4053 + u8 genmask = nft_genmask_cur(info->net); 4054 + struct net *net = info->net; 4054 4055 const struct nft_set *set; 4055 - struct nft_ctx ctx; 4056 4056 struct sk_buff *skb2; 4057 - const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 4057 + struct nft_ctx ctx; 4058 4058 int err; 4059 4059 4060 4060 /* Verify existence before starting dump */ 4061 - err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, extack, 4061 + err = nft_ctx_init_from_setattr(&ctx, net, skb, info->nlh, nla, extack, 4062 4062 genmask, 0); 4063 4063 if (err < 0) 4064 4064 return err; 4065 4065 4066 - if (nlh->nlmsg_flags & NLM_F_DUMP) { 4066 + if (info->nlh->nlmsg_flags & NLM_F_DUMP) { 4067 4067 struct netlink_dump_control c = { 4068 4068 .start = nf_tables_dump_sets_start, 4069 4069 .dump = nf_tables_dump_sets, ··· 4072 4072 .module = THIS_MODULE, 4073 4073 }; 4074 4074 4075 - return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c); 4075 + return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); 4076 4076 } 4077 4077 4078 4078 /* Only accept unspec with dump */ ··· 5063 5063 } 5064 5064 5065 5065 /* called with rcu_read_lock held */ 5066 - static int nf_tables_getsetelem(struct net *net, struct sock *nlsk, 5067 - struct sk_buff *skb, const struct nlmsghdr *nlh, 5068 - const struct nlattr * const nla[], 5069 - struct netlink_ext_ack *extack) 5066 + static int nf_tables_getsetelem(struct sk_buff *skb, 5067 + const struct nfnl_info *info, 5068 + const struct nlattr * const nla[]) 5070 5069 { 5071 - u8 genmask = nft_genmask_cur(net); 5070 + struct netlink_ext_ack *extack = info->extack; 5071 + u8 genmask = nft_genmask_cur(info->net); 5072 + struct net *net = info->net; 5072 5073 struct nft_set *set; 5073 5074 struct nlattr *attr; 5074 5075 struct nft_ctx ctx; 5075 5076 int rem, err = 0; 5076 5077 5077 - err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, extack, 5078 + err = nft_ctx_init_from_elemattr(&ctx, net, skb, info->nlh, nla, extack, 5078 5079 genmask, NETLINK_CB(skb).portid); 5079 5080 if (err < 0) 5080 5081 return err; ··· 5084 5083 if (IS_ERR(set)) 5085 5084 return PTR_ERR(set); 5086 5085 5087 - if (nlh->nlmsg_flags & NLM_F_DUMP) { 5086 + if (info->nlh->nlmsg_flags & NLM_F_DUMP) { 5088 5087 struct netlink_dump_control c = { 5089 5088 .start = nf_tables_dump_set_start, 5090 5089 .dump = nf_tables_dump_set, ··· 5097 5096 }; 5098 5097 5099 5098 c.data = &dump_ctx; 5100 - return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c); 5099 + return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); 5101 5100 } 5102 5101 5103 5102 if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS]) ··· 6417 6416 } 6418 6417 6419 6418 /* called with rcu_read_lock held */ 6420 - static int nf_tables_getobj(struct net *net, struct sock *nlsk, 6421 - struct sk_buff *skb, const struct nlmsghdr *nlh, 6422 - const struct nlattr * const nla[], 6423 - struct netlink_ext_ack *extack) 6419 + static int nf_tables_getobj(struct sk_buff *skb, const struct nfnl_info *info, 6420 + const struct nlattr * const nla[]) 6424 6421 { 6425 - const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 6426 - u8 genmask = nft_genmask_cur(net); 6422 + const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 6423 + struct netlink_ext_ack *extack = info->extack; 6424 + u8 genmask = nft_genmask_cur(info->net); 6427 6425 int family = nfmsg->nfgen_family; 6428 6426 const struct nft_table *table; 6427 + struct net *net = info->net; 6429 6428 struct nft_object *obj; 6430 6429 struct sk_buff *skb2; 6431 6430 bool reset = false; 6432 6431 u32 objtype; 6433 6432 int err; 6434 6433 6435 - if (nlh->nlmsg_flags & NLM_F_DUMP) { 6434 + if (info->nlh->nlmsg_flags & NLM_F_DUMP) { 6436 6435 struct netlink_dump_control c = { 6437 6436 .start = nf_tables_dump_obj_start, 6438 6437 .dump = nf_tables_dump_obj, ··· 6441 6440 .data = (void *)nla, 6442 6441 }; 6443 6442 6444 - return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c); 6443 + return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); 6445 6444 } 6446 6445 6447 6446 if (!nla[NFTA_OBJ_NAME] || ··· 6465 6464 if (!skb2) 6466 6465 return -ENOMEM; 6467 6466 6468 - if (NFNL_MSG_TYPE(nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET) 6467 + if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET) 6469 6468 reset = true; 6470 6469 6471 6470 if (reset) { ··· 6484 6483 } 6485 6484 6486 6485 err = nf_tables_fill_obj_info(skb2, net, NETLINK_CB(skb).portid, 6487 - nlh->nlmsg_seq, NFT_MSG_NEWOBJ, 0, 6486 + info->nlh->nlmsg_seq, NFT_MSG_NEWOBJ, 0, 6488 6487 family, table, obj, reset); 6489 6488 if (err < 0) 6490 6489 goto err_fill_obj_info; ··· 7321 7320 } 7322 7321 7323 7322 /* called with rcu_read_lock held */ 7324 - static int nf_tables_getflowtable(struct net *net, struct sock *nlsk, 7325 - struct sk_buff *skb, 7326 - const struct nlmsghdr *nlh, 7327 - const struct nlattr * const nla[], 7328 - struct netlink_ext_ack *extack) 7323 + static int nf_tables_getflowtable(struct sk_buff *skb, 7324 + const struct nfnl_info *info, 7325 + const struct nlattr * const nla[]) 7329 7326 { 7330 - const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 7331 - u8 genmask = nft_genmask_cur(net); 7327 + const struct nfgenmsg *nfmsg = nlmsg_data(info->nlh); 7328 + u8 genmask = nft_genmask_cur(info->net); 7332 7329 int family = nfmsg->nfgen_family; 7333 7330 struct nft_flowtable *flowtable; 7334 7331 const struct nft_table *table; 7332 + struct net *net = info->net; 7335 7333 struct sk_buff *skb2; 7336 7334 int err; 7337 7335 7338 - if (nlh->nlmsg_flags & NLM_F_DUMP) { 7336 + if (info->nlh->nlmsg_flags & NLM_F_DUMP) { 7339 7337 struct netlink_dump_control c = { 7340 7338 .start = nf_tables_dump_flowtable_start, 7341 7339 .dump = nf_tables_dump_flowtable, ··· 7343 7343 .data = (void *)nla, 7344 7344 }; 7345 7345 7346 - return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c); 7346 + return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); 7347 7347 } 7348 7348 7349 7349 if (!nla[NFTA_FLOWTABLE_NAME]) ··· 7364 7364 return -ENOMEM; 7365 7365 7366 7366 err = nf_tables_fill_flowtable_info(skb2, net, NETLINK_CB(skb).portid, 7367 - nlh->nlmsg_seq, 7367 + info->nlh->nlmsg_seq, 7368 7368 NFT_MSG_NEWFLOWTABLE, 0, family, 7369 7369 flowtable, &flowtable->hook_list); 7370 7370 if (err < 0) ··· 7526 7526 -ENOBUFS); 7527 7527 } 7528 7528 7529 - static int nf_tables_getgen(struct net *net, struct sock *nlsk, 7530 - struct sk_buff *skb, const struct nlmsghdr *nlh, 7531 - const struct nlattr * const nla[], 7532 - struct netlink_ext_ack *extack) 7529 + static int nf_tables_getgen(struct sk_buff *skb, const struct nfnl_info *info, 7530 + const struct nlattr * const nla[]) 7533 7531 { 7534 7532 struct sk_buff *skb2; 7535 7533 int err; ··· 7536 7538 if (skb2 == NULL) 7537 7539 return -ENOMEM; 7538 7540 7539 - err = nf_tables_fill_gen_info(skb2, net, NETLINK_CB(skb).portid, 7540 - nlh->nlmsg_seq); 7541 + err = nf_tables_fill_gen_info(skb2, info->net, NETLINK_CB(skb).portid, 7542 + info->nlh->nlmsg_seq); 7541 7543 if (err < 0) 7542 7544 goto err_fill_gen_info; 7543 7545 7544 - return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid); 7546 + return nfnetlink_unicast(skb2, info->net, NETLINK_CB(skb).portid); 7545 7547 7546 7548 err_fill_gen_info: 7547 7549 kfree_skb(skb2);
+2 -3
net/netfilter/nfnetlink.c
··· 274 274 } 275 275 276 276 if (nc->call_rcu) { 277 - err = nc->call_rcu(net, nfnlnet->nfnl, skb, nlh, 278 - (const struct nlattr **)cda, 279 - extack); 277 + err = nc->call_rcu(skb, &info, 278 + (const struct nlattr **)cda); 280 279 rcu_read_unlock(); 281 280 } else { 282 281 rcu_read_unlock();
+11 -13
net/netfilter/nft_compat.c
··· 613 613 return -1; 614 614 } 615 615 616 - static int nfnl_compat_get_rcu(struct net *net, struct sock *nfnl, 617 - struct sk_buff *skb, const struct nlmsghdr *nlh, 618 - const struct nlattr * const tb[], 619 - struct netlink_ext_ack *extack) 616 + static int nfnl_compat_get_rcu(struct sk_buff *skb, 617 + const struct nfnl_info *info, 618 + const struct nlattr * const tb[]) 620 619 { 621 - int ret = 0, target; 622 620 struct nfgenmsg *nfmsg; 623 - const char *fmt; 624 - const char *name; 625 - u32 rev; 621 + const char *name, *fmt; 626 622 struct sk_buff *skb2; 623 + int ret = 0, target; 624 + u32 rev; 627 625 628 626 if (tb[NFTA_COMPAT_NAME] == NULL || 629 627 tb[NFTA_COMPAT_REV] == NULL || ··· 632 634 rev = ntohl(nla_get_be32(tb[NFTA_COMPAT_REV])); 633 635 target = ntohl(nla_get_be32(tb[NFTA_COMPAT_TYPE])); 634 636 635 - nfmsg = nlmsg_data(nlh); 637 + nfmsg = nlmsg_data(info->nlh); 636 638 637 639 switch(nfmsg->nfgen_family) { 638 640 case AF_INET: ··· 671 673 672 674 /* include the best revision for this extension in the message */ 673 675 if (nfnl_compat_fill_info(skb2, NETLINK_CB(skb).portid, 674 - nlh->nlmsg_seq, 675 - NFNL_MSG_TYPE(nlh->nlmsg_type), 676 + info->nlh->nlmsg_seq, 677 + NFNL_MSG_TYPE(info->nlh->nlmsg_type), 676 678 NFNL_MSG_COMPAT_GET, 677 679 nfmsg->nfgen_family, 678 680 name, ret, target) <= 0) { ··· 680 682 goto out_put; 681 683 } 682 684 683 - ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).portid, 684 - MSG_DONTWAIT); 685 + ret = netlink_unicast(info->sk, skb2, NETLINK_CB(skb).portid, 686 + MSG_DONTWAIT); 685 687 if (ret > 0) 686 688 ret = 0; 687 689 out_put: