All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH nf-next v6 1/3] netfilter: bridge: add nf_afinfo to enable queuing to userspace
@ 2016-03-26  7:42 Stephane Bryant
  2016-03-26  7:42 ` [PATCH nf-next v6 2/3] netfilter: bridge: pass L2 header and VLAN as netlink attributes in queues " Stephane Bryant
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Stephane Bryant @ 2016-03-26  7:42 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, stephane

From: stephane <stephane.ml.bryant@gmail.com>

This just adds and registers a nf_afinfo for the ethernet
bridge, which enables queuing to userspace for the AF_BRIDGE
family. No checksum computation is done.

Signed-off-by: Stephane Bryant <stephane.ml.bryant@gmail.com>
---
 net/bridge/netfilter/nf_tables_bridge.c | 47 +++++++++++++++++++++++++++++++--
 1 file changed, 45 insertions(+), 2 deletions(-)

diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c
index 7fcdd72..a78c4e2 100644
--- a/net/bridge/netfilter/nf_tables_bridge.c
+++ b/net/bridge/netfilter/nf_tables_bridge.c
@@ -162,15 +162,57 @@ static const struct nf_chain_type filter_bridge = {
 			  (1 << NF_BR_POST_ROUTING),
 };
 
+static void nf_br_saveroute(const struct sk_buff *skb,
+			    struct nf_queue_entry *entry)
+{
+}
+
+static int nf_br_reroute(struct net *net, struct sk_buff *skb,
+			 const struct nf_queue_entry *entry)
+{
+	return 0;
+}
+
+static __sum16 nf_br_checksum(struct sk_buff *skb, unsigned int hook,
+			      unsigned int dataoff, u_int8_t protocol)
+{
+	return 0;
+}
+
+static __sum16 nf_br_checksum_partial(struct sk_buff *skb, unsigned int hook,
+				      unsigned int dataoff, unsigned int len,
+				      u_int8_t protocol)
+{
+	return 0;
+}
+
+static int nf_br_route(struct net *net, struct dst_entry **dst,
+		       struct flowi *fl, bool strict __always_unused)
+{
+	return 0;
+}
+
+static const struct nf_afinfo nf_br_afinfo = {
+	.family                 = AF_BRIDGE,
+	.checksum               = nf_br_checksum,
+	.checksum_partial       = nf_br_checksum_partial,
+	.route                  = nf_br_route,
+	.saveroute              = nf_br_saveroute,
+	.reroute                = nf_br_reroute,
+	.route_key_size         = 0,
+};
+
 static int __init nf_tables_bridge_init(void)
 {
 	int ret;
 
+	nf_register_afinfo(&nf_br_afinfo);
 	nft_register_chain_type(&filter_bridge);
 	ret = register_pernet_subsys(&nf_tables_bridge_net_ops);
-	if (ret < 0)
+	if (ret < 0) {
 		nft_unregister_chain_type(&filter_bridge);
-
+		nf_unregister_afinfo(&nf_br_afinfo);
+	}
 	return ret;
 }
 
@@ -178,6 +220,7 @@ static void __exit nf_tables_bridge_exit(void)
 {
 	unregister_pernet_subsys(&nf_tables_bridge_net_ops);
 	nft_unregister_chain_type(&filter_bridge);
+	nf_unregister_afinfo(&nf_br_afinfo);
 }
 
 module_init(nf_tables_bridge_init);
-- 
2.1.4


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

* [PATCH nf-next v6 2/3] netfilter: bridge: pass L2 header and VLAN as netlink attributes in queues to userspace
  2016-03-26  7:42 [PATCH nf-next v6 1/3] netfilter: bridge: add nf_afinfo to enable queuing to userspace Stephane Bryant
@ 2016-03-26  7:42 ` Stephane Bryant
  2016-03-29 11:02   ` Pablo Neira Ayuso
  2016-03-26  7:42 ` [PATCH nf-next v6 3/3] netfilter: bridge: nf queue verdict to use NFQA_VLAN and NFQA_L2HDR Stephane Bryant
  2016-03-29 11:02 ` [PATCH nf-next v6 1/3] netfilter: bridge: add nf_afinfo to enable queuing to userspace Pablo Neira Ayuso
  2 siblings, 1 reply; 6+ messages in thread
From: Stephane Bryant @ 2016-03-26  7:42 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, stephane

From: stephane <stephane.ml.bryant@gmail.com>

-this creates 2 netlink attribute NLQA_VLAN and NLQA_L2HDR
-these are filled up for the PF_BRIDGE family on the way to userspace
-NFQA_VLAN is a nested attribute, with the NFQA_VLAN_PROTO and the
 NFQA_VLAN_TCI carrying the corresponding vlan_proto and vlan_tci
 fields from the skb using big endian ordering (and using the CFI
 bit as the VLAN_TAG_PRESENT flag in vlan_tci as in the skb)

Signed-off-by: Stephane Bryant <stephane.ml.bryant@gmail.com>
---
 include/uapi/linux/netfilter/nfnetlink_queue.h | 10 +++++
 net/netfilter/nfnetlink_queue.c                | 61 ++++++++++++++++++++++++++
 2 files changed, 71 insertions(+)

diff --git a/include/uapi/linux/netfilter/nfnetlink_queue.h b/include/uapi/linux/netfilter/nfnetlink_queue.h
index b67a853..d159e71 100644
--- a/include/uapi/linux/netfilter/nfnetlink_queue.h
+++ b/include/uapi/linux/netfilter/nfnetlink_queue.h
@@ -30,6 +30,14 @@ struct nfqnl_msg_packet_timestamp {
 	__aligned_be64	usec;
 };
 
+enum nfqnl_vlan_attr {
+	NFQA_VLAN_UNSPEC,
+	NFQA_VLAN_PROTO,		/* __be16 skb vlan_proto */
+	NFQA_VLAN_TCI,			/* __be16 skb htons(vlan_tci) */
+	_NFQA_VLAN_MAX,
+};
+#define NFQA_VLAN_MAX (_NFQA_VLAN_MAX + 1)
+
 enum nfqnl_attr_type {
 	NFQA_UNSPEC,
 	NFQA_PACKET_HDR,
@@ -50,6 +58,8 @@ enum nfqnl_attr_type {
 	NFQA_UID,			/* __u32 sk uid */
 	NFQA_GID,			/* __u32 sk gid */
 	NFQA_SECCTX,			/* security context string */
+	NFQA_VLAN,			/* nested attribute: packet vlan info */
+	NFQA_L2HDR,			/* full L2 header */
 
 	__NFQA_MAX
 };
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 7542999..6451f5d 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -295,6 +295,62 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata)
 	return seclen;
 }
 
+static u32 nfqnl_get_bridge_nla_len(struct nf_queue_entry *entry)
+{
+	u32 nlalen = 0;
+	struct sk_buff *entskb = entry->skb;
+
+	if (entry->state.pf != PF_BRIDGE || !skb_mac_header_was_set(entskb))
+		return 0;
+
+	if (skb_vlan_tag_present(entskb))
+		nlalen += nla_total_size(nla_total_size(sizeof(__be16)) +
+					 nla_total_size(sizeof(__be16)));
+
+	if (entskb->network_header > entskb->mac_header)
+		nlalen += nla_total_size((entskb->network_header -
+					  entskb->mac_header));
+
+	return nlalen;
+}
+
+static int nfqnl_put_bridge_nla(struct nf_queue_entry *entry,
+				struct sk_buff *skb)
+{
+	struct sk_buff *entskb = entry->skb;
+
+	if (entry->state.pf != PF_BRIDGE || !skb_mac_header_was_set(entskb))
+		return 0;
+
+	if (skb_vlan_tag_present(entskb)) {
+		struct nlattr *vlan_attr =
+			nla_nest_start(skb, NFQA_VLAN | NLA_F_NESTED);
+
+		if (!vlan_attr)
+			goto nla_put_failure;
+
+		if (nla_put_be16(skb, NFQA_VLAN_TCI, htons(entskb->vlan_tci)))
+			goto nla_put_failure;
+
+		if (nla_put_be16(skb, NFQA_VLAN_PROTO, entskb->vlan_proto))
+			goto nla_put_failure;
+
+		nla_nest_end(skb, vlan_attr);
+	}
+
+	if (entskb->mac_header < entskb->network_header) {
+		int len = (int)(entskb->network_header - entskb->mac_header);
+
+		if (nla_put(skb, NFQA_L2HDR, len, skb_mac_header(entskb)))
+			goto nla_put_failure;
+	}
+
+	return 0;
+
+nla_put_failure:
+	return -1;
+}
+
 static struct sk_buff *
 nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
 			   struct nf_queue_entry *entry,
@@ -334,6 +390,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
 	if (entskb->tstamp.tv64)
 		size += nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp));
 
+	size += nfqnl_get_bridge_nla_len(entry);
+
 	if (entry->state.hook <= NF_INET_FORWARD ||
 	   (entry->state.hook == NF_INET_POST_ROUTING && entskb->sk == NULL))
 		csum_verify = !skb_csum_unnecessary(entskb);
@@ -497,6 +555,9 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
 		}
 	}
 
+	if (nfqnl_put_bridge_nla(entry, skb))
+		goto nla_put_failure;
+
 	if (entskb->tstamp.tv64) {
 		struct nfqnl_msg_packet_timestamp ts;
 		struct timespec64 kts = ktime_to_timespec64(skb->tstamp);
-- 
2.1.4


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

* [PATCH nf-next v6 3/3] netfilter: bridge: nf queue verdict to use NFQA_VLAN and NFQA_L2HDR
  2016-03-26  7:42 [PATCH nf-next v6 1/3] netfilter: bridge: add nf_afinfo to enable queuing to userspace Stephane Bryant
  2016-03-26  7:42 ` [PATCH nf-next v6 2/3] netfilter: bridge: pass L2 header and VLAN as netlink attributes in queues " Stephane Bryant
