2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-01 14:55:18 +00:00

datapath: Add support for kernel 3.14.

Signed-off-by: Pritesh Kothari <pritesh.kothari@cisco.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
This commit is contained in:
Pritesh Kothari
2014-05-01 15:50:48 -07:00
committed by Jesse Gross
parent ca93abce9d
commit e2f3178f05
18 changed files with 78 additions and 59 deletions

2
FAQ
View File

@@ -149,7 +149,7 @@ A: The following table lists the Linux kernel versions against which the
1.11.x 2.6.18 to 3.8
2.0.x 2.6.32 to 3.10
2.1.x 2.6.32 to 3.11
2.2.x 2.6.32 to 3.13
2.2.x 2.6.32 to 3.14
Open vSwitch userspace should also work with the Linux kernel module
built into Linux 3.3 and later.

2
NEWS
View File

@@ -27,7 +27,7 @@ v2.2.0 - xx xxx xxx
- Upon the receipt of a SIGHUP signal, ovs-vswitchd no longer reopens its
log file (it will terminate instead). Please use 'ovs-appctl vlog/reopen'
instead.
- Support for Linux kernels up to 3.13. From Kernel 3.12 onwards OVS uses
- Support for Linux kernels up to 3.14. From Kernel 3.12 onwards OVS uses
tunnel API for GRE and VXLAN.
- Added DPDK support.
- Added support for custom vlog patterns in Python

View File

@@ -134,10 +134,10 @@ AC_DEFUN([OVS_CHECK_LINUX], [
AC_MSG_RESULT([$kversion])
if test "$version" -ge 3; then
if test "$version" = 3 && test "$patchlevel" -le 13; then
if test "$version" = 3 && test "$patchlevel" -le 14; then
: # Linux 3.x
else
AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version newer than 3.13.x is not supported (please refer to the FAQ for advice)])
AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version newer than 3.14.x is not supported (please refer to the FAQ for advice)])
fi
else
if test "$version" -le 1 || test "$patchlevel" -le 5 || test "$sublevel" -le 31; then
@@ -244,6 +244,7 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
OVS_GREP_IFELSE([$KSRC/include/linux/err.h], [ERR_CAST])
OVS_GREP_IFELSE([$KSRC/include/linux/etherdevice.h], [eth_hw_addr_random])
OVS_GREP_IFELSE([$KSRC/include/linux/etherdevice.h], [ether_addr_copy])
OVS_GREP_IFELSE([$KSRC/include/linux/if_vlan.h], [vlan_set_encap_proto])
@@ -255,6 +256,9 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [__skb_gso_segment])
OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [can_checksum_protocol])
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/random.h], [prandom_u32])
OVS_GREP_IFELSE([$KSRC/include/linux/rcupdate.h], [rcu_read_lock_held], [],
[OVS_GREP_IFELSE([$KSRC/include/linux/rtnetlink.h],
@@ -289,6 +293,8 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_reset_mac_len])
OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_unclone])
OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_orphan_frags])
OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_get_hash])
OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_clear_hash])
OVS_GREP_IFELSE([$KSRC/include/linux/types.h], [bool],
[OVS_DEFINE([HAVE_BOOL_TYPE])])

View File

