On Mon, Jun 6, 2016 at 2:34 AM, Yi Yang <yi.y.y...@intel.com> 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 <johnson...@intel.com> > Signed-off-by: Yi Yang <yi.y.y...@intel.com> > --- > 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. ... > 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.