Browse Source

refactor scripts and update NSH patch

Change-Id: Ifc76e9bf2f83f904e765e6e8216ed98910642bae
Signed-off-by: Guo Ruijing <ruijing.guo@intel.com>
tags/10.0-eol
Guo Ruijing 3 years ago
parent
commit
2bad5a25e9

+ 23
- 0
deployment_scripts/install.sh View File

@@ -0,0 +1,23 @@
1
+#!/bin/bash
2
+set -eux
3
+
4
+INSTALL_HOME=/tmp/ovs-nshdpdk
5
+rm -rf $INSTALL_HOME; mkdir -p $INSTALL_HOME
6
+cd $INSTALL_HOME
7
+
8
+host=$1
9
+nsh=$2
10
+dpdk=$3
11
+
12
+wget -r -nd -np http://$host:8080/plugins/fuel-plugin-ovs-0.9/ovs_package/ubuntu
13
+
14
+if [ $nsh = 'true' ]
15
+then
16
+    dpkg -i openvswitch-datapath-dkms_2.5.90-1_all.deb
17
+    dpkg -i openvswitch-common_2.5.90-1_amd64.deb
18
+    dpkg -i openvswitch-switch_2.5.90-1_amd64.deb
19
+    if [ $dpdk = 'true' ]
20
+    then
21
+        dpkg -i openvswitch-switch-dpdk_2.5.90-1_amd64.deb
22
+    fi
23
+fi

+ 6
- 16
deployment_scripts/puppet/manifests/ovs-install-compute.pp View File

@@ -1,21 +1,11 @@
1 1
 $fuel_settings = parseyaml(file('/etc/astute.yaml'))
2
+$master_ip = $::fuel_settings['master_ip']
3
+$support_nsh = $::fuel_settings['fuel-plugin-ovs']['support_nsh']
4
+$support_dpdk = $::fuel_settings['fuel-plugin-ovs']['support_dpdk']
2 5
 if $operatingsystem == 'Ubuntu' {
3
-    if $fuel_settings['fuel-plugin-ovs']['support_nsh'] and
4
-       $fuel_settings['fuel-plugin-ovs']['support_dpdk'] {
5
-        exec { 'install ovs/nsh-dpdk':
6
-            command => '/usr/bin/curl http://10.20.0.2:8080/plugins/fuel-plugin-ovs-0.9/repositories/ubuntu/install.sh | /bin/bash -s nshdpdk'
7
-        }
6
+    exec { 'install ovs_nsh_dpdk':
7
+        command => "curl http://${master_ip}:8080/plugins/fuel-plugin-ovs-0.9/deployment_scripts/install.sh | bash -s ${master_ip} ${support_nsh} ${support_dpdk}",
8
+        path   => "/usr/bin:/usr/sbin:/bin:/sbin";
8 9
     }
9
-    elsif $fuel_settings['fuel-plugin-ovs']['support_dpdk'] {
10
-        exec { 'install ovs/dpdk':
11
-            command => '/usr/bin/curl http://10.20.0.2:8080/plugins/fuel-plugin-ovs-0.9/repositories/ubuntu/install.sh | /bin/bash -s dpdk'
12
-        }
13
-    }
14
-    elsif $fuel_settings['fuel-plugin-ovs']['support_nsh'] {
15
-        exec { 'install ovs/nsh':
16
-            command => '/usr/bin/curl http://10.20.0.2:8080/plugins/fuel-plugin-ovs-0.9/repositories/ubuntu/install.sh | /bin/bash -s nsh'
17
-        }
18
-    }
19
-
20 10
 } elsif $operatingsystem == 'CentOS' {
21 11
 }

+ 20
- 1
deployment_tasks.yaml View File

@@ -1 +1,20 @@
1
-[]
1
+- id: ovs_nsh_dpdk
2
+  type: group
3
+  role: ['compute']
4
+  requires: [deploy_start]
5
+  required_for: [deploy_end]
6
+  tasks: [hiera, setup_repositories, fuel_pkgs, globals, tools, logging, ovs_install_compute]
7
+  parameters:
8
+    strategy:
9
+      type: parallel
10
+
11
+- id: ovs_install_compute
12
+  type: puppet
13
+  version: 2.0.0
14
+  groups: [ovs_nsh_dpdk]
15
+  required_for: [pre_deployment_end]
16
+  requires: [pre_deployment_start]
17
+  parameters:
18
+    puppet_manifest: puppet/manifests/ovs-install-compute.pp
19
+    puppet_modules: puppet/modules:/etc/puppet/modules
20
+    timeout: 720

+ 3
- 7
ovs_build/Dockerfile View File

@@ -3,12 +3,8 @@
3 3
 FROM ubuntu:14.04.3
4 4
 
5 5
 RUN apt-get update -y
6
-
7 6
 RUN rm -rf /lib/modules
8
-RUN apt-get install -y linux-headers-3.13.0-76-generic
9
-RUN ln -s /lib/modules/3.13.0-76-generic /lib/modules/`uname -r`
10
-
11
-RUN apt-get build-dep openvswitch -y
12
-RUN apt-get -y install devscripts dpkg-dev git wget
7
+RUN apt-get install -y linux-headers-3.13.0-86-generic
8
+RUN ln -s /lib/modules/3.13.0-86-generic /lib/modules/`uname -r`
13 9
 
14
-ADD ./  /ovs_build
10
+ADD ./ /ovs_build

+ 35
- 15
ovs_build/build-ovs-dpdk.sh View File

@@ -1,16 +1,20 @@
1 1
 #!/bin/bash
2 2
 
3 3
 OVS_COMMIT=cd4764fdd8ce0aa0063525dad0e67f20b3bcf6e9
4
+URL_OVS=https://github.com/openvswitch/ovs.git
5
+OVS_VER=${OVS_VER:-2.5.1}
6
+BUILD_HOME=$HOME/dpdk
7
+BUILD_DEST=${BUILD_DEST:-/deb}
4 8
 
5
-BUILD_HOME=`pwd`
6
-sudo apt-get update -y
7 9
 sudo apt-get build-dep openvswitch -y
8 10
 sudo apt-get -y install devscripts dpkg-dev git wget
9 11
 
12
+rm -rf ${BUILD_HOME}; mkdir -p ${BUILD_HOME}
13
+
10 14
 cd ${BUILD_HOME}
11
-wget https://launchpad.net/ubuntu/+archive/primary/+files/dpdk_2.2.0-0ubuntu8.dsc
12
-wget https://launchpad.net/ubuntu/+archive/primary/+files/dpdk_2.2.0.orig.tar.gz
13
-wget https://launchpad.net/ubuntu/+archive/primary/+files/dpdk_2.2.0-0ubuntu8.debian.tar.xz
15
+wget -c https://launchpad.net/ubuntu/+archive/primary/+files/dpdk_2.2.0-0ubuntu8.dsc
16
+wget -c https://launchpad.net/ubuntu/+archive/primary/+files/dpdk_2.2.0.orig.tar.gz
17
+wget -c https://launchpad.net/ubuntu/+archive/primary/+files/dpdk_2.2.0-0ubuntu8.debian.tar.xz
14 18
 dpkg-source -x dpdk_2.2.0-0ubuntu8.dsc
15 19
 
16 20
 # copy from debian/control
@@ -29,15 +33,20 @@ sudo apt-get install -y debhelper \
29 33
                texlive-fonts-recommended  \
30 34
                texlive-latex-extra
31 35
 
32
-cd dpdk-2.2.0; rm -rf debian/patches/; debian/rules build; fakeroot debian/rules binary
36
+cd dpdk-2.2.0; rm -rf debian/patches/;
37
+cat << EOF > debian/changelog
38
+dpdk (2.2.0-1) unstable; urgency=low
39
+   [ DPDK team]
40
+   * New upstream version
41
+EOF
42
+debian/rules build; fakeroot debian/rules binary
33 43
 cd ${BUILD_HOME}; sudo dpkg -i *.deb
34 44
 
35 45
 cd ${BUILD_HOME}
36
-wget https://launchpad.net/ubuntu/+archive/primary/+files/openvswitch-dpdk_2.4.0.orig.tar.gz
37
-wget https://launchpad.net/ubuntu/+archive/primary/+files/openvswitch-dpdk_2.4.0-0ubuntu1.dsc
38
-wget https://launchpad.net/ubuntu/+archive/primary/+files/openvswitch-dpdk_2.4.0-0ubuntu1.debian.tar.xz
39
-dpkg-source -x  openvswitch-dpdk_2.4.0-0ubuntu1.dsc
40
-
46
+wget -c https://launchpad.net/ubuntu/+archive/primary/+files/openvswitch-dpdk_2.4.0.orig.tar.gz
47
+wget -c https://launchpad.net/ubuntu/+archive/primary/+files/openvswitch-dpdk_2.4.0-0ubuntu1.dsc
48
+wget -c https://launchpad.net/ubuntu/+archive/primary/+files/openvswitch-dpdk_2.4.0-0ubuntu1.debian.tar.xz
49
+dpkg-source -x openvswitch-dpdk_2.4.0-0ubuntu1.dsc
41 50
 
42 51
 # copy from debian/control
43 52
 sudo apt-get intall -y autoconf \
@@ -56,16 +65,27 @@ sudo apt-get intall -y autoconf \
56 65
                python-all \
57 66
                python-qt4 \
58 67
                python-twisted-conch \
59
-               python-zopeinterface
68
+               python-zopeinterface \
69
+               python-six
60 70
 
61 71
 git clone https://github.com/openvswitch/ovs.git
62 72
 cd ovs; git checkout ${OVS_COMMIT}
63 73
 cd ${BUILD_HOME}; tar czvf ovs.tar.gz ovs
64
-rm -rf openvswitch-dpdk-2.5.0*
65
-cd openvswitch-dpdk-2.4.0; uupdate -v 2.5.0 ../ovs.tar.gz
66
-cd ../openvswitch-dpdk-2.5.0
74
+rm -rf openvswitch-dpdk-${OVS_VER}*
75
+cd openvswitch-dpdk-2.4.0; uupdate -v ${OVS_VER} ../ovs.tar.gz
76
+cd ../openvswitch-dpdk-${OVS_VER}
67 77
 sed -i "s/include\/rte_config.h/include\/dpdk\/rte_config.h/" acinclude.m4
68 78
 sed -i 's/DPDK_INCLUDE=.*/DPDK_INCLUDE=$RTE_SDK\/include\/dpdk/'  acinclude.m4
69 79
 autoreconf --install
70 80
 rm -rf debian/patches/ .git;
81
+cat << EOF > debian/changelog
82
+openvswitch-dpdk (${OVS_VER}-1) unstable; urgency=low
83
+   [ Open vSwitch team ]
84
+   * Open vSwitch Upstream
85
+EOF
71 86
 debian/rules build; fakeroot debian/rules binary
87
+
88
+cd ${BUILD_HOME}/ovs
89
+debian/rules build; fakeroot debian/rules binary
90
+
91
+cp ${BUILD_HOME}/*.deb ${BUILD_DEST}

+ 86
- 32
ovs_build/build-ovs-nsh-dpdk.sh View File

@@ -1,43 +1,97 @@
1 1
 #!/bin/bash
2 2
 
3
-DPDK_VER=2.1.0
4
-BUILD_HOME=`pwd`/tmp
3
+OVS_COMMIT=7d433ae57ebb90cd68e8fa948a096f619ac4e2d8
4
+URL_OVS=https://github.com/openvswitch/ovs.git
5
+OVS_VER=${OVS_VER:-2.5.90}
6
+BUILD_HOME=$HOME/nsh
7
+BUILD_DEST=${BUILD_DEST:-/deb}
5 8
 
6
-export RTE_TARGET=x86_64-native-linuxapp-gcc
7
-export RTE_SDK=${BUILD_HOME}/dpdk-${DPDK_VER}
8
-export DPDK_BUILD=${RTE_SDK}/${RTE_TARGET}
9
+sudo apt-get build-dep openvswitch -y
10
+sudo apt-get -y install devscripts dpkg-dev git wget
9 11
 
10
-OVS_COMMIT=121daded51b9798fe3722824b27a05c16806cbd1
11
-PATCHES="060679 060680 060681 060682 060683 060684 060685"
12
-URL_OVS=https://github.com/openvswitch/ovs.git
13
-URL_DPDK=http://dpdk.org/browse/dpdk/snapshot/dpdk-${DPDK_VER}.tar.gz
12
+rm -rf ${BUILD_HOME}; mkdir -p ${BUILD_HOME}
14 13
 
15
-mkdir -p ${BUILD_HOME}
16 14
 cd ${BUILD_HOME}
17
-wget ${URL_DPDK}
18
-tar -xzvf dpdk-${DPDK_VER}.tar.gz
19
-cd dpdk-${DPDK_VER}
20
-sed -i -e 's/CONFIG_RTE_LIBRTE_VHOST=n/CONFIG_RTE_LIBRTE_VHOST=y/' \
21
-       -e 's/CONFIG_RTE_BUILD_COMBINE_LIBS=n/CONFIG_RTE_BUILD_COMBINE_LIBS=y/' \
22
-       -e 's/CONFIG_RTE_PKTMBUF_HEADROOM=128/CONFIG_RTE_PKTMBUF_HEADROOM=256/' \
23
-       config/common_linuxapp
24
-make install T=${RTE_TARGET}
15
+wget -c https://launchpad.net/ubuntu/+archive/primary/+files/dpdk_2.2.0-0ubuntu8.dsc
16
+wget -c https://launchpad.net/ubuntu/+archive/primary/+files/dpdk_2.2.0.orig.tar.gz
17
+wget -c https://launchpad.net/ubuntu/+archive/primary/+files/dpdk_2.2.0-0ubuntu8.debian.tar.xz
18
+dpkg-source -x dpdk_2.2.0-0ubuntu8.dsc
19
+
20
+# copy from debian/control
21
+sudo apt-get install -y debhelper \
22
+               dh-python \
23
+               dh-systemd \
24
+               doxygen  \
25
+               graphviz  \
26
+               inkscape  \
27
+               libcap-dev  \
28
+               libpcap-dev  \
29
+               libxen-dev  \
30
+               libxenstore3.0  \
31
+               python  \
32
+               python-sphinx  \
33
+               texlive-fonts-recommended  \
34
+               texlive-latex-extra
35
+
36
+cd dpdk-2.2.0; rm -rf debian/patches/;
37
+cat << EOF > debian/changelog
38
+dpdk (2.2.0-1) unstable; urgency=low
39
+   [ DPDK team]
40
+   * New upstream version
41
+EOF
42
+debian/rules build; fakeroot debian/rules binary
43
+cd ${BUILD_HOME}; sudo dpkg -i *.deb
25 44
 
26 45
 cd ${BUILD_HOME}
27
-git clone ${URL_OVS} openvswitch
28
-cd openvswitch
29
-git checkout ${OVS_COMMIT} -b development
46
+wget -c https://launchpad.net/ubuntu/+archive/primary/+files/openvswitch-dpdk_2.4.0.orig.tar.gz
47
+wget -c https://launchpad.net/ubuntu/+archive/primary/+files/openvswitch-dpdk_2.4.0-0ubuntu1.dsc
48
+wget -c https://launchpad.net/ubuntu/+archive/primary/+files/openvswitch-dpdk_2.4.0-0ubuntu1.debian.tar.xz
49
+dpkg-source -x openvswitch-dpdk_2.4.0-0ubuntu1.dsc
50
+
51
+# copy from debian/control
52
+sudo apt-get intall -y autoconf \
53
+               automake \
54
+               bzip2 \
55
+               debhelper \
56
+               dh-autoreconf \
57
+               dh-systemd \
58
+               graphviz \
59
+               libdpdk-dev \
60
+               libfuse-dev \
61
+               libssl-dev \
62
+               libtool \
63
+               openssl \
64
+               procps \
65
+               python-all \
66
+               python-qt4 \
67
+               python-twisted-conch \
68
+               python-zopeinterface \
69
+               python-six
70
+
71
+git clone https://github.com/openvswitch/ovs.git
72
+cd ovs; git checkout ${OVS_COMMIT}
73
+DIR="$(dirname `readlink -f $0`)"
74
+PATCHES=$(cd patches; echo *patch; cd ..)
30 75
 for patch in ${PATCHES}
31 76
 do
32
-    patch -p1 < /ovs_build/patches/${patch}.patch
77
+    patch -p1 < {DIR}/patches/${patch}
33 78
 done
34
-export DEB_BUILD_OPTIONS='parallel=8 nocheck'
35
-sed -i "s/2.4.90/2.4.90.nshdpdk/g" debian/changelog
36
-sed -i "s/DATAPATH_CONFIGURE_OPTS.*=.*//" debian/rules
37
-sed -i "2iDATAPATH_CONFIGURE_OPTS='--with-dpdk=$DPDK_BUILD'" debian/rules
38
-sed -i "s/DATAPATH_CONFIGURE_OPTS.*=.*//" debian/rules.modules
39
-sed -i "2iDATAPATH_CONFIGURE_OPTS='--with-dpdk=$DPDK_BUILD'" debian/rules.modules
40
-debian/rules build
41
-fakeroot debian/rules binary
42
-
43
-cp ${BUILD_HOME}/*.deb /deb
79
+cd ${BUILD_HOME}; tar czvf ovs.tar.gz ovs
80
+rm -rf openvswitch-dpdk-${OVS_VER}*
81
+cd openvswitch-dpdk-2.4.0; uupdate -v ${OVS_VER} ../ovs.tar.gz
82
+cd ../openvswitch-dpdk-${OVS_VER}
83
+sed -i "s/include\/rte_config.h/include\/dpdk\/rte_config.h/" acinclude.m4
84
+sed -i 's/DPDK_INCLUDE=.*/DPDK_INCLUDE=$RTE_SDK\/include\/dpdk/'  acinclude.m4
85
+autoreconf --install
86
+rm -rf debian/patches/ .git;
87
+cat << EOF > debian/changelog
88
+openvswitch-dpdk (${OVS_VER}-1) unstable; urgency=low
89
+   [ Open vSwitch team ]
90
+   * Support NSH
91
+EOF
92
+debian/rules build; fakeroot debian/rules binary
93
+
94
+cd ${BUILD_HOME}/ovs
95
+debian/rules build; fakeroot debian/rules binary
96
+
97
+cp ${BUILD_HOME}/*.deb ${BUILD_DEST}

+ 0
- 23
ovs_build/build-ovs-nsh.sh View File

@@ -1,23 +0,0 @@
1
-#!/bin/bash
2
-
3
-BUILD_HOME=`pwd`/tmp
4
-
5
-OVS_COMMIT=121daded51b9798fe3722824b27a05c16806cbd1
6
-PATCHES="060679 060680 060681 060682 060683 060684 060685"
7
-URL_OVS=https://github.com/openvswitch/ovs.git
8
-
9
-mkdir -p ${BUILD_HOME}
10
-cd ${BUILD_HOME}
11
-git clone ${URL_OVS} openvswitch
12
-cd openvswitch
13
-git checkout ${OVS_COMMIT} -b development
14
-for patch in ${PATCHES}
15
-do
16
-    patch -p1 < /ovs_build/patches/${patch}.patch
17
-done
18
-
19
-export DEB_BUILD_OPTIONS='parallel=8 nocheck'
20
-sed -i "s/2.4.90/2.4.90.nsh/g" debian/changelog
21
-debian/rules build
22
-fakeroot debian/rules binary
23
-cp ${BUILD_HOME}/*.deb /deb

+ 732
- 0
ovs_build/patches/0001-ovs-vxlan-gpe-vxlan-extension-to-support-vxlan-gpe-t.patch View File

@@ -0,0 +1,732 @@
1
+From 5d79831435ec4e5bea20cc36c3f83eacf6fd065c Mon Sep 17 00:00:00 2001
2
+From: Yi Yang <yi.y.yang@intel.com>
3
+Date: Mon, 11 Apr 2016 15:58:14 +0800
4
+Subject: [PATCH 1/5] ovs-vxlan-gpe: vxlan extension to support vxlan-gpe
5
+ tunnel port
6
+
7
+Signed-off-by: Mengke Liu <mengke.liu@intel.com>
8
+Signed-off-by: Ricky Li <ricky.li@intel.com>
9
+Signed-off-by: Johnson Li <johnson.li@intel.com>
10
+Signed-off-by: Yi Yang <yi.y.yang@intel.com>
11
+---
12
+ datapath/flow_netlink.c                           |  8 +-
13
+ datapath/linux/compat/include/linux/openvswitch.h |  1 +
14
+ datapath/linux/compat/include/net/vxlan.h         | 73 +++++++++++++++++++
15
+ datapath/linux/compat/vxlan.c                     | 30 ++++++++
16
+ datapath/vport-vxlan.c                            | 15 ++++
17
+ lib/flow.c                                        |  8 ++
18
+ lib/match.c                                       | 34 +++++++++
19
+ lib/match.h                                       |  4 +
20
+ lib/meta-flow.c                                   | 36 +++++++++
21
+ lib/meta-flow.h                                   | 28 +++++++
22
+ lib/netdev-vport.c                                |  2 +
23
+ lib/nx-match.c                                    |  4 +
24
+ lib/odp-util.c                                    | 89 ++++++++++++++++++++++-
25
+ lib/packets.h                                     |  4 +-
26
+ tests/ofproto.at                                  |  4 +-
27
+ tests/ovs-ofctl.at                                |  4 +
28
+ 16 files changed, 340 insertions(+), 4 deletions(-)
29
+
30
+diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c
31
+index 6ffcc53..351a504 100644
32
+--- a/datapath/flow_netlink.c
33
++++ b/datapath/flow_netlink.c
34
+@@ -309,6 +309,7 @@ size_t ovs_key_attr_size(void)
35
+ 
36
+ static const struct ovs_len_tbl ovs_vxlan_ext_key_lens[OVS_VXLAN_EXT_MAX + 1] = {
37
+ 	[OVS_VXLAN_EXT_GBP]	    = { .len = sizeof(u32) },
38
++	[OVS_VXLAN_EXT_GPE]	    = { .len = sizeof(u32) },
39
+ };
40
+ 
41
+ static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] = {
42
+@@ -521,6 +522,9 @@ static int vxlan_tun_opt_from_nlattr(const struct nlattr *attr,
43
+ 		case OVS_VXLAN_EXT_GBP:
44
+ 			opts.gbp = nla_get_u32(a);
45
+ 			break;
46
++		case OVS_VXLAN_EXT_GPE:
47
++			opts.gpe = nla_get_u32(a);
48
++			break;
49
+ 		default:
50
+ 			OVS_NLERR(log, "Unknown VXLAN extension attribute %d",
51
+ 				  type);
52
+@@ -677,7 +681,9 @@ static int vxlan_opt_to_nlattr(struct sk_buff *skb,
53
+ 	if (!nla)
54
+ 		return -EMSGSIZE;
55
+ 
56
+-	if (nla_put_u32(skb, OVS_VXLAN_EXT_GBP, opts->gbp) < 0)
57
++	if (opts->gbp && nla_put_u32(skb, OVS_VXLAN_EXT_GBP, opts->gbp) < 0)
58
++		return -EMSGSIZE;
59
++	else if (opts->gpe && nla_put_u32(skb, OVS_VXLAN_EXT_GPE, opts->gpe) < 0)
60
+ 		return -EMSGSIZE;
61
+ 
62
+ 	nla_nest_end(skb, nla);
63
+diff --git a/datapath/linux/compat/include/linux/openvswitch.h b/datapath/linux/compat/include/linux/openvswitch.h
64
+index 3b39ebb..44adb81 100644
65
+--- a/datapath/linux/compat/include/linux/openvswitch.h
66
++++ b/datapath/linux/compat/include/linux/openvswitch.h
67
+@@ -287,6 +287,7 @@ enum ovs_vport_attr {
68
+ enum {
69
+ 	OVS_VXLAN_EXT_UNSPEC,
70
+ 	OVS_VXLAN_EXT_GBP,      /* Flag or __u32 */
71
++	OVS_VXLAN_EXT_GPE,
72
+ 	__OVS_VXLAN_EXT_MAX,
73
+ };
74
+ 
75
+diff --git a/datapath/linux/compat/include/net/vxlan.h b/datapath/linux/compat/include/net/vxlan.h
76
+index 75a5a7a..2bfc3f8 100644
77
+--- a/datapath/linux/compat/include/net/vxlan.h
78
++++ b/datapath/linux/compat/include/net/vxlan.h
79
+@@ -84,6 +84,75 @@ struct vxlanhdr_gbp {
80
+ #define VXLAN_GBP_POLICY_APPLIED	(BIT(3) << 16)
81
+ #define VXLAN_GBP_ID_MASK		(0xFFFF)
82
+ 
83
++/*
84
++ * VXLAN Generic Protocol Extension Extension:
85
++ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
86
++ * |R|R|Ver|I|P|R|O|R|R|R|R|R|R|R|R|R|R|R|R|R|R|R|R|  Next Proto   |
87
++ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
88
++ * |                VXLAN Network Identifier (VNI) |   Reserved    |
89
++ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
90
++ * Ver = Version. Indicates VXLAN GPE protocol version.  The initial
91
++ *      version is 0.  If a receiver does not support the version
92
++ *      indicated it MUST drop the packet.
93
++ *
94
++ * I = Instance Bit. The I bit MUST be set to indicate a valid VNI.
95
++ *
96
++ * P = Next Protocol Bit. The P bit is set to indicate that the
97
++ *     Next Protocol field is present.
98
++ *
99
++ * O = OAM Flag Bit. The O bit is set to indicate that the packet
100
++ *     is an OAM packet.
101
++ *
102
++ * [1] https://www.ietf.org/id/draft-ietf-nvo3-vxlan-gpe-01.txt
103
++ */
104
++
105
++struct vxlanhdr_gpe {
106
++#ifdef __LITTLE_ENDIAN_BITFIELD
107
++       uint8_t    oam_flag:1;
108
++       uint8_t    reserved_flags1:1;
109
++       uint8_t    np_applied:1;
110
++       uint8_t    instance_applied:1;
111
++       uint8_t    gpe_version:2;
112
++       uint8_t    reserved_flags2:2;
113
++#elif defined(__BIG_ENDIAN_BITFIELD)
114
++       uint8_t    reserved_flags2:2;
115
++       uint8_t    gpe_version:2;
116
++       uint8_t    instance_applied:1;
117
++       uint8_t    np_applied:1;
118
++       uint8_t    reserved_flags1:1;
119
++       uint8_t    oam_flag:1;
120
++#else
121
++#error "Please fix <asm/byteorder.h>"
122
++#endif
123
++    uint8_t    reserved_flags3;
124
++    uint8_t    reserved_flags4;
125
++    uint8_t    next_proto;
126
++    __be32        vx_vni;
127
++};
128
++
129
++/* VxLAN-GPE Header Next Protocol */
130
++#define VXLAN_GPE_NP_IPV4        0x01
131
++#define VXLAN_GPE_NP_IPV6        0x02
132
++#define VXLAN_GPE_NP_ETHERNET    0x03
133
++#define VXLAN_GPE_NP_NSH        0x04
134
++
135
++/* skb->mark mapping
136
++ *
137
++ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
138
++ * |R|R|Ver|I|P|R|O|R|R|R|R|R|R|R|R|R|R|R|R|R|R|R|R|  Next Proto   |
139
++ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
140
++ */
141
++
142
++#define VXLAN_GPE_OAM_FLAG                     (BIT(0) << 24)
143
++#define VXLAN_GPE_NP_APPLIED           (BIT(0) << 26)
144
++#define VXLAN_GPE_INSTANCE_APPLIED     (BIT(0) << 27)
145
++#define VXLAN_GPE_VERSION                      ((BIT(0) << 28) | (BIT(0) << 29))
146
++
147
++#define VXLAN_GPE_NP_MASK                      (0xFF)
148
++
149
++#define VXLAN_GPE_USED_BITS (VXLAN_GPE_OAM_FLAG | VXLAN_GPE_NP_APPLIED \
150
++                           | VXLAN_GPE_INSTANCE_APPLIED | VXLAN_GPE_VERSION | 0xFF)
151
++
152
+ /* VXLAN protocol header:
153
+  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
154
+  * |G|R|R|R|I|R|R|C|               Reserved                        |
155
+@@ -104,6 +173,7 @@ struct vxlanhdr {
156
+ #define VXLAN_HF_RCO BIT(21)
157
+ #define VXLAN_HF_VNI BIT(27)
158
+ #define VXLAN_HF_GBP BIT(31)
159
++#define VXLAN_HF_GPE BIT(26)
160
+ 
161
+ /* Remote checksum offload header option */
162
+ #define VXLAN_RCO_MASK  0x7f    /* Last byte of vni field */
163
+@@ -120,6 +190,7 @@ struct vxlanhdr {
164
+ struct vxlan_metadata {
165
+ 	__be32          vni;
166
+ 	u32             gbp;
167
++	u32             gpe;
168
+ };
169
+ 
170
+ #define VNI_HASH_BITS	10
171
+@@ -205,11 +276,13 @@ struct vxlan_dev {
172
+ #define VXLAN_F_GBP			0x800
173
+ #define VXLAN_F_REMCSUM_NOPARTIAL	0x1000
174
+ #define VXLAN_F_COLLECT_METADATA	0x2000
175
++#define VXLAN_F_GPE                     0x4000
176
+ 
177
+ /* Flags that are used in the receive path. These flags must match in
178
+  * order for a socket to be shareable
179
+  */
180
+ #define VXLAN_F_RCV_FLAGS		(VXLAN_F_GBP |			\
181
++                                         VXLAN_F_GPE |                  \
182
+ 					 VXLAN_F_UDP_ZERO_CSUM6_RX |	\
183
+ 					 VXLAN_F_REMCSUM_RX |		\
184
+ 					 VXLAN_F_REMCSUM_NOPARTIAL |	\
185
+diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c
186
+index 4faa18f..7ef051c 100644
187
+--- a/datapath/linux/compat/vxlan.c
188
++++ b/datapath/linux/compat/vxlan.c
189
+@@ -971,6 +971,18 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
190
+ 			md->gbp |= VXLAN_GBP_POLICY_APPLIED;
191
+ 
192
+ 		flags &= ~VXLAN_GBP_USED_BITS;
193
++	} else if ((flags & VXLAN_HF_GPE) && (vs->flags & VXLAN_F_GPE)) {
194
++		struct vxlanhdr_gpe *gpe;
195
++
196
++		gpe = (struct vxlanhdr_gpe *)vxh;
197
++		md->gpe = ntohs(gpe->next_proto);
198
++
199
++		buf.dst.u.tun_info.key.tun_flags |= TUNNEL_VXLAN_OPT;
200
++
201
++		if (gpe->oam_flag)
202
++			md->gpe |= VXLAN_GPE_OAM_FLAG;
203
++
204
++		flags &= ~VXLAN_GPE_USED_BITS;
205
+ 	}
206
+ 
207
+ 	if (flags || vni & ~VXLAN_VNI_MASK) {
208
+@@ -1023,6 +1035,22 @@ static void vxlan_build_gbp_hdr(struct vxlanhdr *vxh, u32 vxflags,
209
+ 	gbp->policy_id = htons(md->gbp & VXLAN_GBP_ID_MASK);
210
+ }
211
+ 
212
++static void vxlan_build_gpe_hdr(struct vxlanhdr *vxh, u32 vxflags,
213
++                                struct vxlan_metadata *md)
214
++{
215
++       struct vxlanhdr_gpe *gpe;
216
++
217
++       if (!md->gpe)
218
++               return;
219
++
220
++       gpe = (struct vxlanhdr_gpe*)vxh;
221
++       vxh->vx_flags |= htonl(VXLAN_HF_GPE);
222
++
223
++       if (md->gpe & VXLAN_GPE_OAM_FLAG)
224
++               gpe->oam_flag = 1;
225
++       gpe->next_proto = md->gpe & VXLAN_GPE_NP_MASK;
226
++}
227
++
228
+ #if IS_ENABLED(CONFIG_IPV6)
229
+ static int vxlan6_xmit_skb(struct dst_entry *dst, struct sock *sk,
230
+ 			   struct sk_buff *skb,
231
+@@ -1106,6 +1134,8 @@ static int vxlan6_xmit_skb(struct dst_entry *dst, struct sock *sk,
232
+ 
233
+ 	if (vxflags & VXLAN_F_GBP)
234
+ 		vxlan_build_gbp_hdr(vxh, vxflags, md);
235
++	else if (vxflags & VXLAN_F_GPE)
236
++		vxlan_build_gpe_hdr(vxh, vxflags, md);
237
+ 
238
+ 	ovs_skb_set_inner_protocol(skb, htons(ETH_P_TEB));
239
+ 
240
+diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c
241
+index c05f5d4..5d775cc 100644
242
+--- a/datapath/vport-vxlan.c
243
++++ b/datapath/vport-vxlan.c
244
+@@ -52,6 +52,18 @@ static int vxlan_get_options(const struct vport *vport, struct sk_buff *skb)
245
+ 			return -EMSGSIZE;
246
+ 
247
+ 		nla_nest_end(skb, exts);
248
++	} else if (vxlan->flags & VXLAN_F_GPE) {
249
++		struct nlattr *exts;
250
++
251
++		exts = nla_nest_start(skb, OVS_TUNNEL_ATTR_EXTENSION);
252
++		if (!exts)
253
++			return -EMSGSIZE;
254
++
255
++		if (vxlan->flags & VXLAN_F_GPE &&
256
++		    nla_put_flag(skb, OVS_VXLAN_EXT_GPE))
257
++			return -EMSGSIZE;
258
++
259
++		nla_nest_end(skb, exts);
260
+ 	}
261
+ 
262
+ 	return 0;
263
+@@ -59,6 +71,7 @@ static int vxlan_get_options(const struct vport *vport, struct sk_buff *skb)
264
+ 
265
+ static const struct nla_policy exts_policy[OVS_VXLAN_EXT_MAX + 1] = {
266
+ 	[OVS_VXLAN_EXT_GBP]	= { .type = NLA_FLAG, },
267
++	[OVS_VXLAN_EXT_GPE]	= { .type = NLA_FLAG, },
268
+ };
269
+ 
270
+ static int vxlan_configure_exts(struct vport *vport, struct nlattr *attr,
271
+@@ -76,6 +89,8 @@ static int vxlan_configure_exts(struct vport *vport, struct nlattr *attr,
272
+ 
273
+ 	if (exts[OVS_VXLAN_EXT_GBP])
274
+ 		conf->flags |= VXLAN_F_GBP;
275
++        else if (exts[OVS_VXLAN_EXT_GPE])
276
++                conf->flags |= VXLAN_F_GPE;
277
+ 
278
+ 	return 0;
279
+ }
280
+diff --git a/lib/flow.c b/lib/flow.c
281
+index b9ce331..d24bdc9 100644
282
+--- a/lib/flow.c
283
++++ b/lib/flow.c
284
+@@ -870,6 +870,12 @@ flow_get_metadata(const struct flow *flow, struct match *flow_metadata)
285
+     if (flow->tunnel.gbp_flags) {
286
+         match_set_tun_gbp_flags(flow_metadata, flow->tunnel.gbp_flags);
287
+     }
288
++    if (flow->tunnel.gpe_np != htons(0)) {
289
++        match_set_tun_gpe_np(flow_metadata, flow->tunnel.gpe_np);
290
++    }
291
++    if (flow->tunnel.gpe_flags) {
292
++        match_set_tun_gpe_flags(flow_metadata, flow->tunnel.gpe_flags);
293
++    }
294
+     tun_metadata_get_fmd(&flow->tunnel, flow_metadata);
295
+     if (flow->metadata != htonll(0)) {
296
+         match_set_metadata(flow_metadata, flow->metadata);
297
+@@ -1265,6 +1271,8 @@ void flow_wildcards_init_for_packet(struct flow_wildcards *wc,
298
+         WC_MASK_FIELD(wc, tunnel.tp_dst);
299
+         WC_MASK_FIELD(wc, tunnel.gbp_id);
300
+         WC_MASK_FIELD(wc, tunnel.gbp_flags);
301
++        WC_MASK_FIELD(wc, tunnel.gpe_np);
302
++        WC_MASK_FIELD(wc, tunnel.gpe_flags);
303
+ 
304
+         if (!(flow->tunnel.flags & FLOW_TNL_F_UDPIF)) {
305
+             if (flow->tunnel.metadata.present.map) {
306
+diff --git a/lib/match.c b/lib/match.c
307
+index fd571d9..52437c9 100644
308
+--- a/lib/match.c
309
++++ b/lib/match.c
310
+@@ -289,6 +289,32 @@ match_set_tun_gbp_flags(struct match *match, uint8_t flags)
311
+ }
312
+ 
313
+ void
314
++match_set_tun_gpe_np_masked(struct match *match, uint8_t np, uint8_t mask)
315
++{
316
++    match->wc.masks.tunnel.gpe_np = mask;
317
++    match->flow.tunnel.gpe_np = np & mask;
318
++}
319
++
320
++void
321
++match_set_tun_gpe_np(struct match *match, uint8_t np)
322
++{
323
++    match_set_tun_gpe_np_masked(match, np, UINT8_MAX);
324
++}
325
++
326
++void
327
++match_set_tun_gpe_flags_masked(struct match *match, uint8_t flags, uint8_t mask)
328
++{
329
++    match->wc.masks.tunnel.gpe_flags = mask;
330
++    match->flow.tunnel.gpe_flags = flags & mask;
331
++}
332
++
333
++void
334
++match_set_tun_gpe_flags(struct match *match, uint8_t flags)
335
++{
336
++    match_set_tun_gpe_flags_masked(match, flags, UINT8_MAX);
337
++}
338
++
339
++void
340
+ match_set_in_port(struct match *match, ofp_port_t ofp_port)
341
+ {
342
+     match->wc.masks.in_port.ofp_port = u16_to_ofp(UINT16_MAX);
343
+@@ -1013,6 +1039,14 @@ format_flow_tunnel(struct ds *s, const struct match *match)
344
+         ds_put_format(s, "tun_gbp_flags=%#"PRIx8",", tnl->gbp_flags);
345
+     }
346
+ 
347
++    if (wc->masks.tunnel.gpe_np) {
348
++        ds_put_format(s, "tun_gpe_np=%#"PRIx8",", tnl->gpe_np);
349
++    }
350
++
351
++    if (wc->masks.tunnel.gpe_flags) {
352
++        ds_put_format(s, "tun_gpe_flags=%#"PRIx8",", tnl->gpe_flags);
353
++    }
354
++
355
+     if (wc->masks.tunnel.ip_tos) {
356
+         ds_put_format(s, "tun_tos=%"PRIx8",", tnl->ip_tos);
357
+     }
358
+diff --git a/lib/match.h b/lib/match.h
359
+index 0a6ac29..48aa0b1 100644
360
+--- a/lib/match.h
361
++++ b/lib/match.h
362
+@@ -86,6 +86,10 @@ void match_set_tun_gbp_id_masked(struct match *match, ovs_be16 gbp_id, ovs_be16
363
+ void match_set_tun_gbp_id(struct match *match, ovs_be16 gbp_id);
364
+ void match_set_tun_gbp_flags_masked(struct match *match, uint8_t flags, uint8_t mask);
365
+ void match_set_tun_gbp_flags(struct match *match, uint8_t flags);
366
++void match_set_tun_gpe_np_masked(struct match *match, uint8_t gpe_np, uint8_t mask);
367
++void match_set_tun_gpe_np(struct match *match, uint8_t gpe_np);
368
++void match_set_tun_gpe_flags_masked(struct match *match, uint8_t flags, uint8_t mask);
369
++void match_set_tun_gpe_flags(struct match *match, uint8_t flags);
370
+ void match_set_in_port(struct match *, ofp_port_t ofp_port);
371
+ void match_set_pkt_mark(struct match *, uint32_t pkt_mark);
372
+ void match_set_pkt_mark_masked(struct match *, uint32_t pkt_mark, uint32_t mask);
373
+diff --git a/lib/meta-flow.c b/lib/meta-flow.c
374
+index 721152c..ab77fca 100644
375
+--- a/lib/meta-flow.c
376
++++ b/lib/meta-flow.c
377
+@@ -213,6 +213,10 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
378
+         return !wc->masks.tunnel.gbp_id;
379
+     case MFF_TUN_GBP_FLAGS:
380
+         return !wc->masks.tunnel.gbp_flags;
381
++    case MFF_TUN_GPE_NP:
382
++        return !wc->masks.tunnel.gpe_np;
383
++    case MFF_TUN_GPE_FLAGS:
384
++        return !wc->masks.tunnel.gpe_flags;
385
+     CASE_MFF_TUN_METADATA:
386
+         return !ULLONG_GET(wc->masks.tunnel.metadata.present.map,
387
+                            mf->id - MFF_TUN_METADATA0);
388
+@@ -515,6 +519,8 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
389
+     case MFF_TUN_TTL:
390
+     case MFF_TUN_GBP_ID:
391
+     case MFF_TUN_GBP_FLAGS:
392
++    case MFF_TUN_GPE_NP:
393
++    case MFF_TUN_GPE_FLAGS:
394
+     CASE_MFF_TUN_METADATA:
395
+     case MFF_METADATA:
396
+     case MFF_IN_PORT:
397
+@@ -648,6 +654,12 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
398
+     case MFF_TUN_GBP_FLAGS:
399
+         value->u8 = flow->tunnel.gbp_flags;
400
+         break;
401
++    case MFF_TUN_GPE_NP:
402
++        value->u8 = flow->tunnel.gpe_np;
403
++        break;
404
++    case MFF_TUN_GPE_FLAGS:
405
++        value->u8 = flow->tunnel.gpe_flags;
406
++        break;
407
+     case MFF_TUN_TTL:
408
+         value->u8 = flow->tunnel.ip_ttl;
409
+         break;
410
+@@ -899,6 +911,12 @@ mf_set_value(const struct mf_field *mf,
411
+     case MFF_TUN_GBP_FLAGS:
412
+          match_set_tun_gbp_flags(match, value->u8);
413
+          break;
414
++    case MFF_TUN_GPE_NP:
415
++         match_set_tun_gpe_np(match, value->u8);
416
++         break;
417
++    case MFF_TUN_GPE_FLAGS:
418
++         match_set_tun_gpe_flags(match, value->u8);
419
++         break;
420
+     case MFF_TUN_TOS:
421
+         match_set_tun_tos(match, value->u8);
422
+         break;
423
+@@ -1216,6 +1234,12 @@ mf_set_flow_value(const struct mf_field *mf,
424
+     case MFF_TUN_GBP_FLAGS:
425
+         flow->tunnel.gbp_flags = value->u8;
426
+         break;
427
++    case MFF_TUN_GPE_NP:
428
++        flow->tunnel.gpe_np= value->u8;
429
++        break;
430
++    case MFF_TUN_GPE_FLAGS:
431
++        flow->tunnel.gpe_flags= value->u8;
432
++        break;
433
+     case MFF_TUN_TOS:
434
+         flow->tunnel.ip_tos = value->u8;
435
+         break;
436
+@@ -1535,6 +1559,12 @@ mf_set_wild(const struct mf_field *mf, struct match *match, char **err_str)
437
+     case MFF_TUN_GBP_FLAGS:
438
+         match_set_tun_gbp_flags_masked(match, 0, 0);
439
+         break;
440
++    case MFF_TUN_GPE_NP:
441
++        match_set_tun_gpe_np_masked(match, 0, 0);
442
++        break;
443
++    case MFF_TUN_GPE_FLAGS:
444
++        match_set_tun_gpe_flags_masked(match, 0, 0);
445
++        break;
446
+     case MFF_TUN_TOS:
447
+         match_set_tun_tos_masked(match, 0, 0);
448
+         break;
449
+@@ -1838,6 +1868,12 @@ mf_set(const struct mf_field *mf,
450
+     case MFF_TUN_GBP_FLAGS:
451
+         match_set_tun_gbp_flags_masked(match, value->u8, mask->u8);
452
+         break;
453
++    case MFF_TUN_GPE_NP:
454
++        match_set_tun_gpe_np_masked(match, value->u8, mask->u8);
455
++        break;
456
++    case MFF_TUN_GPE_FLAGS:
457
++        match_set_tun_gpe_flags_masked(match, value->u8, mask->u8);
458
++        break;
459
+     case MFF_TUN_TTL:
460
+         match_set_tun_ttl_masked(match, value->u8, mask->u8);
461
+         break;
462
+diff --git a/lib/meta-flow.h b/lib/meta-flow.h
463
+index c73a1af..4bd9ff6 100644
464
+--- a/lib/meta-flow.h
465
++++ b/lib/meta-flow.h
466
+@@ -491,6 +491,34 @@ enum OVS_PACKED_ENUM mf_field_id {
467
+      */
468
+     MFF_TUN_GBP_FLAGS,
469
+ 
470
++     /* "tun_gpe_np".
471
++     *
472
++     * VXLAN Generic Protocol Extension next_proto
473
++     *
474
++     * Type: u8.
475
++     * Maskable: bitwise.
476
++     * Formatting: hexadecimal.
477
++     * Prerequisites: none.
478
++     * Access: read/write.
479
++     * NXM: NXM_NX_TUN_GPE_NP(111) since v2.4.
480
++     * OXM: none.
481
++     */
482
++    MFF_TUN_GPE_NP,
483
++
484
++     /* "tun_gpe_flags".
485
++     *
486
++     * VXLAN Generic Protocol Extension flag
487
++     *
488
++     * Type: u8.
489
++     * Maskable: bitwise.
490
++     * Formatting: hexadecimal.
491
++     * Prerequisites: none.
492
++     * Access: read/write.
493
++     * NXM: NXM_NX_TUN_GPE_FLAGS(112) since v2.4.
494
++     * OXM: none.
495
++     */
496
++    MFF_TUN_GPE_FLAGS,
497
++
498
+ #if TUN_METADATA_NUM_OPTS == 64
499
+     /* "tun_metadata<N>".
500
+      *
501
+diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
502
+index e398562..92ceec1 100644
503
+--- a/lib/netdev-vport.c
504
++++ b/lib/netdev-vport.c
505
+@@ -583,6 +583,8 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args)
506
+             while (ext) {
507
+                 if (!strcmp(type, "vxlan") && !strcmp(ext, "gbp")) {
508
+                     tnl_cfg.exts |= (1 << OVS_VXLAN_EXT_GBP);
509
++                } else if (!strcmp(type, "vxlan") && !strcmp(ext, "gpe")) {
510
++                    tnl_cfg.exts |= (1 << OVS_VXLAN_EXT_GPE);
511
+                 } else {
512
+                     VLOG_WARN("%s: unknown extension '%s'", name, ext);
513
+                 }
514
+diff --git a/lib/nx-match.c b/lib/nx-match.c
515
+index 9f0f452..0eecac7 100644
516
+--- a/lib/nx-match.c
517
++++ b/lib/nx-match.c
518
+@@ -1037,6 +1037,10 @@ nx_put_raw(struct ofpbuf *b, enum ofp_version oxm, const struct match *match,
519
+                 flow->tunnel.gbp_id, match->wc.masks.tunnel.gbp_id);
520
+     nxm_put_8m(b, MFF_TUN_GBP_FLAGS, oxm,
521
+                flow->tunnel.gbp_flags, match->wc.masks.tunnel.gbp_flags);
522
++    nxm_put_8m(b, MFF_TUN_GPE_NP, oxm,
523
++               flow->tunnel.gpe_np, match->wc.masks.tunnel.gpe_np);
524
++    nxm_put_8m(b, MFF_TUN_GPE_FLAGS, oxm,
525
++               flow->tunnel.gpe_flags, match->wc.masks.tunnel.gpe_flags);
526
+     tun_metadata_to_nx_match(b, oxm, match);
527
+ 
528
+     /* Registers. */
529
+diff --git a/lib/odp-util.c b/lib/odp-util.c
530
+index b4689cc..7983720 100644
531
+--- a/lib/odp-util.c
532
++++ b/lib/odp-util.c
533
+@@ -1727,6 +1727,7 @@ odp_actions_from_string(const char *s, const struct simap *port_names,
534
+ 
535
+ static const struct attr_len_tbl ovs_vxlan_ext_attr_lens[OVS_VXLAN_EXT_MAX + 1] = {
536
+     [OVS_VXLAN_EXT_GBP]                 = { .len = 4 },
537
++    [OVS_VXLAN_EXT_GPE]                 = { .len = 4 },
538
+ };
539
+ 
540
+ static const struct attr_len_tbl ovs_tun_key_attr_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] = {
541
+@@ -1888,7 +1889,10 @@ odp_tun_key_from_attr__(const struct nlattr *attr,
542
+             break;
543
+         case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS: {
544
+             static const struct nl_policy vxlan_opts_policy[] = {
545
+-                [OVS_VXLAN_EXT_GBP] = { .type = NL_A_U32 },
546
++                [OVS_VXLAN_EXT_GBP] = { .type = NL_A_U32 ,
547
++                                        .optional = true },
548
++                [OVS_VXLAN_EXT_GPE] = { .type = NL_A_U32 ,
549
++                                        .optional = true },
550
+             };
551
+             struct nlattr *ext[ARRAY_SIZE(vxlan_opts_policy)];
552
+ 
553
+@@ -1902,6 +1906,12 @@ odp_tun_key_from_attr__(const struct nlattr *attr,
554
+                 tun->gbp_id = htons(gbp & 0xFFFF);
555
+                 tun->gbp_flags = (gbp >> 16) & 0xFF;
556
+             }
557
++            if (ext[OVS_VXLAN_EXT_GPE]) {
558
++                uint32_t gpe = nl_attr_get_u32(ext[OVS_VXLAN_EXT_GPE]);
559
++
560
++                tun->gpe_np = gpe & 0xFF;
561
++                tun->gpe_flags = gpe >> 24;
562
++            }
563
+ 
564
+             break;
565
+         }
566
+@@ -1988,6 +1998,13 @@ tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl *tun_key,
567
+         nl_msg_put_u32(a, OVS_VXLAN_EXT_GBP,
568
+                        (tun_key->gbp_flags << 16) | ntohs(tun_key->gbp_id));
569
+         nl_msg_end_nested(a, vxlan_opts_ofs);
570
++    } else if (tun_key->gpe_flags || tun_key->gpe_np) {
571
++        size_t vxlan_opts_ofs;
572
++
573
++        vxlan_opts_ofs = nl_msg_start_nested(a, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS);
574
++        nl_msg_put_u32(a, OVS_VXLAN_EXT_GPE,
575
++                (tun_key->gpe_flags << 24) | (tun_key->gpe_np));
576
++        nl_msg_end_nested(a, vxlan_opts_ofs);
577
+     }
578
+     tun_metadata_to_geneve_nlattr(tun_key, tun_flow_key, key_buf, a);
579
+ 
580
+@@ -2383,6 +2400,26 @@ format_odp_tun_vxlan_opt(const struct nlattr *attr,
581
+             ds_put_cstr(ds, "),");
582
+             break;
583
+         }
584
++        case OVS_VXLAN_EXT_GPE: {
585
++            uint32_t key = nl_attr_get_u32(a);
586
++            uint8_t np, np_mask;
587
++            uint8_t flags, flags_mask;
588
++
589
++            np = key & 0xFF;
590
++            flags = (key >> 24) & 0xFF;
591
++            if (ma) {
592
++                uint32_t mask = nl_attr_get_u32(ma);
593
++                np_mask = mask & 0xFF;
594
++                flags_mask = (mask >> 24) & 0xFF;
595
++            }
596
++
597
++            ds_put_cstr(ds, "gpe(");
598
++            format_u8x(ds, "np", np, ma ? &np_mask : NULL, verbose);
599
++            format_u8x(ds, "flags", flags, ma ? &flags_mask : NULL, verbose);
600
++            ds_chomp(ds, ',');
601
++            ds_put_cstr(ds, "),");
602
++            break;
603
++        }
604
+ 
605
+         default:
606
+             format_unknown_key(ds, a, ma);
607
+@@ -3670,6 +3707,40 @@ scan_vxlan_gbp(const char *s, uint32_t *key, uint32_t *mask)
608
+ }
609
+ 
610
+ static int
611
++scan_vxlan_gpe(const char *s, uint32_t *key, uint32_t *mask)
612
++{
613
++    const char *s_base = s;
614
++    uint8_t np = 0, np_mask = 0;
615
++    uint8_t flags = 0, flags_mask = 0;
616
++
617
++    if (!strncmp(s, "np=", 3)) {
618
++        s += 3;
619
++        s += scan_u8(s, &np, mask ? &np_mask : NULL);
620
++    }
621
++
622
++    if (s[0] == ',') {
623
++        s++;
624
++    }
625
++    if (!strncmp(s, "flags=", 6)) {
626
++        s += 6;
627
++        s += scan_u8(s, &flags, mask ? &flags_mask : NULL);
628
++    }
629
++
630
++    if (!strncmp(s, "))", 2)) {
631
++        s += 2;
632
++
633
++        *key = (flags << 24) | np;
634
++        if (mask) {
635
++            *mask = (flags_mask << 24) | np_mask;
636
++        }
637
++
638
++        return s - s_base;
639
++    }
640
++
641
++    return 0;
642
++}
643
++
644
++static int
645
+ scan_geneve(const char *s, struct geneve_scan *key, struct geneve_scan *mask)
646
+ {
647
+     const char *s_base = s;
648
+@@ -3796,6 +3867,21 @@ vxlan_gbp_to_attr(struct ofpbuf *a, const void *data_)
649
+ }
650
+ 
651
+ static void
652
++vxlan_gpe_to_attr(struct ofpbuf *a, const void *data_)
653
++{
654
++    const uint32_t *gpe = data_;
655
++
656
++    if (*gpe) {
657
++        size_t vxlan_opts_ofs;
658
++
659
++        vxlan_opts_ofs = nl_msg_start_nested(a, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS);
660
++        nl_msg_put_u32(a, OVS_VXLAN_EXT_GPE, *gpe);
661
++        nl_msg_end_nested(a, vxlan_opts_ofs);
662
++    }
663
++}
664
++
665
++
666
++static void
667
+ geneve_to_attr(struct ofpbuf *a, const void *data_)
668
+ {
669
+     const struct geneve_scan *geneve = data_;
670
+@@ -4031,6 +4117,7 @@ parse_odp_key_mask_attr(const char *s, const struct simap *port_names,
671
+         SCAN_FIELD_NESTED("tp_src=", ovs_be16, be16, OVS_TUNNEL_KEY_ATTR_TP_SRC);
672
+         SCAN_FIELD_NESTED("tp_dst=", ovs_be16, be16, OVS_TUNNEL_KEY_ATTR_TP_DST);
673
+         SCAN_FIELD_NESTED_FUNC("vxlan(gbp(", uint32_t, vxlan_gbp, vxlan_gbp_to_attr);
674
++        SCAN_FIELD_NESTED_FUNC("vxlan(gpe(", uint32_t, vxlan_gpe, vxlan_gpe_to_attr);
675
+         SCAN_FIELD_NESTED_FUNC("geneve(", struct geneve_scan, geneve,
676
+                                geneve_to_attr);
677
+         SCAN_FIELD_NESTED_FUNC("flags(", uint16_t, tun_flags, tun_flags_to_attr);
678
+diff --git a/lib/packets.h b/lib/packets.h
679
+index a8ea24b..dc97333 100644
680
+--- a/lib/packets.h
681
++++ b/lib/packets.h
682
+@@ -49,7 +49,9 @@ struct flow_tnl {
683
+     ovs_be16 tp_dst;
684
+     ovs_be16 gbp_id;
685
+     uint8_t  gbp_flags;
686
+-    uint8_t  pad1[5];        /* Pad to 64 bits. */
687
++    uint8_t  gpe_np;
688
++    uint8_t  gpe_flags;
689
++    uint8_t  pad1[3];        /* Pad to 64 bits. */
690
+     struct tun_metadata metadata;
691
+ };
692
+ 
693
+diff --git a/tests/ofproto.at b/tests/ofproto.at
694
+index fbb6d71..6c7217d 100644
695
+--- a/tests/ofproto.at
696
++++ b/tests/ofproto.at
697
+@@ -1775,7 +1775,7 @@ head_table () {
698
+       instructions: meter,apply_actions,clear_actions,write_actions,write_metadata,goto_table
699
+       Write-Actions and Apply-Actions features:
700
+         actions: output group set_field strip_vlan push_vlan mod_nw_ttl dec_ttl set_mpls_ttl dec_mpls_ttl push_mpls pop_mpls set_queue
701
+-        supported on Set-Field: tun_id tun_src tun_dst tun_ipv6_src tun_ipv6_dst tun_flags tun_gbp_id tun_gbp_flags tun_metadata0 dnl
702
++        supported on Set-Field: tun_id tun_src tun_dst tun_ipv6_src tun_ipv6_dst tun_flags tun_gbp_id tun_gbp_flags tun_gpe_np tun_gpe_flags tun_metadata0 dnl
703
+ tun_metadata1 tun_metadata2 tun_metadata3 tun_metadata4 tun_metadata5 tun_metadata6 tun_metadata7 tun_metadata8 tun_metadata9 tun_metadata10 tun_metadata11 tun_metadata12 tun_metadata13 tun_metadata14 tun_metadata15 tun_metadata16 tun_metadata17 tun_metadata18 tun_metadata19 tun_metadata20 tun_metadata21 tun_metadata22 tun_metadata23 tun_metadata24 tun_metadata25 tun_metadata26 tun_metadata27 tun_metadata28 tun_metadata29 tun_metadata30 tun_metadata31 tun_metadata32 tun_metadata33 tun_metadata34 tun_metadata35 tun_metadata36 tun_metadata37 tun_metadata38 tun_metadata39 tun_metadata40 tun_metadata41 tun_metadata42 tun_metadata43 tun_metadata44 tun_metadata45 tun_metadata46 tun_metadata47 tun_metadata48 tun_metadata49 tun_metadata50 tun_metadata51 tun_metadata52 tun_metadata53 tun_metadata54 tun_metadata55 tun_metadata56 tun_metadata57 tun_metadata58 tun_metadata59 tun_metadata60 tun_metadata61 tun_metadata62 tun_metadata63 dnl
704
+ metadata in_port in_port_oxm pkt_mark ct_mark ct_label reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 xreg0 xreg1 xreg2 xreg3 eth_src eth_dst vlan_tci vlan_vid vlan_pcp mpls_label mpls_tc mpls_ttl ip_src ip_dst ipv6_src ipv6_dst ipv6_label nw_tos ip_dscp nw_ecn nw_ttl arp_op arp_spa arp_tpa arp_sha arp_tha tcp_src tcp_dst udp_src udp_dst sctp_src sctp_dst icmp_type icmp_code icmpv6_type icmpv6_code nd_target nd_sll nd_tll
705
+     matching:
706
+@@ -1790,6 +1790,8 @@ metadata in_port in_port_oxm pkt_mark ct_mark ct_label reg0 reg1 reg2 reg3 reg4
707
+       tun_flags: arbitrary mask
708
+       tun_gbp_id: arbitrary mask
709
+       tun_gbp_flags: arbitrary mask
710
++      tun_gpe_np: arbitrary mask
711
++      tun_gpe_flags: arbitrary mask
712
+       tun_metadata0: arbitrary mask
713
+       tun_metadata1: arbitrary mask
714
+       tun_metadata2: arbitrary mask
715
+diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at
716
+index f26f622..dde603d 100644
717
+--- a/tests/ovs-ofctl.at
718
++++ b/tests/ovs-ofctl.at
719
+@@ -17,6 +17,10 @@ for test_case in \
720
+     'tun_gbp_id=0/0x1                            NXM,OXM' \
721
+     'tun_gbp_flags=0                             NXM,OXM' \
722
+     'tun_gbp_flags=0/0x1                         NXM,OXM' \
723
++    'tun_gpe_np=0                                NXM,OXM' \
724
++    'tun_gpe_np=0/0x1                            NXM,OXM' \
725
++    'tun_gpe_flags=0                             NXM,OXM' \
726
++    'tun_gpe_flags=0/0x1                         NXM,OXM' \
727
+     'tun_metadata0=0                             NXM,OXM' \
728
+     'tun_metadata0=0/0x1                         NXM,OXM' \
729
+     'tun_metadata0                               NXM,OXM' \
730
+-- 
731
+1.9.3
732
+

+ 2746
- 0
ovs_build/patches/0002-ovs-nsh-support-push-and-pop-actions-for-vxlan-gpe-a.patch
File diff suppressed because it is too large
View File


+ 2327
- 0
ovs_build/patches/0003-Add-userspace-dataplane-nsh-support-and-remove-push_.patch
File diff suppressed because it is too large
View File


+ 264
- 0
ovs_build/patches/0004-Fix-too-large-stack-frame-size.patch View File

@@ -0,0 +1,264 @@
1
+From e6f9b1f96a3ac4066c9d7d4c0a9da7e8abb1597f Mon Sep 17 00:00:00 2001
2
+From: Yi Yang <yi.y.yang@intel.com>
3
+Date: Wed, 13 Apr 2016 18:17:21 +0800
4
+Subject: [PATCH 4/5] Fix too large stack frame size
5
+
6
+Signed-off-by: Yi Yang <yi.y.yang@intel.com>
7
+---
8
+ datapath/datapath.c | 92 +++++++++++++++++++++++++++++++++++++++++++++--------
9
+ 1 file changed, 78 insertions(+), 14 deletions(-)
10
+
11
+diff --git a/datapath/datapath.c b/datapath/datapath.c
12
+index 5bec072..4baf242 100644
13
+--- a/datapath/datapath.c
14
++++ b/datapath/datapath.c
15
+@@ -928,7 +928,7 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
16
+ 	struct sw_flow_mask mask;
17
+ 	struct sk_buff *reply;
18
+ 	struct datapath *dp;
19
+-	struct sw_flow_key key;
20
++	struct sw_flow_key *key = NULL;
21
+ 	struct sw_flow_actions *acts;
22
+ 	struct sw_flow_match match;
23
+ 	u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
24
+@@ -946,6 +946,12 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
25
+ 		goto error;
26
+ 	}
27
+ 
28
++        error = -ENOMEM;
29
++        key = kzalloc(sizeof(struct sw_flow_key), GFP_KERNEL);
30
++        if (key == NULL) {
31
++               goto error;
32
++        }
33
++
34
+ 	/* Most of the time we need to allocate a new flow, do it before
35
+ 	 * locking.
36
+ 	 */
37
+@@ -956,17 +962,17 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
38
+ 	}
39
+ 
40
+ 	/* Extract key. */
41
+-	ovs_match_init(&match, &key, &mask);
42
++	ovs_match_init(&match, key, &mask);
43
+ 	error = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
44
+ 				  a[OVS_FLOW_ATTR_MASK], log);
45
+ 	if (error)
46
+ 		goto err_kfree_flow;
47
+ 
48
+-	ovs_flow_mask_key(&new_flow->key, &key, true, &mask);
49
++	ovs_flow_mask_key(&new_flow->key, key, true, &mask);
50
+ 
51
+ 	/* Extract flow identifier. */
52
+ 	error = ovs_nla_get_identifier(&new_flow->id, a[OVS_FLOW_ATTR_UFID],
53
+-				       &key, log);
54
++				       key, log);
55
+ 	if (error)
56
+ 		goto err_kfree_flow;
57
+ 
58
+@@ -996,7 +1002,7 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
59
+ 	if (ovs_identifier_is_ufid(&new_flow->id))
60
+ 		flow = ovs_flow_tbl_lookup_ufid(&dp->table, &new_flow->id);
61
+ 	if (!flow)
62
+-		flow = ovs_flow_tbl_lookup(&dp->table, &key);
63
++		flow = ovs_flow_tbl_lookup(&dp->table, key);
64
+ 	if (likely(!flow)) {
65
+ 		rcu_assign_pointer(new_flow->sf_acts, acts);
66
+ 
67
+@@ -1066,6 +1072,10 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
68
+ 
69
+ 	if (reply)
70
+ 		ovs_notify(&dp_flow_genl_family, &ovs_dp_flow_multicast_group, reply, info);
71
++        if (key != NULL) {
72
++                kfree(key);
73
++                key = NULL;
74
++        }
75
+ 	return 0;
76
+ 
77
+ err_unlock_ovs:
78
+@@ -1076,6 +1086,10 @@ err_kfree_acts:
79
+ err_kfree_flow:
80
+ 	ovs_flow_free(new_flow, false);
81
+ error:
82
++        if (key != NULL) {
83
++                kfree(key);
84
++                key = NULL;
85
++        }
86
+ 	return error;
87
+ }
88
+ 
89
+@@ -1106,7 +1120,7 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
90
+ 	struct net *net = sock_net(skb->sk);
91
+ 	struct nlattr **a = info->attrs;
92
+ 	struct ovs_header *ovs_header = info->userhdr;
93
+-	struct sw_flow_key key;
94
++	struct sw_flow_key *key = NULL;
95
+ 	struct sw_flow *flow;
96
+ 	struct sw_flow_mask mask;
97
+ 	struct sk_buff *reply = NULL;
98
+@@ -1119,6 +1133,12 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
99
+ 	bool log = !a[OVS_FLOW_ATTR_PROBE];
100
+ 	bool ufid_present;
101
+ 
102
++        error = -ENOMEM;
103
++        key = kzalloc(sizeof(struct sw_flow_key), GFP_KERNEL);
104
++        if (key == NULL) {
105
++               goto error;
106
++        }
107
++
108
+ 	/* Extract key. */
109
+ 	error = -EINVAL;
110
+ 	if (!a[OVS_FLOW_ATTR_KEY]) {
111
+@@ -1127,7 +1147,7 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
112
+ 	}
113
+ 
114
+ 	ufid_present = ovs_nla_get_ufid(&sfid, a[OVS_FLOW_ATTR_UFID], log);
115
+-	ovs_match_init(&match, &key, &mask);
116
++	ovs_match_init(&match, key, &mask);
117
+ 	error = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
118
+ 				  a[OVS_FLOW_ATTR_MASK], log);
119
+ 	if (error)
120
+@@ -1135,7 +1155,7 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
121
+ 
122
+ 	/* Validate actions. */
123
+ 	if (a[OVS_FLOW_ATTR_ACTIONS]) {
124
+-		acts = get_flow_actions(net, a[OVS_FLOW_ATTR_ACTIONS], &key,
125
++		acts = get_flow_actions(net, a[OVS_FLOW_ATTR_ACTIONS], key,
126
+ 					&mask, log);
127
+ 		if (IS_ERR(acts)) {
128
+ 			error = PTR_ERR(acts);
129
+@@ -1203,6 +1223,10 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
130
+ 	if (old_acts)
131
+ 		ovs_nla_free_flow_actions_rcu(old_acts);
132
+ 
133
++        if (key != NULL) {
134
++                kfree(key);
135
++                key = NULL;
136
++        }
137
+ 	return 0;
138
+ 
139
+ err_unlock_ovs:
140
+@@ -1211,6 +1235,10 @@ err_unlock_ovs:
141
+ err_kfree_acts:
142
+ 	ovs_nla_free_flow_actions(acts);
143
+ error:
144
++        if (key != NULL) {
145
++                kfree(key);
146
++                key = NULL;
147
++        }
148
+ 	return error;
149
+ }
150
+ 
151
+@@ -1219,7 +1247,7 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
152
+ 	struct nlattr **a = info->attrs;
153
+ 	struct ovs_header *ovs_header = info->userhdr;
154
+ 	struct net *net = sock_net(skb->sk);
155
+-	struct sw_flow_key key;
156
++	struct sw_flow_key *key = NULL;
157
+ 	struct sk_buff *reply;
158
+ 	struct sw_flow *flow;
159
+ 	struct datapath *dp;
160
+@@ -1230,9 +1258,15 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
161
+ 	bool log = !a[OVS_FLOW_ATTR_PROBE];
162
+ 	bool ufid_present;
163
+ 
164
++        err = -ENOMEM;
165
++        key = kzalloc(sizeof(struct sw_flow_key), GFP_KERNEL);
166
++        if (key == NULL) {
167
++               return err;
168
++        }
169
++
170
+ 	ufid_present = ovs_nla_get_ufid(&ufid, a[OVS_FLOW_ATTR_UFID], log);
171
+ 	if (a[OVS_FLOW_ATTR_KEY]) {
172
+-		ovs_match_init(&match, &key, NULL);
173
++		ovs_match_init(&match, key, NULL);
174
+ 		err = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY], NULL,
175
+ 					log);
176
+ 	} else if (!ufid_present) {
177
+@@ -1240,9 +1274,13 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
178
+ 			  "Flow get message rejected, Key attribute missing.");
179
+ 		err = -EINVAL;
180
+ 	}
181
+-	if (err)
182
++	if (err) {
183
++                if (key != NULL) {
184
++                        kfree(key);
185
++                        key = NULL;
186
++                }
187
+ 		return err;
188
+-
189
++        }
190
+ 	ovs_lock();
191
+ 	dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
192
+ 	if (!dp) {
193
+@@ -1267,9 +1305,17 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
194
+ 	}
195
+ 
196
+ 	ovs_unlock();
197
++        if (key != NULL) {
198
++                kfree(key);
199
++                key = NULL;
200
++        }
201
+ 	return genlmsg_reply(reply, info);
202
+ unlock:
203
+ 	ovs_unlock();
204
++        if (key != NULL) {
205
++                kfree(key);
206
++                key = NULL;
207
++        }
208
+ 	return err;
209
+ }
210
+ 
211
+@@ -1278,7 +1324,7 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
212
+ 	struct nlattr **a = info->attrs;
213
+ 	struct ovs_header *ovs_header = info->userhdr;
214
+ 	struct net *net = sock_net(skb->sk);
215
+-	struct sw_flow_key key;
216
++	struct sw_flow_key *key = NULL;
217
+ 	struct sk_buff *reply;
218
+ 	struct sw_flow *flow = NULL;
219
+ 	struct datapath *dp;
220
+@@ -1289,12 +1335,22 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
221
+ 	bool log = !a[OVS_FLOW_ATTR_PROBE];
222
+ 	bool ufid_present;
223
+ 
224
++        err = -ENOMEM;
225
++        key = kzalloc(sizeof(struct sw_flow_key), GFP_KERNEL);
226
++        if (key == NULL) {
227
++               return err;
228
++        }
229
++
230
+ 	ufid_present = ovs_nla_get_ufid(&ufid, a[OVS_FLOW_ATTR_UFID], log);
231
+ 	if (a[OVS_FLOW_ATTR_KEY]) {
232
+-		ovs_match_init(&match, &key, NULL);
233
++		ovs_match_init(&match, key, NULL);
234
+ 		err = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
235
+ 					NULL, log);
236
+ 		if (unlikely(err))
237
++                        if (key != NULL) {
238
++                                kfree(key);
239
++                                key = NULL;
240
++                        }
241
+ 			return err;
242
+ 	}
243
+ 
244
+@@ -1344,9 +1400,17 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
245
+ 	}
246
+ 
247
+ 	ovs_flow_free(flow, true);
248
++        if (key != NULL) {
249
++                kfree(key);
250
++                key = NULL;
251
++        }
252
+ 	return 0;
253
+ unlock:
254
+ 	ovs_unlock();
255
++        if (key != NULL) {
256
++                kfree(key);
257
++                key = NULL;
258
++        }
259
+ 	return err;
260
+ }
261
+ 
262
+-- 
263
+1.9.3
264
+

+ 815
- 0
ovs_build/patches/0005-Ethernet-header-must-be-kept-in-VxLAN-gpe-eth-NSH-fo.patch View File

@@ -0,0 +1,815 @@
1
+
2
+
3
+
4
+
5
+<!DOCTYPE html>
6
+<html lang="en" class="">
7
+  <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# object: http://ogp.me/ns/object# article: http://ogp.me/ns/article# profile: http://ogp.me/ns/profile#">
8
+    <meta charset='utf-8'>
9
+
10
+    <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/frameworks-536bcdee57776d99649d118d29a291c9d7b41d101696162d6456c87b07314253.css" media="all" rel="stylesheet" />
11
+    <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/github-62cdd177894e003285e5b8b6fa72b4a92fb79f11a1ec44c2f2ae0f6f4ad2e724.css" media="all" rel="stylesheet" />
12
+    
13
+    
14
+    <link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/site-c4b4365da282e51c06e107368db8502a2ecf82e64094d29d791b797372212de2.css" media="all" rel="stylesheet" />
15
+    
16
+
17
+    <link as="script" href="https://assets-cdn.github.com/assets/frameworks-b0aaa1e644508a5d5c3f7509d91f5f950c180e1d933a999f21747c5ec5411d92.js" rel="preload" />
18
+    
19
+    <link as="script" href="https://assets-cdn.github.com/assets/github-7c9ed6fd84382ad236d74c9ec5853f75fca061537cb1914241807b12c289216e.js" rel="preload" />
20
+
21
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
22
+    <meta http-equiv="Content-Language" content="en">
23
+    <meta name="viewport" content="width=device-width">
24
+    
25
+    
26
+    <title>ovs_nsh_patches/0005-Ethernet-header-must-be-kept-in-VxLAN-gpe-eth-NSH-fo.patch at master · yyang13/ovs_nsh_patches · GitHub</title>
27
+    <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">
28
+    <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
29
+    <link rel="apple-touch-icon" href="/apple-touch-icon.png">
30
+    <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
31
+    <link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
32
+    <link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
33
+    <link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
34
+    <link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png">
35
+    <link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
36
+    <link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png">
37
+    <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
38
+    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png">
39
+    <meta property="fb:app_id" content="1401488693436528">
40
+
41
+      <meta content="https://avatars0.githubusercontent.com/u/1381010?v=3&amp;s=400" name="twitter:image:src" /><meta content="@github" name="twitter:site" /><meta content="summary" name="twitter:card" /><meta content="yyang13/ovs_nsh_patches" name="twitter:title" /><meta content="Contribute to ovs_nsh_patches development by creating an account on GitHub." name="twitter:description" />
42
+      <meta content="https://avatars0.githubusercontent.com/u/1381010?v=3&amp;s=400" property="og:image" /><meta content="GitHub" property="og:site_name" /><meta content="object" property="og:type" /><meta content="yyang13/ovs_nsh_patches" property="og:title" /><meta content="https://github.com/yyang13/ovs_nsh_patches" property="og:url" /><meta content="Contribute to ovs_nsh_patches development by creating an account on GitHub." property="og:description" />
43
+      <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">
44
+    <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">
45
+    <link rel="assets" href="https://assets-cdn.github.com/">
46
+    
47
+    <meta name="pjax-timeout" content="1000">
48
+    
49
+
50
+    <meta name="msapplication-TileImage" content="/windows-tile.png">
51
+    <meta name="msapplication-TileColor" content="#ffffff">
52
+    <meta name="selected-link" value="repo_source" data-pjax-transient>
53
+
54
+    <meta name="google-site-verification" content="KT5gs8h0wvaagLKAVWq8bbeNwnZZK1r1XQysX3xurLU">
55
+<meta name="google-site-verification" content="ZzhVyEFwb7w3e0-uOTltm8Jsck2F5StVihD0exw2fsA">
56
+    <meta name="google-analytics" content="UA-3769691-2">
57
+
58
+<meta content="collector.githubapp.com" name="octolytics-host" /><meta content="github" name="octolytics-app-id" /><meta content="C0C69725:55E6:90FE12E:57427806" name="octolytics-dimension-request_id" />
59
+<meta content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-pjax-transient="true" name="analytics-location" />
60
+
61
+
62
+
63
+  <meta class="js-ga-set" name="dimension1" content="Logged Out">
64
+
65
+
66
+
67
+        <meta name="hostname" content="github.com">
68
+    <meta name="user-login" content="">
69
+
70
+        <meta name="expected-hostname" content="github.com">
71
+      <meta name="js-proxy-site-detection-payload" content="OWZlYzg2YjY2MGNkZWMzYWIyMjEyODRmYjUxZDc3NDQ2NmZiMDU4MjIzOTM0YTM0M2QxN2UxMDI5ZThiYmMwZnx7InJlbW90ZV9hZGRyZXNzIjoiMTkyLjE5OC4xNTEuMzciLCJyZXF1ZXN0X2lkIjoiQzBDNjk3MjU6NTVFNjo5MEZFMTJFOjU3NDI3ODA2IiwidGltZXN0YW1wIjoxNDYzOTczODk5fQ==">
72
+
73
+
74
+      <link rel="mask-icon" href="https://assets-cdn.github.com/pinned-octocat.svg" color="#4078c0">
75
+      <link rel="icon" type="image/x-icon" href="https://assets-cdn.github.com/favicon.ico">
76
+
77
+    <meta name="html-safe-nonce" content="d5a3f38662558f7acd81904f7ac14af9db6f4815">
78
+    <meta content="336822eb21d878aecfe61a4b1500927049b82186" name="form-nonce" />
79
+
80
+    <meta http-equiv="x-pjax-version" content="7af64f947f90d1be70195bdfb0943dda">
81
+    
82
+
83
+      
84
+  <meta name="description" content="Contribute to ovs_nsh_patches development by creating an account on GitHub.">
85
+  <meta name="go-import" content="github.com/yyang13/ovs_nsh_patches git https://github.com/yyang13/ovs_nsh_patches.git">
86
+
87
+  <meta content="1381010" name="octolytics-dimension-user_id" /><meta content="yyang13" name="octolytics-dimension-user_login" /><meta content="55125011" name="octolytics-dimension-repository_id" /><meta content="yyang13/ovs_nsh_patches" name="octolytics-dimension-repository_nwo" /><meta content="true" name="octolytics-dimension-repository_public" /><meta content="false" name="octolytics-dimension-repository_is_fork" /><meta content="55125011" name="octolytics-dimension-repository_network_root_id" /><meta content="yyang13/ovs_nsh_patches" name="octolytics-dimension-repository_network_root_nwo" />
88
+  <link href="https://github.com/yyang13/ovs_nsh_patches/commits/master.atom" rel="alternate" title="Recent Commits to ovs_nsh_patches:master" type="application/atom+xml">
89
+
90
+
91
+      <link rel="canonical" href="https://github.com/yyang13/ovs_nsh_patches/blob/master/0005-Ethernet-header-must-be-kept-in-VxLAN-gpe-eth-NSH-fo.patch" data-pjax-transient>
92
+  </head>
93
+
94
+
95
+  <body class="logged-out   env-production  vis-public page-blob">
96
+    <div id="js-pjax-loader-bar" class="pjax-loader-bar"></div>
97
+    <a href="#start-of-content" tabindex="1" class="accessibility-aid js-skip-to-content">Skip to content</a>
98
+
99
+    
100
+    
101
+    
102
+
103
+
104
+
105
+          <header class="site-header js-details-container" role="banner">
106
+  <div class="container-responsive">
107
+    <a class="header-logo-invertocat" href="https://github.com/" aria-label="Homepage" data-ga-click="(Logged out) Header, go to homepage, icon:logo-wordmark">
108
+      <svg aria-hidden="true" class="octicon octicon-mark-github" height="32" version="1.1" viewBox="0 0 16 16" width="32"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59 0.4 0.07 0.55-0.17 0.55-0.38 0-0.19-0.01-0.82-0.01-1.49-2.01 0.37-2.53-0.49-2.69-0.94-0.09-0.23-0.48-0.94-0.82-1.13-0.28-0.15-0.68-0.52-0.01-0.53 0.63-0.01 1.08 0.58 1.23 0.82 0.72 1.21 1.87 0.87 2.33 0.66 0.07-0.52 0.28-0.87 0.51-1.07-1.78-0.2-3.64-0.89-3.64-3.95 0-0.87 0.31-1.59 0.82-2.15-0.08-0.2-0.36-1.02 0.08-2.12 0 0 0.67-0.21 2.2 0.82 0.64-0.18 1.32-0.27 2-0.27 0.68 0 1.36 0.09 2 0.27 1.53-1.04 2.2-0.82 2.2-0.82 0.44 1.1 0.16 1.92 0.08 2.12 0.51 0.56 0.82 1.27 0.82 2.15 0 3.07-1.87 3.75-3.65 3.95 0.29 0.25 0.54 0.73 0.54 1.48 0 1.07-0.01 1.93-0.01 2.2 0 0.21 0.15 0.46 0.55 0.38C13.71 14.53 16 11.53 16 8 16 3.58 12.42 0 8 0z"></path></svg>
109
+    </a>
110
+
111
+    <button class="btn-link right site-header-toggle js-details-target" type="button" aria-label="Toggle navigation">
112
+      <svg aria-hidden="true" class="octicon octicon-three-bars" height="24" version="1.1" viewBox="0 0 12 16" width="18"><path d="M11.41 9H0.59c-0.59 0-0.59-0.41-0.59-1s0-1 0.59-1h10.81c0.59 0 0.59 0.41 0.59 1s0 1-0.59 1z m0-4H0.59c-0.59 0-0.59-0.41-0.59-1s0-1 0.59-1h10.81c0.59 0 0.59 0.41 0.59 1s0 1-0.59 1zM0.59 11h10.81c0.59 0 0.59 0.41 0.59 1s0 1-0.59 1H0.59c-0.59 0-0.59-0.41-0.59-1s0-1 0.59-1z"></path></svg>
113
+    </button>
114
+
115
+    <div class="site-header-menu">
116
+      <nav class="site-header-nav site-header-nav-main">
117
+        <a href="/personal" class="js-selected-navigation-item nav-item nav-item-personal" data-ga-click="Header, click, Nav menu - item:personal" data-selected-links="/personal /personal">
118
+          Personal
119
+</a>        <a href="/open-source" class="js-selected-navigation-item nav-item nav-item-opensource" data-ga-click="Header, click, Nav menu - item:opensource" data-selected-links="/open-source /open-source">
120
+          Open source
121
+</a>        <a href="/business" class="js-selected-navigation-item nav-item nav-item-business" data-ga-click="Header, click, Nav menu - item:business" data-selected-links="/business /business/features /business/customers /business">
122
+          Business
123
+</a>        <a href="/explore" class="js-selected-navigation-item nav-item nav-item-explore" data-ga-click="Header, click, Nav menu - item:explore" data-selected-links="/explore /trending /trending/developers /integrations /integrations/feature/code /integrations/feature/collaborate /integrations/feature/ship /explore">
124
+          Explore
125
+</a>      </nav>
126
+
127
+      <div class="site-header-actions">
128
+            <a class="btn btn-primary site-header-actions-btn" href="/join?source=header-repo" data-ga-click="(Logged out) Header, clicked Sign up, text:sign-up">Sign up</a>
129
+          <a class="btn site-header-actions-btn mr-2" href="/login?return_to=%2Fyyang13%2Fovs_nsh_patches%2Fblob%2Fmaster%2F0005-Ethernet-header-must-be-kept-in-VxLAN-gpe-eth-NSH-fo.patch" data-ga-click="(Logged out) Header, clicked Sign in, text:sign-in">Sign in</a>
130
+      </div>
131
+
132
+        <nav class="site-header-nav site-header-nav-secondary">
133
+          <a class="nav-item" href="/pricing">Pricing</a>
134
+          <a class="nav-item" href="/blog">Blog</a>
135
+          <a class="nav-item" href="https://help.github.com">Support</a>
136
+          <a class="nav-item header-search-link" href="https://github.com/search">Search GitHub</a>
137
+              <div class="header-search scoped-search site-scoped-search js-site-search" role="search">
138
+  <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="/yyang13/ovs_nsh_patches/search" class="js-site-search-form" data-scoped-search-url="/yyang13/ovs_nsh_patches/search" data-unscoped-search-url="/search" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
139
+    <label class="form-control header-search-wrapper js-chromeless-input-container">
140
+      <div class="header-search-scope">This repository</div>
141
+      <input type="text"
142
+        class="form-control header-search-input js-site-search-focus js-site-search-field is-clearable"
143
+        data-hotkey="s"
144
+        name="q"
145
+        placeholder="Search"
146
+        aria-label="Search this repository"
147
+        data-unscoped-placeholder="Search GitHub"
148
+        data-scoped-placeholder="Search"
149
+        tabindex="1"
150
+        autocapitalize="off">
151
+    </label>
152
+</form></div>
153
+
154
+        </nav>
155
+    </div>
156
+  </div>
157
+</header>
158
+
159
+
160
+
161
+    <div id="start-of-content" class="accessibility-aid"></div>
162
+
163
+      <div id="js-flash-container">
164
+</div>
165
+
166
+
167
+    <div role="main" class="main-content">
168
+        <div itemscope itemtype="http://schema.org/SoftwareSourceCode">
169
+    <div id="js-repo-pjax-container" data-pjax-container>
170
+      
171
+<div class="pagehead repohead instapaper_ignore readability-menu experiment-repo-nav">
172
+  <div class="container repohead-details-container">
173
+
174
+    
175
+
176
+<ul class="pagehead-actions">
177
+
178
+  <li>
179
+      <a href="/login?return_to=%2Fyyang13%2Fovs_nsh_patches"
180
+    class="btn btn-sm btn-with-count tooltipped tooltipped-n"
181
+    aria-label="You must be signed in to watch a repository" rel="nofollow">
182
+    <svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6c4.94 0 7.94-6 7.94-6S13 2 8.06 2z m-0.06 10c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4z m2-4c0 1.11-0.89 2-2 2s-2-0.89-2-2 0.89-2 2-2 2 0.89 2 2z"></path></svg>
183
+    Watch
184
+  </a>
185
+  <a class="social-count" href="/yyang13/ovs_nsh_patches/watchers">
186
+    3
187
+  </a>
188
+
189
+  </li>
190
+
191
+  <li>
192
+      <a href="/login?return_to=%2Fyyang13%2Fovs_nsh_patches"
193
+    class="btn btn-sm btn-with-count tooltipped tooltipped-n"
194
+    aria-label="You must be signed in to star a repository" rel="nofollow">
195
+    <svg aria-hidden="true" class="octicon octicon-star" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M14 6l-4.9-0.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14l4.33-2.33 4.33 2.33L10.4 9.26 14 6z"></path></svg>
196
+    Star
197
+  </a>
198
+
199
+    <a class="social-count js-social-count" href="/yyang13/ovs_nsh_patches/stargazers">
200
+      3
201
+    </a>
202
+
203
+  </li>
204
+
205
+  <li>
206
+      <a href="/login?return_to=%2Fyyang13%2Fovs_nsh_patches"
207
+        class="btn btn-sm btn-with-count tooltipped tooltipped-n"
208
+        aria-label="You must be signed in to fork a repository" rel="nofollow">
209
+        <svg aria-hidden="true" class="octicon octicon-repo-forked" height="16" version="1.1" viewBox="0 0 10 16" width="10"><path d="M8 1c-1.11 0-2 0.89-2 2 0 0.73 0.41 1.38 1 1.72v1.28L5 8 3 6v-1.28c0.59-0.34 1-0.98 1-1.72 0-1.11-0.89-2-2-2S0 1.89 0 3c0 0.73 0.41 1.38 1 1.72v1.78l3 3v1.78c-0.59 0.34-1 0.98-1 1.72 0 1.11 0.89 2 2 2s2-0.89 2-2c0-0.73-0.41-1.38-1-1.72V9.5l3-3V4.72c0.59-0.34 1-0.98 1-1.72 0-1.11-0.89-2-2-2zM2 4.2c-0.66 0-1.2-0.55-1.2-1.2s0.55-1.2 1.2-1.2 1.2 0.55 1.2 1.2-0.55 1.2-1.2 1.2z m3 10c-0.66 0-1.2-0.55-1.2-1.2s0.55-1.2 1.2-1.2 1.2 0.55 1.2 1.2-0.55 1.2-1.2 1.2z m3-10c-0.66 0-1.2-0.55-1.2-1.2s0.55-1.2 1.2-1.2 1.2 0.55 1.2 1.2-0.55 1.2-1.2 1.2z"></path></svg>
210
+        Fork
211
+      </a>
212
+
213
+    <a href="/yyang13/ovs_nsh_patches/network" class="social-count">
214
+      2
215
+    </a>
216
+  </li>
217
+</ul>
218
+
219
+    <h1 class="entry-title public ">
220
+  <svg aria-hidden="true" class="octicon octicon-repo" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M4 9h-1v-1h1v1z m0-3h-1v1h1v-1z m0-2h-1v1h1v-1z m0-2h-1v1h1v-1z m8-1v12c0 0.55-0.45 1-1 1H6v2l-1.5-1.5-1.5 1.5V14H1c-0.55 0-1-0.45-1-1V1C0 0.45 0.45 0 1 0h10c0.55 0 1 0.45 1 1z m-1 10H1v2h2v-1h3v1h5V11z m0-10H2v9h9V1z"></path></svg>
221
+  <span class="author" itemprop="author"><a href="/yyang13" class="url fn" rel="author">yyang13</a></span><!--
222
+--><span class="path-divider">/</span><!--
223
+--><strong itemprop="name"><a href="/yyang13/ovs_nsh_patches" data-pjax="#js-repo-pjax-container">ovs_nsh_patches</a></strong>
224
+
225
+</h1>
226
+
227
+  </div>
228
+  <div class="container">
229
+    
230
+<nav class="reponav js-repo-nav js-sidenav-container-pjax"
231
+     itemscope
232
+     itemtype="http://schema.org/BreadcrumbList"
233
+     role="navigation"
234
+     data-pjax="#js-repo-pjax-container">
235
+
236
+  <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
237
+    <a href="/yyang13/ovs_nsh_patches" aria-selected="true" class="js-selected-navigation-item selected reponav-item" data-hotkey="g c" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches /yyang13/ovs_nsh_patches" itemprop="url">
238
+      <svg aria-hidden="true" class="octicon octicon-code" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M9.5 3l-1.5 1.5 3.5 3.5L8 11.5l1.5 1.5 4.5-5L9.5 3zM4.5 3L0 8l4.5 5 1.5-1.5L2.5 8l3.5-3.5L4.5 3z"></path></svg>
239
+      <span itemprop="name">Code</span>
240
+      <meta itemprop="position" content="1">
241
+</a>  </span>
242
+
243
+    <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
244
+      <a href="/yyang13/ovs_nsh_patches/issues" class="js-selected-navigation-item reponav-item" data-hotkey="g i" data-selected-links="repo_issues repo_labels repo_milestones /yyang13/ovs_nsh_patches/issues" itemprop="url">
245
+        <svg aria-hidden="true" class="octicon octicon-issue-opened" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7S10.14 13.7 7 13.7 1.3 11.14 1.3 8s2.56-5.7 5.7-5.7m0-1.3C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7S10.86 1 7 1z m1 3H6v5h2V4z m0 6H6v2h2V10z"></path></svg>
246
+        <span itemprop="name">Issues</span>
247
+        <span class="counter">1</span>
248
+        <meta itemprop="position" content="2">
249
+</a>    </span>
250
+
251
+  <span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
252
+    <a href="/yyang13/ovs_nsh_patches/pulls" class="js-selected-navigation-item reponav-item" data-hotkey="g p" data-selected-links="repo_pulls /yyang13/ovs_nsh_patches/pulls" itemprop="url">
253
+      <svg aria-hidden="true" class="octicon octicon-git-pull-request" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M11 11.28c0-1.73 0-6.28 0-6.28-0.03-0.78-0.34-1.47-0.94-2.06s-1.28-0.91-2.06-0.94c0 0-1.02 0-1 0V0L4 3l3 3V4h1c0.27 0.02 0.48 0.11 0.69 0.31s0.3 0.42 0.31 0.69v6.28c-0.59 0.34-1 0.98-1 1.72 0 1.11 0.89 2 2 2s2-0.89 2-2c0-0.73-0.41-1.38-1-1.72z m-1 2.92c-0.66 0-1.2-0.55-1.2-1.2s0.55-1.2 1.2-1.2 1.2 0.55 1.2 1.2-0.55 1.2-1.2 1.2zM4 3c0-1.11-0.89-2-2-2S0 1.89 0 3c0 0.73 0.41 1.38 1 1.72 0 1.55 0 5.56 0 6.56-0.59 0.34-1 0.98-1 1.72 0 1.11 0.89 2 2 2s2-0.89 2-2c0-0.73-0.41-1.38-1-1.72V4.72c0.59-0.34 1-0.98 1-1.72z m-0.8 10c0 0.66-0.55 1.2-1.2 1.2s-1.2-0.55-1.2-1.2 0.55-1.2 1.2-1.2 1.2 0.55 1.2 1.2z m-1.2-8.8c-0.66 0-1.2-0.55-1.2-1.2s0.55-1.2 1.2-1.2 1.2 0.55 1.2 1.2-0.55 1.2-1.2 1.2z"></path></svg>
254
+      <span itemprop="name">Pull requests</span>
255
+      <span class="counter">0</span>
256
+      <meta itemprop="position" content="3">
257
+</a>  </span>
258
+
259
+
260
+
261
+  <a href="/yyang13/ovs_nsh_patches/pulse" class="js-selected-navigation-item reponav-item" data-selected-links="pulse /yyang13/ovs_nsh_patches/pulse">
262
+    <svg aria-hidden="true" class="octicon octicon-pulse" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M11.5 8L8.8 5.4 6.6 8.5 5.5 1.6 2.38 8H0V10h3.6L4.5 8.2l0.9 5.4L9 8.5l1.6 1.5H14V8H11.5z"></path></svg>
263
+    Pulse
264
+</a>
265
+  <a href="/yyang13/ovs_nsh_patches/graphs" class="js-selected-navigation-item reponav-item" data-selected-links="repo_graphs repo_contributors /yyang13/ovs_nsh_patches/graphs">
266
+    <svg aria-hidden="true" class="octicon octicon-graph" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M16 14v1H0V0h1v14h15z m-11-1H3V8h2v5z m4 0H7V3h2v10z m4 0H11V6h2v7z"></path></svg>
267
+    Graphs
268
+</a>
269
+
270
+</nav>
271
+
272
+  </div>
273
+</div>
274
+
275
+<div class="container new-discussion-timeline experiment-repo-nav">
276
+  <div class="repository-content">
277
+
278
+    
279
+
280
+<a href="/yyang13/ovs_nsh_patches/blob/98e1d3d6b1ed49d902edaede11820853b0ad5037/0005-Ethernet-header-must-be-kept-in-VxLAN-gpe-eth-NSH-fo.patch" class="hidden js-permalink-shortcut" data-hotkey="y">Permalink</a>
281
+
282
+<!-- blob contrib key: blob_contributors:v21:9e16b7492ae4319416c7dc2e26b52f73 -->
283
+
284
+<div class="file-navigation js-zeroclipboard-container">
285
+  
286
+<div class="select-menu branch-select-menu js-menu-container js-select-menu left">
287
+  <button class="btn btn-sm select-menu-button js-menu-target css-truncate" data-hotkey="w"
288
+    title="master"
289
+    type="button" aria-label="Switch branches or tags" tabindex="0" aria-haspopup="true">
290
+    <i>Branch:</i>
291
+    <span class="js-select-button css-truncate-target">master</span>
292
+  </button>
293
+
294
+  <div class="select-menu-modal-holder js-menu-content js-navigation-container" data-pjax aria-hidden="true">
295
+
296
+    <div class="select-menu-modal">
297
+      <div class="select-menu-header">
298
+        <svg aria-label="Close" class="octicon octicon-x js-menu-close" height="16" role="img" version="1.1" viewBox="0 0 12 16" width="12"><path d="M7.48 8l3.75 3.75-1.48 1.48-3.75-3.75-3.75 3.75-1.48-1.48 3.75-3.75L0.77 4.25l1.48-1.48 3.75 3.75 3.75-3.75 1.48 1.48-3.75 3.75z"></path></svg>
299
+        <span class="select-menu-title">Switch branches/tags</span>
300
+      </div>
301
+
302
+      <div class="select-menu-filters">
303
+        <div class="select-menu-text-filter">
304
+          <input type="text" aria-label="Filter branches/tags" id="context-commitish-filter-field" class="form-control js-filterable-field js-navigation-enable" placeholder="Filter branches/tags">
305
+        </div>
306
+        <div class="select-menu-tabs">
307
+          <ul>
308
+            <li class="select-menu-tab">
309
+              <a href="#" data-tab-filter="branches" data-filter-placeholder="Filter branches/tags" class="js-select-menu-tab" role="tab">Branches</a>
310
+            </li>
311
+            <li class="select-menu-tab">
312
+              <a href="#" data-tab-filter="tags" data-filter-placeholder="Find a tag…" class="js-select-menu-tab" role="tab">Tags</a>
313
+            </li>
314
+          </ul>
315
+        </div>
316
+      </div>
317
+
318
+      <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="branches" role="menu">
319
+
320
+        <div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
321
+
322
+
323
+            <a class="select-menu-item js-navigation-item js-navigation-open selected"
324
+               href="/yyang13/ovs_nsh_patches/blob/master/0005-Ethernet-header-must-be-kept-in-VxLAN-gpe-eth-NSH-fo.patch"
325
+               data-name="master"
326
+               data-skip-pjax="true"
327
+               rel="nofollow">
328
+              <svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M12 5L4 13 0 9l1.5-1.5 2.5 2.5 6.5-6.5 1.5 1.5z"></path></svg>
329
+              <span class="select-menu-item-text css-truncate-target js-select-menu-filter-text" title="master">
330
+                master
331
+              </span>
332
+            </a>
333
+        </div>
334
+
335
+          <div class="select-menu-no-results">Nothing to show</div>
336
+      </div>
337
+
338
+      <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="tags">
339
+        <div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
340
+
341
+
342
+        </div>
343
+
344
+        <div class="select-menu-no-results">Nothing to show</div>
345
+      </div>
346
+
347
+    </div>
348
+  </div>
349
+</div>
350
+
351
+  <div class="btn-group right">
352
+    <a href="/yyang13/ovs_nsh_patches/find/master"
353
+          class="js-pjax-capture-input btn btn-sm"
354
+          data-pjax
355
+          data-hotkey="t">
356
+      Find file
357
+    </a>
358
+    <button aria-label="Copy file path to clipboard" class="js-zeroclipboard btn btn-sm zeroclipboard-button tooltipped tooltipped-s" data-copied-hint="Copied!" type="button">Copy path</button>
359
+  </div>
360
+  <div class="breadcrumb js-zeroclipboard-target">
361
+    <span class="repo-root js-repo-root"><span class="js-path-segment"><a href="/yyang13/ovs_nsh_patches"><span>ovs_nsh_patches</span></a></span></span><span class="separator">/</span><strong class="final-path">0005-Ethernet-header-must-be-kept-in-VxLAN-gpe-eth-NSH-fo.patch</strong>
362
+  </div>
363
+</div>
364
+
365
+
366
+  <div class="commit-tease">
367
+      <span class="right">
368
+        <a class="commit-tease-sha" href="/yyang13/ovs_nsh_patches/commit/9f8ad552bbfb7f9678f1b6195b2d2c0f34a38352" data-pjax>
369
+          9f8ad55
370
+        </a>
371
+        <relative-time datetime="2016-04-15T07:18:08Z">Apr 15, 2016</relative-time>
372
+      </span>
373
+      <div>
374
+        <img alt="" class="avatar" height="20" src="https://1.gravatar.com/avatar/4dbafb666390db3bde85995883557645?d=https%3A%2F%2Fassets-cdn.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png&amp;r=x&amp;s=140" width="20" />
375
+        <span class="user-mention">Yi Yang</span>
376
+          <a href="/yyang13/ovs_nsh_patches/commit/9f8ad552bbfb7f9678f1b6195b2d2c0f34a38352" class="message" data-pjax="true" title="ovs nsh patches
377
+
378
+Signed-off-by: Yi Yang &lt;yi.y.yang@intel.com&gt;">ovs nsh patches</a>
379
+      </div>
380
+
381
+    <div class="commit-tease-contributors">
382
+      <button type="button" class="btn-link muted-link contributors-toggle" data-facebox="#blob_contributors_box">
383
+        <strong>0</strong>
384
+         contributors
385
+      </button>
386
+      
387
+    </div>
388
+
389
+    <div id="blob_contributors_box" style="display:none">
390
+      <h2 class="facebox-header" data-facebox-id="facebox-header">Users who have contributed to this file</h2>
391
+      <ul class="facebox-user-list" data-facebox-id="facebox-description">
392
+      </ul>
393
+    </div>
394
+  </div>
395
+
396
+<div class="file">
397
+  <div class="file-header">
398
+  <div class="file-actions">
399
+
400
+    <div class="btn-group">
401
+      <a href="/yyang13/ovs_nsh_patches/raw/master/0005-Ethernet-header-must-be-kept-in-VxLAN-gpe-eth-NSH-fo.patch" class="btn btn-sm " id="raw-url">Raw</a>
402
+        <a href="/yyang13/ovs_nsh_patches/blame/master/0005-Ethernet-header-must-be-kept-in-VxLAN-gpe-eth-NSH-fo.patch" class="btn btn-sm js-update-url-with-hash">Blame</a>
403
+      <a href="/yyang13/ovs_nsh_patches/commits/master/0005-Ethernet-header-must-be-kept-in-VxLAN-gpe-eth-NSH-fo.patch" class="btn btn-sm " rel="nofollow">History</a>
404
+    </div>
405
+
406
+
407
+        <button type="button" class="btn-octicon disabled tooltipped tooltipped-nw"
408
+          aria-label="You must be signed in to make or propose changes">
409
+          <svg aria-hidden="true" class="octicon octicon-pencil" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path d="M0 12v3h3l8-8-3-3L0 12z m3 2H1V12h1v1h1v1z m10.3-9.3l-1.3 1.3-3-3 1.3-1.3c0.39-0.39 1.02-0.39 1.41 0l1.59 1.59c0.39 0.39 0.39 1.02 0 1.41z"></path></svg>
410
+        </button>
411
+        <button type="button" class="btn-octicon btn-octicon-danger disabled tooltipped tooltipped-nw"
412
+          aria-label="You must be signed in to make or propose changes">
413
+          <svg aria-hidden="true" class="octicon octicon-trashcan" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M10 2H8c0-0.55-0.45-1-1-1H4c-0.55 0-1 0.45-1 1H1c-0.55 0-1 0.45-1 1v1c0 0.55 0.45 1 1 1v9c0 0.55 0.45 1 1 1h7c0.55 0 1-0.45 1-1V5c0.55 0 1-0.45 1-1v-1c0-0.55-0.45-1-1-1z m-1 12H2V5h1v8h1V5h1v8h1V5h1v8h1V5h1v9z m1-10H1v-1h9v1z"></path></svg>
414
+        </button>
415
+  </div>
416
+
417
+  <div class="file-info">
418
+      75 lines (61 sloc)
419
+      <span class="file-info-divider"></span>
420
+    2.85 KB
421
+  </div>
422
+</div>
423
+
424
+  
425
+
426
+  <div itemprop="text" class="blob-wrapper data type-diff">
427
+      <table class="highlight tab-size js-file-line-container" data-tab-size="8">
428
+      <tr>
429
+        <td id="L1" class="blob-num js-line-number" data-line-number="1"></td>
430
+        <td id="LC1" class="blob-code blob-code-inner js-file-line">From 604bcfaf5211513f665ca05a370bc7f0c0dab39f Mon Sep 17 00:00:00 2001</td>
431
+      </tr>
432
+      <tr>
433
+        <td id="L2" class="blob-num js-line-number" data-line-number="2"></td>
434
+        <td id="LC2" class="blob-code blob-code-inner js-file-line">From: Yi Yang &lt;yi.y.yang@intel.com&gt;</td>
435
+      </tr>
436
+      <tr>
437
+        <td id="L3" class="blob-num js-line-number" data-line-number="3"></td>
438
+        <td id="LC3" class="blob-code blob-code-inner js-file-line">Date: Fri, 15 Apr 2016 14:17:54 +0800</td>
439
+      </tr>
440
+      <tr>
441
+        <td id="L4" class="blob-num js-line-number" data-line-number="4"></td>
442
+        <td id="LC4" class="blob-code blob-code-inner js-file-line">Subject: [PATCH 5/5] Ethernet header must be kept in VxLAN-gpe + eth + NSH for</td>
443
+      </tr>
444
+      <tr>
445
+        <td id="L5" class="blob-num js-line-number" data-line-number="5"></td>
446
+        <td id="LC5" class="blob-code blob-code-inner js-file-line"> new ovs lwtunnel implementation</td>
447
+      </tr>
448
+      <tr>
449
+        <td id="L6" class="blob-num js-line-number" data-line-number="6"></td>
450
+        <td id="LC6" class="blob-code blob-code-inner js-file-line">
451
+</td>
452
+      </tr>
453
+      <tr>
454
+        <td id="L7" class="blob-num js-line-number" data-line-number="7"></td>
455
+        <td id="LC7" class="blob-code blob-code-inner js-file-line">Signed-off-by: Yi Yang &lt;yi.y.yang@intel.com&gt;</td>
456
+      </tr>
457
+      <tr>
458
+        <td id="L8" class="blob-num js-line-number" data-line-number="8"></td>
459
+        <td id="LC8" class="blob-code blob-code-inner js-file-line"><span class="pl-ms">---</span></td>
460
+      </tr>
461
+      <tr>
462
+        <td id="L9" class="blob-num js-line-number" data-line-number="9"></td>
463
+        <td id="LC9" class="blob-code blob-code-inner js-file-line"> datapath/linux/compat/vxlan.c | 16 ++++++++++------</td>
464
+      </tr>
465
+      <tr>
466
+        <td id="L10" class="blob-num js-line-number" data-line-number="10"></td>
467
+        <td id="LC10" class="blob-code blob-code-inner js-file-line"> 1 file changed, 10 insertions(+), 6 deletions(-)</td>
468
+      </tr>
469
+      <tr>
470
+        <td id="L11" class="blob-num js-line-number" data-line-number="11"></td>
471
+        <td id="LC11" class="blob-code blob-code-inner js-file-line">
472
+</td>
473
+      </tr>
474
+      <tr>
475
+        <td id="L12" class="blob-num js-line-number" data-line-number="12"></td>
476
+        <td id="LC12" class="blob-code blob-code-inner js-file-line"><span class="pl-c1">diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c</span></td>
477
+      </tr>
478
+      <tr>
479
+        <td id="L13" class="blob-num js-line-number" data-line-number="13"></td>
480
+        <td id="LC13" class="blob-code blob-code-inner js-file-line">index 888d431..3c05141 100644</td>
481
+      </tr>
482
+      <tr>
483
+        <td id="L14" class="blob-num js-line-number" data-line-number="14"></td>
484
+        <td id="LC14" class="blob-code blob-code-inner js-file-line"><span class="pl-md">--- a/datapath/linux/compat/vxlan.c</span></td>
485
+      </tr>
486
+      <tr>
487
+        <td id="L15" class="blob-num js-line-number" data-line-number="15"></td>
488
+        <td id="LC15" class="blob-code blob-code-inner js-file-line"><span class="pl-mi1">+++ b/datapath/linux/compat/vxlan.c</span></td>
489
+      </tr>
490
+      <tr>
491
+        <td id="L16" class="blob-num js-line-number" data-line-number="16"></td>
492
+        <td id="LC16" class="blob-code blob-code-inner js-file-line"><span class="pl-mdr">@@ -821,7 +821,7 @@</span> static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,</td>
493
+      </tr>
494
+      <tr>
495
+        <td id="L17" class="blob-num js-line-number" data-line-number="17"></td>
496
+        <td id="LC17" class="blob-code blob-code-inner js-file-line"> 	struct vxlan_dev *vxlan;</td>
497
+      </tr>
498
+      <tr>
499
+        <td id="L18" class="blob-num js-line-number" data-line-number="18"></td>
500
+        <td id="LC18" class="blob-code blob-code-inner js-file-line"> 	struct pcpu_sw_netstats *stats;</td>
501
+      </tr>
502
+      <tr>
503
+        <td id="L19" class="blob-num js-line-number" data-line-number="19"></td>
504
+        <td id="LC19" class="blob-code blob-code-inner js-file-line"> 	union vxlan_addr saddr;</td>
505
+      </tr>
506
+      <tr>
507
+        <td id="L20" class="blob-num js-line-number" data-line-number="20"></td>
508
+        <td id="LC20" class="blob-code blob-code-inner js-file-line"><span class="pl-md">-        struct eth_nsh_hdr *eth_nsh_header = NULL;</span></td>
509
+      </tr>
510
+      <tr>
511
+        <td id="L21" class="blob-num js-line-number" data-line-number="21"></td>
512
+        <td id="LC21" class="blob-code blob-code-inner js-file-line"><span class="pl-mi1">+        //struct eth_nsh_hdr *eth_nsh_header = NULL;</span></td>
513
+      </tr>
514
+      <tr>
515
+        <td id="L22" class="blob-num js-line-number" data-line-number="22"></td>
516
+        <td id="LC22" class="blob-code blob-code-inner js-file-line"> 	int err = 0;</td>
517
+      </tr>
518
+      <tr>
519
+        <td id="L23" class="blob-num js-line-number" data-line-number="23"></td>
520
+        <td id="LC23" class="blob-code blob-code-inner js-file-line"> </td>
521
+      </tr>
522
+      <tr>
523
+        <td id="L24" class="blob-num js-line-number" data-line-number="24"></td>
524
+        <td id="LC24" class="blob-code blob-code-inner js-file-line"> 	/* For flow based devices, map all packets to VNI 0 */</td>
525
+      </tr>
526
+      <tr>
527
+        <td id="L25" class="blob-num js-line-number" data-line-number="25"></td>
528
+        <td id="LC25" class="blob-code blob-code-inner js-file-line"><span class="pl-mdr">@@ -891,12 +891,13 @@</span> static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,</td>
529
+      </tr>
530
+      <tr>
531
+        <td id="L26" class="blob-num js-line-number" data-line-number="26"></td>
532
+        <td id="LC26" class="blob-code blob-code-inner js-file-line"> 	u64_stats_update_end(&amp;stats-&gt;syncp);</td>
533
+      </tr>
534
+      <tr>
535
+        <td id="L27" class="blob-num js-line-number" data-line-number="27"></td>
536
+        <td id="LC27" class="blob-code blob-code-inner js-file-line"> </td>
537
+      </tr>
538
+      <tr>
539
+        <td id="L28" class="blob-num js-line-number" data-line-number="28"></td>
540
+        <td id="LC28" class="blob-code blob-code-inner js-file-line">         /* Add a faked encap_eth_header for NSH */</td>
541
+      </tr>
542
+      <tr>
543
+        <td id="L29" class="blob-num js-line-number" data-line-number="29"></td>
544
+        <td id="LC29" class="blob-code blob-code-inner js-file-line"><span class="pl-md">-        if (md &amp;&amp; ((md-&gt;gpe &amp; VXLAN_GPE_NP_MASK) == VXLAN_GPE_NP_NSH)) {</span></td>
545
+      </tr>
546
+      <tr>
547
+        <td id="L30" class="blob-num js-line-number" data-line-number="30"></td>
548
+        <td id="LC30" class="blob-code blob-code-inner js-file-line"><span class="pl-mi1">+        /* ovs changes have ensured it is here, so needn&#39;t add it any more */</span></td>
549
+      </tr>
550
+      <tr>
551
+        <td id="L31" class="blob-num js-line-number" data-line-number="31"></td>
552
+        <td id="LC31" class="blob-code blob-code-inner js-file-line"><span class="pl-mi1">+        /*if (md &amp;&amp; ((md-&gt;gpe &amp; VXLAN_GPE_NP_MASK) == VXLAN_GPE_NP_NSH)) {</span></td>
553
+      </tr>
554
+      <tr>
555
+        <td id="L32" class="blob-num js-line-number" data-line-number="32"></td>
556
+        <td id="LC32" class="blob-code blob-code-inner js-file-line">             skb_push(skb, ENCAP_ETH_LEN);</td>
557
+      </tr>
558
+      <tr>
559
+        <td id="L33" class="blob-num js-line-number" data-line-number="33"></td>
560
+        <td id="LC33" class="blob-code blob-code-inner js-file-line">             eth_nsh_header = (struct eth_nsh_hdr *)skb-&gt;data;</td>
561
+      </tr>
562
+      <tr>
563
+        <td id="L34" class="blob-num js-line-number" data-line-number="34"></td>
564
+        <td id="LC34" class="blob-code blob-code-inner js-file-line">             memmove(eth_nsh_header-&gt;encap_eth_header.encap_eth_dst, skb_mac_header(skb), ENCAP_ETH_LEN);</td>
565
+      </tr>
566
+      <tr>
567
+        <td id="L35" class="blob-num js-line-number" data-line-number="35"></td>
568
+        <td id="LC35" class="blob-code blob-code-inner js-file-line">             eth_nsh_header-&gt;encap_eth_header.encap_eth_type = htons(ETH_P_NSH);</td>
569
+      </tr>
570
+      <tr>
571
+        <td id="L36" class="blob-num js-line-number" data-line-number="36"></td>
572
+        <td id="LC36" class="blob-code blob-code-inner js-file-line"><span class="pl-md">-        }</span></td>
573
+      </tr>
574
+      <tr>
575
+        <td id="L37" class="blob-num js-line-number" data-line-number="37"></td>
576
+        <td id="LC37" class="blob-code blob-code-inner js-file-line"><span class="pl-mi1">+        }*/</span></td>
577
+      </tr>
578
+      <tr>
579
+        <td id="L38" class="blob-num js-line-number" data-line-number="38"></td>
580
+        <td id="LC38" class="blob-code blob-code-inner js-file-line">  </td>
581
+      </tr>
582
+      <tr>
583
+        <td id="L39" class="blob-num js-line-number" data-line-number="39"></td>
584
+        <td id="LC39" class="blob-code blob-code-inner js-file-line"> 	netdev_port_receive(skb, skb_tunnel_info(skb));</td>
585
+      </tr>
586
+      <tr>
587
+        <td id="L40" class="blob-num js-line-number" data-line-number="40"></td>
588
+        <td id="LC40" class="blob-code blob-code-inner js-file-line"> 	return;</td>
589
+      </tr>
590
+      <tr>
591
+        <td id="L41" class="blob-num js-line-number" data-line-number="41"></td>
592
+        <td id="LC41" class="blob-code blob-code-inner js-file-line"><span class="pl-mdr">@@ -985,7 +986,7 @@</span> static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)</td>
593
+      </tr>
594
+      <tr>
595
+        <td id="L42" class="blob-num js-line-number" data-line-number="42"></td>
596
+        <td id="LC42" class="blob-code blob-code-inner js-file-line"> 		struct vxlanhdr_gpe *gpe;</td>
597
+      </tr>
598
+      <tr>
599
+        <td id="L43" class="blob-num js-line-number" data-line-number="43"></td>
600
+        <td id="LC43" class="blob-code blob-code-inner js-file-line"> </td>
601
+      </tr>
602
+      <tr>
603
+        <td id="L44" class="blob-num js-line-number" data-line-number="44"></td>
604
+        <td id="LC44" class="blob-code blob-code-inner js-file-line"> 		gpe = (struct vxlanhdr_gpe *)vxh;</td>
605
+      </tr>
606
+      <tr>
607
+        <td id="L45" class="blob-num js-line-number" data-line-number="45"></td>
608
+        <td id="LC45" class="blob-code blob-code-inner js-file-line"><span class="pl-md">-		md-&gt;gpe = ntohs(gpe-&gt;next_proto);</span></td>
609
+      </tr>
610
+      <tr>
611
+        <td id="L46" class="blob-num js-line-number" data-line-number="46"></td>
612
+        <td id="LC46" class="blob-code blob-code-inner js-file-line"><span class="pl-mi1">+		md-&gt;gpe = gpe-&gt;next_proto;</span></td>
613
+      </tr>
614
+      <tr>
615
+        <td id="L47" class="blob-num js-line-number" data-line-number="47"></td>
616
+        <td id="LC47" class="blob-code blob-code-inner js-file-line"> </td>
617
+      </tr>
618
+      <tr>
619
+        <td id="L48" class="blob-num js-line-number" data-line-number="48"></td>
620
+        <td id="LC48" class="blob-code blob-code-inner js-file-line"> 		buf.dst.u.tun_info.key.tun_flags |= TUNNEL_VXLAN_OPT;</td>
621
+      </tr>
622
+      <tr>
623
+        <td id="L49" class="blob-num js-line-number" data-line-number="49"></td>
624
+        <td id="LC49" class="blob-code blob-code-inner js-file-line"> </td>
625
+      </tr>
626
+      <tr>
627
+        <td id="L50" class="blob-num js-line-number" data-line-number="50"></td>
628
+        <td id="LC50" class="blob-code blob-code-inner js-file-line"><span class="pl-mdr">@@ -1189,9 +1190,10 @@</span> static int vxlan_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *sk</td>
629
+      </tr>
630
+      <tr>
631
+        <td id="L51" class="blob-num js-line-number" data-line-number="51"></td>
632
+        <td id="LC51" class="blob-code blob-code-inner js-file-line"> 	}</td>
633
+      </tr>
634
+      <tr>
635
+        <td id="L52" class="blob-num js-line-number" data-line-number="52"></td>
636
+        <td id="LC52" class="blob-code blob-code-inner js-file-line"> </td>
637
+      </tr>
638
+      <tr>
639
+        <td id="L53" class="blob-num js-line-number" data-line-number="53"></td>
640
+        <td id="LC53" class="blob-code blob-code-inner js-file-line">         /* Skip encap_eth_header on sending Eth+NSH to vxlan-gpe port */</td>
641
+      </tr>
642
+      <tr>
643
+        <td id="L54" class="blob-num js-line-number" data-line-number="54"></td>
644
+        <td id="LC54" class="blob-code blob-code-inner js-file-line"><span class="pl-md">-        if (md &amp;&amp; ((md-&gt;gpe &amp; VXLAN_GPE_NP_MASK) == VXLAN_GPE_NP_NSH)) {</span></td>
645
+      </tr>
646
+      <tr>
647
+        <td id="L55" class="blob-num js-line-number" data-line-number="55"></td>
648
+        <td id="LC55" class="blob-code blob-code-inner js-file-line"><span class="pl-mi1">+        /* ovs needs to keep eth header here */</span></td>
649
+      </tr>
650
+      <tr>
651
+        <td id="L56" class="blob-num js-line-number" data-line-number="56"></td>
652
+        <td id="LC56" class="blob-code blob-code-inner js-file-line"><span class="pl-mi1">+        /*if (md &amp;&amp; ((md-&gt;gpe &amp; VXLAN_GPE_NP_MASK) == VXLAN_GPE_NP_NSH)) {</span></td>
653
+      </tr>
654
+      <tr>
655
+        <td id="L57" class="blob-num js-line-number" data-line-number="57"></td>
656
+        <td id="LC57" class="blob-code blob-code-inner js-file-line">             skb_pull(skb, ENCAP_ETH_LEN);</td>
657
+      </tr>
658
+      <tr>
659
+        <td id="L58" class="blob-num js-line-number" data-line-number="58"></td>
660
+        <td id="LC58" class="blob-code blob-code-inner js-file-line"><span class="pl-md">-        }</span></td>
661
+      </tr>
662
+      <tr>
663
+        <td id="L59" class="blob-num js-line-number" data-line-number="59"></td>
664
+        <td id="LC59" class="blob-code blob-code-inner js-file-line"><span class="pl-mi1">+        }*/</span></td>
665
+      </tr>
666
+      <tr>
667
+        <td id="L60" class="blob-num js-line-number" data-line-number="60"></td>
668
+        <td id="LC60" class="blob-code blob-code-inner js-file-line"> </td>
669
+      </tr>
670
+      <tr>
671
+        <td id="L61" class="blob-num js-line-number" data-line-number="61"></td>
672
+        <td id="LC61" class="blob-code blob-code-inner js-file-line"> 	min_headroom = LL_RESERVED_SPACE(rt-&gt;dst.dev) + rt-&gt;dst.header_len</td>
673
+      </tr>
674
+      <tr>
675
+        <td id="L62" class="blob-num js-line-number" data-line-number="62"></td>
676
+        <td id="LC62" class="blob-code blob-code-inner js-file-line"> 			+ VXLAN_HLEN + sizeof(struct iphdr)</td>
677
+      </tr>
678
+      <tr>
679
+        <td id="L63" class="blob-num js-line-number" data-line-number="63"></td>
680
+        <td id="LC63" class="blob-code blob-code-inner js-file-line"><span class="pl-mdr">@@ -1236,6 +1238,8 @@</span> static int vxlan_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *sk</td>
681
+      </tr>
682
+      <tr>
683
+        <td id="L64" class="blob-num js-line-number" data-line-number="64"></td>
684
+        <td id="LC64" class="blob-code blob-code-inner js-file-line"> 	}</td>
685
+      </tr>
686
+      <tr>
687
+        <td id="L65" class="blob-num js-line-number" data-line-number="65"></td>
688
+        <td id="LC65" class="blob-code blob-code-inner js-file-line"> 	if (vxflags &amp; VXLAN_F_GBP)</td>
689
+      </tr>
690
+      <tr>
691
+        <td id="L66" class="blob-num js-line-number" data-line-number="66"></td>
692
+        <td id="LC66" class="blob-code blob-code-inner js-file-line"> 		vxlan_build_gbp_hdr(vxh, vxflags, md);</td>
693
+      </tr>
694
+      <tr>
695
+        <td id="L67" class="blob-num js-line-number" data-line-number="67"></td>
696
+        <td id="LC67" class="blob-code blob-code-inner js-file-line"><span class="pl-mi1">+        else if (vxflags &amp; VXLAN_F_GPE)</span></td>
697
+      </tr>
698
+      <tr>
699
+        <td id="L68" class="blob-num js-line-number" data-line-number="68"></td>
700
+        <td id="LC68" class="blob-code blob-code-inner js-file-line"><span class="pl-mi1">+                vxlan_build_gpe_hdr(vxh, vxflags, md);</span></td>
701
+      </tr>
702
+      <tr>
703
+        <td id="L69" class="blob-num js-line-number" data-line-number="69"></td>
704
+        <td id="LC69" class="blob-code blob-code-inner js-file-line"> </td>
705
+      </tr>
706
+      <tr>
707
+        <td id="L70" class="blob-num js-line-number" data-line-number="70"></td>
708
+        <td id="LC70" class="blob-code blob-code-inner js-file-line"> 	ovs_skb_set_inner_protocol(skb, htons(ETH_P_TEB));</td>
709
+      </tr>
710
+      <tr>
711
+        <td id="L71" class="blob-num js-line-number" data-line-number="71"></td>
712
+        <td id="LC71" class="blob-code blob-code-inner js-file-line"> </td>
713
+      </tr>
714
+      <tr>
715
+        <td id="L72" class="blob-num js-line-number" data-line-number="72"></td>
716
+        <td id="LC72" class="blob-code blob-code-inner js-file-line"><span class="pl-md">-- </span></td>
717
+      </tr>
718
+      <tr>
719
+        <td id="L73" class="blob-num js-line-number" data-line-number="73"></td>
720
+        <td id="LC73" class="blob-code blob-code-inner js-file-line">1.9.3</td>
721
+      </tr>
722
+      <tr>
723
+        <td id="L74" class="blob-num js-line-number" data-line-number="74"></td>
724
+        <td id="LC74" class="blob-code blob-code-inner js-file-line">
725
+</td>
726
+      </tr>
727
+</table>
728
+
729
+  </div>
730
+
731
+</div>
732
+
733
+<button type="button" data-facebox="#jump-to-line" data-facebox-class="linejump" data-hotkey="l" class="hidden">Jump to Line</button>
734
+<div id="jump-to-line" style="display:none">
735
+  <!-- </textarea> --><!-- '"` --><form accept-charset="UTF-8" action="" class="js-jump-to-line-form" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
736
+    <input class="form-control linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line&hellip;" aria-label="Jump to line" autofocus>
737
+    <button type="submit" class="btn">Go</button>
738
+</form></div>
739
+
740
+  </div>
741
+  <div class="modal-backdrop"></div>
742
+</div>
743
+
744
+
745
+    </div>
746
+  </div>
747
+
748
+    </div>
749
+
750
+        <div class="container site-footer-container">
751
+  <div class="site-footer" role="contentinfo">
752
+    <ul class="site-footer-links right">
753
+        <li><a href="https://status.github.com/" data-ga-click="Footer, go to status, text:status">Status</a></li>
754
+      <li><a href="https://developer.github.com" data-ga-click="Footer, go to api, text:api">API</a></li>
755
+      <li><a href="https://training.github.com" data-ga-click="Footer, go to training, text:training">Training</a></li>
756
+      <li><a href="https://shop.github.com" data-ga-click="Footer, go to shop, text:shop">Shop</a></li>
757
+        <li><a href="https://github.com/blog" data-ga-click="Footer, go to blog, text:blog">Blog</a></li>
758
+        <li><a href="https://github.com/about" data-ga-click="Footer, go to about, text:about">About</a></li>
759
+
760
+    </ul>
761
+
762
+    <a href="https://github.com" aria-label="Homepage" class="site-footer-mark" title="GitHub">
763
+      <svg aria-hidden="true" class="octicon octicon-mark-github" height="24" version="1.1" viewBox="0 0 16 16" width="24"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59 0.4 0.07 0.55-0.17 0.55-0.38 0-0.19-0.01-0.82-0.01-1.49-2.01 0.37-2.53-0.49-2.69-0.94-0.09-0.23-0.48-0.94-0.82-1.13-0.28-0.15-0.68-0.52-0.01-0.53 0.63-0.01 1.08 0.58 1.23 0.82 0.72 1.21 1.87 0.87 2.33 0.66 0.07-0.52 0.28-0.87 0.51-1.07-1.78-0.2-3.64-0.89-3.64-3.95 0-0.87 0.31-1.59 0.82-2.15-0.08-0.2-0.36-1.02 0.08-2.12 0 0 0.67-0.21 2.2 0.82 0.64-0.18 1.32-0.27 2-0.27 0.68 0 1.36 0.09 2 0.27 1.53-1.04 2.2-0.82 2.2-0.82 0.44 1.1 0.16 1.92 0.08 2.12 0.51 0.56 0.82 1.27 0.82 2.15 0 3.07-1.87 3.75-3.65 3.95 0.29 0.25 0.54 0.73 0.54 1.48 0 1.07-0.01 1.93-0.01 2.2 0 0.21 0.15 0.46 0.55 0.38C13.71 14.53 16 11.53 16 8 16 3.58 12.42 0 8 0z"></path></svg>
764
+</a>
765
+    <ul class="site-footer-links">
766
+      <li>&copy; 2016 <span title="0.04211s from github-fe139-cp1-prd.iad.github.net">GitHub</span>, Inc.</li>
767
+        <li><a href="https://github.com/site/terms" data-ga-click="Footer, go to terms, text:terms">Terms</a></li>
768
+        <li><a href="https://github.com/site/privacy" data-ga-click="Footer, go to privacy, text:privacy">Privacy</a></li>
769
+        <li><a href="https://github.com/security" data-ga-click="Footer, go to security, text:security">Security</a></li>
770
+        <li><a href="https://github.com/contact" data-ga-click="Footer, go to contact, text:contact">Contact</a></li>
771
+        <li><a href="https://help.github.com" data-ga-click="Footer, go to help, text:help">Help</a></li>
772
+    </ul>
773
+  </div>
774
+</div>
775
+
776
+
777
+
778
+    
779
+
780
+    <div id="ajax-error-message" class="ajax-error-message flash flash-error">
781
+      <svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M15.72 12.5l-6.85-11.98C8.69 0.21 8.36 0.02 8 0.02s-0.69 0.19-0.87 0.5l-6.85 11.98c-0.18 0.31-0.18 0.69 0 1C0.47 13.81 0.8 14 1.15 14h13.7c0.36 0 0.69-0.19 0.86-0.5S15.89 12.81 15.72 12.5zM9 12H7V10h2V12zM9 9H7V5h2V9z"></path></svg>
782
+      <button type="button" class="flash-close js-flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
783
+        <svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M7.48 8l3.75 3.75-1.48 1.48-3.75-3.75-3.75 3.75-1.48-1.48 3.75-3.75L0.77 4.25l1.48-1.48 3.75 3.75 3.75-3.75 1.48 1.48-3.75 3.75z"></path></svg>
784
+      </button>
785
+      Something went wrong with that request. Please try again.
786
+    </div>
787
+
788
+
789
+      <script crossorigin="anonymous" src="https://assets-cdn.github.com/assets/compat-7db58f8b7b91111107fac755dd8b178fe7db0f209ced51fc339c446ad3f8da2b.js"></script>
790
+      <script crossorigin="anonymous" src="https://assets-cdn.github.com/assets/frameworks-b0aaa1e644508a5d5c3f7509d91f5f950c180e1d933a999f21747c5ec5411d92.js"></script>
791
+      <script async="async" crossorigin="anonymous" src="https://assets-cdn.github.com/assets/github-7c9ed6fd84382ad236d74c9ec5853f75fca061537cb1914241807b12c289216e.js"></script>
792
+      
793
+      
794
+      
795
+      
796
+      
797
+      
798
+    <div class="js-stale-session-flash stale-session-flash flash flash-warn flash-banner hidden">
799
+      <svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M15.72 12.5l-6.85-11.98C8.69 0.21 8.36 0.02 8 0.02s-0.69 0.19-0.87 0.5l-6.85 11.98c-0.18 0.31-0.18 0.69 0 1C0.47 13.81 0.8 14 1.15 14h13.7c0.36 0 0.69-0.19 0.86-0.5S15.89 12.81 15.72 12.5zM9 12H7V10h2V12zM9 9H7V5h2V9z"></path></svg>
800
+      <span class="signed-in-tab-flash">You signed in with another tab or window. <a href="">Reload</a> to refresh your session.</span>
801
+      <span class="signed-out-tab-flash">You signed out in another tab or window. <a href="">Reload</a> to refresh your session.</span>
802
+    </div>
803
+    <div class="facebox" id="facebox" style="display:none;">
804
+  <div class="facebox-popup">
805
+    <div class="facebox-content" role="dialog" aria-labelledby="facebox-header" aria-describedby="facebox-description">
806
+    </div>
807
+    <button type="button" class="facebox-close js-facebox-close" aria-label="Close modal">
808
+      <svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path d="M7.48 8l3.75 3.75-1.48 1.48-3.75-3.75-3.75 3.75-1.48-1.48 3.75-3.75L0.77 4.25l1.48-1.48 3.75 3.75 3.75-3.75 1.48 1.48-3.75 3.75z"></path></svg>
809
+    </button>
810
+  </div>
811
+</div>
812
+
813
+  </body>
814
+</html>
815
+

+ 0
- 3187
ovs_build/patches/060679.patch
File diff suppressed because it is too large
View File


+ 0
- 788
ovs_build/patches/060680.patch View File

@@ -1,788 +0,0 @@
1
-at data plane level in user space and modify the related codes at control plane
2
-level in user space.
3
- 
4
-The design is based on basic VxLAN impletation. When packets are received at
5
-data plane level in user space, function 'dp_netdev_input' will be called for
6
-processing the packets at data plane level in user space.
7
- 
8
-When VXLAN-GPE NSH packets are received, decapsulation will be implemented. For
9
-the first time, the packets are sent to control plane by function 'upcall_cb',
10
-and tunnel port will be lookuped by matching the UDP port which is 4790 for
11
-VxLAN-GPE NSH port, if VxLAN-GPE NSH tunnel port are matched
12
-successfully, the tunnel pop action will be appended and implemented at data
13
-plane level, and the NSH related field will be parsed, then packets will be
14
-reprocessed by function 'dp_netdev_input'.
15
- 
16
-When original packets are sent to VxLAN-GPE NSH port, the encapsulation will
17
-be implemented. For the first time, in the control plane the tunnel
18
-tunnel_push_data are built according to VxLAN-GPE NSH port configuration and
19
-related rules, then the tunnel push actions are appended and implemented at
20
-data plane level. Finally packets will be reprocessed by function
21
-'dp_netdev_input'.
22
- 
23
-Signed-off-by: Ricky Li <<A HREF="http://openvswitch.org/mailman/listinfo/dev">ricky.li at intel.com</A>>
24
-Signed-off-by: Mengke Liu <<A HREF="http://openvswitch.org/mailman/listinfo/dev">mengke.liu at intel.com</A>>
25
----
26
- lib/netdev-vport.c           | 166 +++++++++++++++++++++++++++++++++++-----
27
- lib/odp-util.c               | 175 ++++++++++++++++++++++++++++++-------------
28
- lib/packets.h                | 115 +++++++++++++++++++++++++++-
29
- ofproto/ofproto-dpif-xlate.c |   1 -
30
- tests/tunnel.at              | 118 +++++++++++++++++++++++++++++
31
- 5 files changed, 500 insertions(+), 75 deletions(-)
32
- 
33
-diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
34
-index 3f85386..a0a4da2 100644
35
---- a/lib/netdev-vport.c
36
-+++ b/lib/netdev-vport.c
37
-@@ -67,6 +67,12 @@ static struct vlog_rate_limit err_rl = VLOG_RATE_LIMIT_INIT(60, 5);
38
-                             sizeof(struct udp_header) +         \
39
-                             sizeof(struct genevehdr))
40
- 
41
-+#define VXNSH_HLEN   (sizeof(struct eth_header) +         \
42
-+                      sizeof(struct ip_header)  +         \
43
-+                      sizeof(struct udp_header) +         \
44
-+                      sizeof(struct vxgpehdr)   +         \
45
-+                      sizeof(struct nshhdr))
46
-+
47
- #define DEFAULT_TTL 64
48
- 
49
- struct netdev_vport {
50
-@@ -1462,29 +1468,69 @@ netdev_vxlan_pop_header(struct dp_packet *packet)
51
- {
52
-     struct pkt_metadata *md = &packet->md;
53
-     struct flow_tnl *tnl = &md->tunnel;
54
--    struct vxlanhdr *vxh;
55
-+    struct udp_header *udp;
56
- 
57
-     pkt_metadata_init_tnl(md);
58
-     if (VXLAN_HLEN > dp_packet_size(packet)) {
59
-         return EINVAL;
60
-     }
61
- 
62
--    vxh = udp_extract_tnl_md(packet, tnl);
63
--    if (!vxh) {
64
--        return EINVAL;
65
-+    udp = ip_extract_tnl_md(packet, tnl);
66
-+    if (!udp) {
67
-+        return EINVAL;;
68
-     }
69
- 
70
--    if (get_16aligned_be32(&vxh->vx_flags) != htonl(VXLAN_FLAGS) ||
71
--       (get_16aligned_be32(&vxh->vx_vni) & htonl(0xff))) {
72
--        VLOG_WARN_RL(&err_rl, "invalid vxlan flags=%#x vni=%#x\n",
73
--                     ntohl(get_16aligned_be32(&vxh->vx_flags)),
74
--                     ntohl(get_16aligned_be32(&vxh->vx_vni)));
75
--        return EINVAL;
76
--    }
77
--    tnl->tun_id = htonll(ntohl(get_16aligned_be32(&vxh->vx_vni)) >> 8);
78
--    tnl->flags |= FLOW_TNL_F_KEY;
79
-+    if (ntohs(udp->udp_dst) == VXGPE_DST_PORT) {
80
-+
81
-+        struct vxgpehdr *vxg = (struct vxgpehdr *) (udp + 1);
82
-+
83
-+        if (get_16aligned_be32(&vxg->vx_vni) & htonl(0xff)) {
84
-+            VLOG_WARN_RL(&err_rl, "invalid vxlan-gpe vni=%#x\n",
85
-+                         ntohl(get_16aligned_be32(&vxg->vx_vni)));
86
-+            return EINVAL;;
87
-+        }
88
-+
89
-+        tnl->tp_src = udp->udp_src;
90
-+        tnl->tp_dst = udp->udp_dst;
91
-+        tnl->tun_id = htonll(ntohl(get_16aligned_be32(&vxg->vx_vni)) >> 8);
92
-+
93
-+        if (vxg->p == 0x01 && vxg->proto == VXG_P_NSH) {
94
-+            struct nshhdr *nsh = (struct nshhdr *) (vxg + 1);
95
-+
96
-+            tnl->nsp = nsh->b.b2 << 8;
97
-+            tnl->nsi = nsh->b.svc_idx;
98
-+            tnl->nshc1 = nsh->c.nshc1;
99
-+            tnl->nshc2 = nsh->c.nshc2;
100
-+            tnl->nshc3 = nsh->c.nshc3;
101
-+            tnl->nshc4 = nsh->c.nshc4;
102
-+            tnl->flags |= FLOW_TNL_F_NSP;
103
-+            tnl->flags |= FLOW_TNL_F_NSI;
104
-+            tnl->flags |= FLOW_TNL_F_NSH_C1 | FLOW_TNL_F_NSH_C2 | \
105
-+                        FLOW_TNL_F_NSH_C3 | FLOW_TNL_F_NSH_C4;
106
-+
107
-+            dp_packet_reset_packet(packet, VXNSH_HLEN);
108
-+        } else {
109
-+            VLOG_WARN("Unsupported vxlan GPE + NSH format!");
110
-+            return EINVAL;;
111
-+        }
112
-+
113
-+    } else {
114
-+
115
-+        struct vxlanhdr *vxh = (struct vxlanhdr *) (udp + 1);
116
- 
117
--    dp_packet_reset_packet(packet, VXLAN_HLEN);
118
-+        if (get_16aligned_be32(&vxh->vx_flags) != htonl(VXLAN_FLAGS) ||
119
-+               (get_16aligned_be32(&vxh->vx_vni) & htonl(0xff))) {
120
-+            VLOG_WARN_RL(&err_rl, "invalid vxlan flags=%#x vni=%#x\n",
121
-+                         ntohl(get_16aligned_be32(&vxh->vx_flags)),
122
-+                         ntohl(get_16aligned_be32(&vxh->vx_vni)));
123
-+            return EINVAL;;
124
-+        }
125
-+
126
-+        tnl->tp_src = udp->udp_src;
127
-+        tnl->tp_dst = udp->udp_dst;
128
-+        tnl->tun_id = htonll(ntohl(get_16aligned_be32(&vxh->vx_vni)) >> 8);
129
-+        dp_packet_reset_packet(packet, VXLAN_HLEN);
130
-+    }
131
- 
132
-     return 0;
133
- }
134
-@@ -1496,23 +1542,103 @@ netdev_vxlan_build_header(const struct netdev *netdev,
135
- {
136
-     struct netdev_vport *dev = netdev_vport_cast(netdev);
137
-     struct netdev_tunnel_config *tnl_cfg;
138
--    struct vxlanhdr *vxh;
139
-+    struct ip_header *ip;
140
-+    struct udp_header *udp;
141
-+    bool isnsh = false;
142
- 
143
-     /* XXX: RCUfy tnl_cfg. */
144
-     ovs_mutex_lock(&dev->mutex);
145
-     tnl_cfg = &dev->tnl_cfg;
146
- 
147
--    vxh = udp_build_header(tnl_cfg, tnl_flow, data);
148
-+    ip = ip_hdr(data->header);
149
-+    ip->ip_proto = IPPROTO_UDP;
150
-+
151
-+    udp = (struct udp_header *) (ip + 1);
152
-+    udp->udp_dst = tnl_cfg->dst_port;
153
-+
154
-+    if (tnl_flow->tunnel.flags & FLOW_TNL_F_CSUM) {
155
-+            /* Write a value in now to mark that we should compute the checksum
156
-+             * later. 0xffff is handy because it is transparent to the
157
-+             * calculation. */
158
-+            udp->udp_csum = htons(0xffff);
159
-+    }
160
-+
161
-+    if (ntohs(udp->udp_dst) == VXGPE_DST_PORT){
162
-+        struct vxgpehdr *vxg = (struct vxgpehdr *) (udp + 1);
163
- 
164
--    put_16aligned_be32(&vxh->vx_flags, htonl(VXLAN_FLAGS));
165
--    put_16aligned_be32(&vxh->vx_vni, htonl(ntohll(tnl_flow->tunnel.tun_id) << 8));
166
-+        memset(vxg, 0, sizeof *vxg);
167
-+        vxg->i = 0x01;
168
-+        vxg->p = 0x01;
169
-+        vxg->ver = 0x01;
170
-+        vxg->proto = VXG_P_NSH;
171
-+        put_16aligned_be32(&vxg->vx_vni, htonl(ntohll(tnl_flow->tunnel.tun_id) << 8));
172
-+
173
-+        if (vxg->p && vxg->proto == VXG_P_NSH){
174
-+            struct nshhdr *nsh = (struct nshhdr *) (vxg + 1);
175
-+
176
-+            memset(nsh, 0, sizeof *nsh);
177
-+            nsh->b.ver = 0x01;
178
-+            nsh->b.len = 6;
179
-+            nsh->b.mdtype = NSH_M_TYPE1;
180
-+            nsh->b.proto = NSH_P_ETHERNET;
181
-+
182
-+            nsh->b.b2 = tnl_flow->tunnel.nsp >> 8;
183
-+            nsh->b.svc_idx = tnl_flow->tunnel.nsi;
184
-+
185
-+            nsh->c.nshc1 = tnl_flow->tunnel.nshc1;
186
-+            nsh->c.nshc2 = tnl_flow->tunnel.nshc2;
187
-+            nsh->c.nshc3 = tnl_flow->tunnel.nshc3;
188
-+            nsh->c.nshc4 = tnl_flow->tunnel.nshc4;
189
-+
190
-+            isnsh = true;
191
-+        }
192
-+
193
-+    } else {
194
-+        struct vxlanhdr *vxh = (struct vxlanhdr *) (udp + 1);
195
-+        put_16aligned_be32(&vxh->vx_flags, htonl(VXLAN_FLAGS));
196
-+        put_16aligned_be32(&vxh->vx_vni, htonl(ntohll(tnl_flow->tunnel.tun_id) << 8));
197
-+    }
198
- 
199
-     ovs_mutex_unlock(&dev->mutex);
200
--    data->header_len = VXLAN_HLEN;
201
-+
202
-+    if(isnsh)
203
-+        data->header_len = VXNSH_HLEN;
204
-+    else
205
-+        data->header_len = VXLAN_HLEN;
206
-     data->tnl_type = OVS_VPORT_TYPE_VXLAN;
207
-+
208
-     return 0;
209
- }
210
- 
211
-+static void
212
-+netdev_vxlan_push_header(struct dp_packet *packet,
213
-+                         const struct ovs_action_push_tnl *data)
214
-+{
215
-+    int ip_tot_size;
216
-+    int size = data->header_len;
217
-+    const void *header = data->header;
218
-+    struct udp_header *udp;
219
-+
220
-+    udp = push_ip_header(packet, header, size, &ip_tot_size);
221
-+
222
-+    /* set udp src port */
223
-+    udp->udp_src = get_src_port(packet);
224
-+    udp->udp_len = htons(ip_tot_size - sizeof (struct ip_header));
225
-+    /* udp_csum is zero */
226
-+
227
-+    if (udp->udp_csum) {
228
-+        uint32_t csum = packet_csum_pseudoheader(ip_hdr(dp_packet_data(packet)));
229
-+
230
-+        csum = csum_continue(csum, udp,
231
-+                             ip_tot_size - sizeof (struct ip_header));
232
-+        udp->udp_csum = csum_finish(csum);
233
-+
234
-+        if (!udp->udp_csum) {
235
-+            udp->udp_csum = htons(0xffff);
236
-+        }
237
-+    }
238
-+}
239
-+
240
- static int
241
- netdev_geneve_pop_header(struct dp_packet *packet)
242
- {
243
-@@ -1736,7 +1862,7 @@ netdev_vport_tunnel_register(void)
244
-                                        netdev_gre_pop_header),
245
-         TUNNEL_CLASS("ipsec_gre", "gre_sys", NULL, NULL, NULL),
246
-         TUNNEL_CLASS("vxlan", "vxlan_sys", netdev_vxlan_build_header,
247
--                                           push_udp_header,
248
-+                                           netdev_vxlan_push_header,
249
-                                            netdev_vxlan_pop_header),
250
-         TUNNEL_CLASS("lisp", "lisp_sys", NULL, NULL, NULL),
251
-         TUNNEL_CLASS("stt", "stt_sys", NULL, NULL, NULL),
252
-diff --git a/lib/odp-util.c b/lib/odp-util.c
253
-index e8bc86d..1696f77 100644
254
---- a/lib/odp-util.c
255
-+++ b/lib/odp-util.c
256
-@@ -468,12 +468,42 @@ format_odp_tnl_push_header(struct ds *ds, struct ovs_action_push_tnl *data)
257
- 
258
-     if (data->tnl_type == OVS_VPORT_TYPE_VXLAN) {
259
-         const struct vxlanhdr *vxh;
260
--
261
--        vxh = format_udp_tnl_push_header(ds, ip);
262
--
263
--        ds_put_format(ds, "vxlan(flags=0x%"PRIx32",vni=0x%"PRIx32")",
264
--                      ntohl(get_16aligned_be32(&vxh->vx_flags)),
265
--                      ntohl(get_16aligned_be32(&vxh->vx_vni)) >> 8);
266
-+        const struct udp_header *udp;
267
-+        const struct vxgpehdr *vxg;
268
-+
269
-+        /* UDP */
270
-+        udp = (const struct udp_header *) (ip + 1);
271
-+        ds_put_format(ds, "udp(src=%"PRIu16",dst=%"PRIu16",csum=0x%"PRIx16"),",
272
-+              ntohs(udp->udp_src), ntohs(udp->udp_dst),
273
-+              ntohs(udp->udp_csum));
274
-+
275
-+        /* VxLan & VxLan GPE(UDP port: 4790) */
276
-+        if (ntohs(udp->udp_dst) == 4790) {
277
-+            vxg = (const struct vxgpehdr *)   (udp + 1);
278
-+
279
-+            ds_put_format(ds, "vxlangpe(vni=0x%"PRIx32",",
280
-+                          ntohl(get_16aligned_be32(&vxg->vx_vni)));
281
-+            ds_put_format(ds, "proto=%"PRIu8"),", vxg->proto);
282
-+            if (vxg->p == 0x01 && vxg->proto == VXG_P_NSH) {
283
-+                const struct nshhdr *nsh = (struct nshhdr *) (vxg + 1);
284
-+
285
-+                /* NSH */
286
-+                ds_put_format(ds, "nsh(mdtype=%"PRIu8",proto=%"PRIu8",",
287
-+                              nsh->b.mdtype, nsh->b.proto);
288
-+                ds_put_format(ds, "nsp=%"PRIx32",nsi=%"PRIu8",",
289
-+                              nsh->b.b2 & 0x00FFFFFF, nsh->b.svc_idx);
290
-+                ds_put_format(ds, "nshc1=%"PRIx32",nshc2=%"PRIx32",",
291
-+                              ntohl(nsh->c.nshc1), ntohl(nsh->c.nshc2));
292
-+                ds_put_format(ds, "nshc3=%"PRIx32",nshc4=%"PRIx32",",
293
-+                              ntohl(nsh->c.nshc3), ntohl(nsh->c.nshc4));
294
-+                ds_put_format(ds, ")");
295
-+            }
296
-+        } else {
297
-+            vxh = (const struct vxlanhdr *)   (udp + 1);
298
-+            ds_put_format(ds, "vxlan(flags=0x%"PRIx32",vni=0x%"PRIx32")",
299
-+                          ntohl(get_16aligned_be32(&vxh->vx_flags)),
300
-+                          ntohl(get_16aligned_be32(&vxh->vx_vni))>>8);
301
-+        }
302
-     } else if (data->tnl_type == OVS_VPORT_TYPE_GENEVE) {
303
-         const struct genevehdr *gnh;
304
- 
305
-@@ -490,8 +520,8 @@ format_odp_tnl_push_header(struct ds *ds, struct ovs_action_push_tnl *data)
306
-                                ds, false);
307
-             ds_put_char(ds, ')');
308
-         }
309
--
310
-         ds_put_char(ds, ')');
311
-+
312
-     } else if (data->tnl_type == OVS_VPORT_TYPE_GRE) {
313
-         const struct gre_base_hdr *greh;
314
-         ovs_16aligned_be32 *options;
315
-@@ -504,7 +534,7 @@ format_odp_tnl_push_header(struct ds *ds, struct ovs_action_push_tnl *data)
316
-                            ntohs(greh->flags), ntohs(greh->protocol));
317
-         options = (ovs_16aligned_be32 *)(greh + 1);
318
-         if (greh->flags & htons(GRE_CSUM)) {
319
--            ds_put_format(ds, ",csum=0x%"PRIx16, ntohs(*((ovs_be16 *)options)));
320
-+            ds_put_format(ds, ",csum=0x%"PRIx32, ntohl(get_16aligned_be32(options)));
321
-             options++;
322
-         }
323
-         if (greh->flags & htons(GRE_KEY)) {
324