Commit 1b63d4b9 authored by Alvaro Neira's avatar Alvaro Neira Committed by Pablo Neira Ayuso

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: default avatarAlvaro Neira Ayuso <alvaroneay@gmail.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 68b0faa8
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include <net/netfilter/nf_tables_bridge.h> #include <net/netfilter/nf_tables_bridge.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/ipv6.h> #include <linux/ipv6.h>
#include <net/netfilter/nf_tables_ipv4.h>
#include <net/netfilter/nf_tables_ipv6.h>
int nft_bridge_iphdr_validate(struct sk_buff *skb) int nft_bridge_iphdr_validate(struct sk_buff *skb)
{ {
...@@ -62,6 +64,32 @@ int nft_bridge_ip6hdr_validate(struct sk_buff *skb) ...@@ -62,6 +64,32 @@ int nft_bridge_ip6hdr_validate(struct sk_buff *skb)
} }
EXPORT_SYMBOL_GPL(nft_bridge_ip6hdr_validate); EXPORT_SYMBOL_GPL(nft_bridge_ip6hdr_validate);
static inline void nft_bridge_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
const struct nf_hook_ops *ops,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out)
{
if (nft_bridge_iphdr_validate(skb))
nft_set_pktinfo_ipv4(pkt, ops, skb, in, out);
else
nft_set_pktinfo(pkt, ops, skb, in, out);
}
static inline void nft_bridge_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
const struct nf_hook_ops *ops,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out)
{
#if IS_ENABLED(CONFIG_IPV6)
if (nft_bridge_ip6hdr_validate(skb) &&
nft_set_pktinfo_ipv6(pkt, ops, skb, in, out) == 0)
return;
#endif
nft_set_pktinfo(pkt, ops, skb, in, out);
}
static unsigned int static unsigned int
nft_do_chain_bridge(const struct nf_hook_ops *ops, nft_do_chain_bridge(const struct nf_hook_ops *ops,
struct sk_buff *skb, struct sk_buff *skb,
...@@ -71,7 +99,17 @@ nft_do_chain_bridge(const struct nf_hook_ops *ops, ...@@ -71,7 +99,17 @@ nft_do_chain_bridge(const struct nf_hook_ops *ops,
{ {
struct nft_pktinfo pkt; struct nft_pktinfo pkt;
nft_set_pktinfo(&pkt, ops, skb, in, out); switch (eth_hdr(skb)->h_proto) {
case htons(ETH_P_IP):
nft_bridge_set_pktinfo_ipv4(&pkt, ops, skb, in, out);
break;
case htons(ETH_P_IPV6):
nft_bridge_set_pktinfo_ipv6(&pkt, ops, skb, in, out);
break;
default:
nft_set_pktinfo(&pkt, ops, skb, in, out);
break;
}
return nft_do_chain(&pkt, ops); return nft_do_chain(&pkt, ops);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment