netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v3 0/3] NSH and VxLAN-GPE
@ 2016-03-01 11:11 Brian Russell
  2016-03-01 11:11 ` [PATCH net-next v3 1/3] nsh: encapsulation module Brian Russell
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Brian Russell @ 2016-03-01 11:11 UTC (permalink / raw)
  To: netdev

These patches add a new module to support encap/decap of Network
Service Header (NSH) as defined in:

https://tools.ietf.org/html/draft-ietf-sfc-nsh-01

Both NSH Type 1 and Type 2 metadata are supported with a simple registration
hook to allow listeners to register to see packets with Type 1 or a specific
class of Type 2 metadata. NSH could be added to packets sent over a variety
of link types, eg. VxLAN, GRE, ethernet.

v2 - fix copyright notices and tidy up use of types

v3 - fix various style issues in nsh module
     remove VxLAN-GPE changes
     add nsh logging module as example
     add nsh netfilter encap target as example

The previous version included mods to allow NSH over VxLAN-GPE but I've
withdrawn this as VxLAN-GPE is currently being added in a much more complete
patchset. My intention would be to add NSH support on top of that once it's
applied.

I've added the NSH logging module to illustrate the use of the simple
mechanism to register for incoming decap'd NSH metadata.

I've added the NSH netfilter target to illustrate metadata being NSH
encap'd.

Brian Russell (3):
  nsh: encapsulation module
  nsh: logging module
  nsh: netfilter target

 include/net/nsh.h                     | 147 +++++++++++++++
 include/uapi/linux/if_ether.h         |   1 +
 include/uapi/linux/netfilter/xt_NSH.h |  25 +++
 net/ipv4/Kconfig                      |  18 ++
 net/ipv4/Makefile                     |   2 +
 net/ipv4/nsh.c                        | 335 ++++++++++++++++++++++++++++++++++
 net/ipv4/nsh_log.c                    | 135 ++++++++++++++
 net/netfilter/Kconfig                 |   9 +
 net/netfilter/Makefile                |   1 +
 net/netfilter/xt_NSH.c                |  95 ++++++++++
 10 files changed, 768 insertions(+)
 create mode 100644 include/net/nsh.h
 create mode 100644 include/uapi/linux/netfilter/xt_NSH.h
 create mode 100644 net/ipv4/nsh.c
 create mode 100644 net/ipv4/nsh_log.c
 create mode 100644 net/netfilter/xt_NSH.c

-- 
2.1.4

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

* [PATCH net-next v3 1/3] nsh: encapsulation module
  2016-03-01 11:11 [PATCH net-next v3 0/3] NSH and VxLAN-GPE Brian Russell
@ 2016-03-01 11:11 ` Brian Russell
  2016-03-01 11:11 ` [PATCH net-next v3 2/3] nsh: logging module Brian Russell
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Brian Russell @ 2016-03-01 11:11 UTC (permalink / raw)
  To: netdev

Support encap/decap of Network Service Header (NSH) as defined in
https://tools.ietf.org/html/draft-ietf-sfc-nsh-01

Includes support for Type 1 and Type 2 metadata and a simple registration
for listeners to see decapsulated packets based on the Type/Class.

Signed-off-by: Brian Russell <brussell@brocade.com>
---
 include/net/nsh.h             | 147 ++++++++++++++++++
 include/uapi/linux/if_ether.h |   1 +
 net/ipv4/Kconfig              |  10 ++
 net/ipv4/Makefile             |   1 +
 net/ipv4/nsh.c                | 335 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 494 insertions(+)
 create mode 100644 include/net/nsh.h
 create mode 100644 net/ipv4/nsh.c

diff --git a/include/net/nsh.h b/include/net/nsh.h
new file mode 100644
index 0000000..57b29b8
--- /dev/null
+++ b/include/net/nsh.h
@@ -0,0 +1,147 @@
+/*
+ * Network Service Header (NSH) inserted onto encapsulated packets
+ * or frames to realize service function paths.
+ * NSH also provides a mechanism for metadata exchange along the
+ * instantiated service path.
+ *
+ * https://tools.ietf.org/html/draft-ietf-sfc-nsh-01
+ *
+ * Copyright (c) 2016 by Brocade Communications Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __NET_NSH_H
+#define __NET_NSH_H
+
+#include <linux/types.h>
+#include <linux/skbuff.h>
+
+/*
+ * NSH Base Header + Service Path Header
+ *
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |Ver|O|C|R|R|R|R|R|R|   Length  |    MD Type    | Next Protocol |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |          Service Path ID                      | Service Index |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * Ver - Version, set to 0
+ * O - Indicates payload is OAM.
+ * C - Indicates critical metadata TLV is present (must be 0 for MD type 1).
+ * Length - total header length in 4-byte words.
+ * MD Type - Metadata type
+ *           Type 1 - 4 mandatory 4 byte context headers.
+ *           Type 2 - 0 or more var length context headers.
+ * Next Protocol - protocol type of original packet.
+ * Service Path ID (SPI) - identifies a service path. Participating nodes
+ *                         MUST use this identifier for Service Function
+ *                         Path selection.
+ * Service Index (SI) - provides location within the SFP.
+ */
+#define NSH_BF_VER0     0
+#define NSH_BF_VER_MASK 0xc0
+#define NSH_BF_OAM      BIT(5)
+#define NSH_BF_CRIT     BIT(4)
+#define NSH_N_SPI       (1u << 24)
+#define NSH_SPI_MASK    ((NSH_N_SPI-1) << 8)
+#define NSH_N_SI        (1u << 8)
+#define NSH_SI_MASK     (NSH_N_SI-1)
+
+#define NSH_MD_TYPE_1   1
+#define NSH_MD_TYPE_2   2
+
+#define NSH_NEXT_PROTO_IPv4 1
+#define NSH_NEXT_PROTO_IPv6 2
+#define NSH_NEXT_PROTO_ETH  3
+
+#define NSH_LEN_TYPE_1     6
+#define NSH_LEN_TYPE_2_MIN 2
+
+struct nsh_base {
+	u8 base_flags;
+	u8 length;
+	u8 md_type;
+	u8 next_proto;
+};
+
+struct nsh_header {
+	struct nsh_base base;
+	__be32 sp_header;
+};
+
+/*
+ * When the Base Header specifies MD Type 1, four 4-byte Context Headers
+ * MUST be added immediately following the Service Path Header. Thus length
+ * in the base header is set to 6.
+ * Context Headers that carry no metadata MUST be set to zero.
+ */
+#define NSH_MD_TYPE_1_NUM_HDRS 4
+
+struct nsh_md_type_1 {
+	__be32 ctx_hdr1;
+	__be32 ctx_hdr2;
+	__be32 ctx_hdr3;
+	__be32 ctx_hdr4;
+};
+
+/*
+ * When the Base Header specifies MD Type 2, zero or more variable
+ * length Context Headers follow the Service Path Header.
+ *
+ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *     |          TLV Class            |C|    Type     |R|R|R|   Len   |
+ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *     |                      Variable Metadata                        |
+ *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * TLV Class - Scope of class (e.g. may be vendor or standards body).
+ * Type - Specific type of information within the scope of given class.
+ *        C bit (MSB) indicates criticality. When set, receiver must process.
+ * Len - Length of variable metadata in 4-byte words.
+ */
+#define NSH_TYPE_CRIT BIT(7)
+
+struct nsh_md_type_2 {
+	__be16 tlv_class;
+	u8 tlv_type;
+	u8 length;
+};
+
+/* Context header for encap/decap. */
+#define NSH_MD_CLASS_TYPE_1 USHRT_MAX
+#define NSH_MD_TYPE_TYPE_1  U8_MAX
+#define NSH_MD_LEN_TYPE_1   4
+
+struct nsh_metadata {
+	u16 class;
+	u8 crit;
+	u8 type;
+	u8 len;  /* 4 byte words */
+	void *data;
+};
+
+/* Parse NSH header and notify registered listeners about any metadata.*/
+int nsh_decap(struct sk_buff *skb, u32 *spi, u8 *si, u8 *np);
+
+/* Add NSH header. */
+int nsh_encap(struct sk_buff *skb, u32 spi, u8 si, u8 np,
+	      unsigned int num_ctx_hdrs, struct nsh_metadata *ctx_hdrs);
+
+
+/* Register hooks to be informed of nsh metadata of specified class */
+struct nsh_listener {
+	struct list_head list;
+	u16 class;
+	int (*notify)(struct sk_buff *skb,
+		      u32 service_path_id,
+		      u8 service_index,
+		      u8 next_proto,
+		      struct nsh_metadata *ctx_hdrs,
+		      unsigned int num_ctx_hdrs);
+};
+
+int nsh_register_listener(struct nsh_listener *listener);
+int nsh_unregister_listener(struct nsh_listener *listener);
+#endif /* __NET_NSH_H */
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
index ea9221b..eb512b1 100644
--- a/include/uapi/linux/if_ether.h
+++ b/include/uapi/linux/if_ether.h
@@ -91,6 +91,7 @@
 #define ETH_P_TDLS	0x890D          /* TDLS */
 #define ETH_P_FIP	0x8914		/* FCoE Initialization Protocol */
 #define ETH_P_80221	0x8917		/* IEEE 802.21 Media Independent Handover Protocol */
+#define ETH_P_NSH       0x894F          /* Network Service Header */
 #define ETH_P_LOOPBACK	0x9000		/* Ethernet loopback packet, per IEEE 802.3 */
 #define ETH_P_QINQ1	0x9100		/* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
 #define ETH_P_QINQ2	0x9200		/* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 238225b..df14c59 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -213,6 +213,16 @@ config NET_IPGRE_BROADCAST
 	  Network), but can be distributed all over the Internet. If you want
 	  to do that, say Y here and to "IP multicast routing" below.
 
+config NET_NSH
+        tristate 'Network Servive Header Encapsulation'
+        help
+          Network Service Header (NSH) inserted onto
+          encapsulated packets or frames to realize service function paths.
+          NSH also provides a mechanism for metadata exchange along the
+          instantiated service path.
+
+          To compile it as a module, choose M here.  If unsure, say N.
+
 config IP_MROUTE
 	bool "IP: multicast routing"
 	depends on IP_MULTICAST
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index bfa1336..14b7995 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -24,6 +24,7 @@ gre-y := gre_demux.o
 obj-$(CONFIG_NET_FOU) += fou.o
 obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o
 obj-$(CONFIG_NET_IPGRE) += ip_gre.o
+obj-$(CONFIG_NET_NSH) += nsh.o
 obj-$(CONFIG_NET_UDP_TUNNEL) += udp_tunnel.o
 obj-$(CONFIG_NET_IPVTI) += ip_vti.o
 obj-$(CONFIG_SYN_COOKIES) += syncookies.o
diff --git a/net/ipv4/nsh.c b/net/ipv4/nsh.c
new file mode 100644
index 0000000..2106b70
--- /dev/null
+++ b/net/ipv4/nsh.c
@@ -0,0 +1,335 @@
+/*
+ * Network Service Header (NSH) inserted onto encapsulated packets
+ * or frames to realize service function paths.
+ * NSH also provides a mechanism for metadata exchange along the
+ * instantiated service path.
+ *
+ * https://tools.ietf.org/html/draft-ietf-sfc-nsh-01
+ *
+ * Copyright (c) 2016 by Brocade Communications Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <net/nsh.h>
+
+static struct list_head nsh_listeners;
+static DEFINE_MUTEX(nsh_listener_mutex);
+static struct nsh_metadata *decap_ctx_hdrs;
+
+#define MAX_DECAP_CTX_HDRS 10
+
+int nsh_register_listener(struct nsh_listener *listener)
+{
+	mutex_lock(&nsh_listener_mutex);
+	list_add(&listener->list, &nsh_listeners);
+	mutex_unlock(&nsh_listener_mutex);
+	return 0;
+}
+EXPORT_SYMBOL(nsh_register_listener);
+
+int nsh_unregister_listener(struct nsh_listener *listener)
+{
+	mutex_lock(&nsh_listener_mutex);
+	list_del(&listener->list);
+	mutex_unlock(&nsh_listener_mutex);
+	return 0;
+}
+EXPORT_SYMBOL(nsh_unregister_listener);
+
+static int notify_listeners(struct sk_buff *skb, u32 service_path_id,
+			    u8 service_index, u8 next_proto,
+			    struct nsh_metadata *ctx_hdrs,
+			    unsigned int num_ctx_hdrs)
+{
+	struct nsh_listener *listener;
+	int i, err = 0;
+
+	mutex_lock(&nsh_listener_mutex);
+	list_for_each_entry(listener, &nsh_listeners, list) {
+		for (i = 0; i < num_ctx_hdrs; i++)
+			if (listener->class == ctx_hdrs[i].class) {
+				err = listener->notify(skb,
+						       service_path_id,
+						       service_index,
+						       next_proto,
+						       ctx_hdrs,
+						       num_ctx_hdrs);
+				if (err < 0) {
+					mutex_unlock(&nsh_listener_mutex);
+					return err;
+				}
+				break;
+			}
+	}
+	mutex_unlock(&nsh_listener_mutex);
+	return 0;
+}
+
+static int type_1_decap(struct sk_buff *skb, struct nsh_md_type_1 *md,
+			struct nsh_metadata *ctx_hdrs,
+			unsigned int *num_ctx_hdrs)
+{
+	int i;
+	u32 *data =  &md->ctx_hdr1;
+
+	ctx_hdrs[0].class = NSH_MD_CLASS_TYPE_1;
+	ctx_hdrs[0].type = NSH_MD_TYPE_TYPE_1;
+	ctx_hdrs[0].len = NSH_MD_LEN_TYPE_1;
+	ctx_hdrs[0].data = data;
+
+	for (i = 0; i < NSH_MD_TYPE_1_NUM_HDRS; i++, data++)
+		*data = ntohl(*data);
+
+	*num_ctx_hdrs = 1;
+
+	return 0;
+}
+
+static int type_2_decap(struct sk_buff *skb, struct nsh_md_type_2 *md,
+			u8 md_len, struct nsh_metadata *ctx_hdrs,
+			unsigned int *num_ctx_hdrs)
+{
+	u32 *data;
+	int i = 0, j;
+
+	while (md_len > 0) {
+		if (i > MAX_DECAP_CTX_HDRS)
+			return -ENOMEM;
+
+		ctx_hdrs[i].class = ntohs(md->tlv_class);
+		ctx_hdrs[i].type = md->tlv_type;
+		if (ctx_hdrs[i].type & NSH_TYPE_CRIT) {
+			ctx_hdrs[i].type &= ~NSH_TYPE_CRIT;
+			ctx_hdrs[i].crit = 1;
+		}
+		ctx_hdrs[i].len = md->length;
+
+		data = (u32 *) ++md;
+		md_len--;
+
+		ctx_hdrs[i].data = data;
+
+		for (j = 0; j < ctx_hdrs[i].len; j++)
+			data[j] = ntohl(data[j]);
+
+		md = (struct nsh_md_type_2 *)&data[j];
+		md_len -= j;
+		i++;
+	}
+	*num_ctx_hdrs = i;
+
+	return 0;
+}
+
+/* Parse NSH header.
+ *
+ * No additional memory is allocated. Context header data is pointed
+ * to in the buffer payload. Context headers and skb are passed to anyone
+ * who has registered interest in the class(es) of metadata received.
+ *
+ * Returns the total number of 4 byte words in the NSH headers, <0 on failure.
+ */
+int nsh_decap(struct sk_buff *skb, u32 *spi, u8 *si, u8 *np)
+{
+	struct nsh_header *nsh = (struct nsh_header *)skb->data;
+	struct nsh_base *base = &nsh->base;
+	unsigned int num_ctx_hdrs;
+	u32 service_path_id;
+	u8 service_index;
+	u8 next_proto;
+	u32 sph;
+	u8 md_type;
+	u8 hdrlen; /* 4 byte words */
+	unsigned int len; /* bytes */
+	int err;
+
+	hdrlen = base->length;
+	len = hdrlen * sizeof(u32);
+
+	if (unlikely(!pskb_may_pull(skb, len)))
+		return -ENOMEM;
+
+	skb_pull_rcsum(skb, len);
+
+	if (((base->base_flags & NSH_BF_VER_MASK) >> 6) != NSH_BF_VER0)
+		return -EINVAL;
+
+	next_proto = base->next_proto;
+
+	switch (next_proto) {
+	case NSH_NEXT_PROTO_IPv4:
+		skb->protocol = htons(ETH_P_IP);
+		break;
+	case NSH_NEXT_PROTO_IPv6:
+		skb->protocol = htons(ETH_P_IPV6);
+		break;
+	case NSH_NEXT_PROTO_ETH:
+		skb->protocol = htons(ETH_P_TEB);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (np)
+		*np = next_proto;
+
+	sph = ntohl(nsh->sp_header);
+	service_path_id = (sph & NSH_SPI_MASK) >> 8;
+	service_index = sph & NSH_SI_MASK;
+
+	if (spi)
+		*spi = service_path_id;
+	if (si)
+		*si = service_index;
+
+	md_type = base->md_type;
+
+	switch (md_type) {
+	case NSH_MD_TYPE_1:
+		if (hdrlen != NSH_LEN_TYPE_1)
+			return -EINVAL;
+		err = type_1_decap(skb, (struct nsh_md_type_1 *) ++nsh,
+				   decap_ctx_hdrs, &num_ctx_hdrs);
+		break;
+	case NSH_MD_TYPE_2:
+		if (hdrlen < NSH_LEN_TYPE_2_MIN)
+			return -EINVAL;
+		err = type_2_decap(skb, (struct nsh_md_type_2 *) ++nsh,
+				   hdrlen - NSH_LEN_TYPE_2_MIN,
+				   decap_ctx_hdrs, &num_ctx_hdrs);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (err < 0)
+		return err;
+
+	err = notify_listeners(skb, service_path_id,
+			       service_index, next_proto,
+			       decap_ctx_hdrs, num_ctx_hdrs);
+	if (err < 0)
+		return err;
+
+	return hdrlen;
+}
+EXPORT_SYMBOL_GPL(nsh_decap);
+
+static void type_1_encap(u32 *data_out, struct nsh_metadata *ctx_hdrs)
+{
+	int i;
+	u32 *data_in = (u32 *)ctx_hdrs[0].data;
+
+	for (i = 0; i < NSH_MD_TYPE_1_NUM_HDRS; i++)
+		data_out[i] = htonl(data_in[i]);
+}
+
+static void type_2_encap(struct nsh_md_type_2 *md, unsigned int num_ctx_hdrs,
+			 struct nsh_metadata *ctx_hdrs)
+{
+	int i, j;
+	u32 *data_in, *data_out;
+
+	for (i = 0; i < num_ctx_hdrs; i++) {
+		md->tlv_class = htons(ctx_hdrs[i].class);
+		md->tlv_type = ctx_hdrs[i].type;
+		if (ctx_hdrs[i].crit)
+			md->tlv_type |= NSH_TYPE_CRIT;
+		md->length = ctx_hdrs[i].len;
+
+		data_out = (u32 *) ++md;
+		data_in = (u32 *)ctx_hdrs[i].data;
+
+		for (j = 0; j < ctx_hdrs[i].len; j++)
+			data_out[j] = htonl(data_in[j]);
+
+		md = (struct nsh_md_type_2 *)&data_out[j];
+	}
+}
+
+/* Add NSH header. */
+int nsh_encap(struct sk_buff *skb, u32 spi, u8 si, u8 np,
+	      unsigned int num_ctx_hdrs, struct nsh_metadata *ctx_hdrs)
+{
+	bool has_t1 = false, has_t2 = false;
+	bool has_crit = false;
+	unsigned int headroom = sizeof(struct nsh_header);
+	struct nsh_header *nsh;
+	struct nsh_base *base;
+	int i;
+	int err;
+
+	if (np != NSH_NEXT_PROTO_IPv4 &&
+	    np != NSH_NEXT_PROTO_IPv6 &&
+	    np != NSH_NEXT_PROTO_ETH)
+		return -EINVAL;
+
+	if (spi >= NSH_N_SPI)
+		return -EINVAL;
+
+	for (i = 0; i < num_ctx_hdrs; i++) {
+		if (ctx_hdrs[i].class == NSH_MD_CLASS_TYPE_1) {
+			if (num_ctx_hdrs != 1)
+				return -EINVAL;
+			headroom += NSH_MD_LEN_TYPE_1 * sizeof(u32);
+			has_t1 |= true;
+		} else {
+			headroom += ctx_hdrs[i].len * sizeof(u32) +
+				sizeof(struct nsh_md_type_2);
+			has_t2 |= true;
+			has_crit |= ctx_hdrs[i].type & NSH_TYPE_CRIT;
+		}
+
+		if (has_t1 && has_t2)
+			return -EINVAL;
+	}
+
+	err = skb_cow_head(skb, headroom);
+	if (err)
+		return err;
+
+	nsh = (struct nsh_header *)__skb_push(skb, headroom);
+
+	base = &nsh->base;
+	base->base_flags = has_crit ? NSH_BF_CRIT : 0; /* Ver 0, OAM 0 */
+	base->length = headroom / sizeof(u32);
+	base->md_type = has_t1 ? NSH_MD_TYPE_1 : NSH_MD_TYPE_2;
+	base->next_proto = np;
+
+	nsh->sp_header = htonl((spi << 8) | si);
+
+	if (has_t1)
+		type_1_encap((u32 *) ++nsh, ctx_hdrs);
+	else
+		type_2_encap((struct nsh_md_type_2 *) ++nsh, num_ctx_hdrs,
+			     ctx_hdrs);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(nsh_encap);
+
+static int __init nsh_init(void)
+{
+	INIT_LIST_HEAD(&nsh_listeners);
+
+	decap_ctx_hdrs = kmalloc_array(MAX_DECAP_CTX_HDRS,
+				       sizeof(*decap_ctx_hdrs), GFP_KERNEL);
+	if (!decap_ctx_hdrs)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void __exit nsh_exit(void)
+{
+	kfree(decap_ctx_hdrs);
+}
+
+module_init(nsh_init);
+module_exit(nsh_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Brian Russell <brussell@brocade.com>");
+MODULE_DESCRIPTION("Network Service Header Encap/Decap");
-- 
2.1.4

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

* [PATCH net-next v3 2/3] nsh: logging module
  2016-03-01 11:11 [PATCH net-next v3 0/3] NSH and VxLAN-GPE Brian Russell
  2016-03-01 11:11 ` [PATCH net-next v3 1/3] nsh: encapsulation module Brian Russell
