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

netfilter: nf_tables_inet: don't use multihook infrastructure anymore

Use new native NFPROTO_INET support in netfilter core, this gets rid of
ad-hoc code in the nf_tables API codebase.

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

+59 -19
-2
include/net/netfilter/nf_tables_ipv4.h
··· 53 53 nft_set_pktinfo_unspec(pkt, skb); 54 54 } 55 55 56 - extern struct nft_af_info nft_af_ipv4; 57 - 58 56 #endif
-2
include/net/netfilter/nf_tables_ipv6.h
··· 69 69 nft_set_pktinfo_unspec(pkt, skb); 70 70 } 71 71 72 - extern struct nft_af_info nft_af_ipv6; 73 - 74 72 #endif
+1 -2
net/ipv4/netfilter/nf_tables_ipv4.c
··· 45 45 return nft_do_chain_ipv4(priv, skb, state); 46 46 } 47 47 48 - struct nft_af_info nft_af_ipv4 __read_mostly = { 48 + static struct nft_af_info nft_af_ipv4 __read_mostly = { 49 49 .family = NFPROTO_IPV4, 50 50 .nhooks = NF_INET_NUMHOOKS, 51 51 .owner = THIS_MODULE, ··· 58 58 [NF_INET_POST_ROUTING] = nft_do_chain_ipv4, 59 59 }, 60 60 }; 61 - EXPORT_SYMBOL_GPL(nft_af_ipv4); 62 61 63 62 static int nf_tables_ipv4_init_net(struct net *net) 64 63 {
+1 -2
net/ipv6/netfilter/nf_tables_ipv6.c
··· 42 42 return nft_do_chain_ipv6(priv, skb, state); 43 43 } 44 44 45 - struct nft_af_info nft_af_ipv6 __read_mostly = { 45 + static struct nft_af_info nft_af_ipv6 __read_mostly = { 46 46 .family = NFPROTO_IPV6, 47 47 .nhooks = NF_INET_NUMHOOKS, 48 48 .owner = THIS_MODULE, ··· 55 55 [NF_INET_POST_ROUTING] = nft_do_chain_ipv6, 56 56 }, 57 57 }; 58 - EXPORT_SYMBOL_GPL(nft_af_ipv6); 59 58 60 59 static int nf_tables_ipv6_init_net(struct net *net) 61 60 {
+57 -11
net/netfilter/nf_tables_inet.c
··· 9 9 #include <linux/init.h> 10 10 #include <linux/module.h> 11 11 #include <linux/ip.h> 12 + #include <linux/ipv6.h> 12 13 #include <linux/netfilter_ipv4.h> 13 14 #include <linux/netfilter_ipv6.h> 14 15 #include <net/netfilter/nf_tables.h> ··· 17 16 #include <net/netfilter/nf_tables_ipv6.h> 18 17 #include <net/ip.h> 19 18 20 - static void nft_inet_hook_ops_init(struct nf_hook_ops *ops, unsigned int n) 19 + static unsigned int nft_do_chain_inet(void *priv, struct sk_buff *skb, 20 + const struct nf_hook_state *state) 21 21 { 22 - struct nft_af_info *afi; 22 + struct nft_pktinfo pkt; 23 23 24 - if (n == 1) 25 - afi = &nft_af_ipv4; 26 - else 27 - afi = &nft_af_ipv6; 24 + nft_set_pktinfo(&pkt, skb, state); 28 25 29 - ops->pf = afi->family; 30 - if (afi->hooks[ops->hooknum]) 31 - ops->hook = afi->hooks[ops->hooknum]; 26 + switch (state->pf) { 27 + case NFPROTO_IPV4: 28 + nft_set_pktinfo_ipv4(&pkt, skb); 29 + break; 30 + case NFPROTO_IPV6: 31 + nft_set_pktinfo_ipv6(&pkt, skb); 32 + break; 33 + default: 34 + break; 35 + } 36 + 37 + return nft_do_chain(&pkt, priv); 38 + } 39 + 40 + static unsigned int nft_inet_output(void *priv, struct sk_buff *skb, 41 + const struct nf_hook_state *state) 42 + { 43 + struct nft_pktinfo pkt; 44 + 45 + nft_set_pktinfo(&pkt, skb, state); 46 + 47 + switch (state->pf) { 48 + case NFPROTO_IPV4: 49 + if (unlikely(skb->len < sizeof(struct iphdr) || 50 + ip_hdr(skb)->ihl < sizeof(struct iphdr) / 4)) { 51 + if (net_ratelimit()) 52 + pr_info("ignoring short SOCK_RAW packet\n"); 53 + return NF_ACCEPT; 54 + } 55 + nft_set_pktinfo_ipv4(&pkt, skb); 56 + break; 57 + case NFPROTO_IPV6: 58 + if (unlikely(skb->len < sizeof(struct ipv6hdr))) { 59 + if (net_ratelimit()) 60 + pr_info("ignoring short SOCK_RAW packet\n"); 61 + return NF_ACCEPT; 62 + } 63 + nft_set_pktinfo_ipv6(&pkt, skb); 64 + break; 65 + default: 66 + break; 67 + } 68 + 69 + return nft_do_chain(&pkt, priv); 32 70 } 33 71 34 72 static struct nft_af_info nft_af_inet __read_mostly = { 35 73 .family = NFPROTO_INET, 36 74 .nhooks = NF_INET_NUMHOOKS, 37 75 .owner = THIS_MODULE, 38 - .nops = 2, 39 - .hook_ops_init = nft_inet_hook_ops_init, 76 + .nops = 1, 77 + .hooks = { 78 + [NF_INET_LOCAL_IN] = nft_do_chain_inet, 79 + [NF_INET_LOCAL_OUT] = nft_inet_output, 80 + [NF_INET_FORWARD] = nft_do_chain_inet, 81 + [NF_INET_PRE_ROUTING] = nft_do_chain_inet, 82 + [NF_INET_POST_ROUTING] = nft_do_chain_inet, 83 + }, 40 84 }; 41 85 42 86 static int __net_init nf_tables_inet_init_net(struct net *net)