aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlvaro Neira <alvaroneay@gmail.com>2014-11-26 04:21:37 -0500
committerPablo Neira Ayuso <pablo@netfilter.org>2014-11-27 07:08:29 -0500
commit1b63d4b9b54cee6002757a8d20b537aa4037ae8f (patch)
treebb4e04a4c5dc692d3fa4886fb9fc58c7421bfdcb
parent68b0faa87d167ec87ba2a26be62241ad94eb449b (diff)
netfilter: nf_tables_bridge: set the pktinfo for IPv4/IPv6 traffic
This patch adds the missing bits to allow to match per meta l4proto from the bridge. Example: nft add rule bridge filter input ether type {ip, ip6} meta l4proto udp counter Signed-off-by: Alvaro Neira Ayuso <alvaroneay@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--net/bridge/netfilter/nf_tables_bridge.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c
index d468c19faecd..19473a9371b8 100644
--- a/net/bridge/netfilter/nf_tables_bridge.c
+++ b/net/bridge/netfilter/nf_tables_bridge.c
@@ -16,6 +16,8 @@
16#include <net/netfilter/nf_tables_bridge.h> 16#include <net/netfilter/nf_tables_bridge.h>
17#include <linux/ip.h> 17#include <linux/ip.h>
18#include <linux/ipv6.h> 18#include <linux/ipv6.h>
19#include <net/netfilter/nf_tables_ipv4.h>
20#include <net/netfilter/nf_tables_ipv6.h>
19 21
20int nft_bridge_iphdr_validate(struct sk_buff *skb) 22int nft_bridge_iphdr_validate(struct sk_buff *skb)
21{ 23{
@@ -62,6 +64,32 @@ int nft_bridge_ip6hdr_validate(struct sk_buff *skb)
62} 64}
63EXPORT_SYMBOL_GPL(nft_bridge_ip6hdr_validate); 65EXPORT_SYMBOL_GPL(nft_bridge_ip6hdr_validate);
64 66
67static inline void nft_bridge_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
68 const struct nf_hook_ops *ops,
69 struct sk_buff *skb,
70 const struct net_device *in,
71 const struct net_device *out)
72{
73 if (nft_bridge_iphdr_validate(skb))
74 nft_set_pktinfo_ipv4(pkt, ops, skb, in, out);
75 else
76 nft_set_pktinfo(pkt, ops, skb, in, out);
77}
78
79static inline void nft_bridge_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
80 const struct nf_hook_ops *ops,
81 struct sk_buff *skb,
82 const struct net_device *in,
83 const struct net_device *out)
84{
85#if IS_ENABLED(CONFIG_IPV6)
86 if (nft_bridge_ip6hdr_validate(skb) &&
87 nft_set_pktinfo_ipv6(pkt, ops, skb, in, out) == 0)
88 return;
89#endif
90 nft_set_pktinfo(pkt, ops, skb, in, out);
91}
92
65static unsigned int 93static unsigned int
66nft_do_chain_bridge(const struct nf_hook_ops *ops, 94nft_do_chain_bridge(const struct nf_hook_ops *ops,
67 struct sk_buff *skb, 95 struct sk_buff *skb,
@@ -71,7 +99,17 @@ nft_do_chain_bridge(const struct nf_hook_ops *ops,
71{ 99{
72 struct nft_pktinfo pkt; 100 struct nft_pktinfo pkt;
73 101
74 nft_set_pktinfo(&pkt, ops, skb, in, out); 102 switch (eth_hdr(skb)->h_proto) {
103 case htons(ETH_P_IP):
104 nft_bridge_set_pktinfo_ipv4(&pkt, ops, skb, in, out);
105 break;
106 case htons(ETH_P_IPV6):
107 nft_bridge_set_pktinfo_ipv6(&pkt, ops, skb, in, out);
108 break;
109 default:
110 nft_set_pktinfo(&pkt, ops, skb, in, out);
111 break;
112 }
75 113
76 return nft_do_chain(&pkt, ops); 114 return nft_do_chain(&pkt, ops);
77} 115}