@ 2016-03-01 11:11 ` Brian Russell
  2016-03-01 18:25   ` Joe Perches
  2016-03-01 11:11 ` [PATCH net-next v3 3/3] nsh: netfilter target Brian Russell
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Brian Russell @ 2016-03-01 11:11 UTC (permalink / raw)
  To: netdev

Module can register for Type 1 or specified classes of Type 2 metadata
and will then log incoming matching packets.

Signed-off-by: Brian Russell <brussell@brocade.com>
---
 net/ipv4/Kconfig   |   8 ++++
 net/ipv4/Makefile  |   1 +
 net/ipv4/nsh_log.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 144 insertions(+)
 create mode 100644 net/ipv4/nsh_log.c

diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index df14c59..87b6dde 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -223,6 +223,14 @@ config NET_NSH
 
           To compile it as a module, choose M here.  If unsure, say N.
 
+config NET_NSH_LOG
+        tristate 'NSH Metadata Logger'
+	depends on NET_NSH
+	help
+          Log packets with incoming NSH metadata.
+
+          To compile it as a module, choose M here.  If unsure, say N.
+
 config IP_MROUTE
 	bool "IP: multicast routing"
 	depends on IP_MULTICAST
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 14b7995..69377fb 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_NET_FOU) += fou.o
 obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o
 obj-$(CONFIG_NET_IPGRE) += ip_gre.o
 obj-$(CONFIG_NET_NSH) += nsh.o
+obj-$(CONFIG_NET_NSH_LOG) += nsh_log.o
 obj-$(CONFIG_NET_UDP_TUNNEL) += udp_tunnel.o
 obj-$(CONFIG_NET_IPVTI) += ip_vti.o
 obj-$(CONFIG_SYN_COOKIES) += syncookies.o
diff --git a/net/ipv4/nsh_log.c b/net/ipv4/nsh_log.c
new file mode 100644
index 0000000..3d774ed
--- /dev/null
+++ b/net/ipv4/nsh_log.c
@@ -0,0 +1,135 @@
+/*
+ * Network Service Header (NSH) logging module.
+ *
+ * Copyright (c) 2016 by Brocade Communications Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <net/nsh.h>
+
+static bool t1_enabled = false;
+module_param(t1_enabled, bool, 0444);
+MODULE_PARM_DESC(t1_enabled, "Type 1 Metadata log enabled");
+
+#define MAX_T2_CLASSES 10
+static unsigned int t2_classes[MAX_T2_CLASSES];
+static int num_t2 = 0;
+module_param_array(t2_classes, uint, &num_t2, 0444);
+MODULE_PARM_DESC(t2_classes, "Type 2 Metadata classes log enabled");
+
+static const char *nsh_next_proto(u8 next_proto)
+{
+	switch (next_proto) {
+	case NSH_NEXT_PROTO_IPv4:
+		return "IPv4";
+	case NSH_NEXT_PROTO_IPv6:
+		return "IPv6";
+	case NSH_NEXT_PROTO_ETH:
+		return "Eth";
+	default:
+		return "Unknown";
+	}
+}
+
+/* Type 1 metadata has fixed length, 4 x 32-bit words */
+static int nsh_log_t1(struct sk_buff *skb, u32 service_path_id,
+		      u8 service_index, u8 next_proto,
+		      struct nsh_metadata *ctx_hdr, unsigned int num_ctx_hdrs)
+{
+	u32 *data;
+
+	if ((ctx_hdr->class != NSH_MD_CLASS_TYPE_1) ||
+	    (ctx_hdr->type != NSH_MD_TYPE_TYPE_1) ||
+	    (ctx_hdr->len != NSH_MD_LEN_TYPE_1) ||
+	    (num_ctx_hdrs != 1))
+		return -EINVAL;
+
+	data = ctx_hdr->data;
+	pr_info("NSH T1 Rx(%s): SPI=%u SI=%u Next=%s"
+		" MD 0x%08x 0x%08x 0x%08x 0x%08x\n", skb->dev->name,
+		service_path_id, service_index, nsh_next_proto(next_proto),
+		data[0], data[1], data[2], data[3]);
+
+	return 0;
+}
+
+/* Type 2 metadata consists of a variable number of TLVs */
+#define T2_BUFSIZE 512
+static int nsh_log_t2(struct sk_buff *skb, u32 service_path_id,
+		      u8 service_index, u8 next_proto,
+		      struct nsh_metadata *ctx_hdrs, unsigned int num_ctx_hdrs)
+{
+	char t2_buf[T2_BUFSIZE];
+	int wrlen;
+	u32 *data;
+	int i,j;
+
+	wrlen = snprintf(t2_buf, T2_BUFSIZE,
+			 "NSH T2 Class %u Rx(%s): SPI=%u SI=%u Next=%s MD",
+			 ctx_hdrs[0].class, skb->dev->name, service_path_id,
+			 service_index, nsh_next_proto(next_proto));
+
+	for (i = 0; i < num_ctx_hdrs; i++) {
+		wrlen += snprintf(t2_buf+wrlen, T2_BUFSIZE-wrlen,
+				  " TLV%d Type=%u Len=%u", i+1,
+				  ctx_hdrs[i].type, ctx_hdrs[i].len);
+		data = ctx_hdrs[i].data;
+		for (j = 0; j < ctx_hdrs[i].len; j++)
+			wrlen += snprintf(t2_buf+wrlen, T2_BUFSIZE-wrlen,
+					  " 0x%08x", data[j]);
+	}
+	pr_info("%s\n", t2_buf);
+	return 0;
+}
+
+static struct nsh_listener nsh_log_t1_entry = {
+	.class = NSH_MD_CLASS_TYPE_1,
+	.notify = nsh_log_t1,
+};
+
+static struct nsh_listener nsh_log_t2_entry[MAX_T2_CLASSES];
+
+static int __init nsh_log_init(void)
+{
+	int i, err;
+
+	if (t1_enabled) {
+		err = nsh_register_listener(&nsh_log_t1_entry);
+
+		if (err)
+			return err;
+	}
+
+	for (i = 0; i < num_t2; i++) {
+		nsh_log_t2_entry[i].class = t2_classes[i];
+		nsh_log_t2_entry[i].notify = nsh_log_t2;
+
+		err = nsh_register_listener(&nsh_log_t2_entry[i]);
+
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
+static void __exit nsh_log_exit(void)
+{
+	int i;
+
+	if (t1_enabled)
+		nsh_unregister_listener(&nsh_log_t1_entry);
+
+	for (i = 0; i < num_t2; i++)
+		nsh_unregister_listener(&nsh_log_t2_entry[i]);
+}
+
+module_init(nsh_log_init);
+module_exit(nsh_log_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Brian Russell <brussell@brocade.com>");
+MODULE_DESCRIPTION("NSH Metadata logger");
-- 
2.1.4

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

* [PATCH net-next v3 3/3] nsh: netfilter target
  2016-03-01 11:11 [PATCH net-next v3 0/3] NSH and VxLAN-GPE Brian Russell
  2016-03-01 11:11 ` [PATCH net-next v3 1/3] nsh: encapsulation module Brian Russell
  2016-03-01 11:11 ` [PATCH net-next v3 2/3] nsh: logging module Brian Russell
@ 2016-03-01 11:11 ` Brian Russell
  2016-03-01 18:12 ` [PATCH net-next v3 0/3] NSH and VxLAN-GPE Alexei Starovoitov
  2016-03-04 17:15 ` Tom Herbert
  4 siblings, 0 replies; 10+ messages in thread