@ 2016-03-26  7:42 ` Stephane Bryant
  2016-03-29 11:04   ` Pablo Neira Ayuso
  2016-03-29 11:02 ` [PATCH nf-next v6 1/3] netfilter: bridge: add nf_afinfo to enable queuing to userspace Pablo Neira Ayuso
  2 siblings, 1 reply; 6+ messages in thread
From: Stephane Bryant @ 2016-03-26  7:42 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, Stephane Bryant

This makes nf queues use NFQA_VLAN and NFQA_L2HDR in verdict to modify the
original skb

Signed-off-by: Stephane Bryant <stephane.ml.bryant@gmail.com>
---
 net/netfilter/nfnetlink_queue.c | 45 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 6451f5d..a7ad25a 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -967,12 +967,18 @@ static struct notifier_block nfqnl_rtnl_notifier = {
 	.notifier_call	= nfqnl_rcv_nl_event,
 };
 
+static const struct nla_policy nfqa_vlan_policy[NFQA_VLAN_MAX + 1] = {
+	[NFQA_VLAN_TCI]		= { .type = NLA_U16},
+	[NFQA_VLAN_PROTO]	= { .type = NLA_U16},
+};
+
 static const struct nla_policy nfqa_verdict_policy[NFQA_MAX+1] = {
 	[NFQA_VERDICT_HDR]	= { .len = sizeof(struct nfqnl_msg_verdict_hdr) },
 	[NFQA_MARK]		= { .type = NLA_U32 },
 	[NFQA_PAYLOAD]		= { .type = NLA_UNSPEC },
 	[NFQA_CT]		= { .type = NLA_UNSPEC },
 	[NFQA_EXP]		= { .type = NLA_UNSPEC },
+	[NFQA_VLAN]		= { .type = NLA_NESTED },
 };
 
 static const struct nla_policy nfqa_verdict_batch_policy[NFQA_MAX+1] = {
@@ -1086,6 +1092,40 @@ static struct nf_conn *nfqnl_ct_parse(struct nfnl_ct_hook *nfnl_ct,
 	return ct;
 }
 
+static int nfqa_parse_bridge(struct nf_queue_entry *entry,
+			     const struct nlattr * const nfqa[])
+{
+	if (nfqa[NFQA_VLAN]) {
+		int err;
+		struct nlattr *tb[NFQA_VLAN_MAX + 1];
+
+		err = nla_parse_nested(tb, NFQA_VLAN_MAX, nfqa[NFQA_VLAN],
+				       nfqa_vlan_policy);
+		if (err < 0)
+			return err;
+
+		if (!tb[NFQA_VLAN_TCI] || !tb[NFQA_VLAN_PROTO])
+			return -EINVAL;
+
+		entry->skb->vlan_tci = ntohs(nla_get_be16(tb[NFQA_VLAN_TCI]));
+		entry->skb->vlan_proto = nla_get_be16(tb[NFQA_VLAN_PROTO]);
+	}
+
+	if (nfqa[NFQA_L2HDR]) {
+		int mac_header_len = entry->skb->network_header -
+			entry->skb->mac_header;
+
+		if (mac_header_len != nla_len(nfqa[NFQA_L2HDR]))
+			return -EINVAL;
+		else if (mac_header_len > 0)
+			memcpy(skb_mac_header(entry->skb),
+			       nla_data(nfqa[NFQA_L2HDR]),
+			       mac_header_len);
+	}
+
+	return 0;
+}
+
 static int nfqnl_recv_verdict(struct net *net, struct sock *ctnl,
 			      struct sk_buff *skb,
 			      const struct nlmsghdr *nlh,
@@ -1127,6 +1167,11 @@ static int nfqnl_recv_verdict(struct net *net, struct sock *ctnl,
 			ct = nfqnl_ct_parse(nfnl_ct, nlh, nfqa, entry, &ctinfo);
 	}
 
+	if (entry->state.pf == PF_BRIDGE) {
+		if (nfqa_parse_bridge(entry, nfqa) < 0)
+			verdict = NF_DROP;
+	}
+
 	if (nfqa[NFQA_PAYLOAD]) {
 		u16 payload_len = nla_len(nfqa[NFQA_PAYLOAD]);
 		int diff = payload_len - entry->skb->len;
-- 
2.1.4


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

* Re: [PATCH nf-next v6 1/3] netfilter: bridge: add nf_afinfo to enable queuing to userspace
  2016-03-26  7:42 [PATCH nf-next v6 1/3] netfilter: bridge: add nf_afinfo to enable queuing to userspace Stephane Bryant
  2016-03-26  7:42 ` [PATCH nf-next v6 2/3] netfilter: bridge: pass L2 header and VLAN as netlink attributes in queues " Stephane Bryant
  2016-03-26  7:42 ` [PATCH nf-next v6 3/3] netfilter: bridge: nf queue verdict to use NFQA_VLAN and NFQA_L2HDR Stephane Bryant
@ 2016-03-29 11:02 ` Pablo Neira Ayuso
  2 siblings, 0 replies; 6+ messages in thread
