Regards _Sugesh
> -----Original Message----- > From: dev [mailto:dev-boun...@openvswitch.org] On Behalf Of Johnson Li > Sent: Tuesday, June 7, 2016 7:10 PM > To: dev@openvswitch.org > Subject: [ovs-dev] [CudaMailTagged] [RFC PATCH 09/14] parse NSH key in > key_extract of openvswitch > Importance: Low > > Parse the Network Service Header to fullfill the fields in the struct > sw_flow_key. > > Signed-off-by: Johnson Li <johnson...@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; [Sugesh] Should we need a length check for MD_TYPE1? > + > + 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 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev