Subject: Re: [PATCH net-next] NSH(Network Service Header) implementation

From: "Yang, Yi" <[email-masked]>
Date: Sun, 12 Jun 2016 15:53:50 +0800

On Mon, Jun 06, 2016 at 05:45:08PM -0700, pravin shelar wrote:
> On Mon, Jun 6, 2016 at 2:34 AM, Yi Yang <[email-masked]> wrote:
> > IETF defined NSH(Network Service Header) for Service
> > Function Chaining, this is an IETF draft
> >
> > https://tools.ietf.org/html/draft-ietf-sfc-nsh-05
> >
> > It will be a IETF standard shortly, this patch implemented
> > NSH for Open vSwitch.
> >
> > Signed-off-by: Johnson Li <[email-masked]>
> > Signed-off-by: Yi Yang <[email-masked]>
> > ---
> >  drivers/net/vxlan.c              |   7 ++
> >  include/net/nsh.h                | 117 +++++++++++++++++++++++
> >  include/uapi/linux/openvswitch.h |  32 +++++++
> >  net/openvswitch/actions.c        |  68 +++++++++++++
> >  net/openvswitch/flow.c           |  45 ++++++++-
> >  net/openvswitch/flow.h           |  15 +++
> >  net/openvswitch/flow_netlink.c   | 202 ++++++++++++++++++++++++++++++++++++++-
> >  net/openvswitch/vport-netdev.c   |   3 +-
> >  net/openvswitch/vport-vxlan.c    |  15 +++
> >  9 files changed, 501 insertions(+), 3 deletions(-)
> >  create mode 100644 include/net/nsh.h
> >
> 
> ...
> ...
> > diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
> > index 9a3eb7a..38e787c 100644
> > --- a/net/openvswitch/actions.c
> > +++ b/net/openvswitch/actions.c
> > @@ -29,6 +29,7 @@
> >  #include <linux/in6.h>
> >  #include <linux/if_arp.h>
> >  #include <linux/if_vlan.h>
> > +#include <linux/if_ether.h>
> >
> >  #include <net/dst.h>
> >  #include <net/ip.h>
> > @@ -38,6 +39,7 @@
> >  #include <net/dsfield.h>
> >  #include <net/mpls.h>
> >  #include <net/sctp/checksum.h>
> > +#include <net/nsh.h>
> >
> >  #include "datapath.h"
> >  #include "flow.h"
> > @@ -259,6 +261,64 @@ static int push_vlan(struct sk_buff *skb, struct sw_flow_key *key,
> >                              ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT);
> >  }
> >
> ...
> ...
> > +
> > +static int push_nsh(struct sk_buff *skb, struct sw_flow_key *key,
> > +                   const struct ovs_action_push_nsh *nsh)
> > +{
> > +       if (nsh->len > 0 && nsh->len <= 256) {
> > +               struct nsh_hdr *nsh_hdr = NULL;
> > +
> > +               if (skb_cow_head(skb, nsh->len) < 0)
> > +                       return -ENOMEM;
> > +
> > +               skb_push(skb, nsh->len);
> > +               nsh_hdr = (struct nsh_hdr *)(skb->data);
> > +               memcpy(nsh_hdr, nsh->header, nsh->len);
> > +
> > +               if (!skb->inner_protocol)
> > +                       skb_set_inner_protocol(skb, skb->protocol);
> > +
> > +               skb->protocol = htons(ETH_P_NSH); /* 0x894F */
> > +               key->eth.type = htons(ETH_P_NSH);
> > +       } else {
> > +               return -EINVAL;
> > +       }
> > +
> > +       return 0;
> > +}
> 
> Networking stack or OVS can not handle arbitrary skb-protocol. For
> example what happens if OVS has push vlan action or it sends this nsh
> packet to net device which can not handle nsh packet? Even networking
> stack can not parse such packet for handling offloads in software.
> ...
>
ovs nsh patch set have been sent out, they can handle nsh header. This
patch just implemented NSH push and pop actions, we do need some cdoe to
do some sanity check for the case you mentioned, but I think it is out
of scope of thi patch.

> > diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
> > index 5eb7694..3d060c4 100644
> > --- a/net/openvswitch/vport-vxlan.c
> > +++ b/net/openvswitch/vport-vxlan.c
> > @@ -52,6 +52,18 @@ static int vxlan_get_options(const struct vport *vport, struct sk_buff *skb)
> >                         return -EMSGSIZE;
> >
> >                 nla_nest_end(skb, exts);
> > +       } else if (vxlan->flags & VXLAN_F_GPE) {
> > +               struct nlattr *exts;
> > +
> > +               exts = nla_nest_start(skb, OVS_TUNNEL_ATTR_EXTENSION);
> > +               if (!exts)
> > +                       return -EMSGSIZE;
> > +
> > +               if (vxlan->flags & VXLAN_F_GPE &&
> > +                   nla_put_flag(skb, OVS_VXLAN_EXT_GPE))
> > +                       return -EMSGSIZE;
> > +
> > +               nla_nest_end(skb, exts);
> >         }
> >
> >         return 0;
> > @@ -59,6 +71,7 @@ static int vxlan_get_options(const struct vport *vport, struct sk_buff *skb)
> >
> >  static const struct nla_policy exts_policy[OVS_VXLAN_EXT_MAX + 1] = {
> >         [OVS_VXLAN_EXT_GBP]     = { .type = NLA_FLAG, },
> > +       [OVS_VXLAN_EXT_GPE]     = { .type = NLA_FLAG, },
> >  };
> >
> >  static int vxlan_configure_exts(struct vport *vport, struct nlattr *attr,
> > @@ -76,6 +89,8 @@ static int vxlan_configure_exts(struct vport *vport, struct nlattr *attr,
> >
> >         if (exts[OVS_VXLAN_EXT_GBP])
> >                 conf->flags |= VXLAN_F_GBP;
> > +       else if (exts[OVS_VXLAN_EXT_GPE])
> > +               conf->flags |= VXLAN_F_GPE;
> >
> This is compatibility code, no need to add new features to this code.
> Now we should be directly using net devices.
Will use net device after those patches are merged into net-next, It
seems current net device implementation in net-next doesn't include it,
do you mean this one
"http://article.gmane.org/gmane.network.openvswitch.devel/64799"?
_______________________________________________
dev mailing list
[email-masked]
http://openvswitch.org/mailman/listinfo/dev