datapath: Drop support for kernel older than 3.10
authorPravin B Shelar <pshelar@ovn.org>
Mon, 29 Feb 2016 17:54:15 +0000 (09:54 -0800)
committerPravin B Shelar <pshelar@ovn.org>
Mon, 14 Mar 2016 16:53:51 +0000 (09:53 -0700)
Currently OVS out of tree datapath supports a large number of kernel
versions. From 2.6.32 to 4.3 and various distribution-specific
kernels. But at this point major features are only available on more
recent kernels.  For example, stateful services are only available
starting in kernel 3.10 and STT is available on starting with 3.5.

Since these features are becoming essential to many OVS deployments,
and the effort of maintaining the backports is high. We have decided
to drop support for older kernel. Following patch drops supports
for kernel older than 3.10.

Signed-off-by: Pravin B Shelar <pshelar@ovn.org>
Acked-by: Jesse Gross <jesse@kernel.org>
33 files changed:
.travis.yml
CONTRIBUTING.md
FAQ.md
INSTALL.md
NEWS
README.md
acinclude.m4
datapath/actions.c
datapath/compat.h
datapath/conntrack.c
datapath/conntrack.h
datapath/datapath.c
datapath/datapath.h
datapath/flow.c
datapath/flow_table.c
datapath/linux/compat/dev-openvswitch.c
datapath/linux/compat/geneve.c
datapath/linux/compat/gso.c
datapath/linux/compat/include/linux/netdevice.h
datapath/linux/compat/include/net/net_namespace.h
datapath/linux/compat/include/net/vxlan.h
datapath/linux/compat/ip_gre.c
datapath/linux/compat/ip_tunnel.c
datapath/linux/compat/ip_tunnels_core.c
datapath/linux/compat/lisp.c
datapath/linux/compat/vxlan.c
datapath/vlan.h [deleted file]
datapath/vport-geneve.c
datapath/vport-internal_dev.c
datapath/vport-netdev.c
datapath/vport-netdev.h
datapath/vport.c
datapath/vport.h

index 52c9362..2b262e4 100644 (file)
@@ -30,9 +30,6 @@ env:
   - KERNEL=3.14.60
   - KERNEL=3.12.53
   - KERNEL=3.10.96
-  - KERNEL=3.4.110
-  - KERNEL=3.2.76
-  - KERNEL=2.6.32.70
 
 script: ./.travis/build.sh $OPTS
 
index 6f69cff..439c56a 100644 (file)
@@ -38,7 +38,7 @@ Testing is also important:
 
   - A patch that modifies Linux kernel code should be at least
     build-tested on various Linux kernel versions before
-    submission.  I suggest versions 2.6.32 and whatever
+    submission.  I suggest versions 3.10 and whatever
     the current latest release version is at the time.
 
   - A patch that modifies the ofproto or vswitchd code should be
diff --git a/FAQ.md b/FAQ.md
index 8bd7ab9..0ebf1d5 100644 (file)
--- a/FAQ.md
+++ b/FAQ.md
@@ -27,7 +27,7 @@ A: Open vSwitch is a production quality open source software switch
 ### Q: What virtualization platforms can use Open vSwitch?
 
 A: Open vSwitch can currently run on any Linux-based virtualization
-   platform (kernel 2.6.32 and newer), including: KVM, VirtualBox, Xen,
+   platform (kernel 3.10 and newer), including: KVM, VirtualBox, Xen,
    Xen Cloud Platform, XenServer. As of Linux 3.3 it is part of the
    mainline kernel.  The bulk of the code is written in platform-
    independent C and is easily ported to other environments.  We welcome
@@ -157,6 +157,7 @@ A: The following table lists the Linux kernel versions against which the
 |    2.3.x     | 2.6.32 to 3.14
 |    2.4.x     | 2.6.32 to 4.0
 |    2.5.x     | 2.6.32 to 4.3
+|    2.6.x     | 3.10 to 4.3
 
    Open vSwitch userspace should also work with the Linux kernel module
    built into Linux 3.3 and later.
index 9c96bbe..9dadcee 100644 (file)
@@ -63,23 +63,13 @@ install the following:
   - A supported Linux kernel version.  Please refer to [README.md] for a
     list of supported versions.
 
-    The Open vSwitch datapath requires bridging support
-    (CONFIG_BRIDGE) to be built as a kernel module.  (This is common
-    in kernels provided by Linux distributions.)  The bridge module
-    must not be loaded or in use.  If the bridge module is running
-    (check with "lsmod | grep bridge"), you must remove it ("rmmod
-    bridge") before starting the datapath.
-
     For optional support of ingress policing, you must enable kernel
     configuration options NET_CLS_BASIC, NET_SCH_INGRESS, and
     NET_ACT_POLICE, either built-in or as modules.  (NET_CLS_POLICE is
     obsolete and not needed.)
 
-    To use GRE tunneling on Linux 2.6.37 or newer, kernel support
-    for GRE demultiplexing (CONFIG_NET_IPGRE_DEMUX) must be compiled
-    in or available as a module.  Also, on kernels before 3.11, the
-    ip_gre module, for GRE tunnels over IP (NET_IPGRE), must not be
-    loaded or compiled in.
+    On kernels before 3.11, the ip_gre module, for GRE tunnels over IP
+    (NET_IPGRE), must not be loaded or compiled in.
 
     To configure HTB or HFSC quality of service with Open vSwitch,
     you must enable the respective configuration options.
@@ -301,23 +291,6 @@ Building the Sources
    If the `modprobe` operation fails, look at the last few kernel log
    messages (e.g. with `dmesg | tail`):
 
-      - The message "openvswitch: exports duplicate symbol
-        br_should_route_hook (owned by bridge)" means that the bridge
-        module is loaded.  Run `/sbin/rmmod bridge` to remove it.
-
-        If `/sbin/rmmod bridge` fails with "ERROR: Module bridge does
-        not exist in /proc/modules", then the bridge is compiled into
-        the kernel, rather than as a module.  Open vSwitch does not
-        support this configuration (see "Build Requirements", above).
-
-      - The message "openvswitch: exports duplicate symbol
-        dp_ioctl_hook (owned by ofdatapath)" means that the ofdatapath
-        module from the OpenFlow reference implementation is loaded.
-        Run `/sbin/rmmod ofdatapath` to remove it.  (You might have to
-        delete any existing datapaths beforehand, using the "dpctl"
-        program included with the OpenFlow reference implementation.
-        "ovs-dpctl" will not work.)
-
       - Otherwise, the most likely problem is that Open vSwitch was
         built for a kernel different from the one into which you are
         trying to load it.  Run `modinfo` on openvswitch.ko and on
@@ -335,18 +308,6 @@ Building the Sources
         module loading, please include the output from the `dmesg` and
         `modinfo` commands mentioned above.
 
-There is an optional module parameter to openvswitch.ko called
-vlan_tso that enables TCP segmentation offload over VLANs on NICs
-that support it. Many drivers do not expose support for TSO on VLANs
-in a way that Open vSwitch can use but there is no way to detect
-whether this is the case. If you know that your particular driver can
-handle it (for example by testing sending large TCP packets over VLANs)
-then passing in a value of 1 may improve performance. Modules built for
-Linux kernels 2.6.37 and later, as well as specially patched versions
-of earlier kernels, do not need this and do not have this parameter. If
-you do not understand what this means or do not know if your driver
-will work, do not set this.
-
 6. Initialize the configuration database using ovsdb-tool, e.g.:
 
       `% mkdir -p /usr/local/etc/openvswitch`
diff --git a/NEWS b/NEWS
index 38f6b56..e612f76 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -37,6 +37,8 @@ Post-v2.5.0
        for 2.7+.
    - SELinux:
      * Introduced SELinux policy package.
+   - Datapath Linux kernel compatibility.
+     * Dropped support for kernel older than 3.10.
 
 v2.5.0 - xx xxx xxxx
 ---------------------
index 82065c7..69c4912 100644 (file)
--- a/README.md
+++ b/README.md
@@ -36,10 +36,7 @@ vSwitch supports the following features:
 * Transactional configuration database with C and Python bindings
 * High-performance forwarding using a Linux kernel module
 
-The included Linux kernel module supports Linux 2.6.32 and up, with
-testing focused on 2.6.32 with Centos and Xen patches.  Open vSwitch
-also has special support for Citrix XenServer and Red Hat Enterprise
-Linux hosts.
+The included Linux kernel module supports Linux 3.10 and up.
 
 Open vSwitch can also operate, at a cost in performance, entirely in
 userspace, without assistance from a kernel module.  This userspace
index 11c7787..ed8ab78 100644 (file)
@@ -139,14 +139,10 @@ AC_DEFUN([OVS_CHECK_LINUX], [
        else
           AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version newer than 4.3.x is not supported (please refer to the FAQ for advice)])
        fi
-    elif test "$version" = 3; then
+    elif test "$version" = 3 && test "$patchlevel" -ge 10; then
        : # Linux 3.x
     else
-       if test "$version" -le 1 || test "$patchlevel" -le 5 || test "$sublevel" -le 31; then
-         AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version 2.6.32 or later is required])
-       else
-         : # Linux 2.6.x
-       fi
+       AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version 3.10 or later is required])
     fi
     if (test ! -e "$KBUILD"/include/linux/version.h && \
         test ! -e "$KBUILD"/include/generated/uapi/linux/version.h)|| \
@@ -307,7 +303,7 @@ AC_DEFUN([OVS_DEFINE], [
 
 dnl OVS_CHECK_LINUX_COMPAT
 dnl
-dnl Runs various Autoconf checks on the Linux 2.6 kernel source in
+dnl Runs various Autoconf checks on the Linux kernel source in
 dnl the directory in $KBUILD.
 AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
   rm -f datapath/linux/kcompat.h.new
@@ -381,11 +377,10 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
   OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [can_checksum_protocol])
   OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [ndo_get_iflink])
   OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [netdev_features_t])
-  OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [pcpu_sw_netstats])
-  OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [netdev_rx_handler_register])
-  OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [net_device_extended])
-  OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [rx_handler_func_t.*pskb],
-                  [OVS_DEFINE([HAVE_RX_HANDLER_PSKB])])
+  dnl Ubuntu kernel 3.13 has defined this struct but not used for netdev->tstats.
+  dnl So check type of tstats.
+  OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [pcpu_sw_netstats.*tstats],
+                  [OVS_DEFINE([HAVE_PCPU_SW_NETSTATS])])
   OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [netif_needs_gso.*net_device],
                   [OVS_DEFINE([HAVE_NETIF_NEEDS_GSO_NETDEV])])
   OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [udp_offload])
@@ -530,8 +525,6 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
 
   OVS_GREP_IFELSE([$KSRC/include/linux/u64_stats_sync.h], [u64_stats_fetch_begin_irq])
 
-  OVS_GREP_IFELSE([$KSRC/include/linux/openvswitch.h], [openvswitch_handle_frame_hook],
-                  [OVS_DEFINE([HAVE_RHEL_OVS_HOOK])])
   OVS_GREP_IFELSE([$KSRC/include/net/vxlan.h], [struct vxlan_metadata],
                   [OVS_DEFINE([HAVE_VXLAN_METADATA])])
   OVS_GREP_IFELSE([$KSRC/include/net/vxlan.h], [VXLAN_HF_RCO])
index 20413c9..dcf8591 100644 (file)
@@ -41,7 +41,6 @@
 #include "datapath.h"
 #include "conntrack.h"
 #include "gso.h"
-#include "vlan.h"
 #include "vport.h"
 
 static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
@@ -68,9 +67,7 @@ struct ovs_frag_data {
        u8 l2_data[MAX_L2_LEN];
 };
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
 static DEFINE_PER_CPU(struct ovs_frag_data, ovs_frag_data_storage);
-#endif
 
 #define DEFERRED_ACTION_FIFO_SIZE 10
 struct action_fifo {
@@ -149,7 +146,7 @@ static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,
        struct ethhdr *hdr;
 
        /* Networking stack do not allow simultaneous Tunnel and MPLS GSO. */
-       if (skb_encapsulation(skb))
+       if (skb->encapsulation)
                return -ENOTSUPP;
 
        if (skb_cow_head(skb, MPLS_HLEN) < 0)
@@ -302,14 +299,14 @@ static void update_ip_l4_checksum(struct sk_buff *skb, struct iphdr *nh,
        if (nh->protocol == IPPROTO_TCP) {
                if (likely(transport_len >= sizeof(struct tcphdr)))
                        inet_proto_csum_replace4(&tcp_hdr(skb)->check, skb,
-                                                addr, new_addr, 1);
+                                                addr, new_addr, true);
        } else if (nh->protocol == IPPROTO_UDP) {
                if (likely(transport_len >= sizeof(struct udphdr))) {
                        struct udphdr *uh = udp_hdr(skb);
 
                        if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) {
                                inet_proto_csum_replace4(&uh->check, skb,
-                                                        addr, new_addr, 1);
+                                                        addr, new_addr, true);
                                if (!uh->check)
                                        uh->check = CSUM_MANGLED_0;
                        }
@@ -335,14 +332,14 @@ static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto,
        if (l4_proto == NEXTHDR_TCP) {
                if (likely(transport_len >= sizeof(struct tcphdr)))
                        inet_proto_csum_replace16(&tcp_hdr(skb)->check, skb,
-                                                 addr, new_addr, 1);
+                                                 addr, new_addr, true);
        } else if (l4_proto == NEXTHDR_UDP) {
                if (likely(transport_len >= sizeof(struct udphdr))) {
                        struct udphdr *uh = udp_hdr(skb);
 
                        if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) {
                                inet_proto_csum_replace16(&uh->check, skb,
-                                                         addr, new_addr, 1);
+                                                         addr, new_addr, true);
                                if (!uh->check)
                                        uh->check = CSUM_MANGLED_0;
                        }
@@ -350,7 +347,7 @@ static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto,
        } else if (l4_proto == NEXTHDR_ICMP) {
                if (likely(transport_len >= sizeof(struct icmp6hdr)))
                        inet_proto_csum_replace16(&icmp6_hdr(skb)->icmp6_cksum,
-                                                 skb, addr, new_addr, 1);
+                                                 skb, addr, new_addr, true);
        }
 }
 
@@ -518,7 +515,7 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key,
 static void set_tp_port(struct sk_buff *skb, __be16 *port,
                        __be16 new_port, __sum16 *check)
 {
-       inet_proto_csum_replace2(check, skb, *port, new_port, 0);
+       inet_proto_csum_replace2(check, skb, *port, new_port, false);
        *port = new_port;
 }
 
@@ -625,7 +622,6 @@ static int set_sctp(struct sk_buff *skb, struct sw_flow_key *flow_key,
        return 0;
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
 static int ovs_vport_output(OVS_VPORT_OUTPUT_PARAMS)
 {
        struct ovs_frag_data *data = get_pcpu_ptr(ovs_frag_data_storage);
@@ -740,16 +736,6 @@ static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru,
 err:
        kfree_skb(skb);
 }
-#else /* < 3.10 */
-static void ovs_fragment(struct vport *vport, struct sk_buff *skb, u16 mru,
-                        __be16 ethertype)
-{
-       WARN_ONCE(1, "Fragment unavailable ->%s: eth=%04x, MRU=%d, MTU=%d.",
-                 ovs_vport_name(vport), ntohs(ethertype), mru,
-                 vport->dev->mtu);
-       kfree_skb(skb);
-}
-#endif
 
 static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
                      struct sw_flow_key *key)
index 0e19051..8bf779f 100644 (file)
 #include <net/xfrm.h>
 #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
 
+/* Even though vanilla 3.10 kernel has grp->id, RHEL 7 kernel is missing
+ * this field. */
 #ifdef HAVE_GENL_MULTICAST_GROUP_WITH_ID
 #define GROUP_ID(grp)  ((grp)->id)
 #else
 #define GROUP_ID(grp)  0
 #endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
-#define rt_dst(rt) (rt->dst)
-#else
-#define rt_dst(rt) (rt->u.dst)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
-#define inet_sport(sk) (inet_sk(sk)->sport)
-#else
-#define inet_sport(sk) (inet_sk(sk)->inet_sport)
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
-static inline bool skb_encapsulation(struct sk_buff *skb)
-{
-       return skb->encapsulation;
-}
-#else
-#define skb_encapsulation(skb) false
-#endif
-
 #ifdef OVS_FRAGMENT_BACKPORT
 #ifdef HAVE_NF_IPV6_OPS_FRAGMENT
 static inline int __init ip6_output_init(void) { return 0; }
index 795ed91..0338f9f 100644 (file)
@@ -14,8 +14,7 @@
 #include <linux/kconfig.h>
 #include <linux/version.h>
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) && \
-    IS_ENABLED(CONFIG_NF_CONNTRACK)
+#if IS_ENABLED(CONFIG_NF_CONNTRACK)
 
 #include <linux/module.h>
 #include <linux/openvswitch.h>