From: Brian Russell @ 2016-03-01 11:11 UTC (permalink / raw)
  To: netdev

Add an NSH netfilter target, to add NSH encap'd metadata to outgoing
packets.

Signed-off-by: Brian Russell <brussell@brocade.com>
---
 include/uapi/linux/netfilter/xt_NSH.h | 25 +++++++++
 net/netfilter/Kconfig                 |  9 ++++
 net/netfilter/Makefile                |  1 +
 net/netfilter/xt_NSH.c                | 95 +++++++++++++++++++++++++++++++++++
 4 files changed, 130 insertions(+)
 create mode 100644 include/uapi/linux/netfilter/xt_NSH.h
 create mode 100644 net/netfilter/xt_NSH.c

diff --git a/include/uapi/linux/netfilter/xt_NSH.h b/include/uapi/linux/netfilter/xt_NSH.h
new file mode 100644
index 0000000..82b76f6
--- /dev/null
+++ b/include/uapi/linux/netfilter/xt_NSH.h
@@ -0,0 +1,25 @@
+/* Header file for NSH target extension for xtables.
+ *
+ * Copyright (c) 2016 by Brocade Communications Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _XT_NSH_H
+#define _XT_NSH_H
+
+struct xt_nsh_info {
+	__u32 service_path_id;
+	__u8 service_index;
+	__u8 metadata_type;
+	__u16 t2_class;
+	__u8 t2_type;
+	__u8 t2_len;
+	__u32 value1;
+	__u32 value2;
+	__u32 value3;
+	__u32 value4;
+};
+
+#endif /* _XT_NSH_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 95e757c..6349d56 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -863,6 +863,15 @@ config NETFILTER_XT_TARGET_NOTRACK
 	depends on NETFILTER_ADVANCED
 	select NETFILTER_XT_TARGET_CT
 
+config NETFILTER_XT_TARGET_NSH
+       tristate '"NSH" target support'
+       depends on NETFILTER_ADVANCED
+       help
+         This options adds a `NSH' target, which allows to add NSH metadata
+	 to outgoing packets.
+
+         To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_TARGET_RATEEST
 	tristate '"RATEEST" target support'
 	depends on NETFILTER_ADVANCED
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 6913454..59ea6f6 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -120,6 +120,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_LOG) += xt_LOG.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NETMAP) += xt_NETMAP.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_NSH) += xt_NSH.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_REDIRECT) += xt_REDIRECT.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
diff --git a/net/netfilter/xt_NSH.c b/net/netfilter/xt_NSH.c
new file mode 100644
index 0000000..b1c930c
--- /dev/null
+++ b/net/netfilter/xt_NSH.c
@@ -0,0 +1,95 @@
+/* Network Service Header (NSH) target extension for xtables.
+ *
+ * Copyright (c) 2016 by Brocade Communications Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/netfilter.h>
+#include <linux/skbuff.h>
+#include <linux/notifier.h>
+#include <linux/netfilter/x_tables.h>
+#include <uapi/linux/netfilter/xt_NSH.h>
+#include <net/nsh.h>
+
+static unsigned int nsh_tg(struct sk_buff *skb,
+			   const struct xt_action_param *par)
+{
+	const struct xt_nsh_info *info = par->targinfo;
+	struct nsh_metadata ctx_hdr;
+	u32 data[4];
+	int err;
+
+	skb->protocol = htons(ETH_P_NSH);
+
+	if (info->metadata_type == NSH_MD_TYPE_1) {
+		ctx_hdr.class = NSH_MD_CLASS_TYPE_1;
+		ctx_hdr.type = NSH_MD_TYPE_TYPE_1;
+		ctx_hdr.len = NSH_MD_LEN_TYPE_1;
+	} else {
+		ctx_hdr.class = info->t2_class;
+		ctx_hdr.type = info->t2_type;
+		ctx_hdr.len = info->t2_len;
+	}
+
+	data[0] = info->value1;
+	data[1] = info->value2;
+	data[2] = info->value3;
+	data[3] = info->value4;
+
+	ctx_hdr.data = &data;
+	ctx_hdr.crit = 1;
+
+	err = nsh_encap(skb, info->service_path_id, info->service_index,
+			NSH_NEXT_PROTO_IPv4, 1, &ctx_hdr);
+	if (err < 0)
+		return NF_DROP;
+
+	return NF_ACCEPT;
+}
+
+static int nsh_tg_check(const struct xt_tgchk_param *par)
+{
+	struct xt_nsh_info *info = par->targinfo;
+
+	if (info->metadata_type != NSH_MD_TYPE_1 &&
+	    info->metadata_type != NSH_MD_TYPE_2)
+		return -EINVAL;
+	if (info->service_path_id >= NSH_N_SPI)
+		return -EINVAL;
+	if (info->metadata_type == NSH_MD_TYPE_2 &&
+	    (info->t2_len > 4 || info->t2_class == NSH_MD_CLASS_TYPE_1))
+		return -EINVAL;
+	return 0;
+}
+
+static struct xt_target nsh_tg_reg[] __read_mostly = {
+	{
+		.name     = "NSH",
+		.revision = 0,
+		.family   = NFPROTO_IPV4,
+		.target   = nsh_tg,
+		.targetsize = sizeof(struct xt_nsh_info),
+		.checkentry = nsh_tg_check,
+		.me       = THIS_MODULE,
+	},
+};
+
+static int __init nsh_tg_init(void)
+{
+	return xt_register_targets(nsh_tg_reg, ARRAY_SIZE(nsh_tg_reg));
+}
+
+static void __exit nsh_tg_exit(void)
+{
+	xt_unregister_targets(nsh_tg_reg, ARRAY_SIZE(nsh_tg_reg));
+}
+
+module_init(nsh_tg_init);
+module_exit(nsh_tg_exit);
+MODULE_AUTHOR("Brian Russell <brussell@brocade.com>");
+MODULE_DESCRIPTION("Xtables: Add NSH metadata");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_NSH");
-- 
2.1.4

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

* Re: [PATCH net-next v3 0/3] NSH and VxLAN-GPE
  2016-03-01 11:11 [PATCH net-next v3 0/3] NSH and VxLAN-GPE Brian Russell
                   ` (2 preceding siblings ...)
  2016-03-01 11:11 ` [PATCH net-next v3 3/3] nsh: netfilter target Brian Russell
@ 2016-03-01 18:12 ` Alexei Starovoitov
  2016-03-04 15:38   ` Brian Russell
  2016-03-04 17:15 ` Tom Herbert
  4 siblings, 1 reply; 10+ messages in thread
From: Alexei Starovoitov @ 2016-03-01 18:12 UTC (permalink / raw)
  To: Brian Russell; +Cc: netdev

On Tue, Mar 01, 2016 at 11:11:46AM +0000, Brian Russell wrote:
> These patches add a new module to support encap/decap of Network
> Service Header (NSH) as defined in:
> 
> https://tools.ietf.org/html/draft-ietf-sfc-nsh-01
> 
> Both NSH Type 1 and Type 2 metadata are supported with a simple registration
> hook to allow listeners to register to see packets with Type 1 or a specific
> class of Type 2 metadata. NSH could be added to packets sent over a variety
> of link types, eg. VxLAN, GRE, ethernet.
> 
> v2 - fix copyright notices and tidy up use of types
> 
> v3 - fix various style issues in nsh module
>      remove VxLAN-GPE changes
>      add nsh logging module as example
>      add nsh netfilter encap target as example

two fake examples are trying to justify EXPORT_SYMBOL(nsh_register_listener) ?!
what's the real meaning of this patch set?
As far as I can see in-tree users cannot do anything useful with it.

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

* Re: [PATCH net-next v3 2/3] nsh: logging module
  2016-03-01 11:11 ` [PATCH net-next v3 2/3] nsh: logging module Brian Russell
@ 2016-03-01 18:25   ` Joe Perches
  2016-03-04 15:39     ` Brian Russell
  0 siblings, 1 reply; 10+ messages in thread
From: Joe Perches @ 2016-03-01 18:25 UTC (permalink / raw)
  To: Brian Russell, netdev

On Tue, 2016-03-01 at 11:11 +0000, Brian Russell wrote:
> Module can register for Type 1 or specified classes of Type 2 metadata
> and will then log incoming matching packets.

This logging mechanism seems like a way to fill/DoS logs.

Maybe use pr_info_ratelimit?
Maybe use the trace_events mechanisms instead?

> Signed-off-by: Brian Russell <brussell@brocade.com>
> ---
>  net/ipv4/Kconfig   |   8 ++++
>  net/ipv4/Makefile  |   1 +
>  net/ipv4/nsh_log.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 144 insertions(+)
>  create mode 100644 net/ipv4/nsh_log.c
> 
> diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
> index df14c59..87b6dde 100644
> --- a/net/ipv4/Kconfig
> +++ b/net/ipv4/Kconfig
> @@ -223,6 +223,14 @@ config NET_NSH
>  
>            To compile it as a module, choose M here.  If unsure, say N.
>  
> +config NET_NSH_LOG
> +        tristate 'NSH Metadata Logger'
> +	depends on NET_NSH
> +	help
> +          Log packets with incoming NSH metadata.
> +
> +          To compile it as a module, choose M here.  If unsure, say N.
> +
>  config IP_MROUTE
>  	bool "IP: multicast routing"
>  	depends on IP_MULTICAST
> diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
> index 14b7995..69377fb 100644
> --- a/net/ipv4/Makefile
> +++ b/net/ipv4/Makefile
> @@ -25,6 +25,7 @@ obj-$(CONFIG_NET_FOU) += fou.o
>  obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o
>  obj-$(CONFIG_NET_IPGRE) += ip_gre.o
>  obj-$(CONFIG_NET_NSH) += nsh.o
> +obj-$(CONFIG_NET_NSH_LOG) += nsh_log.o
>  obj-$(CONFIG_NET_UDP_TUNNEL) += udp_tunnel.o
>  obj-$(CONFIG_NET_IPVTI) += ip_vti.o
>  obj-$(CONFIG_SYN_COOKIES) += syncookies.o
> diff --git a/net/ipv4/nsh_log.c b/net/ipv4/nsh_log.c
> new file mode 100644
> index 0000000..3d774ed
> --- /dev/null
> +++ b/net/ipv4/nsh_log.c
> @@ -0,0 +1,135 @@
> +/*
> + * Network Service Header (NSH) logging module.
> + *
> + * Copyright (c) 2016 by Brocade Communications Systems, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include 
> +#include 
> +#include 
> +
> +static bool t1_enabled = false;
> +module_param(t1_enabled, bool, 0444);
> +MODULE_PARM_DESC(t1_enabled, "Type 1 Metadata log enabled");
> +
> +#define MAX_T2_CLASSES 10
> +static unsigned int t2_classes[MAX_T2_CLASSES];
> +static int num_t2 = 0;
> +module_param_array(t2_classes, uint, &num_t2, 0444);
> +MODULE_PARM_DESC(t2_classes, "Type 2 Metadata classes log enabled");
> +
> +static const char *nsh_next_proto(u8 next_proto)
> +{
> +	switch (next_proto) {
> +	case NSH_NEXT_PROTO_IPv4:
> +		return "IPv4";
> +	case NSH_NEXT_PROTO_IPv6:
> +		return "IPv6";
> +	case NSH_NEXT_PROTO_ETH:
> +		return "Eth";
> +	default:
> +		return "Unknown";
> +	}
> +}
> +
> +/* Type 1 metadata has fixed length, 4 x 32-bit words */
> +static int nsh_log_t1(struct sk_buff *skb, u32 service_path_id,
> +		      u8 service_index, u8 next_proto,
> +		      struct nsh_metadata *ctx_hdr, unsigned int num_ctx_hdrs)
> +{
> +	u32 *data;
> +
> +	if ((ctx_hdr->class != NSH_MD_CLASS_TYPE_1) ||
> +	    (ctx_hdr->type != NSH_MD_TYPE_TYPE_1) ||
> +	    (ctx_hdr->len != NSH_MD_LEN_TYPE_1) ||
> +	    (num_ctx_hdrs != 1))
> +		return -EINVAL;
> +
> +	data = ctx_hdr->data;
> +	pr_info("NSH T1 Rx(%s): SPI=%u SI=%u Next=%s"
> +		" MD 0x%08x 0x%08x 0x%08x 0x%08x\n", skb->dev->name,
> +		service_path_id, service_index, nsh_next_proto(next_proto),
> +		data[0], data[1], data[2], data[3]);
> +
> +	return 0;
> +}
> +
> +/* Type 2 metadata consists of a variable number of TLVs */
> +#define T2_BUFSIZE 512
> +static int nsh_log_t2(struct sk_buff *skb, u32 service_path_id,
> +		      u8 service_index, u8 next_proto,
> +		      struct nsh_metadata *ctx_hdrs, unsigned int num_ctx_hdrs)
> +{
> +	char t2_buf[T2_BUFSIZE];
> +	int wrlen;
> +	u32 *data;
> +	int i,j;
> +
> +	wrlen = snprintf(t2_buf, T2_BUFSIZE,
> +			 "NSH T2 Class %u Rx(%s): SPI=%u SI=%u Next=%s MD",
> +			 ctx_hdrs[0].class, skb->dev->name, service_path_id,
> +			 service_index, nsh_next_proto(next_proto));
> +
> +	for (i = 0; i < num_ctx_hdrs; i++) {
> +		wrlen += snprintf(t2_buf+wrlen, T2_BUFSIZE-wrlen,
> +				  " TLV%d Type=%u Len=%u", i+1,
> +				  ctx_hdrs[i].type, ctx_hdrs[i].len);
> +		data = ctx_hdrs[i].data;
> +		for (j = 0; j < ctx_hdrs[i].len; j++)
> +			wrlen += snprintf(t2_buf+wrlen, T2_BUFSIZE-wrlen,
> +					  " 0x%08x", data[j]);
> +	}
> +	pr_info("%s\n", t2_buf);
> +	return 0;
> +}
> +
> +static struct nsh_listener nsh_log_t1_entry = {
> +	.class = NSH_MD_CLASS_TYPE_1,
> +	.notify = nsh_log_t1,
> +};
> +
> +static struct nsh_listener nsh_log_t2_entry[MAX_T2_CLASSES];
> +
> +static int __init nsh_log_init(void)
> +{
> +	int i, err;
> +
> +	if (t1_enabled) {
> +		err = nsh_register_listener(&nsh_log_t1_entry);
> +
> +		if (err)
> +			return err;
> +	}
> +
> +	for (i = 0; i < num_t2; i++) {
> +		nsh_log_t2_entry[i].class = t2_classes[i];
> +		nsh_log_t2_entry[i].notify = nsh_log_t2;
> +
> +		err = nsh_register_listener(&nsh_log_t2_entry[i]);
> +
> +		if (err)
> +			return err;
> +	}
> +	return 0;
> +}
> +
> +static void __exit nsh_log_exit(void)
> +{
> +	int i;
> +
> +	if (t1_enabled)
> +		nsh_unregister_listener(&nsh_log_t1_entry);
> +
> +	for (i = 0; i < num_t2; i++)
> +		nsh_unregister_listener(&nsh_log_t2_entry[i]);
> +}
> +
> +module_init(nsh_log_init);
> +module_exit(nsh_log_exit);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Brian Russell <brussell@brocade.com>");
> +MODULE_DESCRIPTION("NSH Metadata logger");

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

