diff options
author | Alvaro Neira <alvaroneay@gmail.com> | 2014-11-26 04:21:37 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-11-27 07:08:29 -0500 |
commit | 1b63d4b9b54cee6002757a8d20b537aa4037ae8f (patch) | |
tree | bb4e04a4c5dc692d3fa4886fb9fc58c7421bfdcb | |
parent | 68b0faa87d167ec87ba2a26be62241ad94eb449b (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.c | 40 |
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 | ||
20 | int nft_bridge_iphdr_validate(struct sk_buff *skb) | 22 | int 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 | } |
63 | EXPORT_SYMBOL_GPL(nft_bridge_ip6hdr_validate); | 65 | EXPORT_SYMBOL_GPL(nft_bridge_ip6hdr_validate); |
64 | 66 | ||
67 | static 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 | |||
79 | static 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 | |||
65 | static unsigned int | 93 | static unsigned int |
66 | nft_do_chain_bridge(const struct nf_hook_ops *ops, | 94 | nft_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 | } |