From: Pablo Neira Ayuso @ 2016-03-29 11:02 UTC (permalink / raw)
  To: Stephane Bryant; +Cc: netfilter-devel

On Sat, Mar 26, 2016 at 08:42:10AM +0100, Stephane Bryant wrote:
> From: stephane <stephane.ml.bryant@gmail.com>
> 
> This just adds and registers a nf_afinfo for the ethernet
> bridge, which enables queuing to userspace for the AF_BRIDGE
> family. No checksum computation is done.

Applied, thanks Stephane.

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

* Re: [PATCH nf-next v6 2/3] netfilter: bridge: pass L2 header and VLAN as netlink attributes in queues to userspace
  2016-03-26  7:42 ` [PATCH nf-next v6 2/3] netfilter: bridge: pass L2 header and VLAN as netlink attributes in queues " Stephane Bryant
@ 2016-03-29 11:02   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 6+ messages in thread
From: Pablo Neira Ayuso @ 2016-03-29 11:02 UTC (permalink / raw)
  To: Stephane Bryant; +Cc: netfilter-devel

On Sat, Mar 26, 2016 at 08:42:11AM +0100, Stephane Bryant wrote:
> From: stephane <stephane.ml.bryant@gmail.com>
> 
> -this creates 2 netlink attribute NLQA_VLAN and NLQA_L2HDR
> -these are filled up for the PF_BRIDGE family on the way to userspace
> -NFQA_VLAN is a nested attribute, with the NFQA_VLAN_PROTO and the
>  NFQA_VLAN_TCI carrying the corresponding vlan_proto and vlan_tci
>  fields from the skb using big endian ordering (and using the CFI
>  bit as the VLAN_TAG_PRESENT flag in vlan_tci as in the skb)

Also applied, thanks.

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

* Re: [PATCH nf-next v6 3/3] netfilter: bridge: nf queue verdict to use NFQA_VLAN and NFQA_L2HDR
  2016-03-26  7:42 ` [PATCH nf-next v6 3/3] netfilter: bridge: nf queue verdict to use NFQA_VLAN and NFQA_L2HDR Stephane Bryant
@ 2016-03-29 11:04   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 6+ messages in thread
From: Pablo Neira Ayuso @ 2016-03-29 11:04 UTC (permalink / raw)
  To: Stephane Bryant; +Cc: netfilter-devel

On Sat, Mar 26, 2016 at 08:42:12AM +0100, Stephane Bryant wrote:
> This makes nf queues use NFQA_VLAN and NFQA_L2HDR in verdict to modify the
> original skb

Applied this too, thanks. Just one minor glitch.

> Signed-off-by: Stephane Bryant <stephane.ml.bryant@gmail.com>
> ---
>  net/netfilter/nfnetlink_queue.c | 45 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
> 
> diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
> index 6451f5d..a7ad25a 100644
> --- a/net/netfilter/nfnetlink_queue.c
> +++ b/net/netfilter/nfnetlink_queue.c
> @@ -967,12 +967,18 @@ static struct notifier_block nfqnl_rtnl_notifier = {
>  	.notifier_call	= nfqnl_rcv_nl_event,
>  };
>  
> +static const struct nla_policy nfqa_vlan_policy[NFQA_VLAN_MAX + 1] = {
> +	[NFQA_VLAN_TCI]		= { .type = NLA_U16},
> +	[NFQA_VLAN_PROTO]	= { .type = NLA_U16},
> +};
> +
>  static const struct nla_policy nfqa_verdict_policy[NFQA_MAX+1] = {
>  	[NFQA_VERDICT_HDR]	= { .len = sizeof(struct nfqnl_msg_verdict_hdr) },
>  	[NFQA_MARK]		= { .type = NLA_U32 },
>  	[NFQA_PAYLOAD]		= { .type = NLA_UNSPEC },
>  	[NFQA_CT]		= { .type = NLA_UNSPEC },
>  	[NFQA_EXP]		= { .type = NLA_UNSPEC },
> +	[NFQA_VLAN]		= { .type = NLA_NESTED },
>  };
>  
>  static const struct nla_policy nfqa_verdict_batch_policy[NFQA_MAX+1] = {
> @@ -1086,6 +1092,40 @@ static struct nf_conn *nfqnl_ct_parse(struct nfnl_ct_hook *nfnl_ct,
>  	return ct;
>  }
>  
> +static int nfqa_parse_bridge(struct nf_queue_entry *entry,
> +			     const struct nlattr * const nfqa[])
> +{
> +	if (nfqa[NFQA_VLAN]) {
> +		int err;
> +		struct nlattr *tb[NFQA_VLAN_MAX + 1];
> +
> +		err = nla_parse_nested(tb, NFQA_VLAN_MAX, nfqa[NFQA_VLAN],
> +				       nfqa_vlan_policy);
> +		if (err < 0)
> +			return err;
> +
> +		if (!tb[NFQA_VLAN_TCI] || !tb[NFQA_VLAN_PROTO])
> +			return -EINVAL;
> +
> +		entry->skb->vlan_tci = ntohs(nla_get_be16(tb[NFQA_VLAN_TCI]));
> +		entry->skb->vlan_proto = nla_get_be16(tb[NFQA_VLAN_PROTO]);
> +	}
> +
> +	if (nfqa[NFQA_L2HDR]) {
> +		int mac_header_len = entry->skb->network_header -
> +			entry->skb->mac_header;
> +
> +		if (mac_header_len != nla_len(nfqa[NFQA_L2HDR]))
> +			return -EINVAL;
> +		else if (mac_header_len > 0)
> +			memcpy(skb_mac_header(entry->skb),
> +			       nla_data(nfqa[NFQA_L2HDR]),
> +			       mac_header_len);
> +	}
> +
> +	return 0;
> +}
> +
>  static int nfqnl_recv_verdict(struct net *net, struct sock *ctnl,
>  			      struct sk_buff *skb,
>  			      const struct nlmsghdr *nlh,
> @@ -1127,6 +1167,11 @@ static int nfqnl_recv_verdict(struct net *net, struct sock *ctnl,
>  			ct = nfqnl_ct_parse(nfnl_ct, nlh, nfqa, entry, &ctinfo);
>  	}
>  
> +	if (entry->state.pf == PF_BRIDGE) {
> +		if (nfqa_parse_bridge(entry, nfqa) < 0)
> +			verdict = NF_DROP;

I have changed this to return -EINVAL instead, so userspace knows that
what it is doing is wrong.

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

end of thread, other threads:[~2016-03-29 11:04 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-26  7:42 [PATCH nf-next v6 1/3] netfilter: bridge: add nf_afinfo to enable queuing to userspace Stephane Bryant
2016-03-26  7:42 ` [PATCH nf-next v6 2/3] netfilter: bridge: pass L2 header and VLAN as netlink attributes in queues " Stephane Bryant
2016-03-29 11:02   ` Pablo Neira Ayuso
2016-03-26  7:42 ` [PATCH nf-next v6 3/3] netfilter: bridge: nf queue verdict to use NFQA_VLAN and NFQA_L2HDR Stephane Bryant
2016-03-29 11:04   ` Pablo Neira Ayuso
2016-03-29 11:02 ` [PATCH nf-next v6 1/3] netfilter: bridge: add nf_afinfo to enable queuing to userspace Pablo Neira Ayuso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.