* Re: [PATCH net-next v3 0/3] NSH and VxLAN-GPE
  2016-03-01 18:12 ` [PATCH net-next v3 0/3] NSH and VxLAN-GPE Alexei Starovoitov
@ 2016-03-04 15:38   ` Brian Russell
  2016-03-04 22:14     ` David Miller
  0 siblings, 1 reply; 10+ messages in thread
From: Brian Russell @ 2016-03-04 15:38 UTC (permalink / raw)
  To: Alexei Starovoitov, Brian Russell; +Cc: netdev


On 01/03/16 18:12, Alexei Starovoitov wrote:
> On Tue, Mar 01, 2016 at 11:11:46AM +0000, Brian Russell wrote:
>> These patches add a new module to support encap/decap of Network
>> Service Header (NSH) as defined in:
>>
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__tools.ietf.org_html_draft-2Dietf-2Dsfc-2Dnsh-2D01&d=CwIBAg&c=IL_XqQWOjubgfqINi2jTzg&r=Doie302MT-sezztwQymkPQ3_4X5Q3a0mKbiZzzoNm-0&m=GXnpiqS7PmfkgZFQ49KQrVhoa7H-hyPyPstkZdCi7hQ&s=Ncdq5xpzX-AAUeSDXaoU_zxqfXSdoI_qvgFZVyUclV0&e= 
>>
>> Both NSH Type 1 and Type 2 metadata are supported with a simple registration
>> hook to allow listeners to register to see packets with Type 1 or a specific
>> class of Type 2 metadata. NSH could be added to packets sent over a variety
>> of link types, eg. VxLAN, GRE, ethernet.
>>
>> v2 - fix copyright notices and tidy up use of types
>>
>> v3 - fix various style issues in nsh module
>>      remove VxLAN-GPE changes
>>      add nsh logging module as example
>>      add nsh netfilter encap target as example
> 
> two fake examples are trying to justify EXPORT_SYMBOL(nsh_register_listener) ?!
> what's the real meaning of this patch set?
> As far as I can see in-tree users cannot do anything useful with it.
> 

I don't see what you're getting at. I thought the "real meaning" was obvious?

The NSH draft says:

" Optional Variable Length Metadata

...
   TLV Class: describes the scope of the "Type" field.  In some cases,
   the TLV Class will identify a specific vendor, in others, the TLV
   Class will identify specific standards body allocated types.  A new
   IANA registry will be created for TLV Class type.

   Type: the specific type of information being carried, within the
   scope of a given TLV Class.  Value allocation is the responsibility
   of the TLV Class owner."

So it seems reasonable to have a hook to hang metadata interpretation on?

Thanks and regards,

Brian

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

* Re: [PATCH net-next v3 2/3] nsh: logging module
  2016-03-01 18:25   ` Joe Perches