@@ -799,4 +798,4 @@ void ovs_ct_exit(struct net *net)
                nf_connlabels_put(net);
 }
 
-#endif /* CONFIG_NF_CONNTRACK && LINUX > 3.10 */
+#endif /* CONFIG_NF_CONNTRACK */
index 90b91be..8a849e8 100644 (file)
@@ -20,7 +20,7 @@
 struct ovs_conntrack_info;
 enum ovs_key_attr;
 
-#if IS_ENABLED(CONFIG_NF_CONNTRACK) && LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+#if IS_ENABLED(CONFIG_NF_CONNTRACK)
 void ovs_ct_init(struct net *);
 void ovs_ct_exit(struct net *);
 bool ovs_ct_verify(struct net *, enum ovs_key_attr attr);
index e3d3c8c..5bec072 100644 (file)
@@ -58,7 +58,6 @@
 #include "flow_table.h"
 #include "flow_netlink.h"
 #include "gso.h"
-#include "vlan.h"
 #include "vport-internal_dev.h"
 #include "vport-netdev.h"
 
@@ -450,12 +449,10 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
                if (!nskb)
                        return -ENOMEM;
 
-               nskb = vlan_insert_tag_set_proto(nskb, nskb->vlan_proto, skb_vlan_tag_get(nskb));
+               nskb = __vlan_hwaccel_push_inside(nskb);
                if (!nskb)
                        return -ENOMEM;
 
-               vlan_set_tci(nskb, 0);
-
                skb = nskb;
        }
 
@@ -2316,8 +2313,6 @@ static struct pernet_operations ovs_net_ops = {
        .size = sizeof(struct ovs_net),
 };
 
