> 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?
[JL] yes, more strict check is required.  
> > +
> > +   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

Reply via email to