@ 2016-03-04 15:39     ` Brian Russell
  0 siblings, 0 replies; 10+ messages in thread
From: Brian Russell @ 2016-03-04 15:39 UTC (permalink / raw)
  To: Joe Perches, netdev



On 01/03/16 18:25, Joe Perches wrote:
> On Tue, 2016-03-01 at 11:11 +0000, Brian Russell wrote:
>> Module can register for Type 1 or specified classes of Type 2 metadata
>> and will then log incoming matching packets.
> 
> This logging mechanism seems like a way to fill/DoS logs.
> 
> Maybe use pr_info_ratelimit?
> Maybe use the trace_events mechanisms instead?
> 

Thanks, will do.

Brian

>> Signed-off-by: Brian Russell <brussell@brocade.com>
>> ---
>>  net/ipv4/Kconfig   |   8 ++++
>>  net/ipv4/Makefile  |   1 +
>>  net/ipv4/nsh_log.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 144 insertions(+)
>>  create mode 100644 net/ipv4/nsh_log.c
>>
>> diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
>> index df14c59..87b6dde 100644
>> --- a/net/ipv4/Kconfig
>> +++ b/net/ipv4/Kconfig
>> @@ -223,6 +223,14 @@ config NET_NSH
>>  
>>            To compile it as a module, choose M here.  If unsure, say N.
>>  
>> +config NET_NSH_LOG
>> +        tristate 'NSH Metadata Logger'
>> +	depends on NET_NSH
>> +	help
>> +          Log packets with incoming NSH metadata.
>> +
>> +          To compile it as a module, choose M here.  If unsure, say N.
>> +
>>  config IP_MROUTE
>>  	bool "IP: multicast routing"
>>  	depends on IP_MULTICAST
>> diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
>> index 14b7995..69377fb 100644
>> --- a/net/ipv4/Makefile
>> +++ b/net/ipv4/Makefile
>> @@ -25,6 +25,7 @@ obj-$(CONFIG_NET_FOU) += fou.o
>>  obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o
>>  obj-$(CONFIG_NET_IPGRE) += ip_gre.o
>>  obj-$(CONFIG_NET_NSH) += nsh.o
>> +obj-$(CONFIG_NET_NSH_LOG) += nsh_log.o
>>  obj-$(CONFIG_NET_UDP_TUNNEL) += udp_tunnel.o
>>  obj-$(CONFIG_NET_IPVTI) += ip_vti.o
>>  obj-$(CONFIG_SYN_COOKIES) += syncookies.o
>> diff --git a/net/ipv4/nsh_log.c b/net/ipv4/nsh_log.c
>> new file mode 100644
>> index 0000000..3d774ed
>> --- /dev/null
>> +++ b/net/ipv4/nsh_log.c
>> @@ -0,0 +1,135 @@
>> +/*
>> + * Network Service Header (NSH) logging module.
>> + *
>> + * Copyright (c) 2016 by Brocade Communications Systems, Inc.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +#include 
>> +#include 
>> +#include 
>> +
>> +static bool t1_enabled = false;
>> +module_param(t1_enabled, bool, 0444);
>> +MODULE_PARM_DESC(t1_enabled, "Type 1 Metadata log enabled");
>> +
>> +#define MAX_T2_CLASSES 10
>> +static unsigned int t2_classes[MAX_T2_CLASSES];
>> +static int num_t2 = 0;
>> +module_param_array(t2_classes, uint, &num_t2, 0444);
>> +MODULE_PARM_DESC(t2_classes, "Type 2 Metadata classes log enabled");
>> +
>> +static const char *nsh_next_proto(u8 next_proto)
>> +{
>> +	switch (next_proto) {
>> +	case NSH_NEXT_PROTO_IPv4:
>> +		return "IPv4";
>> +	case NSH_NEXT_PROTO_IPv6:
>> +		return "IPv6";
>> +	case NSH_NEXT_PROTO_ETH:
>> +		return "Eth";
>> +	default:
>> +		return "Unknown";
>> +	}
>> +}
>> +
>> +/* Type 1 metadata has fixed length, 4 x 32-bit words */
>> +static int nsh_log_t1(struct sk_buff *skb, u32 service_path_id,
>> +		      u8 service_index, u8 next_proto,
>> +		      struct nsh_metadata *ctx_hdr, unsigned int num_ctx_hdrs)
>> +{
>> +	u32 *data;
>> +
>> +	if ((ctx_hdr->class != NSH_MD_CLASS_TYPE_1) ||
>> +	    (ctx_hdr->type != NSH_MD_TYPE_TYPE_1) ||
>> +	    (ctx_hdr->len != NSH_MD_LEN_TYPE_1) ||
>> +	    (num_ctx_hdrs != 1))
>> +		return -EINVAL;
>> +
>> +	data = ctx_hdr->data;
>> +	pr_info("NSH T1 Rx(%s): SPI=%u SI=%u Next=%s"
>> +		" MD 0x%08x 0x%08x 0x%08x 0x%08x\n", skb->dev->name,
>> +		service_path_id, service_index, nsh_next_proto(next_proto),
>> +		data[0], data[1], data[2], data[3]);
>> +
>> +	return 0;
>> +}
>> +
>> +/* Type 2 metadata consists of a variable number of TLVs */
>> +#define T2_BUFSIZE 512
>> +static int nsh_log_t2(struct sk_buff *skb, u32 service_path_id,
>> +		      u8 service_index, u8 next_proto,
>> +		      struct nsh_metadata *ctx_hdrs, unsigned int num_ctx_hdrs)
>> +{
>> +	char t2_buf[T2_BUFSIZE];
>> +	int wrlen;
>> +	u32 *data;
>> +	int i,j;
>> +
>> +	wrlen = snprintf(t2_buf, T2_BUFSIZE,
>> +			 "NSH T2 Class %u Rx(%s): SPI=%u SI=%u Next=%s MD",
>> +			 ctx_hdrs[0].class, skb->dev->name, service_path_id,
>> +			 service_index, nsh_next_proto(next_proto));
>> +
>> +	for (i = 0; i < num_ctx_hdrs; i++) {
>> +		wrlen += snprintf(t2_buf+wrlen, T2_BUFSIZE-wrlen,
>> +				  " TLV%d Type=%u Len=%u", i+1,
>> +				  ctx_hdrs[i].type, ctx_hdrs[i].len);
>> +		data = ctx_hdrs[i].data;
>> +		for (j = 0; j < ctx_hdrs[i].len; j++)
>> +			wrlen += snprintf(t2_buf+wrlen, T2_BUFSIZE-wrlen,
>> +					  " 0x%08x", data[j]);
>> +	}
>> +	pr_info("%s\n", t2_buf);
>> +	return 0;
>> +}
>> +
>> +static struct nsh_listener nsh_log_t1_entry = {
>> +	.class = NSH_MD_CLASS_TYPE_1,
>> +	.notify = nsh_log_t1,
>> +};
>> +
>> +static struct nsh_listener nsh_log_t2_entry[MAX_T2_CLASSES];
>> +
>> +static int __init nsh_log_init(void)
>> +{
>> +	int i, err;
>> +
>> +	if (t1_enabled) {
>> +		err = nsh_register_listener(&nsh_log_t1_entry);
>> +
>> +		if (err)
>> +			return err;
>> +	}
>> +
>> +	for (i = 0; i < num_t2; i++) {
>> +		nsh_log_t2_entry[i].class = t2_classes[i];
>> +		nsh_log_t2_entry[i].notify = nsh_log_t2;
>> +
>> +		err = nsh_register_listener(&nsh_log_t2_entry[i]);
>> +
>> +		if (err)
>> +			return err;
>> +	}
>> +	return 0;
>> +}
>> +
>> +static void __exit nsh_log_exit(void)
>> +{
>> +	int i;
>> +
>> +	if (t1_enabled)
>> +		nsh_unregister_listener(&nsh_log_t1_entry);
>> +
>> +	for (i = 0; i < num_t2; i++)
>> +		nsh_unregister_listener(&nsh_log_t2_entry[i]);
>> +}
>> +
>> +module_init(nsh_log_init);
>> +module_exit(nsh_log_exit);
>> +
>> +MODULE_LICENSE("GPL");
>> +MODULE_AUTHOR("Brian Russell <brussell@brocade.com>");
>> +MODULE_DESCRIPTION("NSH Metadata logger");
> 

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

* Re: [PATCH net-next v3 0/3] NSH and VxLAN-GPE
  2016-03-01 11:11 [PATCH net-next v3 0/3] NSH and VxLAN-GPE Brian Russell
                   ` (3 preceding siblings ...)
  2016-03-01 18:12 ` [PATCH net-next v3 0/3] NSH and VxLAN-GPE Alexei Starovoitov
@ 2016-03-04 17:15 ` Tom Herbert
  4 siblings, 0 replies; 10+ messages in thread