-DEFINE_COMPAT_PNET_REG_FUNC(device);
-
 static int __init dp_init(void)
 {
        int err;
index ce5b82a..ceb3372 100644 (file)
@@ -31,7 +31,6 @@
 #include "compat.h"
 #include "flow.h"
 #include "flow_table.h"
-#include "vlan.h"
 
 #define DP_MAX_PORTS           USHRT_MAX
 #define DP_VPORT_HASH_BUCKETS  1024
index 057dde1..c97c9c9 100644 (file)
@@ -50,7 +50,6 @@
 #include "flow.h"
 #include "flow_netlink.h"
 #include "vport.h"
-#include "vlan.h"
 
 u64 ovs_flow_used_time(unsigned long flow_jiffies)
 {
@@ -477,7 +476,7 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
 
        key->eth.tci = 0;
        if (skb_vlan_tag_present(skb))
-               key->eth.tci = htons(vlan_get_tci(skb));
+               key->eth.tci = htons(skb->vlan_tci);
        else if (eth->h_proto == htons(ETH_P_8021Q))
                if (unlikely(parse_vlan(skb, key)))
                        return -ENOMEM;
index b51be69..dd77922 100644 (file)
@@ -44,7 +44,6 @@
 #include <net/ipv6.h>
 #include <net/ndisc.h>
 
-#include "vlan.h"
 #include "flow_netlink.h"
 
 #define TBL_MIN_BUCKETS                1024
@@ -168,13 +167,6 @@ static void rcu_free_flow_callback(struct rcu_head *rcu)
        flow_free(flow);
 }
 
-static void rcu_free_sw_flow_mask_cb(struct rcu_head *rcu)
-{
-       struct sw_flow_mask *mask = container_of(rcu, struct sw_flow_mask, rcu);
-
-       kfree(mask);
-}
-
 void ovs_flow_free(struct sw_flow *flow, bool deferred)
 {
        if (!flow)
@@ -774,7 +766,7 @@ static void tbl_mask_array_delete_mask(struct mask_array *ma,
                if (mask == ovsl_dereference(ma->masks[i])) {
                        RCU_INIT_POINTER(ma->masks[i], NULL);
                        ma->count--;
-                       call_rcu(&mask->rcu, rcu_free_sw_flow_mask_cb);
+                       kfree_rcu(mask, rcu);
                        return;
                }
        }
index d7d4224..0d2088b 100644 (file)
@@ -34,67 +34,6 @@ void dev_disable_lro(struct net_device *dev) { }
 
 #endif /* HAVE_DEV_DISABLE_LRO */
 
-#if !defined HAVE_NETDEV_RX_HANDLER_REGISTER || \
-    defined HAVE_RHEL_OVS_HOOK
-
-static int nr_bridges;
-
-#ifdef HAVE_RHEL_OVS_HOOK
-int rpl_netdev_rx_handler_register(struct net_device *dev,
-                                  openvswitch_handle_frame_hook_t *hook,
-                                  void *rx_handler_data)
-{
-       nr_bridges++;
-       rcu_assign_pointer(dev->ax25_ptr, rx_handler_data);
-
-       if (nr_bridges == 1)
-               rcu_assign_pointer(openvswitch_handle_frame_hook, hook);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(rpl_netdev_rx_handler_register);
-#else
-
-int rpl_netdev_rx_handler_register(struct net_device *dev,
-                                  struct sk_buff *(*hook)(struct net_bridge_port *p,
-                                                          struct sk_buff *skb),
-                                  void *rx_handler_data)
-{
-       nr_bridges++;
-       if (dev->br_port)
-               return -EBUSY;
-
-       rcu_assign_pointer(dev->br_port, rx_handler_data);
-
-       if (nr_bridges == 1)
-               br_handle_frame_hook = hook;
-       return 0;
-}
-EXPORT_SYMBOL_GPL(rpl_netdev_rx_handler_register);
-#endif
-
-void rpl_netdev_rx_handler_unregister(struct net_device *dev)
-{
-       nr_bridges--;
-#ifdef HAVE_RHEL_OVS_HOOK
-       rcu_assign_pointer(dev->ax25_ptr, NULL);
-
-       if (nr_bridges)
-               return;
-
-       rcu_assign_pointer(openvswitch_handle_frame_hook, NULL);
-#else
-       rcu_assign_pointer(dev->br_port, NULL);
-
-       if (nr_bridges)
-               return;
-
-       br_handle_frame_hook = NULL;
-#endif
-}
-EXPORT_SYMBOL_GPL(rpl_netdev_rx_handler_unregister);
-
-#endif
-
 int rpl_rtnl_delete_link(struct net_device *dev)
 {
        const struct rtnl_link_ops *ops;
index 92feeef..0399de7 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/etherdevice.h>
 #include <linux/hash.h>
 #include <linux/if_link.h>
+#include <linux/if_vlan.h>
 
 #include <net/dst_metadata.h>
 #include <net/net_namespace.h>
@@ -125,9 +126,7 @@ static void geneve_rx(struct geneve_sock *gs, struct sk_buff *skb)
        struct genevehdr *gnvh = geneve_hdr(skb);
        struct metadata_dst *tun_dst;
        struct geneve_dev *geneve = NULL;
-#ifdef HAVE_DEV_TSTATS
        struct pcpu_sw_netstats *stats;
-#endif
        struct iphdr *iph;
        u8 *vni;
        __be32 addr;
@@ -200,13 +199,11 @@ static void geneve_rx(struct geneve_sock *gs, struct sk_buff *skb)
                }
        }
 
-#ifdef HAVE_DEV_TSTATS
        stats = this_cpu_ptr((struct pcpu_sw_netstats __percpu *)geneve->dev->tstats);
        u64_stats_update_begin(&stats->syncp);
        stats->rx_packets++;
        stats->rx_bytes += skb->len;
        u64_stats_update_end(&stats->syncp);
-#endif
        netdev_port_receive(skb, &tun_dst->u.tun_info);
        return;
 drop:
@@ -214,7 +211,6 @@ drop:
        kfree_skb(skb);
 }
 
-#ifdef HAVE_DEV_TSTATS
 /* Setup stats when device is created */
 static int geneve_init(struct net_device *dev)
 {
@@ -229,7 +225,6 @@ static void geneve_uninit(struct net_device *dev)
 {
        free_percpu(dev->tstats);
 }
-#endif
 
 /* Callback from net/ipv4/udp.c to receive packets */
 static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
@@ -495,7 +490,7 @@ static struct geneve_sock *geneve_find_sock(struct geneve_net *gn,
        struct geneve_sock *gs;
 
        list_for_each_entry(gs, &gn->sock_list, list) {
-               if (inet_sport(gs->sock->sk) == dst_port &&
+               if (inet_sk(gs->sock->sk)->inet_sport == dst_port &&
                    inet_sk(gs->sock->sk)->sk.sk_family == AF_INET) {
                        return gs;
                }
@@ -549,7 +544,7 @@ static int geneve_build_skb(struct rtable *rt, struct sk_buff *skb,
        int min_headroom;
        int err;
 
-       min_headroom = LL_RESERVED_SPACE(rt_dst(rt).dev) + rt_dst(rt).header_len
+       min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
                        + GENEVE_BASE_HLEN + opt_len + sizeof(struct iphdr)
                        + (skb_vlan_tag_present(skb) ? VLAN_HLEN : 0);
        err = skb_cow_head(skb, min_headroom);
@@ -623,7 +618,7 @@ static struct rtable *geneve_get_rt(struct sk_buff *skb,
                dev->stats.tx_carrier_errors++;
                return rt;
        }
-       if (rt_dst(rt).dev == dev) { /* is this necessary? */
+       if (rt->dst.dev == dev) { /* is this necessary? */
                netdev_dbg(dev, "circular route to %pI4\n", &fl4->daddr);
                dev->stats.collisions++;
                ip_rt_put(rt);
@@ -712,7 +707,7 @@ netdev_tx_t rpl_geneve_xmit(struct sk_buff *skb)
                ttl = geneve->ttl;
                if (!ttl && IN_MULTICAST(ntohl(fl4.daddr)))
                        ttl = 1;
-               ttl = ttl ? : ip4_dst_hoplimit(&rt_dst(rt));
+               ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
                df = 0;
        }
        err = udp_tunnel_xmit_skb(rt, gs->sock->sk, skb, fl4.saddr, fl4.daddr,
@@ -771,11 +766,9 @@ static int geneve_change_mtu(struct net_device *dev, int new_mtu)
 }
 
 static const struct net_device_ops geneve_netdev_ops = {
-#ifdef HAVE_DEV_TSTATS
        .ndo_init               = geneve_init,
        .ndo_uninit             = geneve_uninit,
        .ndo_get_stats64        = ip_tunnel_get_stats64,
-#endif
        .ndo_open               = geneve_open,
        .ndo_stop               = geneve_stop,
        .ndo_start_xmit         = geneve_dev_xmit,
@@ -1118,7 +1111,6 @@ static struct pernet_operations geneve_net_ops = {
        .size = sizeof(struct geneve_net),
 };
 
-DEFINE_COMPAT_PNET_REG_FUNC(device)
 int rpl_geneve_init_module(void)
 {
        int rc;
index c52b2b1..fb4749a 100644 (file)
 #include <net/xfrm.h>
 
 #include "gso.h"
-#include "vlan.h"
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) && \
-       !defined(HAVE_VLAN_BUG_WORKAROUND)
-#include <linux/module.h>
-
-static int vlan_tso __read_mostly;
-module_param(vlan_tso, int, 0644);
-MODULE_PARM_DESC(vlan_tso, "Enable TSO for VLAN packets");
-#else
-#define vlan_tso true
-#endif
 
 #ifdef OVS_USE_COMPAT_GSO_SEGMENTATION
 static bool dev_supports_vlan_tx(struct net_device *dev)
@@ -106,15 +94,11 @@ int rpl_dev_queue_xmit(struct sk_buff *skb)
                features = netif_skb_features(skb);
 
                if (vlan) {
-                       if (!vlan_tso)
-                               features &= ~(NETIF_F_TSO | NETIF_F_TSO6 |
-                                             NETIF_F_UFO | NETIF_F_FSO);
-
                        skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto,
                                                        skb_vlan_tag_get(skb));
                        if (unlikely(!skb))
                                return err;
-                       vlan_set_tci(skb, 0);
+                       skb->vlan_tci = 0;
                }
 
                /* As of v3.11 the kernel provides an mpls_features field in
index 19a7b8e..e9fa995 100644 (file)
@@ -49,30 +49,6 @@ struct net;
 extern void dev_disable_lro(struct net_device *dev);
 #endif
 
-#if !defined HAVE_NETDEV_RX_HANDLER_REGISTER || \
-    defined HAVE_RHEL_OVS_HOOK
-
-#ifdef HAVE_RHEL_OVS_HOOK
-typedef struct sk_buff *(openvswitch_handle_frame_hook_t)(struct sk_buff *skb);
-extern openvswitch_handle_frame_hook_t *openvswitch_handle_frame_hook;
-
-#define netdev_rx_handler_register rpl_netdev_rx_handler_register
-int rpl_netdev_rx_handler_register(struct net_device *dev,
-                                  openvswitch_handle_frame_hook_t *hook,
-                                  void *rx_handler_data);
-#else
-
-#define netdev_rx_handler_register rpl_netdev_rx_handler_register
-int rpl_netdev_rx_handler_register(struct net_device *dev,
-                                  struct sk_buff *(*netdev_hook)(struct net_bridge_port *p,
-                                                          struct sk_buff *skb),
-                                  void *rx_handler_data);
-#endif
-
-#define netdev_rx_handler_unregister rpl_netdev_rx_handler_unregister
-void rpl_netdev_rx_handler_unregister(struct net_device *dev);
-#endif
-
 #ifndef HAVE_DEV_GET_BY_INDEX_RCU
 static inline struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex)
 {
@@ -166,16 +142,7 @@ static inline struct net_device *netdev_notifier_info_to_dev(void *info)
 #endif
 
 #ifndef HAVE_PCPU_SW_NETSTATS
-
-#include <linux/u64_stats_sync.h>
-
-struct pcpu_sw_netstats {
-       u64     rx_packets;
-       u64     rx_bytes;
-       u64     tx_packets;
-       u64     tx_bytes;
-       struct u64_stats_sync   syncp;
-};
+#define pcpu_sw_netstats pcpu_tstats
 #endif
 
 #if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,0)
@@ -258,12 +225,6 @@ static inline void *skb_gro_remcsum_process(struct sk_buff *skb, void *ptr,
 #define dev_get_stats rpl_dev_get_stats
 struct rtnl_link_stats64 *rpl_dev_get_stats(struct net_device *dev,
                                        struct rtnl_link_stats64 *storage);
-
-#else
-#define HAVE_DEV_TSTATS
-#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)
-#undef HAVE_DEV_TSTATS
-#endif
 #endif
 
 #if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)
index 9f50872..4270722 100644 (file)
@@ -3,57 +3,6 @@
 
 #include_next <net/net_namespace.h>
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
-/* for 2.6.32* */
-struct rpl_pernet_operations {
-       int (*init)(struct net *net);
-       void (*exit)(struct net *net);
-       int *id;
-       size_t size;
-       struct pernet_operations ops;
-};
-#define pernet_operations rpl_pernet_operations
-
-#define register_pernet_device rpl_register_pernet_gen_device
-#define unregister_pernet_device rpl_unregister_pernet_gen_device
-
-#define register_pernet_subsys rpl_register_pernet_gen_device
-#define unregister_pernet_subsys rpl_unregister_pernet_gen_device
-
-#define compat_init_net ovs_compat_init_net
-int ovs_compat_init_net(struct net *net, struct rpl_pernet_operations *pnet);
-#define compat_exit_net ovs_compat_exit_net
-void ovs_compat_exit_net(struct net *net, struct rpl_pernet_operations *pnet);
-
-#define DEFINE_COMPAT_PNET_REG_FUNC(TYPE)                                      \
-                                                                       \
-static struct rpl_pernet_operations *pnet_gen_##TYPE;                  \
-static int compat_init_net_gen_##TYPE(struct net *net) \
-{                                                                      \
-       return compat_init_net(net, pnet_gen_##TYPE);                   \
-}                                                                      \
-                                                                       \
-static void compat_exit_net_gen_##TYPE(struct net *net)        \
-{                                                                      \
-       compat_exit_net(net, pnet_gen_##TYPE);                          \
-}                                                                      \
-                                                                       \
-static int rpl_register_pernet_gen_##TYPE(struct rpl_pernet_operations *rpl_pnet)      \
-{                                                                              \
-       pnet_gen_##TYPE = rpl_pnet;                                             \
-       rpl_pnet->ops.init = compat_init_net_gen_##TYPE;                        \
-       rpl_pnet->ops.exit = compat_exit_net_gen_##TYPE;                        \
-       return register_pernet_gen_##TYPE(pnet_gen_##TYPE->id, &rpl_pnet->ops); \
-}                                                                                      \
-                                                                                       \
-static void rpl_unregister_pernet_gen_##TYPE(struct rpl_pernet_operations *rpl_pnet)           \
-{                                                                                      \
-       unregister_pernet_gen_##TYPE(*pnet_gen_##TYPE->id, &rpl_pnet->ops);             \
-}
-#else
-#define DEFINE_COMPAT_PNET_REG_FUNC(TYPE)
-#endif /* 2.6.33 */
-
 #ifndef HAVE_POSSIBLE_NET_T
 typedef struct {
 #ifdef CONFIG_NET_NS
index b50cd17..75a5a7a 100644 (file)
@@ -220,7 +220,7 @@ struct net_device *rpl_vxlan_dev_create(struct net *net, const char *name,
 
 static inline __be16 vxlan_dev_dst_port(struct vxlan_dev *vxlan)
 {
-       return inet_sport(vxlan->vn_sock->sock->sk);
+       return inet_sk(vxlan->vn_sock->sock->sk)->inet_sport;
 }
 
 static inline netdev_features_t vxlan_features_check(struct sk_buff *skb,
@@ -228,7 +228,7 @@ static inline netdev_features_t vxlan_features_check(struct sk_buff *skb,
 {
        u8 l4_hdr = 0;
 
-       if (!skb_encapsulation(skb))
+       if (!skb->encapsulation)
                return features;
 
        switch (vlan_get_protocol(skb)) {
index f6a841f..2e13843 100644 (file)
@@ -289,7 +289,7 @@ netdev_tx_t rpl_gre_fb_xmit(struct sk_buff *skb)
 
        tunnel_hlen = ip_gre_calc_hlen(key->tun_flags);
 
-       min_headroom = LL_RESERVED_SPACE(rt_dst(rt).dev) + rt_dst(rt).header_len
+       min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
                        + tunnel_hlen + sizeof(struct iphdr)
                        + (skb_vlan_tag_present(skb) ? VLAN_HLEN : 0);
        if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) {
@@ -647,8 +647,6 @@ static struct pernet_operations ipgre_tap_net_ops = {
        .size = sizeof(struct ip_tunnel_net),
 };
 
-DEFINE_COMPAT_PNET_REG_FUNC(device);
-
 int rpl_ipgre_init(void)
 {
        int err;
index 8190937..b3b4fde 100644 (file)
@@ -113,7 +113,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev)
                rt = ip_route_output_key(tunnel->net, &fl4);
 
                if (!IS_ERR(rt)) {
-                       tdev = rt_dst(rt).dev;
+                       tdev = rt->dst.dev;
                        ip_rt_put(rt);
                }
                if (dev->type != ARPHRD_ETHER)
@@ -164,9 +164,7 @@ int rpl_ip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
 
 static void ip_tunnel_dev_free(struct net_device *dev)
 {
-#ifdef HAVE_DEV_TSTATS
        free_percpu(dev->tstats);
-#endif
        free_netdev(dev);
 }
 
@@ -261,11 +259,9 @@ int rpl_ip_tunnel_init(struct net_device *dev)
        struct iphdr *iph = &tunnel->parms.iph;
 
        dev->destructor = ip_tunnel_dev_free;
-#ifdef HAVE_DEV_TSTATS
        dev->tstats = (typeof(dev->tstats)) netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
        if (!dev->tstats)
                return -ENOMEM;
-#endif
        tunnel->dev = dev;
        tunnel->net = dev_net(dev);
        strcpy(tunnel->parms.name, dev->name);
index 179fa47..0858d02 100644 (file)
@@ -19,6 +19,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/if_vlan.h>
 #include <linux/in.h>
 #include <linux/in_route.h>
 #include <linux/inetdevice.h>
@@ -48,7 +49,7 @@ int rpl_iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
        skb_scrub_packet(skb, xnet);
 
        skb_clear_hash(skb);
-       skb_dst_set(skb, &rt_dst(rt));
+       skb_dst_set(skb, &rt->dst);
 
 #if 0
        /* Do not clear ovs_skb_cb.  It will be done in gso code. */
@@ -71,7 +72,7 @@ int rpl_iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
        iph->ttl        =       ttl;
 
 #ifdef HAVE_IP_SELECT_IDENT_USING_DST_ENTRY
-       __ip_select_ident(iph, &rt_dst(rt), (skb_shinfo(skb)->gso_segs ?: 1) - 1);
+       __ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1);
 #elif defined(HAVE_IP_SELECT_IDENT_USING_NET)
        __ip_select_ident(dev_net(rt->dst.dev), iph,
                          skb_shinfo(skb)->gso_segs ?: 1);
@@ -167,7 +168,7 @@ int rpl_iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_prot
        secpath_reset(skb);
        skb_clear_hash(skb);
        skb_dst_drop(skb);
-       vlan_set_tci(skb, 0);
+       skb->vlan_tci = 0;
        skb_set_queue_mapping(skb, 0);
        skb->pkt_type = PACKET_HOST;
        return 0;
@@ -181,7 +182,7 @@ bool ovs_skb_is_encapsulated(struct sk_buff *skb)
        /* checking for inner protocol should be sufficient on newer kernel, but
         * old kernel just set encapsulation bit.
         */
-       return ovs_skb_get_inner_protocol(skb) || skb_encapsulation(skb);
+       return ovs_skb_get_inner_protocol(skb) || skb->encapsulation;
 }
 EXPORT_SYMBOL_GPL(ovs_skb_is_encapsulated);
 
index fa6da6c..f1f50ae 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/version.h>
 
+#include <linux/etherdevice.h>
 #include <linux/in.h>
 #include <linux/ip.h>
 #include <linux/net.h>
@@ -310,7 +311,7 @@ netdev_tx_t rpl_lisp_xmit(struct sk_buff *skb)
                goto error;
        }
 
-       min_headroom = LL_RESERVED_SPACE(rt_dst(rt).dev) + rt_dst(rt).header_len
+       min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
                + sizeof(struct iphdr) + LISP_HLEN;
 
        if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) {
@@ -327,7 +328,7 @@ netdev_tx_t rpl_lisp_xmit(struct sk_buff *skb)
        /* Reset l2 headers. */
        skb_pull(skb, network_offset);
        skb_reset_mac_header(skb);
-       vlan_set_tci(skb, 0);
+       skb->vlan_tci = 0;
 
        skb = udp_tunnel_handle_offloads(skb, false, 0, false);
        if (IS_ERR(skb)) {
@@ -362,7 +363,6 @@ error:
 }
 EXPORT_SYMBOL(rpl_lisp_xmit);
 
-#ifdef HAVE_DEV_TSTATS
 /* Setup stats when device is created */
 static int lisp_init(struct net_device *dev)
 {
@@ -377,7 +377,6 @@ static void lisp_uninit(struct net_device *dev)
 {
        free_percpu(dev->tstats);
 }
-#endif
 
 static struct socket *create_sock(struct net *net, bool ipv6,
                                       __be16 port)
@@ -458,11 +457,9 @@ static int lisp_change_mtu(struct net_device *dev, int new_mtu)
 }
 
 static const struct net_device_ops lisp_netdev_ops = {
-#ifdef HAVE_DEV_TSTATS
        .ndo_init               = lisp_init,
        .ndo_uninit             = lisp_uninit,
        .ndo_get_stats64        = ip_tunnel_get_stats64,
-#endif
        .ndo_open               = lisp_open,
        .ndo_stop               = lisp_stop,
        .ndo_start_xmit         = lisp_dev_xmit,
@@ -697,7 +694,6 @@ static struct pernet_operations lisp_net_ops = {
        .size = sizeof(struct lisp_net),
 };
 
-DEFINE_COMPAT_PNET_REG_FUNC(device)
 int rpl_lisp_init_module(void)
 {
        int rc;
index 769b76f..4faa18f 100644 (file)
@@ -199,7 +199,7 @@ static struct vxlan_sock *vxlan_find_sock(struct net *net, sa_family_t family,
        flags &= VXLAN_F_RCV_FLAGS;
 
        hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
-               if (inet_sport(vs->sock->sk) == port &&
+               if (inet_sk(vs->sock->sk)->inet_sport == port &&
                    vxlan_get_sk_family(vs) == family &&
                    vs->flags == flags)
                        return vs;
@@ -819,9 +819,7 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
        struct iphdr *oip = NULL;
        struct ipv6hdr *oip6 = NULL;
        struct vxlan_dev *vxlan;
-#ifdef HAVE_DEV_TSTATS
        struct pcpu_sw_netstats *stats;
-#endif
        union vxlan_addr saddr;
        int err = 0;
 
@@ -885,13 +883,11 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
                }
        }
 
-#ifdef HAVE_DEV_TSTATS
        stats = this_cpu_ptr((struct pcpu_sw_netstats __percpu *)vxlan->dev->tstats);
        u64_stats_update_begin(&stats->syncp);
        stats->rx_packets++;
        stats->rx_bytes += skb->len;
        u64_stats_update_end(&stats->syncp);
-#endif
        netdev_port_receive(skb, skb_tunnel_info(skb));
        return;
 drop:
@@ -1152,7 +1148,7 @@ static int vxlan_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *sk
                }
        }
 
-       min_headroom = LL_RESERVED_SPACE(rt_dst(rt).dev) + rt_dst(rt).header_len
+       min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
                        + VXLAN_HLEN + sizeof(struct iphdr)
                        + (skb_vlan_tag_present(skb) ? VLAN_HLEN : 0);
 
@@ -1306,7 +1302,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                        goto tx_error;
                }
 
-               if (rt_dst(rt).dev == dev) {
+               if (rt->dst.dev == dev) {
                        netdev_dbg(dev, "circular route to %pI4\n",
                                   &dst->sin.sin_addr.s_addr);
                        dev->stats.collisions++;
@@ -1330,7 +1326,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                }
 
                tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
-               ttl = ttl ? : ip4_dst_hoplimit(&rt_dst(rt));
+               ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
                err = vxlan_xmit_skb(rt, sk, skb, fl4.saddr,
                                     dst->sin.sin_addr.s_addr, tos, ttl, df,
                                     src_port, dst_port, htonl(vni << 8), md,
@@ -1500,7 +1496,6 @@ static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan)
 }
 
 /* Setup stats when device is created */
-#ifdef HAVE_DEV_TSTATS
 static int vxlan_init(struct net_device *dev)
 {
        dev->tstats = (typeof(dev->tstats)) netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
@@ -1509,7 +1504,6 @@ static int vxlan_init(struct net_device *dev)
 
        return 0;
 }
-#endif
 
 static void vxlan_fdb_delete_default(struct vxlan_dev *vxlan)
 {
@@ -1522,7 +1516,6 @@ static void vxlan_fdb_delete_default(struct vxlan_dev *vxlan)
        spin_unlock_bh(&vxlan->hash_lock);
 }
 
-#ifdef HAVE_DEV_TSTATS
 static void vxlan_uninit(struct net_device *dev)
 {
        struct vxlan_dev *vxlan = netdev_priv(dev);
@@ -1531,7 +1524,6 @@ static void vxlan_uninit(struct net_device *dev)
 
        free_percpu(dev->tstats);
 }
-#endif
 
 /* Start ageing timer and join group when device is brought up */
 static int vxlan_open(struct net_device *dev)
@@ -1657,11 +1649,9 @@ static netdev_tx_t vxlan_dev_xmit(struct sk_buff *skb, struct net_device *dev)
 }
 
 static const struct net_device_ops vxlan_netdev_ops = {
-#ifdef HAVE_DEV_TSTATS
        .ndo_init               = vxlan_init,
        .ndo_uninit             = vxlan_uninit,
        .ndo_get_stats64        = ip_tunnel_get_stats64,
-#endif
        .ndo_open               = vxlan_open,
        .ndo_stop               = vxlan_stop,
        .ndo_start_xmit         = vxlan_dev_xmit,
@@ -2206,7 +2196,6 @@ static struct pernet_operations vxlan_net_ops = {
        .size = sizeof(struct vxlan_net),
 };
 
-DEFINE_COMPAT_PNET_REG_FUNC(device)
 int rpl_vxlan_init_module(void)
 {
        int rc;
diff --git a/datapath/vlan.h b/datapath/vlan.h
deleted file mode 100644 (file)
index 13ae6a7..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2007-2011 Nicira, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- */
-
-#ifndef VLAN_H
-#define VLAN_H 1
-
-#include <linux/if_vlan.h>
-#include <linux/skbuff.h>
-#include <linux/version.h>
-
-/**
- * DOC: VLAN tag manipulation.
- *
- * &struct sk_buff handling of VLAN tags has evolved over time:
- *
- * In 2.6.26 and earlier, VLAN tags did not have any generic representation in
- * an skb, other than as a raw 802.1Q header inside the packet data.
- *
- * In 2.6.27 &struct sk_buff added a @vlan_tci member.  Between 2.6.27 and
- * 2.6.32, its value was the raw contents of the 802.1Q TCI field, or zero if
- * no 802.1Q header was present.  This worked OK except for the corner case of
- * an 802.1Q header with an all-0-bits TCI, which could not be represented.
- *
- * In 2.6.33, @vlan_tci semantics changed.  Now, if an 802.1Q header is
- * present, then the VLAN_TAG_PRESENT bit is always set.  This fixes the
- * all-0-bits TCI corner case.
- *
- * For compatibility we emulate the 2.6.33+ behavior on earlier kernel
- * versions.  The client must not access @vlan_tci directly.  Instead, use
- * vlan_get_tci() to read it or vlan_set_tci() to write it, with semantics
- * equivalent to those on 2.6.33+.
- */
-
-static inline u16 vlan_get_tci(struct sk_buff *skb)
-{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
-       if (skb->vlan_tci)
-               return skb->vlan_tci | VLAN_TAG_PRESENT;
-#endif
-       return skb->vlan_tci;
-}
-
-static inline void vlan_set_tci(struct sk_buff *skb, u16 vlan_tci)
-{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
-       vlan_tci &= ~VLAN_TAG_PRESENT;
-#endif
-       skb->vlan_tci = vlan_tci;
-}
-#endif /* vlan.h */
index 392d750..e65e43d 100644 (file)
@@ -34,7 +34,7 @@ static struct vport_ops ovs_geneve_vport_ops;
  * @dst_port: destination port.
  */
 struct geneve_port {
-       u16 port_no;
+       u16 dst_port;
 };
 
 static inline struct geneve_port *geneve_vport(const struct vport *vport)
@@ -47,7 +47,7 @@ static int geneve_get_options(const struct vport *vport,
 {
        struct geneve_port *geneve_port = geneve_vport(vport);
 
-       if (nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT, geneve_port->port_no))
+       if (nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT, geneve_port->dst_port))
                return -EMSGSIZE;
        return 0;
 }
@@ -57,7 +57,7 @@ static int geneve_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
 {
        struct geneve_port *geneve_port = geneve_vport(vport);
        struct net *net = ovs_dp_get_net(vport->dp);
-       __be16 dport = htons(geneve_port->port_no);
+       __be16 dport = htons(geneve_port->dst_port);
        __be16 sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true);
 
        return ovs_tunnel_get_egress_info(upcall, ovs_dp_get_net(vport->dp),
@@ -95,7 +95,7 @@ static struct vport *geneve_tnl_create(const struct vport_parms *parms)
                return vport;
 
        geneve_port = geneve_vport(vport);
-       geneve_port->port_no = dst_port;
+       geneve_port->dst_port = dst_port;
 
        rtnl_lock();
        dev = geneve_dev_create_fb(net, parms->name, NET_NAME_USER, dst_port);
index 7f21679..ec76398 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007-2015 Nicira, Inc.
+ * Copyright (c) 2007-2012 Nicira, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
@@ -23,9 +23,6 @@
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/skbuff.h>
-#include <linux/percpu.h>
-#include <linux/u64_stats_sync.h>
-#include <linux/netdev_features.h>
 
 #include <net/dst.h>
 #include <net/xfrm.h>
@@ -57,16 +54,12 @@ static int internal_dev_xmit(struct sk_buff *skb, struct net_device *netdev)
        rcu_read_unlock();
 
        if (likely(!err)) {
-#ifdef HAVE_DEV_TSTATS
-               struct pcpu_sw_netstats *tstats;
-
-               tstats = this_cpu_ptr((struct pcpu_sw_netstats __percpu *)netdev->tstats);
+               struct pcpu_sw_netstats *tstats = this_cpu_ptr(netdev->tstats);
 
                u64_stats_update_begin(&tstats->syncp);
                tstats->tx_bytes += len;
                tstats->tx_packets++;
                u64_stats_update_end(&tstats->syncp);
-#endif
        } else {
                netdev->stats.tx_errors++;
        }
@@ -94,14 +87,6 @@ static void internal_dev_getinfo(struct net_device *netdev,
 static const struct ethtool_ops internal_dev_ethtool_ops = {
        .get_drvinfo    = internal_dev_getinfo,
        .get_link       = ethtool_op_get_link,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)
-       .get_sg         = ethtool_op_get_sg,
-       .set_sg         = ethtool_op_set_sg,
-       .get_tx_csum    = ethtool_op_get_tx_csum,
-       .set_tx_csum    = ethtool_op_set_tx_hw_csum,
-       .get_tso        = ethtool_op_get_tso,
-       .set_tso        = ethtool_op_set_tso,
-#endif
 };
 
 static int internal_dev_change_mtu(struct net_device *netdev, int new_mtu)
@@ -121,32 +106,45 @@ static void internal_dev_destructor(struct net_device *dev)
        free_netdev(dev);
 }
 
-#ifdef HAVE_DEV_TSTATS
-static int internal_dev_init(struct net_device *dev)
+static struct rtnl_link_stats64 *
+internal_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
 {
-       dev->tstats = (typeof(dev->tstats)) netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
-       if (!dev->tstats)
-               return -ENOMEM;
-       return 0;
-}
+       int i;
+
+       memset(stats, 0, sizeof(*stats));
+       stats->rx_errors  = dev->stats.rx_errors;
+       stats->tx_errors  = dev->stats.tx_errors;
+       stats->tx_dropped = dev->stats.tx_dropped;
+       stats->rx_dropped = dev->stats.rx_dropped;
+
+       for_each_possible_cpu(i) {
+               const struct pcpu_sw_netstats *percpu_stats;
+               struct pcpu_sw_netstats local_stats;
+               unsigned int start;
+
+               percpu_stats = per_cpu_ptr(dev->tstats, i);
+
+               do {
+                       start = u64_stats_fetch_begin_irq(&percpu_stats->syncp);
+                       local_stats = *percpu_stats;
+               } while (u64_stats_fetch_retry_irq(&percpu_stats->syncp, start));
+
+               stats->rx_bytes         += local_stats.rx_bytes;
+               stats->rx_packets       += local_stats.rx_packets;
+               stats->tx_bytes         += local_stats.tx_bytes;
+               stats->tx_packets       += local_stats.tx_packets;
+       }
 
-static void internal_dev_uninit(struct net_device *dev)
-{
-       free_percpu(dev->tstats);
+       return stats;
 }
-#endif
 
 static const struct net_device_ops internal_dev_netdev_ops = {
-#ifdef HAVE_DEV_TSTATS
-       .ndo_init = internal_dev_init,
-       .ndo_uninit = internal_dev_uninit,
-       .ndo_get_stats64 = ip_tunnel_get_stats64,
-#endif
        .ndo_open = internal_dev_open,
        .ndo_stop = internal_dev_stop,
        .ndo_start_xmit = internal_dev_xmit,
        .ndo_set_mac_address = eth_mac_addr,
        .ndo_change_mtu = internal_dev_change_mtu,
+       .ndo_get_stats64 = internal_get_stats,
 };
 
 static struct rtnl_link_ops internal_dev_link_ops __read_mostly = {
@@ -171,14 +169,10 @@ static void do_setup(struct net_device *netdev)
                           NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL;
 
        netdev->vlan_features = netdev->features;
-       netdev->features |= NETIF_F_HW_VLAN_CTAG_TX;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
        netdev->hw_enc_features = netdev->features;
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
+       netdev->features |= NETIF_F_HW_VLAN_CTAG_TX;
        netdev->hw_features = netdev->features & ~NETIF_F_LLTX;
-#endif
+
        eth_hw_addr_random(netdev);
 }
 
@@ -200,6 +194,11 @@ static struct vport *internal_dev_create(const struct vport_parms *parms)
                err = -ENOMEM;
                goto error_free_vport;
        }
+       vport->dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
+       if (!vport->dev->tstats) {
+               err = -ENOMEM;
+               goto error_free_netdev;
+       }
 
        dev_net_set(vport->dev, ovs_dp_get_net(vport->dp));
        internal_dev = internal_dev_priv(vport->dev);
@@ -212,7 +211,7 @@ static struct vport *internal_dev_create(const struct vport_parms *parms)
        rtnl_lock();
        err = register_netdevice(vport->dev);
        if (err)
-               goto error_free_netdev;
+               goto error_unlock;
 
        dev_set_promiscuity(vport->dev, 1);
        rtnl_unlock();
@@ -220,8 +219,10 @@ static struct vport *internal_dev_create(const struct vport_parms *parms)
 
        return vport;
 
-error_free_netdev:
+error_unlock:
        rtnl_unlock();
+       free_percpu(vport->dev->tstats);
+error_free_netdev:
        free_netdev(vport->dev);
 error_free_vport:
        ovs_vport_free(vport);
@@ -237,16 +238,14 @@ static void internal_dev_destroy(struct vport *vport)
 
        /* unregister_netdevice() waits for an RCU grace period. */
        unregister_netdevice(vport->dev);
-
+       free_percpu(vport->dev->tstats);
        rtnl_unlock();
 }
 
 static netdev_tx_t internal_dev_recv(struct sk_buff *skb)
 {
        struct net_device *netdev = skb->dev;
-#ifdef HAVE_DEV_TSTATS
        struct pcpu_sw_netstats *stats;
-#endif
 
        if (unlikely(!(netdev->flags & IFF_UP))) {
                kfree_skb(skb);
@@ -254,22 +253,6 @@ static netdev_tx_t internal_dev_recv(struct sk_buff *skb)
                return NETDEV_TX_OK;
        }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
-       if (skb_vlan_tag_present(skb)) {
-               if (unlikely(!vlan_insert_tag_set_proto(skb,
-                                                       skb->vlan_proto,
-                                                       skb_vlan_tag_get(skb))))
-                       return NETDEV_TX_OK;
-
-               if (skb->ip_summed == CHECKSUM_COMPLETE)
-                       skb->csum = csum_add(skb->csum,
-                                            csum_partial(skb->data + (2 * ETH_ALEN),
-                                                         VLAN_HLEN, 0));
-
-               vlan_set_tci(skb, 0);
-       }
-#endif
-
        skb_dst_drop(skb);
        nf_reset(skb);
        secpath_reset(skb);
@@ -278,13 +261,11 @@ static netdev_tx_t internal_dev_recv(struct sk_buff *skb)
        skb->protocol = eth_type_trans(skb, netdev);
        skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
 
-#ifdef HAVE_DEV_TSTATS
-       stats = this_cpu_ptr((struct pcpu_sw_netstats __percpu *)netdev->tstats);
+       stats = this_cpu_ptr(netdev->tstats);
        u64_stats_update_begin(&stats->syncp);
        stats->rx_packets++;
        stats->rx_bytes += skb->len;
        u64_stats_update_end(&stats->syncp);
-#endif
 
        netif_rx(skb);
        return NETDEV_TX_OK;
index a1df79b..ddd3f5c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007-2015 Nicira, Inc.
+ * Copyright (c) 2007-2012 Nicira, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
@@ -26,6 +26,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
 #include <linux/openvswitch.h>
+#include <linux/export.h>
 
 #include <net/ip_tunnels.h>
 #include <net/rtnetlink.h>
@@ -65,13 +66,6 @@ error:
        kfree_skb(skb);
 }
 
-#ifndef HAVE_METADATA_DST
-#define port_receive(skb)  netdev_port_receive(skb, NULL)
-#else
-#define port_receive(skb)  netdev_port_receive(skb, skb_tunnel_info(skb))
-#endif
-
-#if defined HAVE_RX_HANDLER_PSKB  /* 2.6.39 and above or backports */
 /* Called with rcu_read_lock and bottom-halves disabled. */
 static rx_handler_result_t netdev_frame_hook(struct sk_buff **pskb)
 {
@@ -80,35 +74,13 @@ static rx_handler_result_t netdev_frame_hook(struct sk_buff **pskb)
        if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
                return RX_HANDLER_PASS;
 
-       port_receive(skb);
-       return RX_HANDLER_CONSUMED;
-}
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) || \
-      defined HAVE_RHEL_OVS_HOOK
-/* Called with rcu_read_lock and bottom-halves disabled. */
-static struct sk_buff *netdev_frame_hook(struct sk_buff *skb)
-{
-       if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
-               return skb;
-
-       port_receive(skb);
-       return NULL;
-}
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
-/*
- * Used as br_handle_frame_hook.  (Cannot run bridge at the same time, even on
- * different set of devices!)
- */
-/* Called with rcu_read_lock and bottom-halves disabled. */
-static struct sk_buff *netdev_frame_hook(struct net_bridge_port *p,
-                                        struct sk_buff *skb)
-{
-       port_receive(skb);
-       return NULL;
-}
+#ifndef HAVE_METADATA_DST
+       netdev_port_receive(skb, NULL);
 #else
-#error
+       netdev_port_receive(skb, skb_tunnel_info(skb));
 #endif
+       return RX_HANDLER_CONSUMED;
+}
 
 static struct net_device *get_dpdev(const struct datapath *dp)
 {
@@ -217,10 +189,8 @@ void ovs_netdev_tunnel_destroy(struct vport *vport)
         * underlying netdev deregistration; delete the link only
         * if it's not already shutting down.
         */
-
        if (vport->dev->reg_state == NETREG_REGISTERED)
                rtnl_delete_link(vport->dev);
-
        dev_put(vport->dev);
        vport->dev = NULL;
        rtnl_unlock();
@@ -232,28 +202,11 @@ EXPORT_SYMBOL_GPL(ovs_netdev_tunnel_destroy);
 /* Returns null if this device is not attached to a datapath. */
 struct vport *ovs_netdev_get_vport(struct net_device *dev)
 {
-#if defined HAVE_NETDEV_RX_HANDLER_REGISTER || \
-    defined HAVE_RHEL_OVS_HOOK
-#ifdef HAVE_OVS_DATAPATH
        if (likely(dev->priv_flags & IFF_OVS_DATAPATH))
-#else
-       if (likely(rcu_access_pointer(dev->rx_handler) == netdev_frame_hook))
-#endif
-#ifdef HAVE_RHEL_OVS_HOOK
-               return (struct vport *)rcu_dereference_rtnl(dev->ax25_ptr);
-#else
-#ifdef HAVE_NET_DEVICE_EXTENDED
                return (struct vport *)
-                       rcu_dereference_rtnl(netdev_extended(dev)->rx_handler_data);
-#else
-               return (struct vport *)rcu_dereference_rtnl(dev->rx_handler_data);
-#endif
-#endif
+                       rcu_dereference_rtnl(dev->rx_handler_data);
        else
                return NULL;
-#else
-       return (struct vport *)rcu_dereference_rtnl(dev->br_port);
-#endif
 }
 
 static struct vport_ops ovs_netdev_vport_ops = {
@@ -272,23 +225,3 @@ void ovs_netdev_exit(void)
 {
        ovs_vport_ops_unregister(&ovs_netdev_vport_ops);
 }
-
-#if !defined HAVE_NETDEV_RX_HANDLER_REGISTER && \
-    !defined HAVE_RHEL_OVS_HOOK
-/*
- * Enforces, mutual exclusion with the Linux bridge module, by declaring and
- * exporting br_should_route_hook.  Because the bridge module also exports the
- * same symbol, the module loader will refuse to load both modules at the same
- * time (e.g. "bridge: exports duplicate symbol br_should_route_hook (owned by
- * openvswitch)").
- *
- * Before Linux 2.6.36, Open vSwitch cannot safely coexist with the Linux
- * bridge module, so openvswitch uses this macro in those versions.  In
- * Linux 2.6.36 and later, Open vSwitch can coexist with the bridge module.
- *
- * The use of "typeof" here avoids the need to track changes in the type of
- * br_should_route_hook over various kernel versions.
- */
-typeof(br_should_route_hook) br_should_route_hook;
-EXPORT_SYMBOL(br_should_route_hook);
-#endif
index f8fbb86..04ad190 100644 (file)
@@ -27,7 +27,6 @@
 struct vport *ovs_netdev_get_vport(struct net_device *dev);
 
 struct vport *ovs_netdev_link(struct vport *vport, const char *name);
-void ovs_netdev_send(struct vport *vport, struct sk_buff *skb);
 void ovs_netdev_detach_dev(struct vport *);
 
 int __init ovs_netdev_init(void);
index 7fd9858..44b9dfb 100644 (file)
@@ -33,8 +33,9 @@
 #include <net/lisp.h>
 #include <net/gre.h>
 #include <net/geneve.h>
-#include <net/vxlan.h>
+#include <net/route.h>
 #include <net/stt.h>
+#include <net/vxlan.h>
 
 #include "datapath.h"
 #include "gso.h"
@@ -375,14 +376,6 @@ int ovs_vport_get_options(const struct vport *vport, struct sk_buff *skb)
        return 0;
 }
 
-static void vport_portids_destroy_rcu_cb(struct rcu_head *rcu)
-{
-       struct vport_portids *ids = container_of(rcu, struct vport_portids,
-                                                rcu);
-
-       kfree(ids);
-}
-
 /**
  *     ovs_vport_set_upcall_portids - set upcall portids of @vport.
  *
@@ -417,7 +410,7 @@ int ovs_vport_set_upcall_portids(struct vport *vport, const struct nlattr *ids)
        rcu_assign_pointer(vport->upcall_portids, vport_portids);
 
        if (old)
-               call_rcu(&old->rcu, vport_portids_destroy_rcu_cb);
+               kfree_rcu(old, rcu);
        return 0;
 }
 
@@ -532,6 +525,25 @@ void ovs_vport_deferred_free(struct vport *vport)
 }
 EXPORT_SYMBOL_GPL(ovs_vport_deferred_free);
 
+static struct rtable *ovs_tunnel_route_lookup(struct net *net,
+                                             const struct ip_tunnel_key *key,
+                                             u32 mark,
+                                             struct flowi4 *fl,
+                                             u8 protocol)
+{
+       struct rtable *rt;
+
+       memset(fl, 0, sizeof(*fl));
+       fl->daddr = key->u.ipv4.dst;
+       fl->saddr = key->u.ipv4.src;
+       fl->flowi4_tos = RT_TOS(key->tos);
+       fl->flowi4_mark = mark;
+       fl->flowi4_proto = protocol;
+
+       rt = ip_route_output_key(net, fl);
+       return rt;
+}
+
 int ovs_tunnel_get_egress_info(struct dp_upcall_info *upcall,
                               struct net *net,
                               struct sk_buff *skb,
index 33c3935..6e80493 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/u64_stats_sync.h>
-#include <net/route.h>
 
 #include "datapath.h"
 
@@ -81,7 +80,7 @@ struct vport_portids {
 
 /**
  * struct vport - one port within a datapath
- * @rcu: RCU callback head for deferred destruction.
+ * @dev: Pointer to net_device.
  * @dp: Datapath to which this port belongs.
  * @upcall_portids: RCU protected 'struct vport_portids'.
  * @port_no: Index into @dp's @ports array.
@@ -89,6 +88,7 @@ struct vport_portids {
  * @dp_hash_node: Element in @datapath->ports hash table in datapath.c.
  * @ops: Class structure.
  * @detach_list: list used for detaching vport in net-exit call.
+ * @rcu: RCU callback head for deferred destruction.
  */
 struct vport {
        struct net_device *dev;
@@ -153,9 +153,9 @@ struct vport_ops {
        int (*set_options)(struct vport *, struct nlattr *);
        int (*get_options)(const struct vport *, struct sk_buff *);
 
+       netdev_tx_t (*send)(struct sk_buff *skb);
        int (*get_egress_tun_info)(struct vport *, struct sk_buff *,
                                   struct dp_upcall_info *upcall);
-       netdev_tx_t (*send)(struct sk_buff *skb);
 
        struct module *owner;
        struct list_head list;
@@ -214,31 +214,12 @@ static inline const char *ovs_vport_name(struct vport *vport)
 
 int __ovs_vport_ops_register(struct vport_ops *ops);
 #define ovs_vport_ops_register(ops)            \
-({                                             \
-       (ops)->owner = THIS_MODULE;             \
-       __ovs_vport_ops_register(ops);          \
-})
+       ({                                      \
+               (ops)->owner = THIS_MODULE;     \
+               __ovs_vport_ops_register(ops);  \
+       })
 
 void ovs_vport_ops_unregister(struct vport_ops *ops);
-
-static inline struct rtable *ovs_tunnel_route_lookup(struct net *net,
-                                                    const struct ip_tunnel_key *key,
-                                                    u32 mark,
-                                                    struct flowi4 *fl,
-                                                    u8 protocol)
-{
-       struct rtable *rt;
-
-       memset(fl, 0, sizeof(*fl));
-       fl->daddr = key->u.ipv4.dst;
-       fl->saddr = key->u.ipv4.src;
-       fl->flowi4_tos = RT_TOS(key->tos);
-       fl->flowi4_mark = mark;
-       fl->flowi4_proto = protocol;
-
-       rt = ip_route_output_key(net, fl);
-       return rt;
-}
-
 void ovs_vport_send(struct vport *vport, struct sk_buff *skb);
+
 #endif /* vport.h */