netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH nf 1/2 v4] bridge: export nft_reject_ip*hdr_validate functions
@ 2014-11-26  9:21 Alvaro Neira Ayuso
  2014-11-26  9:21 ` [PATCH nf 2/2 v4] bridge: set the pktinfo for IPv4/IPv6 traffic Alvaro Neira Ayuso
  2014-11-27 11:59 ` [PATCH nf 1/2 v4] bridge: export nft_reject_ip*hdr_validate functions Pablo Neira Ayuso
  0 siblings, 2 replies; 4+ messages in thread
From: Alvaro Neira Ayuso @ 2014-11-26  9:21 UTC (permalink / raw)
  To: netfilter-devel

This patch exports the functions nft_reject_iphdr_validate and
nft_reject_ip6hdr_validate to use it in follow up patches.
These functions check if the ethernet header is correct.

Signed-off-by: Alvaro Neira Ayuso <alvaroneay@gmail.com>
---
[no changes in v4]

 include/net/netfilter/nf_tables_bridge.h |    7 ++++
 net/bridge/netfilter/nf_tables_bridge.c  |   48 +++++++++++++++++++++++++++
 net/bridge/netfilter/nft_reject_bridge.c |   52 +++---------------------------
 3 files changed, 60 insertions(+), 47 deletions(-)
 create mode 100644 include/net/netfilter/nf_tables_bridge.h

diff --git a/include/net/netfilter/nf_tables_bridge.h b/include/net/netfilter/nf_tables_bridge.h
new file mode 100644
index 0000000..511fb79
--- /dev/null
+++ b/include/net/netfilter/nf_tables_bridge.h
@@ -0,0 +1,7 @@
+#ifndef _NET_NF_TABLES_BRIDGE_H
+#define _NET_NF_TABLES_BRIDGE_H
+
+int nft_bridge_iphdr_validate(struct sk_buff *skb);
+int nft_bridge_ip6hdr_validate(struct sk_buff *skb);
+
+#endif /* _NET_NF_TABLES_BRIDGE_H */
diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c
index 074c557..d468c19 100644
--- a/net/bridge/netfilter/nf_tables_bridge.c
+++ b/net/bridge/netfilter/nf_tables_bridge.c
@@ -13,6 +13,54 @@
 #include <linux/module.h>
 #include <linux/netfilter_bridge.h>
 #include <net/netfilter/nf_tables.h>