From: Tom Herbert @ 2016-03-04 17:15 UTC (permalink / raw)
  To: Brian Russell; +Cc: Linux Kernel Network Developers

On Tue, Mar 1, 2016 at 3:11 AM, Brian Russell <brussell@brocade.com> wrote:
> These patches add a new module to support encap/decap of Network
> Service Header (NSH) as defined in:
>
> https://tools.ietf.org/html/draft-ietf-sfc-nsh-01
>
> Both NSH Type 1 and Type 2 metadata are supported with a simple registration
> hook to allow listeners to register to see packets with Type 1 or a specific
> class of Type 2 metadata. NSH could be added to packets sent over a variety
> of link types, eg. VxLAN, GRE, ethernet.
>
> v2 - fix copyright notices and tidy up use of types
>
> v3 - fix various style issues in nsh module
>      remove VxLAN-GPE changes
>      add nsh logging module as example
>      add nsh netfilter encap target as example
>
> The previous version included mods to allow NSH over VxLAN-GPE but I've
> withdrawn this as VxLAN-GPE is currently being added in a much more complete
> patchset. My intention would be to add NSH support on top of that once it's
> applied.
>
What about NSH/GRE, NSH/Ethernet, and NSH/UDP?

> I've added the NSH logging module to illustrate the use of the simple
> mechanism to register for incoming decap'd NSH metadata.
>

