[ovs-dev] [CudaMailTagged] [RFC PATCH 09/14] parse NSH key in key_extract of openvswitch
Johnson Li
johnson.li at intel.com
Tue Jun 7 18:09:51 UTC 2016
Parse the Network Service Header to fullfill the fields in the
struct sw_flow_key.
Signed-off-by: Johnson Li <johnson.li at intel.com>
diff --git a/datapath/flow.c b/datapath/flow.c
index fd09cec..223ff5c 100644
--- a/datapath/flow.c
+++ b/datapath/flow.c
@@ -44,6 +44,7 @@
#include <net/ipv6.h>
#include <net/mpls.h>
#include <net/ndisc.h>
+#include <net/nsh.h>
#include "datapath.h"
#include "conntrack.h"
@@ -296,6 +297,36 @@ static bool icmp6hdr_ok(struct sk_buff *skb)
sizeof(struct icmp6hdr));
}
+/**
+ * Basic assumption is that the MD Type equals 1.
+ */
+static int parse_nsh(struct sk_buff *skb, struct sw_flow_key *key)
+{
+ struct nsh_hdr *nsh_hdr = (struct nsh_hdr *)skb_mac_header(skb);
+ struct nsh_md1_ctx *ctx = NULL;
+ int length = 0;
+
+ length = nsh_hdr->base.length << 2;
+ if (length > NSH_LEN_MAX)
+ return -EINVAL;
+
+ if (nsh_hdr->base.md_type != NSH_M_TYPE1)
+ return -EINVAL;
+
+ ctx = (struct nsh_md1_ctx *)(nsh_hdr->ctx);
+ key->nsh.md_type = nsh_hdr->base.md_type;
+ key->nsh.next_proto = nsh_hdr->base.next_proto;
+ key->nsh.nsi = nsh_hdr->base.svc_idx;
+ key->nsh.nsp = nsh_hdr->base.path_hdr << 8;
+ key->nsh.nshc1 = ctx->nshc1;
+ key->nsh.nshc2 = ctx->nshc2;
+ key->nsh.nshc3 = ctx->nshc3;
+ key->nsh.nshc4 = ctx->nshc4;
+
+ __skb_pull(skb, length);
+ return length;
+}
+
static int parse_vlan(struct sk_buff *skb, struct sw_flow_key *key)
{
struct qtag_prefix {
@@ -454,7 +485,7 @@ invalid:
*/
static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
{
- int error;
+ int error, nsh_len = 0;
struct ethhdr *eth;
/* Flags are always used as part of stats */
@@ -491,6 +522,11 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
/* Network Service Header */
memset(&key->nsh, 0, sizeof(key->nsh));
+ if (skb->protocol == htons(ETH_P_NSH)) {
+ nsh_len = parse_nsh(skb, key);
+ if (unlikely(nsh_len <= 0))
+ return -EINVAL;
+ }
/* Network layer. */
if (key->eth.type == htons(ETH_P_IP)) {
@@ -679,6 +715,10 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
}
}
}
+
+ if (nsh_len > 0)
+ __skb_push(skb, nsh_len);
+
return 0;
}
diff --git a/datapath/linux/Modules.mk b/datapath/linux/Modules.mk
index 5d38766..3df91e2 100644
--- a/datapath/linux/Modules.mk
+++ b/datapath/linux/Modules.mk
@@ -92,6 +92,7 @@ openvswitch_headers += \
linux/compat/include/net/stt.h \
linux/compat/include/net/vrf.h \
linux/compat/include/net/vxlan.h \
+ linux/compat/include/net/nsh.h \
linux/compat/include/net/netfilter/nf_conntrack.h \
linux/compat/include/net/netfilter/nf_conntrack_core.h \
linux/compat/include/net/netfilter/nf_conntrack_expect.h \
diff --git a/datapath/linux/compat/include/net/nsh.h b/datapath/linux/compat/include/net/nsh.h
new file mode 100644
index 0000000..98a342f
--- /dev/null
+++ b/datapath/linux/compat/include/net/nsh.h
@@ -0,0 +1,117 @@
+#ifndef __NET_NSH_H
+#define __NET_NSH_H 1
+
+#include <asm/byteorder.h>
+
+/*
+ * Network Service Header:
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |Ver|O|C|R|R|R|R|R|R| Length | MD Type | Next Proto |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Service Path ID | Service Index |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * ~ Mandatory/Optional Context Header ~
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * Ver = The version field is used to ensure backward compatibility
+ * going forward with future NSH updates. It MUST be set to 0x0
+ * by the sender, in this first revision of NSH.
+ *
+ * O = OAM. when set to 0x1 indicates that this packet is an operations
+ * and management (OAM) packet. The receiving SFF and SFs nodes
+ * MUST examine the payload and take appropriate action.
+ *
+ * C = context. Indicates that a critical metadata TLV is present.
+ *
+ * Length : total length, in 4-byte words, of NSH including the Base
+ * Header, the Service Path Header and the optional variable
+ * TLVs.
+ * MD Type: indicates the format of NSH beyond the mandatory Base Header
+ * and the Service Path Header.
+ *
+ * Next Protocol: indicates the protocol type of the original packet. A
+ * new IANA registry will be created for protocol type.
+ *
+ * Service Path Identifier (SPI): identifies a service path.
+ * Participating nodes MUST use this identifier for Service
+ * Function Path selection.
+ *
+ * Service Index (SI): provides location within the SFP.
+ *
+ * [0] https://tools.ietf.org/html/draft-ietf-sfc-nsh-01
+ */
+struct nsh_base {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 reserved_flags1:4;
+ __u8 context_flag:1;
+ __u8 oam_flag:1;
+ __u8 version:2;
+
+ __u8 length:6;
+ __u8 reserved_flags2:2;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u8 version:2;
+ __u8 oam_flag:1;
+ __u8 context_flag:1;
+ __u8 reserved_flags1:4;
+
+ __u8 reserved_flags2:2;
+ __u8 length:6;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ __u8 md_type;
+ __u8 next_proto;
+ union {
+ struct {
+ __u8 svc_path[3];
+ __u8 svc_idx;
+ };
+ __be32 path_hdr;
+ };
+};
+
+/**
+ * struct nsh_md1_ctx - Keeps track of NSH context data
+ * @nshc<1-4>: NSH Contexts.
+ */
+struct nsh_md1_ctx {
+ __be32 nshc1;
+ __be32 nshc2;
+ __be32 nshc3;
+ __be32 nshc4;
+};
+
+/**
+ * struct nshdr - Network Service header
+ * @base: Network Service Base Header.
+ * @ctx: Network Service Context Header.
+ */
+struct nsh_hdr {
+ struct nsh_base base;
+ __be32 ctx[0]; /* Mandatory/optional Context Header */
+};
+
+#define NSH_DST_PORT 4790 /* UDP Port for NSH on VXLAN */
+#define ETH_P_NSH 0x894F /* Ethertype for NSH */
+
+/* NSH Base Header Next Protocol */
+#define NSH_P_IPV4 0x01
+#define NSH_P_IPV6 0x02
+#define NSH_P_ETHERNET 0x03
+
+/* MD Type Registry */
+#define NSH_M_TYPE1 0x01
+#define NSH_M_EXP1 0xFE
+#define NSH_M_EXP2 0xFF
+
+/* Used for masking nsp and nsi values in field nsp below */
+#define NSH_M_NSP 0x00FFFFFF
+#define NSH_M_NSI 0xFF000000
+
+/* sizeof(struct nsh_hdr) + sizeof(struct nsh_md1_ctx) */
+#define NSH_M_TYPE1_LEN 24
+#define NSH_LEN_MAX 256
+
+#endif
--
1.8.4.2
More information about the dev
mailing list