+#include <net/netfilter/nf_tables_bridge.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+
+int nft_bridge_iphdr_validate(struct sk_buff *skb)
+{
+	struct iphdr *iph;
+	u32 len;
+
+	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+		return 0;
+
+	iph = ip_hdr(skb);
+	if (iph->ihl < 5 || iph->version != 4)
+		return 0;
+
+	len = ntohs(iph->tot_len);
+	if (skb->len < len)
+		return 0;
+	else if (len < (iph->ihl*4))
+		return 0;
+
+	if (!pskb_may_pull(skb, iph->ihl*4))
+		return 0;
+
+	return 1;
+}
+EXPORT_SYMBOL_GPL(nft_bridge_iphdr_validate);
+
+int nft_bridge_ip6hdr_validate(struct sk_buff *skb)
+{
+	struct ipv6hdr *hdr;
+	u32 pkt_len;
+
+	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
+		return 0;
+
+	hdr = ipv6_hdr(skb);
+	if (hdr->version != 6)
+		return 0;
+
+	pkt_len = ntohs(hdr->payload_len);
+	if (pkt_len + sizeof(struct ipv6hdr) > skb->len)
+		return 0;
+
+	return 1;
+}
+EXPORT_SYMBOL_GPL(nft_bridge_ip6hdr_validate);
 
 static unsigned int
 nft_do_chain_bridge(const struct nf_hook_ops *ops,
diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c
index 48da2c5..b0330ae 100644
--- a/net/bridge/netfilter/nft_reject_bridge.c
+++ b/net/bridge/netfilter/nft_reject_bridge.c
@@ -14,6 +14,7 @@
 #include <linux/netfilter/nf_tables.h>
 #include <net/netfilter/nf_tables.h>
 #include <net/netfilter/nft_reject.h>
+#include <net/netfilter/nf_tables_bridge.h>
 #include <net/netfilter/ipv4/nf_reject.h>
 #include <net/netfilter/ipv6/nf_reject.h>
 #include <linux/ip.h>
@@ -35,30 +36,6 @@ static void nft_reject_br_push_etherhdr(struct sk_buff *oldskb,
 	skb_pull(nskb, ETH_HLEN);
 }
 
-static int nft_reject_iphdr_validate(struct sk_buff *oldskb)
-{
-	struct iphdr *iph;
-	u32 len;
-
-	if (!pskb_may_pull(oldskb, sizeof(struct iphdr)))
-		return 0;
-
-	iph = ip_hdr(oldskb);
-	if (iph->ihl < 5 || iph->version != 4)
-		return 0;
-
-	len = ntohs(iph->tot_len);
-	if (oldskb->len < len)
-		return 0;
-	else if (len < (iph->ihl*4))
-		return 0;
-
-	if (!pskb_may_pull(oldskb, iph->ihl*4))
-		return 0;
-
-	return 1;
-}
-
 static void nft_reject_br_send_v4_tcp_reset(struct sk_buff *oldskb, int hook)
 {
 	struct sk_buff *nskb;
@@ -66,7 +43,7 @@ static void nft_reject_br_send_v4_tcp_reset(struct sk_buff *oldskb, int hook)
 	const struct tcphdr *oth;
 	struct tcphdr _oth;
 
-	if (!nft_reject_iphdr_validate(oldskb))
+	if (!nft_bridge_iphdr_validate(oldskb))
 		return;
 
 	oth = nf_reject_ip_tcphdr_get(oldskb, &_oth, hook);
@@ -101,7 +78,7 @@ static void nft_reject_br_send_v4_unreach(struct sk_buff *oldskb, int hook,
 	void *payload;
 	__wsum csum;
 
-	if (!nft_reject_iphdr_validate(oldskb))
+	if (!nft_bridge_iphdr_validate(oldskb))
 		return;
 
 	/* IP header checks: fragment. */
@@ -146,25 +123,6 @@ static void nft_reject_br_send_v4_unreach(struct sk_buff *oldskb, int hook,
 	br_deliver(br_port_get_rcu(oldskb->dev), nskb);
 }
 
-static int nft_reject_ip6hdr_validate(struct sk_buff *oldskb)
-{
-	struct ipv6hdr *hdr;
-	u32 pkt_len;
-
-	if (!pskb_may_pull(oldskb, sizeof(struct ipv6hdr)))
-		return 0;
-
-	hdr = ipv6_hdr(oldskb);
-	if (hdr->version != 6)
-		return 0;
-
-	pkt_len = ntohs(hdr->payload_len);
-	if (pkt_len + sizeof(struct ipv6hdr) > oldskb->len)
-		return 0;
-
-	return 1;
-}
-
 static void nft_reject_br_send_v6_tcp_reset(struct net *net,
 					    struct sk_buff *oldskb, int hook)
 {
@@ -174,7 +132,7 @@ static void nft_reject_br_send_v6_tcp_reset(struct net *net,
 	unsigned int otcplen;
 	struct ipv6hdr *nip6h;
 
-	if (!nft_reject_ip6hdr_validate(oldskb))
+	if (!nft_bridge_ip6hdr_validate(oldskb))
 		return;
 
 	oth = nf_reject_ip6_tcphdr_get(oldskb, &_oth, &otcplen, hook);
@@ -207,7 +165,7 @@ static void nft_reject_br_send_v6_unreach(struct net *net,
 	unsigned int len;
 	void *payload;
 
-	if (!nft_reject_ip6hdr_validate(oldskb))
+	if (!nft_bridge_ip6hdr_validate(oldskb))
 		return;
 
 	/* Include "As much of invoking packet as possible without the ICMPv6
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH nf 2/2 v4] bridge: set the pktinfo for IPv4/IPv6 traffic
  2014-11-26  9:21 [PATCH nf 1/2 v4] bridge: export nft_reject_ip*hdr_validate functions Alvaro Neira Ayuso
@ 2014-11-26  9:21 ` Alvaro Neira Ayuso
  2014-11-27 11:59   ` Pablo Neira Ayuso
  2014-11-27 11:59 ` [PATCH nf 1/2 v4] bridge: export nft_reject_ip*hdr_validate functions Pablo Neira Ayuso
  1 sibling, 1 reply; 4+ messages in thread
From: Alvaro Neira Ayuso @ 2014-11-26  9:21 UTC (permalink / raw)
  To: netfilter-devel

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>
---
[changes in v4]
 * refactor the code in two functions nft_bridge_set_pktinfo_ipv*

 net/bridge/netfilter/nf_tables_bridge.c |   42 ++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c
index d468c19..32341fd 100644
--- a/net/bridge/netfilter/nf_tables_bridge.c
+++ b/net/bridge/netfilter/nf_tables_bridge.c
@@ -16,6 +16,8 @@
 #include <net/netfilter/nf_tables_bridge.h>
 #include <linux/ip.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)
 {
@@ -62,6 +64,34 @@ int nft_bridge_ip6hdr_validate(struct sk_buff *skb)
 }
 EXPORT_SYMBOL_GPL(nft_bridge_ip6hdr_validate);
 
+static inline int 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(pkt, ops, skb, in, out);
+	else
+		nft_set_pktinfo_ipv4(pkt, ops, skb, in, out);
+
+	return 0;
+}
+
+static inline int 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 1;
+#endif
+	return 0;
+}
+
 static unsigned int
 nft_do_chain_bridge(const struct nf_hook_ops *ops,
 		    struct sk_buff *skb,
@@ -71,7 +101,17 @@ nft_do_chain_bridge(const struct nf_hook_ops *ops,
 {
 	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):
+		if (nft_bridge_set_pktinfo_ipv6(&pkt, ops, skb, in, out) > 0)
+			break;
+	default:
+		nft_set_pktinfo(&pkt, ops, skb, in, out);
+		break;
+	}
 
 	return nft_do_chain(&pkt, ops);
 }
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH nf 1/2 v4] bridge: export nft_reject_ip*hdr_validate functions
  2014-11-26  9:21 [PATCH nf 1/2 v4] bridge: export nft_reject_ip*hdr_validate functions Alvaro Neira Ayuso
  2014-11-26  9:21 ` [PATCH nf 2/2 v4] bridge: set the pktinfo for IPv4/IPv6 traffic Alvaro Neira Ayuso
@ 2014-11-27 11:59 ` Pablo Neira Ayuso
  1 sibling, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2014-11-27 11:59 UTC (permalink / raw)
  To: Alvaro Neira Ayuso; +Cc: netfilter-devel

On Wed, Nov 26, 2014 at 10:21:36AM +0100, Alvaro Neira Ayuso wrote:
> This patch exports the functions nft_reject_iphdr_validate and
> nft_reject_ip6hdr_validate to use it in follow up patches.
> These functions check if the ethernet header is correct.

Applied, thanks.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH nf 2/2 v4] bridge: set the pktinfo for IPv4/IPv6 traffic
  2014-11-26  9:21 ` [PATCH nf 2/2 v4] bridge: set the pktinfo for IPv4/IPv6 traffic Alvaro Neira Ayuso
@ 2014-11-27 11:59   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2014-11-27 11:59 UTC (permalink / raw)
  To: Alvaro Neira Ayuso; +Cc: netfilter-devel

On Wed, Nov 26, 2014 at 10:21:37AM +0100, Alvaro Neira Ayuso wrote:
> 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

Applied with changes, please see the nf-next tree.

Thanks.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-11-27 11:57 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-26  9:21 [PATCH nf 1/2 v4] bridge: export nft_reject_ip*hdr_validate functions Alvaro Neira Ayuso
2014-11-26  9:21 ` [PATCH nf 2/2 v4] bridge: set the pktinfo for IPv4/IPv6 traffic Alvaro Neira Ayuso
2014-11-27 11:59   ` Pablo Neira Ayuso
2014-11-27 11:59 ` [PATCH nf 1/2 v4] bridge: export nft_reject_ip*hdr_validate functions Pablo Neira Ayuso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).