Shouldn't that be in netfilter also?

> I've added the NSH netfilter target to illustrate metadata being NSH
> encap'd.
>
I think this patch set would be more compelling with an actual real
use case of SFC functionality. The ability to parse this stuff and
pass it to various layers or log that we are receiving it is nice and
all, but what is the functionality that we really need the kernel to
support here?

Tom

> Brian Russell (3):
>   nsh: encapsulation module
>   nsh: logging module
>   nsh: netfilter target
>
>  include/net/nsh.h                     | 147 +++++++++++++++
>  include/uapi/linux/if_ether.h         |   1 +
>  include/uapi/linux/netfilter/xt_NSH.h |  25 +++
>  net/ipv4/Kconfig                      |  18 ++
>  net/ipv4/Makefile                     |   2 +
>  net/ipv4/nsh.c                        | 335 ++++++++++++++++++++++++++++++++++
>  net/ipv4/nsh_log.c                    | 135 ++++++++++++++
>  net/netfilter/Kconfig                 |   9 +
>  net/netfilter/Makefile                |   1 +
>  net/netfilter/xt_NSH.c                |  95 ++++++++++
>  10 files changed, 768 insertions(+)
>  create mode 100644 include/net/nsh.h
>  create mode 100644 include/uapi/linux/netfilter/xt_NSH.h
>  create mode 100644 net/ipv4/nsh.c
>  create mode 100644 net/ipv4/nsh_log.c
>  create mode 100644 net/netfilter/xt_NSH.c
>
> --
> 2.1.4
>

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