@@ -166,7 +166,7 @@ static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh,
}
csum_replace4(&nh->check, *addr, new_addr);
skb_clear_rxhash(skb);
skb_clear_hash(skb);
*addr = new_addr;
}
@@ -200,7 +200,7 @@ static void set_ipv6_addr(struct sk_buff *skb, u8 l4_proto,
if (recalculate_csum)
update_ipv6_checksum(skb, l4_proto, addr, new_addr);
skb_clear_rxhash(skb);
skb_clear_hash(skb);
memcpy(addr, new_addr, sizeof(__be32[4]));
}
@@ -297,7 +297,7 @@ static void set_tp_port(struct sk_buff *skb, __be16 *port,
{
inet_proto_csum_replace2(check, skb, *port, new_port, 0);
*port = new_port;
skb_clear_rxhash(skb);
skb_clear_hash(skb);
}
static void set_udp_port(struct sk_buff *skb, __be16 *port, __be16 new_port)
@@ -311,7 +311,7 @@ static void set_udp_port(struct sk_buff *skb, __be16 *port, __be16 new_port)
uh->check = CSUM_MANGLED_0;
} else {
*port = new_port;
skb_clear_rxhash(skb);
skb_clear_hash(skb);
}
}
@@ -382,7 +382,7 @@ static int set_sctp(struct sk_buff *skb,
/* Carry any checksum errors through. */
sh->checksum = old_csum ^ old_correct_csum ^ new_csum;
skb_clear_rxhash(skb);
skb_clear_hash(skb);
}
return 0;
@@ -446,7 +446,7 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
a = nla_next(a, &rem)) {
switch (nla_type(a)) {
case OVS_SAMPLE_ATTR_PROBABILITY:
if (net_random() >= nla_get_u32(a))
if (prandom_u32() >= nla_get_u32(a))
return 0;
break;
@@ -467,7 +467,7 @@ static void execute_hash(struct sk_buff *skb, const struct nlattr *attr)
u32 hash = 0;
/* OVS_HASH_ALG_L4 is the only possible hash algorithm. */
hash = skb_get_rxhash(skb);
hash = skb_get_hash(skb);
hash = jhash_1word(hash, hash_act->hash_basis);
if (!hash)
hash = 0x1;

View File

@@ -25,13 +25,6 @@
#include <net/route.h>
#include <net/xfrm.h>
static inline void skb_clear_rxhash(struct sk_buff *skb)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
skb->rxhash = 0;
#endif
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)
#define GROUP_ID(grp) 0
#else

View File

@@ -254,7 +254,7 @@ void ovs_dp_process_packet_with_key(struct sk_buff *skb,
stats = this_cpu_ptr(dp->stats_percpu);
/* Look up flow. */
flow = ovs_flow_tbl_lookup_stats(&dp->table, pkt_key, skb_get_rxhash(skb),
flow = ovs_flow_tbl_lookup_stats(&dp->table, pkt_key, skb_get_hash(skb),
&n_mask_hit);
if (unlikely(!flow)) {
struct dp_upcall_info upcall;

View File

@@ -32,7 +32,6 @@ openvswitch_headers += \
linux/compat/include/linux/if.h \
linux/compat/include/linux/if_arp.h \
linux/compat/include/linux/if_ether.h \
linux/compat/include/linux/if_tunnel.h \
linux/compat/include/linux/if_vlan.h \
linux/compat/include/linux/in.h \
linux/compat/include/linux/ip.h \
@@ -43,6 +42,7 @@ openvswitch_headers += \
linux/compat/include/linux/list.h \
linux/compat/include/linux/log2.h \
linux/compat/include/linux/net.h \
linux/compat/include/linux/random.h \
linux/compat/include/linux/netdevice.h \
linux/compat/include/linux/netdev_features.h \
linux/compat/include/linux/netlink.h \

View File

@@ -204,7 +204,7 @@ static __always_inline u32 __flow_hash_3words(u32 a, u32 b, u32 c)
return jhash_3words(a, b, c, hashrnd);
}
u32 __skb_get_rxhash(struct sk_buff *skb)
u32 __skb_get_hash(struct sk_buff *skb)
{
struct flow_keys keys;
u32 hash;

View File

@@ -34,6 +34,7 @@ static inline int eth_mac_addr(struct net_device *dev, void *p)
}
#endif
#ifndef HAVE_ETHER_ADDR_COPY
static inline void ether_addr_copy(u8 *dst, const u8 *src)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
@@ -48,5 +49,6 @@ static inline void ether_addr_copy(u8 *dst, const u8 *src)
a[2] = b[2];
#endif
}
#endif
#endif

View File

@@ -1,20 +0,0 @@
#ifndef _IF_TUNNEL_WRAPPER_H_
#define _IF_TUNNEL_WRAPPER_H_
#include <linux/version.h>
#include_next <linux/if_tunnel.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
#include <linux/u64_stats_sync.h>
struct pcpu_tstats {
u64 rx_packets;
u64 rx_bytes;
u64 tx_packets;
u64 tx_bytes;
struct u64_stats_sync syncp;
};
#endif
#endif /* _IF_TUNNEL_WRAPPER_H_ */

View File

@@ -125,4 +125,17 @@ 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;
};
#endif
#endif

View File

@@ -0,0 +1,10 @@
#ifndef __LINUX_RANDOM_WRAPPER_H
#define __LINUX_RANDOM_WRAPPER_H 1
#include_next <linux/random.h>
#ifndef HAVE_PRANDOM_U32
#define prandom_u32() random32()
#endif
#endif

View File

@@ -250,20 +250,27 @@ static inline int skb_orphan_frags(struct sk_buff *skb, gfp_t gfp_mask)
}
#endif
#ifndef HAVE_SKB_GET_HASH
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
#define __skb_get_rxhash rpl__skb_get_rxhash
#define skb_get_rxhash rpl_skb_get_rxhash
#define __skb_get_hash rpl__skb_get_rxhash
#define skb_get_hash rpl_skb_get_rxhash
extern u32 __skb_get_rxhash(struct sk_buff *skb);
static inline __u32 skb_get_rxhash(struct sk_buff *skb)
extern u32 __skb_get_hash(struct sk_buff *skb);
static inline __u32 skb_get_hash(struct sk_buff *skb)
{
#ifdef HAVE_RXHASH
if (skb->rxhash)
return skb->rxhash;
#endif
return __skb_get_rxhash(skb);
return __skb_get_hash(skb);
}
#else
#define skb_get_hash skb_get_rxhash
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) */
#endif /* HAVE_SKB_GET_HASH */
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
static inline void skb_tx_error(struct sk_buff *skb)
{
return;
@@ -276,6 +283,14 @@ int skb_zerocopy(struct sk_buff *to, struct sk_buff *from, int len,
int hlen);
#endif
#ifndef HAVE_SKB_CLEAR_HASH
static inline void skb_clear_hash(struct sk_buff *skb)
{
#if HAVE_RXHASH
skb->rxhash = 0;
#endif
}
#endif
#ifndef HAVE_SKB_HAS_FRAG_LIST
#define skb_has_frag_list skb_has_frags

View File

@@ -48,7 +48,7 @@ int iptunnel_xmit(struct rtable *rt,
nf_reset(skb);
secpath_reset(skb);
skb_clear_rxhash(skb);
skb_clear_hash(skb);
skb_dst_drop(skb);
skb_dst_set(skb, &rt_dst(rt));
#if 0
@@ -104,7 +104,7 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto)
nf_reset(skb);
secpath_reset(skb);
skb_clear_rxhash(skb);
skb_clear_hash(skb);
skb_dst_drop(skb);
vlan_set_tci(skb, 0);
skb_set_queue_mapping(skb, 0);

View File

@@ -132,7 +132,7 @@ __be16 vxlan_src_port(__u16 port_min, __u16 port_max, struct sk_buff *skb)
unsigned int range = (port_max - port_min) + 1;
u32 hash;
hash = skb_get_rxhash(skb);
hash = skb_get_hash(skb);
if (!hash)
hash = jhash(skb->data, 2 * ETH_ALEN,
(__force u32) skb->protocol);

View File

@@ -165,7 +165,7 @@ static __be64 instance_id_to_tunnel_id(__u8 *iid)
*/
static u16 get_src_port(struct net *net, struct sk_buff *skb)
{
u32 hash = skb_get_rxhash(skb);
u32 hash = skb_get_hash(skb);
unsigned int range;
int high;
int low;

View File

@@ -142,14 +142,14 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops,
if (ovs_vport_set_upcall_portids(vport, parms->upcall_portids))
return ERR_PTR(-EINVAL);
vport->percpu_stats = alloc_percpu(struct pcpu_tstats);
vport->percpu_stats = alloc_percpu(struct pcpu_sw_netstats);
if (!vport->percpu_stats) {
kfree(vport);
return ERR_PTR(-ENOMEM);
}
for_each_possible_cpu(i) {
struct pcpu_tstats *vport_stats;
struct pcpu_sw_netstats *vport_stats;
vport_stats = per_cpu_ptr(vport->percpu_stats, i);
u64_stats_init(&vport_stats->syncp);
}
@@ -302,8 +302,8 @@ void ovs_vport_get_stats(struct vport *vport, struct ovs_vport_stats *stats)
spin_unlock_bh(&vport->stats_lock);
for_each_possible_cpu(i) {
const struct pcpu_tstats *percpu_stats;
struct pcpu_tstats local_stats;
const struct pcpu_sw_netstats *percpu_stats;
struct pcpu_sw_netstats local_stats;
unsigned int start;
percpu_stats = per_cpu_ptr(vport->percpu_stats, i);
@@ -436,7 +436,7 @@ int ovs_vport_get_upcall_portids(const struct vport *vport,
* @vport: vport from which the missed packet is received.
* @skb: skb that the missed packet was received.
*
* Uses the skb_get_rxhash() to select the upcall portid to send the
* Uses the skb_get_hash() to select the upcall portid to send the
* upcall.
*
* Returns the portid of the target socket. Must be called with rcu_read_lock.
@@ -451,7 +451,7 @@ u32 ovs_vport_find_upcall_portid(const struct vport *p, struct sk_buff *skb)
if (ids->n_ids == 1 && ids->ids[0] == 0)
return 0;
hash = skb_get_rxhash(skb);
hash = skb_get_hash(skb);
return ids->ids[hash - ids->n_ids * reciprocal_divide(hash, ids->rn_ids)];
}
@@ -469,7 +469,7 @@ u32 ovs_vport_find_upcall_portid(const struct vport *p, struct sk_buff *skb)
void ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
struct ovs_key_ipv4_tunnel *tun_key)
{
struct pcpu_tstats *stats;
struct pcpu_sw_netstats *stats;
stats = this_cpu_ptr(vport->percpu_stats);
u64_stats_update_begin(&stats->syncp);
@@ -495,7 +495,7 @@ int ovs_vport_send(struct vport *vport, struct sk_buff *skb)
int sent = vport->ops->send(vport, skb);
if (likely(sent > 0)) {
struct pcpu_tstats *stats;
struct pcpu_sw_netstats *stats;
stats = this_cpu_ptr(vport->percpu_stats);

View File

@@ -106,7 +106,7 @@ struct vport {
struct hlist_node dp_hash_node;
const struct vport_ops *ops;
struct pcpu_tstats __percpu *percpu_stats;
struct pcpu_sw_netstats __percpu *percpu_stats;
spinlock_t stats_lock;
struct vport_err_stats err_stats;