diff options
| -rw-r--r-- | include/net/netfilter/nf_tables.h | 23 | ||||
| -rw-r--r-- | net/bridge/netfilter/nf_tables_bridge.c | 25 | ||||
| -rw-r--r-- | net/ipv4/netfilter/nf_tables_arp.c | 25 | ||||
| -rw-r--r-- | net/ipv4/netfilter/nf_tables_ipv4.c | 24 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nf_tables_ipv6.c | 24 | ||||
| -rw-r--r-- | net/netfilter/nf_tables_api.c | 305 | ||||
| -rw-r--r-- | net/netfilter/nf_tables_inet.c | 23 | ||||
| -rw-r--r-- | net/netfilter/nf_tables_netdev.c | 19 |
8 files changed, 86 insertions, 382 deletions
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 12f83d223caa..4aca413367ee 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h | |||
| @@ -960,28 +960,12 @@ struct nft_table { | |||
| 960 | struct list_head flowtables; | 960 | struct list_head flowtables; |
| 961 | u64 hgenerator; | 961 | u64 hgenerator; |
| 962 | u32 use; | 962 | u32 use; |
| 963 | u16 flags:14, | 963 | u16 family:6, |
| 964 | flags:8, | ||
| 964 | genmask:2; | 965 | genmask:2; |
| 965 | struct nft_af_info *afi; | ||
| 966 | char *name; | 966 | char *name; |
| 967 | }; | 967 | }; |
| 968 | 968 | ||
| 969 | /** | ||
| 970 | * struct nft_af_info - nf_tables address family info | ||
| 971 | * | ||
| 972 | * @list: used internally | ||
| 973 | * @family: address family | ||
| 974 | * @owner: module owner | ||
| 975 | */ | ||
| 976 | struct nft_af_info { | ||
| 977 | struct list_head list; | ||
| 978 | int family; | ||
| 979 | struct module *owner; | ||
| 980 | }; | ||
| 981 | |||
| 982 | int nft_register_afinfo(struct nft_af_info *); | ||
| 983 | void nft_unregister_afinfo(struct nft_af_info *); | ||
| 984 | |||
| 985 | int nft_register_chain_type(const struct nf_chain_type *); | 969 | int nft_register_chain_type(const struct nf_chain_type *); |
| 986 | void nft_unregister_chain_type(const struct nf_chain_type *); | 970 | void nft_unregister_chain_type(const struct nf_chain_type *); |
| 987 | 971 | ||
| @@ -1146,9 +1130,6 @@ void nft_trace_init(struct nft_traceinfo *info, const struct nft_pktinfo *pkt, | |||
| 1146 | 1130 | ||
| 1147 | void nft_trace_notify(struct nft_traceinfo *info); | 1131 | void nft_trace_notify(struct nft_traceinfo *info); |
| 1148 | 1132 | ||
| 1149 | #define MODULE_ALIAS_NFT_FAMILY(family) \ | ||
| 1150 | MODULE_ALIAS("nft-afinfo-" __stringify(family)) | ||
| 1151 | |||
| 1152 | #define MODULE_ALIAS_NFT_CHAIN(family, name) \ | 1133 | #define MODULE_ALIAS_NFT_CHAIN(family, name) \ |
| 1153 | MODULE_ALIAS("nft-chain-" __stringify(family) "-" name) | 1134 | MODULE_ALIAS("nft-chain-" __stringify(family) "-" name) |
| 1154 | 1135 | ||
diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c index dbf7195f059c..5160cf614176 100644 --- a/net/bridge/netfilter/nf_tables_bridge.c +++ b/net/bridge/netfilter/nf_tables_bridge.c | |||
| @@ -42,11 +42,6 @@ nft_do_chain_bridge(void *priv, | |||
| 42 | return nft_do_chain(&pkt, priv); | 42 | return nft_do_chain(&pkt, priv); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | static struct nft_af_info nft_af_bridge __read_mostly = { | ||
| 46 | .family = NFPROTO_BRIDGE, | ||
| 47 | .owner = THIS_MODULE, | ||
| 48 | }; | ||
| 49 | |||
| 50 | static const struct nf_chain_type filter_bridge = { | 45 | static const struct nf_chain_type filter_bridge = { |
| 51 | .name = "filter", | 46 | .name = "filter", |
| 52 | .type = NFT_CHAIN_T_DEFAULT, | 47 | .type = NFT_CHAIN_T_DEFAULT, |
| @@ -68,28 +63,12 @@ static const struct nf_chain_type filter_bridge = { | |||
| 68 | 63 | ||
| 69 | static int __init nf_tables_bridge_init(void) | 64 | static int __init nf_tables_bridge_init(void) |
| 70 | { | 65 | { |
| 71 | int ret; | 66 | return nft_register_chain_type(&filter_bridge); |
| 72 | |||
| 73 | ret = nft_register_afinfo(&nft_af_bridge); | ||
| 74 | if (ret < 0) | ||
| 75 | return ret; | ||
| 76 | |||
| 77 | ret = nft_register_chain_type(&filter_bridge); | ||
| 78 | if (ret < 0) | ||
| 79 | goto err_register_chain; | ||
| 80 | |||
| 81 | return ret; | ||
| 82 | |||
| 83 | err_register_chain: | ||
| 84 | nft_unregister_chain_type(&filter_bridge); | ||
| 85 | |||
| 86 | return ret; | ||
| 87 | } | 67 | } |
| 88 | 68 | ||
| 89 | static void __exit nf_tables_bridge_exit(void) | 69 | static void __exit nf_tables_bridge_exit(void) |
| 90 | { | 70 | { |
| 91 | nft_unregister_chain_type(&filter_bridge); | 71 | nft_unregister_chain_type(&filter_bridge); |
| 92 | nft_unregister_afinfo(&nft_af_bridge); | ||
| 93 | } | 72 | } |
| 94 | 73 | ||
| 95 | module_init(nf_tables_bridge_init); | 74 | module_init(nf_tables_bridge_init); |
| @@ -97,4 +76,4 @@ module_exit(nf_tables_bridge_exit); | |||
| 97 | 76 | ||
| 98 | MODULE_LICENSE("GPL"); | 77 | MODULE_LICENSE("GPL"); |
| 99 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | 78 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); |
| 100 | MODULE_ALIAS_NFT_FAMILY(AF_BRIDGE); | 79 | MODULE_ALIAS_NFT_CHAIN(AF_BRIDGE, "filter"); |
diff --git a/net/ipv4/netfilter/nf_tables_arp.c b/net/ipv4/netfilter/nf_tables_arp.c index 07667388ceb5..036c074736b0 100644 --- a/net/ipv4/netfilter/nf_tables_arp.c +++ b/net/ipv4/netfilter/nf_tables_arp.c | |||
| @@ -27,11 +27,6 @@ nft_do_chain_arp(void *priv, | |||
| 27 | return nft_do_chain(&pkt, priv); | 27 | return nft_do_chain(&pkt, priv); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | static struct nft_af_info nft_af_arp __read_mostly = { | ||
| 31 | .family = NFPROTO_ARP, | ||
| 32 | .owner = THIS_MODULE, | ||
| 33 | }; | ||
| 34 | |||
| 35 | static const struct nf_chain_type filter_arp = { | 30 | static const struct nf_chain_type filter_arp = { |
| 36 | .name = "filter", | 31 | .name = "filter", |
| 37 | .type = NFT_CHAIN_T_DEFAULT, | 32 | .type = NFT_CHAIN_T_DEFAULT, |
| @@ -47,28 +42,12 @@ static const struct nf_chain_type filter_arp = { | |||
| 47 | 42 | ||
| 48 | static int __init nf_tables_arp_init(void) | 43 | static int __init nf_tables_arp_init(void) |
| 49 | { | 44 | { |
| 50 | int ret; | 45 | return nft_register_chain_type(&filter_arp); |
| 51 | |||
| 52 | ret = nft_register_afinfo(&nft_af_arp); | ||
| 53 | if (ret < 0) | ||
| 54 | return ret; | ||
| 55 | |||
| 56 | ret = nft_register_chain_type(&filter_arp); | ||
| 57 | if (ret < 0) | ||
| 58 | goto err_register_chain; | ||
| 59 | |||
| 60 | return 0; | ||
| 61 | |||
| 62 | err_register_chain: | ||
| 63 | nft_unregister_chain_type(&filter_arp); | ||
| 64 | |||
| 65 | return ret; | ||
| 66 | } | 46 | } |
| 67 | 47 | ||
| 68 | static void __exit nf_tables_arp_exit(void) | 48 | static void __exit nf_tables_arp_exit(void) |
| 69 | { | 49 | { |
| 70 | nft_unregister_chain_type(&filter_arp); | 50 | nft_unregister_chain_type(&filter_arp); |
| 71 | nft_unregister_afinfo(&nft_af_arp); | ||
| 72 | } | 51 | } |
| 73 | 52 | ||
| 74 | module_init(nf_tables_arp_init); | 53 | module_init(nf_tables_arp_init); |
| @@ -76,4 +55,4 @@ module_exit(nf_tables_arp_exit); | |||
| 76 | 55 | ||
| 77 | MODULE_LICENSE("GPL"); | 56 | MODULE_LICENSE("GPL"); |
| 78 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | 57 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); |
| 79 | MODULE_ALIAS_NFT_FAMILY(3); /* NFPROTO_ARP */ | 58 | MODULE_ALIAS_NFT_CHAIN(3, "filter"); /* NFPROTO_ARP */ |
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c index e1441738acb4..96f955496d5f 100644 --- a/net/ipv4/netfilter/nf_tables_ipv4.c +++ b/net/ipv4/netfilter/nf_tables_ipv4.c | |||
| @@ -30,11 +30,6 @@ static unsigned int nft_do_chain_ipv4(void *priv, | |||
| 30 | return nft_do_chain(&pkt, priv); | 30 | return nft_do_chain(&pkt, priv); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | static struct nft_af_info nft_af_ipv4 __read_mostly = { | ||
| 34 | .family = NFPROTO_IPV4, | ||
| 35 | .owner = THIS_MODULE, | ||
| 36 | }; | ||
| 37 | |||
| 38 | static const struct nf_chain_type filter_ipv4 = { | 33 | static const struct nf_chain_type filter_ipv4 = { |
| 39 | .name = "filter", | 34 | .name = "filter", |
| 40 | .type = NFT_CHAIN_T_DEFAULT, | 35 | .type = NFT_CHAIN_T_DEFAULT, |
| @@ -56,27 +51,12 @@ static const struct nf_chain_type filter_ipv4 = { | |||
| 56 | 51 | ||
| 57 | static int __init nf_tables_ipv4_init(void) | 52 | static int __init nf_tables_ipv4_init(void) |
| 58 | { | 53 | { |
| 59 | int ret; | 54 | return nft_register_chain_type(&filter_ipv4); |
| 60 | |||
| 61 | ret = nft_register_afinfo(&nft_af_ipv4); | ||
| 62 | if (ret < 0) | ||
| 63 | return ret; | ||
| 64 | |||
| 65 | ret = nft_register_chain_type(&filter_ipv4); | ||
| 66 | if (ret < 0) | ||
| 67 | goto err_register_chain; | ||
| 68 | |||
| 69 | return 0; | ||
| 70 | |||
| 71 | err_register_chain: | ||
| 72 | nft_unregister_afinfo(&nft_af_ipv4); | ||
| 73 | return ret; | ||
| 74 | } | 55 | } |
| 75 | 56 | ||
| 76 | static void __exit nf_tables_ipv4_exit(void) | 57 | static void __exit nf_tables_ipv4_exit(void) |
| 77 | { | 58 | { |
| 78 | nft_unregister_chain_type(&filter_ipv4); | 59 | nft_unregister_chain_type(&filter_ipv4); |
| 79 | nft_unregister_afinfo(&nft_af_ipv4); | ||
| 80 | } | 60 | } |
| 81 | 61 | ||
| 82 | module_init(nf_tables_ipv4_init); | 62 | module_init(nf_tables_ipv4_init); |
| @@ -84,4 +64,4 @@ module_exit(nf_tables_ipv4_exit); | |||
| 84 | 64 | ||
| 85 | MODULE_LICENSE("GPL"); | 65 | MODULE_LICENSE("GPL"); |
| 86 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | 66 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); |
| 87 | MODULE_ALIAS_NFT_FAMILY(AF_INET); | 67 | MODULE_ALIAS_NFT_CHAIN(AF_INET, "filter"); |
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c index 912d0e5516b0..17e03589331c 100644 --- a/net/ipv6/netfilter/nf_tables_ipv6.c +++ b/net/ipv6/netfilter/nf_tables_ipv6.c | |||
| @@ -28,11 +28,6 @@ static unsigned int nft_do_chain_ipv6(void *priv, | |||
| 28 | return nft_do_chain(&pkt, priv); | 28 | return nft_do_chain(&pkt, priv); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | static struct nft_af_info nft_af_ipv6 __read_mostly = { | ||
| 32 | .family = NFPROTO_IPV6, | ||
| 33 | .owner = THIS_MODULE, | ||
| 34 | }; | ||
| 35 | |||
| 36 | static const struct nf_chain_type filter_ipv6 = { | 31 | static const struct nf_chain_type filter_ipv6 = { |
| 37 | .name = "filter", | 32 | .name = "filter", |
| 38 | .type = NFT_CHAIN_T_DEFAULT, | 33 | .type = NFT_CHAIN_T_DEFAULT, |
| @@ -54,26 +49,11 @@ static const struct nf_chain_type filter_ipv6 = { | |||
| 54 | 49 | ||
| 55 | static int __init nf_tables_ipv6_init(void) | 50 | static int __init nf_tables_ipv6_init(void) |
| 56 | { | 51 | { |
| 57 | int ret; | 52 | return nft_register_chain_type(&filter_ipv6); |
| 58 | |||
| 59 | ret = nft_register_afinfo(&nft_af_ipv6); | ||
| 60 | if (ret < 0) | ||
| 61 | return ret; | ||
| 62 | |||
| 63 | ret = nft_register_chain_type(&filter_ipv6); | ||
| 64 | if (ret < 0) | ||
| 65 | goto err_register_chain; | ||
| 66 | |||
| 67 | return 0; | ||
| 68 | |||
| 69 | err_register_chain: | ||
| 70 | nft_unregister_afinfo(&nft_af_ipv6); | ||
| 71 | return ret; | ||
| 72 | } | 53 | } |
| 73 | 54 | ||
| 74 | static void __exit nf_tables_ipv6_exit(void) | 55 | static void __exit nf_tables_ipv6_exit(void) |
| 75 | { | 56 | { |
| 76 | nft_unregister_afinfo(&nft_af_ipv6); | ||
| 77 | nft_unregister_chain_type(&filter_ipv6); | 57 | nft_unregister_chain_type(&filter_ipv6); |
| 78 | } | 58 | } |
| 79 | 59 | ||
| @@ -82,4 +62,4 @@ module_exit(nf_tables_ipv6_exit); | |||
| 82 | 62 | ||
| 83 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
| 84 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | 64 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); |
| 85 | MODULE_ALIAS_NFT_FAMILY(AF_INET6); | 65 | MODULE_ALIAS_NFT_CHAIN(AF_INET6, "filter"); |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index b0ff26beec80..0b814cbcd45e 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
| @@ -26,71 +26,6 @@ | |||
| 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 LIST_HEAD(nf_tables_af_info); | ||
| 30 | |||
| 31 | /** | ||
| 32 | * nft_register_afinfo - register nf_tables address family info | ||
| 33 | * | ||
| 34 | * @afi: address family info to register | ||
| 35 | * | ||
| 36 | * Register the address family for use with nf_tables. Returns zero on | ||
| 37 | * success or a negative errno code otherwise. | ||
| 38 | */ | ||
| 39 | int nft_register_afinfo(struct nft_af_info *afi) | ||
| 40 | { | ||
| 41 | nfnl_lock(NFNL_SUBSYS_NFTABLES); | ||
| 42 | list_add_tail_rcu(&afi->list, &nf_tables_af_info); | ||
| 43 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); | ||
| 44 | return 0; | ||
| 45 | } | ||
| 46 | EXPORT_SYMBOL_GPL(nft_register_afinfo); | ||
| 47 | |||
| 48 | /** | ||
| 49 | * nft_unregister_afinfo - unregister nf_tables address family info | ||
| 50 | * | ||
| 51 | * @afi: address family info to unregister | ||
| 52 | * | ||
| 53 | * Unregister the address family for use with nf_tables. | ||
| 54 | */ | ||
| 55 | void nft_unregister_afinfo(struct nft_af_info *afi) | ||
| 56 | { | ||
| 57 | nfnl_lock(NFNL_SUBSYS_NFTABLES); | ||
| 58 | list_del_rcu(&afi->list); | ||
| 59 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); | ||
| 60 | } | ||
| 61 | EXPORT_SYMBOL_GPL(nft_unregister_afinfo); | ||
| 62 | |||
| 63 | static struct nft_af_info *nft_afinfo_lookup(struct net *net, int family) | ||
| 64 | { | ||
| 65 | struct nft_af_info *afi; | ||
| 66 | |||
| 67 | list_for_each_entry(afi, &nf_tables_af_info, list) { | ||
| 68 | if (afi->family == family) | ||
| 69 | return afi; | ||
| 70 | } | ||
| 71 | return NULL; | ||
| 72 | } | ||
| 73 | |||
| 74 | static struct nft_af_info * | ||
| 75 | nf_tables_afinfo_lookup(struct net *net, int family, bool autoload) | ||
| 76 | { | ||
| 77 | struct nft_af_info *afi; | ||
| 78 | |||
| 79 | afi = nft_afinfo_lookup(net, family); | ||
| 80 | if (afi != NULL) | ||
| 81 | return afi; | ||
| 82 | #ifdef CONFIG_MODULES | ||
| 83 | if (autoload) { | ||
| 84 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); | ||
| 85 | request_module("nft-afinfo-%u", family); | ||
| 86 | nfnl_lock(NFNL_SUBSYS_NFTABLES); | ||
| 87 | afi = nft_afinfo_lookup(net, family); | ||
| 88 | if (afi != NULL) | ||
| 89 | return ERR_PTR(-EAGAIN); | ||
| 90 | } | ||
| 91 | #endif | ||
| 92 | return ERR_PTR(-EAFNOSUPPORT); | ||
| 93 | } | ||
| 94 | 29 | ||
| 95 | static void nft_ctx_init(struct nft_ctx *ctx, | 30 | static void nft_ctx_init(struct nft_ctx *ctx, |
| 96 | struct net *net, | 31 | struct net *net, |
| @@ -390,7 +325,7 @@ static struct nft_table *nft_table_lookup(const struct net *net, | |||
| 390 | 325 | ||
| 391 | list_for_each_entry(table, &net->nft.tables, list) { | 326 | list_for_each_entry(table, &net->nft.tables, list) { |
| 392 | if (!nla_strcmp(nla, table->name) && | 327 | if (!nla_strcmp(nla, table->name) && |
| 393 | table->afi->family == family && | 328 | table->family == family && |
| 394 | nft_active_genmask(table, genmask)) | 329 | nft_active_genmask(table, genmask)) |
| 395 | return table; | 330 | return table; |
| 396 | } | 331 | } |
| @@ -531,7 +466,7 @@ static int nf_tables_dump_tables(struct sk_buff *skb, | |||
| 531 | cb->seq = net->nft.base_seq; | 466 | cb->seq = net->nft.base_seq; |
| 532 | 467 | ||
| 533 | list_for_each_entry_rcu(table, &net->nft.tables, list) { | 468 | list_for_each_entry_rcu(table, &net->nft.tables, list) { |
| 534 | if (family != NFPROTO_UNSPEC && family != table->afi->family) | 469 | if (family != NFPROTO_UNSPEC && family != table->family) |
| 535 | continue; | 470 | continue; |
| 536 | 471 | ||
| 537 | if (idx < s_idx) | 472 | if (idx < s_idx) |
| @@ -545,7 +480,7 @@ static int nf_tables_dump_tables(struct sk_buff *skb, | |||
| 545 | NETLINK_CB(cb->skb).portid, | 480 | NETLINK_CB(cb->skb).portid, |
| 546 | cb->nlh->nlmsg_seq, | 481 | cb->nlh->nlmsg_seq, |
| 547 | NFT_MSG_NEWTABLE, NLM_F_MULTI, | 482 | NFT_MSG_NEWTABLE, NLM_F_MULTI, |
| 548 | table->afi->family, table) < 0) | 483 | table->family, table) < 0) |
| 549 | goto done; | 484 | goto done; |
| 550 | 485 | ||
| 551 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | 486 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); |
| @@ -565,7 +500,6 @@ static int nf_tables_gettable(struct net *net, struct sock *nlsk, | |||
| 565 | { | 500 | { |
| 566 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 501 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
| 567 | u8 genmask = nft_genmask_cur(net); | 502 | u8 genmask = nft_genmask_cur(net); |
| 568 | const struct nft_af_info *afi; | ||
| 569 | const struct nft_table *table; | 503 | const struct nft_table *table; |
| 570 | struct sk_buff *skb2; | 504 | struct sk_buff *skb2; |
| 571 | int family = nfmsg->nfgen_family; | 505 | int family = nfmsg->nfgen_family; |
| @@ -578,11 +512,7 @@ static int nf_tables_gettable(struct net *net, struct sock *nlsk, | |||
| 578 | return netlink_dump_start(nlsk, skb, nlh, &c); | 512 | return netlink_dump_start(nlsk, skb, nlh, &c); |
| 579 | } | 513 | } |
| 580 | 514 | ||
| 581 | afi = nf_tables_afinfo_lookup(net, family, false); | 515 | table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], family, |
| 582 | if (IS_ERR(afi)) | ||
| 583 | return PTR_ERR(afi); | ||
| 584 | |||
| 585 | table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], afi->family, | ||
| 586 | genmask); | 516 | genmask); |
| 587 | if (IS_ERR(table)) | 517 | if (IS_ERR(table)) |
| 588 | return PTR_ERR(table); | 518 | return PTR_ERR(table); |
| @@ -702,19 +632,14 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk, | |||
| 702 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 632 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
| 703 | u8 genmask = nft_genmask_next(net); | 633 | u8 genmask = nft_genmask_next(net); |
| 704 | const struct nlattr *name; | 634 | const struct nlattr *name; |
| 705 | struct nft_af_info *afi; | ||
| 706 | struct nft_table *table; | 635 | struct nft_table *table; |
| 707 | int family = nfmsg->nfgen_family; | 636 | int family = nfmsg->nfgen_family; |
| 708 | u32 flags = 0; | 637 | u32 flags = 0; |
| 709 | struct nft_ctx ctx; | 638 | struct nft_ctx ctx; |
| 710 | int err; | 639 | int err; |
| 711 | 640 | ||
| 712 | afi = nf_tables_afinfo_lookup(net, family, true); | ||
| 713 | if (IS_ERR(afi)) | ||
| 714 | return PTR_ERR(afi); | ||
| 715 | |||
| 716 | name = nla[NFTA_TABLE_NAME]; | 641 | name = nla[NFTA_TABLE_NAME]; |
| 717 | table = nf_tables_table_lookup(net, name, afi->family, genmask); | 642 | table = nf_tables_table_lookup(net, name, family, genmask); |
| 718 | if (IS_ERR(table)) { | 643 | if (IS_ERR(table)) { |
| 719 | if (PTR_ERR(table) != -ENOENT) | 644 | if (PTR_ERR(table) != -ENOENT) |
| 720 | return PTR_ERR(table); | 645 | return PTR_ERR(table); |
| @@ -724,7 +649,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk, | |||
| 724 | if (nlh->nlmsg_flags & NLM_F_REPLACE) | 649 | if (nlh->nlmsg_flags & NLM_F_REPLACE) |
| 725 | return -EOPNOTSUPP; | 650 | return -EOPNOTSUPP; |
| 726 | 651 | ||
| 727 | nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); | 652 | nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); |
| 728 | return nf_tables_updtable(&ctx); | 653 | return nf_tables_updtable(&ctx); |
| 729 | } | 654 | } |
| 730 | 655 | ||
| @@ -734,40 +659,34 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk, | |||
| 734 | return -EINVAL; | 659 | return -EINVAL; |
| 735 | } | 660 | } |
| 736 | 661 | ||
| 737 | err = -EAFNOSUPPORT; | ||
| 738 | if (!try_module_get(afi->owner)) | ||
| 739 | goto err1; | ||
| 740 | |||
| 741 | err = -ENOMEM; | 662 | err = -ENOMEM; |
| 742 | table = kzalloc(sizeof(*table), GFP_KERNEL); | 663 | table = kzalloc(sizeof(*table), GFP_KERNEL); |
| 743 | if (table == NULL) | 664 | if (table == NULL) |
| 744 | goto err2; | 665 | goto err_kzalloc; |
| 745 | 666 | ||
| 746 | table->name = nla_strdup(name, GFP_KERNEL); | 667 | table->name = nla_strdup(name, GFP_KERNEL); |
| 747 | if (table->name == NULL) | 668 | if (table->name == NULL) |
| 748 | goto err3; | 669 | goto err_strdup; |
| 749 | 670 | ||
| 750 | INIT_LIST_HEAD(&table->chains); | 671 | INIT_LIST_HEAD(&table->chains); |
| 751 | INIT_LIST_HEAD(&table->sets); | 672 | INIT_LIST_HEAD(&table->sets); |
| 752 | INIT_LIST_HEAD(&table->objects); | 673 | INIT_LIST_HEAD(&table->objects); |
| 753 | INIT_LIST_HEAD(&table->flowtables); | 674 | INIT_LIST_HEAD(&table->flowtables); |
| 754 | table->afi = afi; | 675 | table->family = family; |
| 755 | table->flags = flags; | 676 | table->flags = flags; |
| 756 | 677 | ||
| 757 | nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); | 678 | nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); |
| 758 | err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE); | 679 | err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE); |
| 759 | if (err < 0) | 680 | if (err < 0) |
| 760 | goto err4; | 681 | goto err_trans; |
| 761 | 682 | ||
| 762 | list_add_tail_rcu(&table->list, &net->nft.tables); | 683 | list_add_tail_rcu(&table->list, &net->nft.tables); |
| 763 | return 0; | 684 | return 0; |
| 764 | err4: | 685 | err_trans: |
| 765 | kfree(table->name); | 686 | kfree(table->name); |
| 766 | err3: | 687 | err_strdup: |
| 767 | kfree(table); | 688 | kfree(table); |
| 768 | err2: | 689 | err_kzalloc: |
| 769 | module_put(afi->owner); | ||
| 770 | err1: | ||
| 771 | return err; | 690 | return err; |
| 772 | } | 691 | } |
| 773 | 692 | ||
| @@ -838,10 +757,10 @@ static int nft_flush(struct nft_ctx *ctx, int family) | |||
| 838 | int err = 0; | 757 | int err = 0; |
| 839 | 758 | ||
| 840 | list_for_each_entry_safe(table, nt, &ctx->net->nft.tables, list) { | 759 | list_for_each_entry_safe(table, nt, &ctx->net->nft.tables, list) { |
| 841 | if (family != AF_UNSPEC && table->afi->family != family) | 760 | if (family != AF_UNSPEC && table->family != family) |
| 842 | continue; | 761 | continue; |
| 843 | 762 | ||
| 844 | ctx->family = table->afi->family; | 763 | ctx->family = table->family; |
| 845 | 764 | ||
| 846 | if (!nft_is_active_next(ctx->net, table)) | 765 | if (!nft_is_active_next(ctx->net, table)) |
| 847 | continue; | 766 | continue; |
| @@ -867,7 +786,6 @@ static int nf_tables_deltable(struct net *net, struct sock *nlsk, | |||
| 867 | { | 786 | { |
| 868 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 787 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
| 869 | u8 genmask = nft_genmask_next(net); | 788 | u8 genmask = nft_genmask_next(net); |
| 870 | struct nft_af_info *afi; | ||
| 871 | struct nft_table *table; | 789 | struct nft_table *table; |
| 872 | int family = nfmsg->nfgen_family; | 790 | int family = nfmsg->nfgen_family; |
| 873 | struct nft_ctx ctx; | 791 | struct nft_ctx ctx; |
| @@ -876,11 +794,7 @@ static int nf_tables_deltable(struct net *net, struct sock *nlsk, | |||
| 876 | if (family == AF_UNSPEC || nla[NFTA_TABLE_NAME] == NULL) | 794 | if (family == AF_UNSPEC || nla[NFTA_TABLE_NAME] == NULL) |
| 877 | return nft_flush(&ctx, family); | 795 | return nft_flush(&ctx, family); |
| 878 | 796 | ||
| 879 | afi = nf_tables_afinfo_lookup(net, family, false); | 797 | table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], family, |
| 880 | if (IS_ERR(afi)) | ||
| 881 | return PTR_ERR(afi); | ||
| 882 | |||
| 883 | table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], afi->family, | ||
| 884 | genmask); | 798 | genmask); |
| 885 | if (IS_ERR(table)) | 799 | if (IS_ERR(table)) |
| 886 | return PTR_ERR(table); | 800 | return PTR_ERR(table); |
| @@ -889,7 +803,7 @@ static int nf_tables_deltable(struct net *net, struct sock *nlsk, | |||
| 889 | table->use > 0) | 803 | table->use > 0) |
| 890 | return -EBUSY; | 804 | return -EBUSY; |
| 891 | 805 | ||
| 892 | ctx.family = afi->family; | 806 | ctx.family = family; |
| 893 | ctx.table = table; | 807 | ctx.table = table; |
| 894 | 808 | ||
| 895 | return nft_flush_table(&ctx); | 809 | return nft_flush_table(&ctx); |
| @@ -901,7 +815,6 @@ static void nf_tables_table_destroy(struct nft_ctx *ctx) | |||
| 901 | 815 | ||
| 902 | kfree(ctx->table->name); | 816 | kfree(ctx->table->name); |
| 903 | kfree(ctx->table); | 817 | kfree(ctx->table); |
| 904 | module_put(ctx->table->afi->owner); | ||
| 905 | } | 818 | } |
| 906 | 819 | ||
| 907 | int nft_register_chain_type(const struct nf_chain_type *ctype) | 820 | int nft_register_chain_type(const struct nf_chain_type *ctype) |
| @@ -1130,7 +1043,7 @@ static int nf_tables_dump_chains(struct sk_buff *skb, | |||
| 1130 | cb->seq = net->nft.base_seq; | 1043 | cb->seq = net->nft.base_seq; |
| 1131 | 1044 | ||
| 1132 | list_for_each_entry_rcu(table, &net->nft.tables, list) { | 1045 | list_for_each_entry_rcu(table, &net->nft.tables, list) { |
| 1133 | if (family != NFPROTO_UNSPEC && family != table->afi->family) | 1046 | if (family != NFPROTO_UNSPEC && family != table->family) |
| 1134 | continue; | 1047 | continue; |
| 1135 | 1048 | ||
| 1136 | list_for_each_entry_rcu(chain, &table->chains, list) { | 1049 | list_for_each_entry_rcu(chain, &table->chains, list) { |
| @@ -1146,7 +1059,7 @@ static int nf_tables_dump_chains(struct sk_buff *skb, | |||
| 1146 | cb->nlh->nlmsg_seq, | 1059 | cb->nlh->nlmsg_seq, |
| 1147 | NFT_MSG_NEWCHAIN, | 1060 | NFT_MSG_NEWCHAIN, |
| 1148 | NLM_F_MULTI, | 1061 | NLM_F_MULTI, |
| 1149 | table->afi->family, table, | 1062 | table->family, table, |
| 1150 | chain) < 0) | 1063 | chain) < 0) |
| 1151 | goto done; | 1064 | goto done; |
| 1152 | 1065 | ||
| @@ -1168,7 +1081,6 @@ static int nf_tables_getchain(struct net *net, struct sock *nlsk, | |||
| 1168 | { | 1081 | { |
| 1169 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 1082 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
| 1170 | u8 genmask = nft_genmask_cur(net); | 1083 | u8 genmask = nft_genmask_cur(net); |
| 1171 | const struct nft_af_info *afi; | ||
| 1172 | const struct nft_table *table; | 1084 | const struct nft_table *table; |
| 1173 | const struct nft_chain *chain; | 1085 | const struct nft_chain *chain; |
| 1174 | struct sk_buff *skb2; | 1086 | struct sk_buff *skb2; |
| @@ -1182,11 +1094,7 @@ static int nf_tables_getchain(struct net *net, struct sock *nlsk, | |||
| 1182 | return netlink_dump_start(nlsk, skb, nlh, &c); | 1094 | return netlink_dump_start(nlsk, skb, nlh, &c); |
| 1183 | } | 1095 | } |
| 1184 | 1096 | ||
| 1185 | afi = nf_tables_afinfo_lookup(net, family, false); | 1097 | table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, |
| 1186 | if (IS_ERR(afi)) | ||
| 1187 | return PTR_ERR(afi); | ||
| 1188 | |||
| 1189 | table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], afi->family, | ||
| 1190 | genmask); | 1098 | genmask); |
| 1191 | if (IS_ERR(table)) | 1099 | if (IS_ERR(table)) |
| 1192 | return PTR_ERR(table); | 1100 | return PTR_ERR(table); |
| @@ -1555,7 +1463,6 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk, | |||
| 1555 | const struct nlattr * uninitialized_var(name); | 1463 | const struct nlattr * uninitialized_var(name); |
| 1556 | u8 genmask = nft_genmask_next(net); | 1464 | u8 genmask = nft_genmask_next(net); |
| 1557 | int family = nfmsg->nfgen_family; | 1465 | int family = nfmsg->nfgen_family; |
| 1558 | struct nft_af_info *afi; | ||
| 1559 | struct nft_table *table; | 1466 | struct nft_table *table; |
| 1560 | struct nft_chain *chain; | 1467 | struct nft_chain *chain; |
| 1561 | u8 policy = NF_ACCEPT; | 1468 | u8 policy = NF_ACCEPT; |
| @@ -1565,11 +1472,7 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk, | |||
| 1565 | 1472 | ||
| 1566 | create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false; | 1473 | create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false; |
| 1567 | 1474 | ||
| 1568 | afi = nf_tables_afinfo_lookup(net, family, true); | 1475 | table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, |
| 1569 | if (IS_ERR(afi)) | ||
| 1570 | return PTR_ERR(afi); | ||
| 1571 | |||
| 1572 | table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], afi->family, | ||
| 1573 | genmask); | 1476 | genmask); |
| 1574 | if (IS_ERR(table)) | 1477 | if (IS_ERR(table)) |
| 1575 | return PTR_ERR(table); | 1478 | return PTR_ERR(table); |
| @@ -1610,7 +1513,7 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk, | |||
| 1610 | } | 1513 | } |
| 1611 | } | 1514 | } |
| 1612 | 1515 | ||
| 1613 | nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla); | 1516 | nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla); |
| 1614 | 1517 | ||
| 1615 | if (chain != NULL) { | 1518 | if (chain != NULL) { |
| 1616 | if (nlh->nlmsg_flags & NLM_F_EXCL) | 1519 | if (nlh->nlmsg_flags & NLM_F_EXCL) |
| @@ -1631,7 +1534,6 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk, | |||
| 1631 | { | 1534 | { |
| 1632 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 1535 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
| 1633 | u8 genmask = nft_genmask_next(net); | 1536 | u8 genmask = nft_genmask_next(net); |
| 1634 | struct nft_af_info *afi; | ||
| 1635 | struct nft_table *table; | 1537 | struct nft_table *table; |
| 1636 | struct nft_chain *chain; | 1538 | struct nft_chain *chain; |
| 1637 | struct nft_rule *rule; | 1539 | struct nft_rule *rule; |
| @@ -1640,11 +1542,7 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk, | |||
| 1640 | u32 use; | 1542 | u32 use; |
| 1641 | int err; | 1543 | int err; |
| 1642 | 1544 | ||
| 1643 | afi = nf_tables_afinfo_lookup(net, family, false); | 1545 | table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, |
| 1644 | if (IS_ERR(afi)) | ||
| 1645 | return PTR_ERR(afi); | ||
| 1646 | |||
| 1647 | table = nf_tables_table_lookup(net, nla[NFTA_CHAIN_TABLE], afi->family, | ||
| 1648 | genmask); | 1546 | genmask); |
| 1649 | if (IS_ERR(table)) | 1547 | if (IS_ERR(table)) |
| 1650 | return PTR_ERR(table); | 1548 | return PTR_ERR(table); |
| @@ -1657,7 +1555,7 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk, | |||
| 1657 | chain->use > 0) | 1555 | chain->use > 0) |
| 1658 | return -EBUSY; | 1556 | return -EBUSY; |
| 1659 | 1557 | ||
| 1660 | nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla); | 1558 | nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla); |
| 1661 | 1559 | ||
| 1662 | use = chain->use; | 1560 | use = chain->use; |
| 1663 | list_for_each_entry(rule, &chain->rules, list) { | 1561 | list_for_each_entry(rule, &chain->rules, list) { |
| @@ -2080,7 +1978,7 @@ static int nf_tables_dump_rules(struct sk_buff *skb, | |||
| 2080 | cb->seq = net->nft.base_seq; | 1978 | cb->seq = net->nft.base_seq; |
| 2081 | 1979 | ||
| 2082 | list_for_each_entry_rcu(table, &net->nft.tables, list) { | 1980 | list_for_each_entry_rcu(table, &net->nft.tables, list) { |
| 2083 | if (family != NFPROTO_UNSPEC && family != table->afi->family) | 1981 | if (family != NFPROTO_UNSPEC && family != table->family) |
| 2084 | continue; | 1982 | continue; |
| 2085 | 1983 | ||
| 2086 | if (ctx && ctx->table && strcmp(ctx->table, table->name) != 0) | 1984 | if (ctx && ctx->table && strcmp(ctx->table, table->name) != 0) |
| @@ -2103,7 +2001,7 @@ static int nf_tables_dump_rules(struct sk_buff *skb, | |||
| 2103 | cb->nlh->nlmsg_seq, | 2001 | cb->nlh->nlmsg_seq, |
| 2104 | NFT_MSG_NEWRULE, | 2002 | NFT_MSG_NEWRULE, |
| 2105 | NLM_F_MULTI | NLM_F_APPEND, | 2003 | NLM_F_MULTI | NLM_F_APPEND, |
| 2106 | table->afi->family, | 2004 | table->family, |
| 2107 | table, chain, rule) < 0) | 2005 | table, chain, rule) < 0) |
| 2108 | goto done; | 2006 | goto done; |
| 2109 | 2007 | ||
| @@ -2139,7 +2037,6 @@ static int nf_tables_getrule(struct net *net, struct sock *nlsk, | |||
| 2139 | { | 2037 | { |
| 2140 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 2038 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
| 2141 | u8 genmask = nft_genmask_cur(net); | 2039 | u8 genmask = nft_genmask_cur(net); |
| 2142 | const struct nft_af_info *afi; | ||
| 2143 | const struct nft_table *table; | 2040 | const struct nft_table *table; |
| 2144 | const struct nft_chain *chain; | 2041 | const struct nft_chain *chain; |
| 2145 | const struct nft_rule *rule; | 2042 | const struct nft_rule *rule; |
| @@ -2183,11 +2080,7 @@ static int nf_tables_getrule(struct net *net, struct sock *nlsk, | |||
| 2183 | return netlink_dump_start(nlsk, skb, nlh, &c); | 2080 | return netlink_dump_start(nlsk, skb, nlh, &c); |
| 2184 | } | 2081 | } |
| 2185 | 2082 | ||
| 2186 | afi = nf_tables_afinfo_lookup(net, family, false); | 2083 | table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], family, |
| 2187 | if (IS_ERR(afi)) | ||
| 2188 | return PTR_ERR(afi); | ||
| 2189 | |||
| 2190 | table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], afi->family, | ||
| 2191 | genmask); | 2084 | genmask); |
| 2192 | if (IS_ERR(table)) | 2085 | if (IS_ERR(table)) |
| 2193 | return PTR_ERR(table); | 2086 | return PTR_ERR(table); |
| @@ -2245,7 +2138,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk, | |||
| 2245 | { | 2138 | { |
| 2246 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 2139 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
| 2247 | u8 genmask = nft_genmask_next(net); | 2140 | u8 genmask = nft_genmask_next(net); |
| 2248 | struct nft_af_info *afi; | 2141 | int family = nfmsg->nfgen_family; |
| 2249 | struct nft_table *table; | 2142 | struct nft_table *table; |
| 2250 | struct nft_chain *chain; | 2143 | struct nft_chain *chain; |
| 2251 | struct nft_rule *rule, *old_rule = NULL; | 2144 | struct nft_rule *rule, *old_rule = NULL; |
| @@ -2261,11 +2154,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk, | |||
| 2261 | 2154 | ||
| 2262 | create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false; | 2155 | create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false; |
| 2263 | 2156 | ||
| 2264 | afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create); | 2157 | table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], family, |
| 2265 | if (IS_ERR(afi)) | ||
| 2266 | return PTR_ERR(afi); | ||
| 2267 | |||
| 2268 | table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], afi->family, | ||
| 2269 | genmask); | 2158 | genmask); |
| 2270 | if (IS_ERR(table)) | 2159 | if (IS_ERR(table)) |
| 2271 | return PTR_ERR(table); | 2160 | return PTR_ERR(table); |
| @@ -2305,7 +2194,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk, | |||
| 2305 | return PTR_ERR(old_rule); | 2194 | return PTR_ERR(old_rule); |
| 2306 | } | 2195 | } |
| 2307 | 2196 | ||
| 2308 | nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla); | 2197 | nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla); |
| 2309 | 2198 | ||
| 2310 | n = 0; | 2199 | n = 0; |
| 2311 | size = 0; | 2200 | size = 0; |
| @@ -2429,18 +2318,13 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk, | |||
| 2429 | { | 2318 | { |
| 2430 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 2319 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
| 2431 | u8 genmask = nft_genmask_next(net); | 2320 | u8 genmask = nft_genmask_next(net); |
| 2432 | struct nft_af_info *afi; | ||
| 2433 | struct nft_table *table; | 2321 | struct nft_table *table; |
| 2434 | struct nft_chain *chain = NULL; | 2322 | struct nft_chain *chain = NULL; |
| 2435 | struct nft_rule *rule; | 2323 | struct nft_rule *rule; |
| 2436 | int family = nfmsg->nfgen_family, err = 0; | 2324 | int family = nfmsg->nfgen_family, err = 0; |
| 2437 | struct nft_ctx ctx; | 2325 | struct nft_ctx ctx; |
| 2438 | 2326 | ||
| 2439 | afi = nf_tables_afinfo_lookup(net, family, false); | 2327 | table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], family, |
| 2440 | if (IS_ERR(afi)) | ||
| 2441 | return PTR_ERR(afi); | ||
| 2442 | |||
| 2443 | table = nf_tables_table_lookup(net, nla[NFTA_RULE_TABLE], afi->family, | ||
| 2444 | genmask); | 2328 | genmask); |
| 2445 | if (IS_ERR(table)) | 2329 | if (IS_ERR(table)) |
| 2446 | return PTR_ERR(table); | 2330 | return PTR_ERR(table); |
| @@ -2452,7 +2336,7 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk, | |||
| 2452 | return PTR_ERR(chain); | 2336 | return PTR_ERR(chain); |
| 2453 | } | 2337 | } |
| 2454 | 2338 | ||
| 2455 | nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, chain, nla); | 2339 | nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla); |
| 2456 | 2340 | ||
| 2457 | if (chain) { | 2341 | if (chain) { |
| 2458 | if (nla[NFTA_RULE_HANDLE]) { | 2342 | if (nla[NFTA_RULE_HANDLE]) { |
| @@ -2632,26 +2516,17 @@ static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net, | |||
| 2632 | u8 genmask) | 2516 | u8 genmask) |
| 2633 | { | 2517 | { |
| 2634 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 2518 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
| 2635 | struct nft_af_info *afi = NULL; | 2519 | int family = nfmsg->nfgen_family; |
| 2636 | struct nft_table *table = NULL; | 2520 | struct nft_table *table = NULL; |
| 2637 | 2521 | ||
| 2638 | if (nfmsg->nfgen_family != NFPROTO_UNSPEC) { | ||
| 2639 | afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false); | ||
| 2640 | if (IS_ERR(afi)) | ||
| 2641 | return PTR_ERR(afi); | ||
| 2642 | } | ||
| 2643 | |||
| 2644 | if (nla[NFTA_SET_TABLE] != NULL) { | 2522 | if (nla[NFTA_SET_TABLE] != NULL) { |
| 2645 | if (afi == NULL) | ||
| 2646 | return -EAFNOSUPPORT; | ||
| 2647 | |||
| 2648 | table = nf_tables_table_lookup(net, nla[NFTA_SET_TABLE], | 2523 | table = nf_tables_table_lookup(net, nla[NFTA_SET_TABLE], |
| 2649 | afi->family, genmask); | 2524 | family, genmask); |
| 2650 | if (IS_ERR(table)) | 2525 | if (IS_ERR(table)) |
| 2651 | return PTR_ERR(table); | 2526 | return PTR_ERR(table); |
| 2652 | } | 2527 | } |
| 2653 | 2528 | ||
| 2654 | nft_ctx_init(ctx, net, skb, nlh, afi->family, table, NULL, nla); | 2529 | nft_ctx_init(ctx, net, skb, nlh, family, table, NULL, nla); |
| 2655 | return 0; | 2530 | return 0; |
| 2656 | } | 2531 | } |
| 2657 | 2532 | ||
| @@ -2882,7 +2757,7 @@ static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2882 | 2757 | ||
| 2883 | list_for_each_entry_rcu(table, &net->nft.tables, list) { | 2758 | list_for_each_entry_rcu(table, &net->nft.tables, list) { |
| 2884 | if (ctx->family != NFPROTO_UNSPEC && | 2759 | if (ctx->family != NFPROTO_UNSPEC && |
| 2885 | ctx->family != table->afi->family) | 2760 | ctx->family != table->family) |
| 2886 | continue; | 2761 | continue; |
| 2887 | 2762 | ||
| 2888 | if (ctx->table && ctx->table != table) | 2763 | if (ctx->table && ctx->table != table) |
| @@ -2903,7 +2778,7 @@ static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 2903 | 2778 | ||
| 2904 | ctx_set = *ctx; | 2779 | ctx_set = *ctx; |
| 2905 | ctx_set.table = table; | 2780 | ctx_set.table = table; |
| 2906 | ctx_set.family = table->afi->family; | 2781 | ctx_set.family = table->family; |
| 2907 | 2782 | ||
| 2908 | if (nf_tables_fill_set(skb, &ctx_set, set, | 2783 | if (nf_tables_fill_set(skb, &ctx_set, set, |
| 2909 | NFT_MSG_NEWSET, | 2784 | NFT_MSG_NEWSET, |
| @@ -3015,8 +2890,8 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, | |||
| 3015 | { | 2890 | { |
| 3016 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 2891 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
| 3017 | u8 genmask = nft_genmask_next(net); | 2892 | u8 genmask = nft_genmask_next(net); |
| 2893 | int family = nfmsg->nfgen_family; | ||
| 3018 | const struct nft_set_ops *ops; | 2894 | const struct nft_set_ops *ops; |
| 3019 | struct nft_af_info *afi; | ||
| 3020 | struct nft_table *table; | 2895 | struct nft_table *table; |
| 3021 | struct nft_set *set; | 2896 | struct nft_set *set; |
| 3022 | struct nft_ctx ctx; | 2897 | struct nft_ctx ctx; |
| @@ -3123,16 +2998,12 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, | |||
| 3123 | 2998 | ||
| 3124 | create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false; | 2999 | create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false; |
| 3125 | 3000 | ||
| 3126 | afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create); | 3001 | table = nf_tables_table_lookup(net, nla[NFTA_SET_TABLE], family, |
| 3127 | if (IS_ERR(afi)) | ||
| 3128 | return PTR_ERR(afi); | ||
| 3129 | |||
| 3130 | table = nf_tables_table_lookup(net, nla[NFTA_SET_TABLE], afi->family, | ||
| 3131 | genmask); | 3002 | genmask); |
| 3132 | if (IS_ERR(table)) | 3003 | if (IS_ERR(table)) |
| 3133 | return PTR_ERR(table); | 3004 | return PTR_ERR(table); |
| 3134 | 3005 | ||
| 3135 | nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); | 3006 | nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); |
| 3136 | 3007 | ||
| 3137 | set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME], genmask); | 3008 | set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME], genmask); |
| 3138 | if (IS_ERR(set)) { | 3009 | if (IS_ERR(set)) { |
| @@ -3390,19 +3261,15 @@ static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net, | |||
| 3390 | u8 genmask) | 3261 | u8 genmask) |
| 3391 | { | 3262 | { |
| 3392 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 3263 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
| 3393 | struct nft_af_info *afi; | 3264 | int family = nfmsg->nfgen_family; |
| 3394 | struct nft_table *table; | 3265 | struct nft_table *table; |
| 3395 | 3266 | ||
| 3396 | afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false); | ||
| 3397 | if (IS_ERR(afi)) | ||
| 3398 | return PTR_ERR(afi); | ||
| 3399 | |||
| 3400 | table = nf_tables_table_lookup(net, nla[NFTA_SET_ELEM_LIST_TABLE], | 3267 | table = nf_tables_table_lookup(net, nla[NFTA_SET_ELEM_LIST_TABLE], |
| 3401 | afi->family, genmask); | 3268 | family, genmask); |
| 3402 | if (IS_ERR(table)) | 3269 | if (IS_ERR(table)) |
| 3403 | return PTR_ERR(table); | 3270 | return PTR_ERR(table); |
| 3404 | 3271 | ||
| 3405 | nft_ctx_init(ctx, net, skb, nlh, afi->family, table, NULL, nla); | 3272 | nft_ctx_init(ctx, net, skb, nlh, family, table, NULL, nla); |
| 3406 | return 0; | 3273 | return 0; |
| 3407 | } | 3274 | } |
| 3408 | 3275 | ||
| @@ -3520,7 +3387,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 3520 | rcu_read_lock(); | 3387 | rcu_read_lock(); |
| 3521 | list_for_each_entry_rcu(table, &net->nft.tables, list) { | 3388 | list_for_each_entry_rcu(table, &net->nft.tables, list) { |
| 3522 | if (dump_ctx->ctx.family != NFPROTO_UNSPEC && | 3389 | if (dump_ctx->ctx.family != NFPROTO_UNSPEC && |
| 3523 | dump_ctx->ctx.family != table->afi->family) | 3390 | dump_ctx->ctx.family != table->family) |
| 3524 | continue; | 3391 | continue; |
| 3525 | 3392 | ||
| 3526 | if (table != dump_ctx->ctx.table) | 3393 | if (table != dump_ctx->ctx.table) |
| @@ -3550,7 +3417,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 3550 | goto nla_put_failure; | 3417 | goto nla_put_failure; |
| 3551 | 3418 | ||
| 3552 | nfmsg = nlmsg_data(nlh); | 3419 | nfmsg = nlmsg_data(nlh); |
| 3553 | nfmsg->nfgen_family = table->afi->family; | 3420 | nfmsg->nfgen_family = table->family; |
| 3554 | nfmsg->version = NFNETLINK_V0; | 3421 | nfmsg->version = NFNETLINK_V0; |
| 3555 | nfmsg->res_id = htons(net->nft.base_seq & 0xffff); | 3422 | nfmsg->res_id = htons(net->nft.base_seq & 0xffff); |
| 3556 | 3423 | ||
| @@ -4501,7 +4368,6 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk, | |||
| 4501 | const struct nft_object_type *type; | 4368 | const struct nft_object_type *type; |
| 4502 | u8 genmask = nft_genmask_next(net); | 4369 | u8 genmask = nft_genmask_next(net); |
| 4503 | int family = nfmsg->nfgen_family; | 4370 | int family = nfmsg->nfgen_family; |
| 4504 | struct nft_af_info *afi; | ||
| 4505 | struct nft_table *table; | 4371 | struct nft_table *table; |
| 4506 | struct nft_object *obj; | 4372 | struct nft_object *obj; |
| 4507 | struct nft_ctx ctx; | 4373 | struct nft_ctx ctx; |
| @@ -4513,11 +4379,7 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk, | |||
| 4513 | !nla[NFTA_OBJ_DATA]) | 4379 | !nla[NFTA_OBJ_DATA]) |
| 4514 | return -EINVAL; | 4380 | return -EINVAL; |
| 4515 | 4381 | ||
| 4516 | afi = nf_tables_afinfo_lookup(net, family, true); | 4382 | table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], family, |
| 4517 | if (IS_ERR(afi)) | ||
| 4518 | return PTR_ERR(afi); | ||
| 4519 | |||
| 4520 | table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], afi->family, | ||
| 4521 | genmask); | 4383 | genmask); |
| 4522 | if (IS_ERR(table)) | 4384 | if (IS_ERR(table)) |
| 4523 | return PTR_ERR(table); | 4385 | return PTR_ERR(table); |
| @@ -4536,7 +4398,7 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk, | |||
| 4536 | return 0; | 4398 | return 0; |
| 4537 | } | 4399 | } |
| 4538 | 4400 | ||
| 4539 | nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); | 4401 | nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); |
| 4540 | 4402 | ||
| 4541 | type = nft_obj_type_get(objtype); | 4403 | type = nft_obj_type_get(objtype); |
| 4542 | if (IS_ERR(type)) | 4404 | if (IS_ERR(type)) |
| @@ -4628,7 +4490,7 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 4628 | cb->seq = net->nft.base_seq; | 4490 | cb->seq = net->nft.base_seq; |
| 4629 | 4491 | ||
| 4630 | list_for_each_entry_rcu(table, &net->nft.tables, list) { | 4492 | list_for_each_entry_rcu(table, &net->nft.tables, list) { |
| 4631 | if (family != NFPROTO_UNSPEC && family != table->afi->family) | 4493 | if (family != NFPROTO_UNSPEC && family != table->family) |
| 4632 | continue; | 4494 | continue; |
| 4633 | 4495 | ||
| 4634 | list_for_each_entry_rcu(obj, &table->objects, list) { | 4496 | list_for_each_entry_rcu(obj, &table->objects, list) { |
| @@ -4651,7 +4513,7 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 4651 | cb->nlh->nlmsg_seq, | 4513 | cb->nlh->nlmsg_seq, |
| 4652 | NFT_MSG_NEWOBJ, | 4514 | NFT_MSG_NEWOBJ, |
| 4653 | NLM_F_MULTI | NLM_F_APPEND, | 4515 | NLM_F_MULTI | NLM_F_APPEND, |
| 4654 | table->afi->family, table, | 4516 | table->family, table, |
| 4655 | obj, reset) < 0) | 4517 | obj, reset) < 0) |
| 4656 | goto done; | 4518 | goto done; |
| 4657 | 4519 | ||
| @@ -4709,7 +4571,6 @@ static int nf_tables_getobj(struct net *net, struct sock *nlsk, | |||
| 4709 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 4571 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
| 4710 | u8 genmask = nft_genmask_cur(net); | 4572 | u8 genmask = nft_genmask_cur(net); |
| 4711 | int family = nfmsg->nfgen_family; | 4573 | int family = nfmsg->nfgen_family; |
| 4712 | const struct nft_af_info *afi; | ||
| 4713 | const struct nft_table *table; | 4574 | const struct nft_table *table; |
| 4714 | struct nft_object *obj; | 4575 | struct nft_object *obj; |
| 4715 | struct sk_buff *skb2; | 4576 | struct sk_buff *skb2; |
| @@ -4740,11 +4601,7 @@ static int nf_tables_getobj(struct net *net, struct sock *nlsk, | |||
| 4740 | !nla[NFTA_OBJ_TYPE]) | 4601 | !nla[NFTA_OBJ_TYPE]) |
| 4741 | return -EINVAL; | 4602 | return -EINVAL; |
| 4742 | 4603 | ||
| 4743 | afi = nf_tables_afinfo_lookup(net, family, false); | 4604 | table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], family, |
| 4744 | if (IS_ERR(afi)) | ||
| 4745 | return PTR_ERR(afi); | ||
| 4746 | |||
| 4747 | table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], afi->family, | ||
| 4748 | genmask); | 4605 | genmask); |
| 4749 | if (IS_ERR(table)) | 4606 | if (IS_ERR(table)) |
| 4750 | return PTR_ERR(table); | 4607 | return PTR_ERR(table); |
| @@ -4791,7 +4648,6 @@ static int nf_tables_delobj(struct net *net, struct sock *nlsk, | |||
| 4791 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 4648 | const struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
| 4792 | u8 genmask = nft_genmask_next(net); | 4649 | u8 genmask = nft_genmask_next(net); |
| 4793 | int family = nfmsg->nfgen_family; | 4650 | int family = nfmsg->nfgen_family; |
| 4794 | struct nft_af_info *afi; | ||
| 4795 | struct nft_table *table; | 4651 | struct nft_table *table; |
| 4796 | struct nft_object *obj; | 4652 | struct nft_object *obj; |
| 4797 | struct nft_ctx ctx; | 4653 | struct nft_ctx ctx; |
| @@ -4801,11 +4657,7 @@ static int nf_tables_delobj(struct net *net, struct sock *nlsk, | |||
| 4801 | !nla[NFTA_OBJ_NAME]) | 4657 | !nla[NFTA_OBJ_NAME]) |
| 4802 | return -EINVAL; | 4658 | return -EINVAL; |
| 4803 | 4659 | ||
| 4804 | afi = nf_tables_afinfo_lookup(net, family, true); | 4660 | table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], family, |
| 4805 | if (IS_ERR(afi)) | ||
| 4806 | return PTR_ERR(afi); | ||
| 4807 | |||
| 4808 | table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], afi->family, | ||
| 4809 | genmask); | 4661 | genmask); |
| 4810 | if (IS_ERR(table)) | 4662 | if (IS_ERR(table)) |
| 4811 | return PTR_ERR(table); | 4663 | return PTR_ERR(table); |
| @@ -4817,7 +4669,7 @@ static int nf_tables_delobj(struct net *net, struct sock *nlsk, | |||
| 4817 | if (obj->use > 0) | 4669 | if (obj->use > 0) |
| 4818 | return -EBUSY; | 4670 | return -EBUSY; |
| 4819 | 4671 | ||
| 4820 | nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); | 4672 | nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); |
| 4821 | 4673 | ||
| 4822 | return nft_delobj(&ctx, obj); | 4674 | return nft_delobj(&ctx, obj); |
| 4823 | } | 4675 | } |
| @@ -5002,33 +4854,31 @@ err1: | |||
| 5002 | return err; | 4854 | return err; |
| 5003 | } | 4855 | } |
| 5004 | 4856 | ||
| 5005 | static const struct nf_flowtable_type * | 4857 | static const struct nf_flowtable_type *__nft_flowtable_type_get(u8 family) |
| 5006 | __nft_flowtable_type_get(const struct nft_af_info *afi) | ||
| 5007 | { | 4858 | { |
| 5008 | const struct nf_flowtable_type *type; | 4859 | const struct nf_flowtable_type *type; |
| 5009 | 4860 | ||
| 5010 | list_for_each_entry(type, &nf_tables_flowtables, list) { | 4861 | list_for_each_entry(type, &nf_tables_flowtables, list) { |
| 5011 | if (afi->family == type->family) | 4862 | if (family == type->family) |
| 5012 | return type; | 4863 | return type; |
| 5013 | } | 4864 | } |
| 5014 | return NULL; | 4865 | return NULL; |
| 5015 | } | 4866 | } |
| 5016 | 4867 | ||
| 5017 | static const struct nf_flowtable_type * | 4868 | static const struct nf_flowtable_type *nft_flowtable_type_get(u8 family) |
| 5018 | nft_flowtable_type_get(const struct nft_af_info *afi) | ||
| 5019 | { | 4869 | { |
| 5020 | const struct nf_flowtable_type *type; | 4870 | const struct nf_flowtable_type *type; |
| 5021 | 4871 | ||
| 5022 | type = __nft_flowtable_type_get(afi); | 4872 | type = __nft_flowtable_type_get(family); |
| 5023 | if (type != NULL && try_module_get(type->owner)) | 4873 | if (type != NULL && try_module_get(type->owner)) |
| 5024 | return type; | 4874 | return type; |
| 5025 | 4875 | ||
| 5026 | #ifdef CONFIG_MODULES | 4876 | #ifdef CONFIG_MODULES |
| 5027 | if (type == NULL) { | 4877 | if (type == NULL) { |
| 5028 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); | 4878 | nfnl_unlock(NFNL_SUBSYS_NFTABLES); |
| 5029 | request_module("nf-flowtable-%u", afi->family); | 4879 | request_module("nf-flowtable-%u", family); |
| 5030 | nfnl_lock(NFNL_SUBSYS_NFTABLES); | 4880 | nfnl_lock(NFNL_SUBSYS_NFTABLES); |
| 5031 | if (__nft_flowtable_type_get(afi)) | 4881 | if (__nft_flowtable_type_get(family)) |
| 5032 | return ERR_PTR(-EAGAIN); | 4882 | return ERR_PTR(-EAGAIN); |
| 5033 | } | 4883 | } |
| 5034 | #endif | 4884 | #endif |
| @@ -5076,7 +4926,6 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk, | |||
| 5076 | u8 genmask = nft_genmask_next(net); | 4926 | u8 genmask = nft_genmask_next(net); |
| 5077 | int family = nfmsg->nfgen_family; | 4927 | int family = nfmsg->nfgen_family; |
| 5078 | struct nft_flowtable *flowtable; | 4928 | struct nft_flowtable *flowtable; |
| 5079 | struct nft_af_info *afi; | ||
| 5080 | struct nft_table *table; | 4929 | struct nft_table *table; |
| 5081 | struct nft_ctx ctx; | 4930 | struct nft_ctx ctx; |
| 5082 | int err, i, k; | 4931 | int err, i, k; |
| @@ -5086,12 +4935,8 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk, | |||
| 5086 | !nla[NFTA_FLOWTABLE_HOOK]) | 4935 | !nla[NFTA_FLOWTABLE_HOOK]) |
| 5087 | return -EINVAL; | 4936 | return -EINVAL; |
| 5088 | 4937 | ||
| 5089 | afi = nf_tables_afinfo_lookup(net, family, true); | ||
| 5090 | if (IS_ERR(afi)) | ||
| 5091 | return PTR_ERR(afi); | ||
| 5092 | |||
| 5093 | table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], | 4938 | table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], |
| 5094 | afi->family, genmask); | 4939 | family, genmask); |
| 5095 | if (IS_ERR(table)) | 4940 | if (IS_ERR(table)) |
| 5096 | return PTR_ERR(table); | 4941 | return PTR_ERR(table); |
| 5097 | 4942 | ||
| @@ -5108,7 +4953,7 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk, | |||
| 5108 | return 0; | 4953 | return 0; |
| 5109 | } | 4954 | } |
| 5110 | 4955 | ||
| 5111 | nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); | 4956 | nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); |
| 5112 | 4957 | ||
| 5113 | flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL); | 4958 | flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL); |
| 5114 | if (!flowtable) | 4959 | if (!flowtable) |
| @@ -5121,7 +4966,7 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk, | |||
| 5121 | goto err1; | 4966 | goto err1; |
| 5122 | } | 4967 | } |
| 5123 | 4968 | ||
| 5124 | type = nft_flowtable_type_get(afi); | 4969 | type = nft_flowtable_type_get(family); |
| 5125 | if (IS_ERR(type)) { | 4970 | if (IS_ERR(type)) { |
| 5126 | err = PTR_ERR(type); | 4971 | err = PTR_ERR(type); |
| 5127 | goto err2; | 4972 | goto err2; |
| @@ -5181,16 +5026,11 @@ static int nf_tables_delflowtable(struct net *net, struct sock *nlsk, | |||
| 5181 | u8 genmask = nft_genmask_next(net); | 5026 | u8 genmask = nft_genmask_next(net); |
| 5182 | int family = nfmsg->nfgen_family; | 5027 | int family = nfmsg->nfgen_family; |
| 5183 | struct nft_flowtable *flowtable; | 5028 | struct nft_flowtable *flowtable; |
| 5184 | struct nft_af_info *afi; | ||
| 5185 | struct nft_table *table; | 5029 | struct nft_table *table; |
| 5186 | struct nft_ctx ctx; | 5030 | struct nft_ctx ctx; |
| 5187 | 5031 | ||
| 5188 | afi = nf_tables_afinfo_lookup(net, family, true); | ||
| 5189 | if (IS_ERR(afi)) | ||
| 5190 | return PTR_ERR(afi); | ||
| 5191 | |||
| 5192 | table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], | 5032 | table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], |
| 5193 | afi->family, genmask); | 5033 | family, genmask); |
| 5194 | if (IS_ERR(table)) | 5034 | if (IS_ERR(table)) |
| 5195 | return PTR_ERR(table); | 5035 | return PTR_ERR(table); |
| 5196 | 5036 | ||
| @@ -5201,7 +5041,7 @@ static int nf_tables_delflowtable(struct net *net, struct sock *nlsk, | |||
| 5201 | if (flowtable->use > 0) | 5041 | if (flowtable->use > 0) |
| 5202 | return -EBUSY; | 5042 | return -EBUSY; |
| 5203 | 5043 | ||
| 5204 | nft_ctx_init(&ctx, net, skb, nlh, afi->family, table, NULL, nla); | 5044 | nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); |
| 5205 | 5045 | ||
| 5206 | return nft_delflowtable(&ctx, flowtable); | 5046 | return nft_delflowtable(&ctx, flowtable); |
| 5207 | } | 5047 | } |
| @@ -5276,7 +5116,7 @@ static int nf_tables_dump_flowtable(struct sk_buff *skb, | |||
| 5276 | cb->seq = net->nft.base_seq; | 5116 | cb->seq = net->nft.base_seq; |
| 5277 | 5117 | ||
| 5278 | list_for_each_entry_rcu(table, &net->nft.tables, list) { | 5118 | list_for_each_entry_rcu(table, &net->nft.tables, list) { |
| 5279 | if (family != NFPROTO_UNSPEC && family != table->afi->family) | 5119 | if (family != NFPROTO_UNSPEC && family != table->family) |
| 5280 | continue; | 5120 | continue; |
| 5281 | 5121 | ||
| 5282 | list_for_each_entry_rcu(flowtable, &table->flowtables, list) { | 5122 | list_for_each_entry_rcu(flowtable, &table->flowtables, list) { |
| @@ -5295,7 +5135,7 @@ static int nf_tables_dump_flowtable(struct sk_buff *skb, | |||
| 5295 | cb->nlh->nlmsg_seq, | 5135 | cb->nlh->nlmsg_seq, |
| 5296 | NFT_MSG_NEWFLOWTABLE, | 5136 | NFT_MSG_NEWFLOWTABLE, |
| 5297 | NLM_F_MULTI | NLM_F_APPEND, | 5137 | NLM_F_MULTI | NLM_F_APPEND, |
| 5298 | table->afi->family, flowtable) < 0) | 5138 | table->family, flowtable) < 0) |
| 5299 | goto done; | 5139 | goto done; |
| 5300 | 5140 | ||
| 5301 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | 5141 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); |
| @@ -5353,7 +5193,6 @@ static int nf_tables_getflowtable(struct net *net, struct sock *nlsk, | |||
| 5353 | u8 genmask = nft_genmask_cur(net); | 5193 | u8 genmask = nft_genmask_cur(net); |
| 5354 | int family = nfmsg->nfgen_family; | 5194 | int family = nfmsg->nfgen_family; |
| 5355 | struct nft_flowtable *flowtable; | 5195 | struct nft_flowtable *flowtable; |
| 5356 | const struct nft_af_info *afi; | ||
| 5357 | const struct nft_table *table; | 5196 | const struct nft_table *table; |
| 5358 | struct sk_buff *skb2; | 5197 | struct sk_buff *skb2; |
| 5359 | int err; | 5198 | int err; |
| @@ -5379,12 +5218,8 @@ static int nf_tables_getflowtable(struct net *net, struct sock *nlsk, | |||
| 5379 | if (!nla[NFTA_FLOWTABLE_NAME]) | 5218 | if (!nla[NFTA_FLOWTABLE_NAME]) |
| 5380 | return -EINVAL; | 5219 | return -EINVAL; |
| 5381 | 5220 | ||
| 5382 | afi = nf_tables_afinfo_lookup(net, family, false); | ||
| 5383 | if (IS_ERR(afi)) | ||
| 5384 | return PTR_ERR(afi); | ||
| 5385 | |||
| 5386 | table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], | 5221 | table = nf_tables_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], |
| 5387 | afi->family, genmask); | 5222 | family, genmask); |
| 5388 | if (IS_ERR(table)) | 5223 | if (IS_ERR(table)) |
| 5389 | return PTR_ERR(table); | 5224 | return PTR_ERR(table); |
| 5390 | 5225 | ||
| @@ -6548,7 +6383,7 @@ int __nft_release_basechain(struct nft_ctx *ctx) | |||
| 6548 | } | 6383 | } |
| 6549 | EXPORT_SYMBOL_GPL(__nft_release_basechain); | 6384 | EXPORT_SYMBOL_GPL(__nft_release_basechain); |
| 6550 | 6385 | ||
| 6551 | static void __nft_release_afinfo(struct net *net) | 6386 | static void __nft_release_tables(struct net *net) |
| 6552 | { | 6387 | { |
| 6553 | struct nft_flowtable *flowtable, *nf; | 6388 | struct nft_flowtable *flowtable, *nf; |
| 6554 | struct nft_table *table, *nt; | 6389 | struct nft_table *table, *nt; |
| @@ -6561,7 +6396,7 @@ static void __nft_release_afinfo(struct net *net) | |||
| 6561 | }; | 6396 | }; |
| 6562 | 6397 | ||
| 6563 | list_for_each_entry_safe(table, nt, &net->nft.tables, list) { | 6398 | list_for_each_entry_safe(table, nt, &net->nft.tables, list) { |
| 6564 | ctx.family = table->afi->family; | 6399 | ctx.family = table->family; |
| 6565 | 6400 | ||
| 6566 | list_for_each_entry(chain, &table->chains, list) | 6401 | list_for_each_entry(chain, &table->chains, list) |
| 6567 | nf_tables_unregister_hook(net, table, chain); | 6402 | nf_tables_unregister_hook(net, table, chain); |
| @@ -6613,7 +6448,7 @@ static int __net_init nf_tables_init_net(struct net *net) | |||
| 6613 | 6448 | ||
| 6614 | static void __net_exit nf_tables_exit_net(struct net *net) | 6449 | static void __net_exit nf_tables_exit_net(struct net *net) |
| 6615 | { | 6450 | { |
| 6616 | __nft_release_afinfo(net); | 6451 | __nft_release_tables(net); |
| 6617 | WARN_ON_ONCE(!list_empty(&net->nft.tables)); | 6452 | WARN_ON_ONCE(!list_empty(&net->nft.tables)); |
| 6618 | WARN_ON_ONCE(!list_empty(&net->nft.commit_list)); | 6453 | WARN_ON_ONCE(!list_empty(&net->nft.commit_list)); |
| 6619 | } | 6454 | } |
diff --git a/net/netfilter/nf_tables_inet.c b/net/netfilter/nf_tables_inet.c index d486ced4de84..e30c7da09d0d 100644 --- a/net/netfilter/nf_tables_inet.c +++ b/net/netfilter/nf_tables_inet.c | |||
| @@ -38,11 +38,6 @@ static unsigned int nft_do_chain_inet(void *priv, struct sk_buff *skb, | |||
| 38 | return nft_do_chain(&pkt, priv); | 38 | return nft_do_chain(&pkt, priv); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | static struct nft_af_info nft_af_inet __read_mostly = { | ||
| 42 | .family = NFPROTO_INET, | ||
| 43 | .owner = THIS_MODULE, | ||
| 44 | }; | ||
| 45 | |||
| 46 | static const struct nf_chain_type filter_inet = { | 41 | static const struct nf_chain_type filter_inet = { |
| 47 | .name = "filter", | 42 | .name = "filter", |
| 48 | .type = NFT_CHAIN_T_DEFAULT, | 43 | .type = NFT_CHAIN_T_DEFAULT, |
| @@ -64,26 +59,12 @@ static const struct nf_chain_type filter_inet = { | |||
| 64 | 59 | ||
| 65 | static int __init nf_tables_inet_init(void) | 60 | static int __init nf_tables_inet_init(void) |
| 66 | { | 61 | { |
| 67 | int ret; | 62 | return nft_register_chain_type(&filter_inet); |
| 68 | |||
| 69 | if (nft_register_afinfo(&nft_af_inet) < 0) | ||
| 70 | return ret; | ||
| 71 | |||
| 72 | ret = nft_register_chain_type(&filter_inet); | ||
| 73 | if (ret < 0) | ||
| 74 | goto err_register_chain; | ||
| 75 | |||
| 76 | return ret; | ||
| 77 | |||
| 78 | err_register_chain: | ||
| 79 | nft_unregister_afinfo(&nft_af_inet); | ||
| 80 | return ret; | ||
| 81 | } | 63 | } |
| 82 | 64 | ||
| 83 | static void __exit nf_tables_inet_exit(void) | 65 | static void __exit nf_tables_inet_exit(void) |
| 84 | { | 66 | { |
| 85 | nft_unregister_chain_type(&filter_inet); | 67 | nft_unregister_chain_type(&filter_inet); |
| 86 | nft_unregister_afinfo(&nft_af_inet); | ||
| 87 | } | 68 | } |
| 88 | 69 | ||
| 89 | module_init(nf_tables_inet_init); | 70 | module_init(nf_tables_inet_init); |
| @@ -91,4 +72,4 @@ module_exit(nf_tables_inet_exit); | |||
| 91 | 72 | ||
| 92 | MODULE_LICENSE("GPL"); | 73 | MODULE_LICENSE("GPL"); |
| 93 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | 74 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); |
| 94 | MODULE_ALIAS_NFT_FAMILY(1); | 75 | MODULE_ALIAS_NFT_CHAIN(1, "filter"); |
diff --git a/net/netfilter/nf_tables_netdev.c b/net/netfilter/nf_tables_netdev.c index 404b49acb125..4041fafca934 100644 --- a/net/netfilter/nf_tables_netdev.c +++ b/net/netfilter/nf_tables_netdev.c | |||
| @@ -38,11 +38,6 @@ nft_do_chain_netdev(void *priv, struct sk_buff *skb, | |||
| 38 | return nft_do_chain(&pkt, priv); | 38 | return nft_do_chain(&pkt, priv); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | static struct nft_af_info nft_af_netdev __read_mostly = { | ||
| 42 | .family = NFPROTO_NETDEV, | ||
| 43 | .owner = THIS_MODULE, | ||
| 44 | }; | ||
| 45 | |||
| 46 | static const struct nf_chain_type nft_filter_chain_netdev = { | 41 | static const struct nf_chain_type nft_filter_chain_netdev = { |
| 47 | .name = "filter", | 42 | .name = "filter", |
| 48 | .type = NFT_CHAIN_T_DEFAULT, | 43 | .type = NFT_CHAIN_T_DEFAULT, |
| @@ -91,10 +86,10 @@ static int nf_tables_netdev_event(struct notifier_block *this, | |||
| 91 | 86 | ||
| 92 | nfnl_lock(NFNL_SUBSYS_NFTABLES); | 87 | nfnl_lock(NFNL_SUBSYS_NFTABLES); |
| 93 | list_for_each_entry(table, &ctx.net->nft.tables, list) { | 88 | list_for_each_entry(table, &ctx.net->nft.tables, list) { |
| 94 | if (table->afi->family != NFPROTO_NETDEV) | 89 | if (table->family != NFPROTO_NETDEV) |
| 95 | continue; | 90 | continue; |
| 96 | 91 | ||
| 97 | ctx.family = table->afi->family; | 92 | ctx.family = table->family; |
| 98 | ctx.table = table; | 93 | ctx.table = table; |
| 99 | list_for_each_entry_safe(chain, nr, &table->chains, list) { | 94 | list_for_each_entry_safe(chain, nr, &table->chains, list) { |
| 100 | if (!nft_is_base_chain(chain)) | 95 | if (!nft_is_base_chain(chain)) |
| @@ -117,12 +112,9 @@ static int __init nf_tables_netdev_init(void) | |||
| 117 | { | 112 | { |
| 118 | int ret; | 113 | int ret; |
| 119 | 114 | ||
| 120 | if (nft_register_afinfo(&nft_af_netdev) < 0) | ||
| 121 | return ret; | ||
| 122 | |||
| 123 | ret = nft_register_chain_type(&nft_filter_chain_netdev); | 115 | ret = nft_register_chain_type(&nft_filter_chain_netdev); |
| 124 | if (ret) | 116 | if (ret) |
| 125 | goto err_register_chain_type; | 117 | return ret; |
| 126 | 118 | ||
| 127 | ret = register_netdevice_notifier(&nf_tables_netdev_notifier); | 119 | ret = register_netdevice_notifier(&nf_tables_netdev_notifier); |
| 128 | if (ret) | 120 | if (ret) |
| @@ -132,8 +124,6 @@ static int __init nf_tables_netdev_init(void) | |||
| 132 | 124 | ||
| 133 | err_register_netdevice_notifier: | 125 | err_register_netdevice_notifier: |
| 134 | nft_unregister_chain_type(&nft_filter_chain_netdev); | 126 | nft_unregister_chain_type(&nft_filter_chain_netdev); |
| 135 | err_register_chain_type: | ||
| 136 | nft_unregister_afinfo(&nft_af_netdev); | ||
| 137 | 127 | ||
| 138 | return ret; | 128 | return ret; |
| 139 | } | 129 | } |
| @@ -142,7 +132,6 @@ static void __exit nf_tables_netdev_exit(void) | |||
| 142 | { | 132 | { |
| 143 | unregister_netdevice_notifier(&nf_tables_netdev_notifier); | 133 | unregister_netdevice_notifier(&nf_tables_netdev_notifier); |
| 144 | nft_unregister_chain_type(&nft_filter_chain_netdev); | 134 | nft_unregister_chain_type(&nft_filter_chain_netdev); |
| 145 | nft_unregister_afinfo(&nft_af_netdev); | ||
| 146 | } | 135 | } |
| 147 | 136 | ||
| 148 | module_init(nf_tables_netdev_init); | 137 | module_init(nf_tables_netdev_init); |
| @@ -150,4 +139,4 @@ module_exit(nf_tables_netdev_exit); | |||
| 150 | 139 | ||
| 151 | MODULE_LICENSE("GPL"); | 140 | MODULE_LICENSE("GPL"); |
| 152 | MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>"); | 141 | MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>"); |
| 153 | MODULE_ALIAS_NFT_FAMILY(5); /* NFPROTO_NETDEV */ | 142 | MODULE_ALIAS_NFT_CHAIN(5, "filter"); /* NFPROTO_NETDEV */ |