* Re: [PATCH net-next v3 0/3] NSH and VxLAN-GPE
  2016-03-04 15:38   ` Brian Russell
@ 2016-03-04 22:14     ` David Miller
  0 siblings, 0 replies; 10+ messages in thread
From: David Miller @ 2016-03-04 22:14 UTC (permalink / raw)
  To: brian.russell; +Cc: alexei.starovoitov, brussell, netdev

From: Brian Russell <brian.russell@brocade.com>
Date: Fri, 4 Mar 2016 15:38:47 +0000

> So it seems reasonable to have a hook to hang metadata
> interpretation on?

Nope.

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

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

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-01 11:11 [PATCH net-next v3 0/3] NSH and VxLAN-GPE Brian Russell
2016-03-01 11:11 ` [PATCH net-next v3 1/3] nsh: encapsulation module Brian Russell
2016-03-01 11:11 ` [PATCH net-next v3 2/3] nsh: logging module Brian Russell
2016-03-01 18:25   ` Joe Perches
2016-03-04 15:39     ` Brian Russell
2016-03-01 11:11 ` [PATCH net-next v3 3/3] nsh: netfilter target Brian Russell
2016-03-01 18:12 ` [PATCH net-next v3 0/3] NSH and VxLAN-GPE Alexei Starovoitov
2016-03-04 15:38   ` Brian Russell
2016-03-04 22:14     ` David Miller
2016-03-04 17:15 ` Tom Herbert

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).