aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-11-04 16:25:04 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-04 16:25:04 -0500
commit6fcf018ae4491dc11b080892fa9f3dbd928fdbb9 (patch)
treef28592676e295183581d59149fd1eac913b229a2
parent5a6e55c461db3364aa5be919101db972bc859133 (diff)
parent8ddd094675cfd453fc9838caa46ea108a4107183 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jesse/openvswitch
Jesse Gross says: ==================== Open vSwitch A set of updates for net-next/3.13. Major changes are: * Restructure flow handling code to be more logically organized and easier to read. * Rehashing of the flow table is moved from a workqueue to flow installation time. Before, heavy load could block the workqueue for excessive periods of time. * Additional debugging information is provided to help diagnose megaflows. * It's now possible to match on TCP flags. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/uapi/linux/openvswitch.h18
-rw-r--r--net/openvswitch/Makefile2
-rw-r--r--net/openvswitch/datapath.c668
-rw-r--r--net/openvswitch/datapath.h9
-rw-r--r--net/openvswitch/flow.c1605
-rw-r--r--net/openvswitch/flow.h132
-rw-r--r--net/openvswitch/flow_netlink.c1630
-rw-r--r--net/openvswitch/flow_netlink.h60
-rw-r--r--net/openvswitch/flow_table.c592
-rw-r--r--net/openvswitch/flow_table.h81
-rw-r--r--net/openvswitch/vport-gre.c2
-rw-r--r--net/openvswitch/vport-internal_dev.c2
-rw-r--r--net/openvswitch/vport-vxlan.c1
13 files changed, 2511 insertions, 2291 deletions
diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h
index a74d375b439b..d120f9fe0017 100644
--- a/include/uapi/linux/openvswitch.h
+++ b/include/uapi/linux/openvswitch.h
@@ -63,15 +63,18 @@ enum ovs_datapath_cmd {
63 * not be sent. 63 * not be sent.
64 * @OVS_DP_ATTR_STATS: Statistics about packets that have passed through the 64 * @OVS_DP_ATTR_STATS: Statistics about packets that have passed through the
65 * datapath. Always present in notifications. 65 * datapath. Always present in notifications.
66 * @OVS_DP_ATTR_MEGAFLOW_STATS: Statistics about mega flow masks usage for the
67 * datapath. Always present in notifications.
66 * 68 *
67 * These attributes follow the &struct ovs_header within the Generic Netlink 69 * These attributes follow the &struct ovs_header within the Generic Netlink
68 * payload for %OVS_DP_* commands. 70 * payload for %OVS_DP_* commands.
69 */ 71 */
70enum ovs_datapath_attr { 72enum ovs_datapath_attr {
71 OVS_DP_ATTR_UNSPEC, 73 OVS_DP_ATTR_UNSPEC,
72 OVS_DP_ATTR_NAME, /* name of dp_ifindex netdev */ 74 OVS_DP_ATTR_NAME, /* name of dp_ifindex netdev */
73 OVS_DP_ATTR_UPCALL_PID, /* Netlink PID to receive upcalls */ 75 OVS_DP_ATTR_UPCALL_PID, /* Netlink PID to receive upcalls */
74 OVS_DP_ATTR_STATS, /* struct ovs_dp_stats */ 76 OVS_DP_ATTR_STATS, /* struct ovs_dp_stats */
77 OVS_DP_ATTR_MEGAFLOW_STATS, /* struct ovs_dp_megaflow_stats */
75 __OVS_DP_ATTR_MAX 78 __OVS_DP_ATTR_MAX
76}; 79};
77 80
@@ -84,6 +87,14 @@ struct ovs_dp_stats {
84 __u64 n_flows; /* Number of flows present */ 87 __u64 n_flows; /* Number of flows present */
85}; 88};
86 89
90struct ovs_dp_megaflow_stats {
91 __u64 n_mask_hit; /* Number of masks used for flow lookups. */
92 __u32 n_masks; /* Number of masks for the datapath. */
93 __u32 pad0; /* Pad for future expension. */
94 __u64 pad1; /* Pad for future expension. */
95 __u64 pad2; /* Pad for future expension. */
96};
97
87struct ovs_vport_stats { 98struct ovs_vport_stats {
88 __u64 rx_packets; /* total packets received */ 99 __u64 rx_packets; /* total packets received */
89 __u64 tx_packets; /* total packets transmitted */ 100 __u64 tx_packets; /* total packets transmitted */
@@ -260,6 +271,7 @@ enum ovs_key_attr {
260 OVS_KEY_ATTR_SKB_MARK, /* u32 skb mark */ 271 OVS_KEY_ATTR_SKB_MARK, /* u32 skb mark */
261 OVS_KEY_ATTR_TUNNEL, /* Nested set of ovs_tunnel attributes */ 272 OVS_KEY_ATTR_TUNNEL, /* Nested set of ovs_tunnel attributes */
262 OVS_KEY_ATTR_SCTP, /* struct ovs_key_sctp */ 273 OVS_KEY_ATTR_SCTP, /* struct ovs_key_sctp */
274 OVS_KEY_ATTR_TCP_FLAGS, /* be16 TCP flags. */
263 275
264#ifdef __KERNEL__ 276#ifdef __KERNEL__
265 OVS_KEY_ATTR_IPV4_TUNNEL, /* struct ovs_key_ipv4_tunnel */ 277 OVS_KEY_ATTR_IPV4_TUNNEL, /* struct ovs_key_ipv4_tunnel */
diff --git a/net/openvswitch/Makefile b/net/openvswitch/Makefile
index ea36e99089af..3591cb5dae91 100644
--- a/net/openvswitch/Makefile
+++ b/net/openvswitch/Makefile
@@ -9,6 +9,8 @@ openvswitch-y := \
9 datapath.o \ 9 datapath.o \
10 dp_notify.o \ 10 dp_notify.o \
11 flow.o \ 11 flow.o \
12 flow_netlink.o \
13 flow_table.o \
12 vport.o \ 14 vport.o \
13 vport-internal_dev.o \ 15 vport-internal_dev.o \
14 vport-netdev.o 16 vport-netdev.o
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 2aa13bd7f2b2..1408adc2a2a7 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -55,14 +55,10 @@
55 55
56#include "datapath.h" 56#include "datapath.h"
57#include "flow.h" 57#include "flow.h"
58#include "flow_netlink.h"
58#include "vport-internal_dev.h" 59#include "vport-internal_dev.h"
59#include "vport-netdev.h" 60#include "vport-netdev.h"
60 61
61
62#define REHASH_FLOW_INTERVAL (10 * 60 * HZ)
63static void rehash_flow_table(struct work_struct *work);
64static DECLARE_DELAYED_WORK(rehash_flow_wq, rehash_flow_table);
65
66int ovs_net_id __read_mostly; 62int ovs_net_id __read_mostly;
67 63
68static void ovs_notify(struct sk_buff *skb, struct genl_info *info, 64static void ovs_notify(struct sk_buff *skb, struct genl_info *info,
@@ -165,7 +161,7 @@ static void destroy_dp_rcu(struct rcu_head *rcu)
165{ 161{
166 struct datapath *dp = container_of(rcu, struct datapath, rcu); 162 struct datapath *dp = container_of(rcu, struct datapath, rcu);
167 163
168 ovs_flow_tbl_destroy((__force struct flow_table *)dp->table, false); 164 ovs_flow_tbl_destroy(&dp->table);
169 free_percpu(dp->stats_percpu); 165 free_percpu(dp->stats_percpu);
170 release_net(ovs_dp_get_net(dp)); 166 release_net(ovs_dp_get_net(dp));
171 kfree(dp->ports); 167 kfree(dp->ports);
@@ -225,6 +221,7 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
225 struct dp_stats_percpu *stats; 221 struct dp_stats_percpu *stats;
226 struct sw_flow_key key; 222 struct sw_flow_key key;
227 u64 *stats_counter; 223 u64 *stats_counter;
224 u32 n_mask_hit;
228 int error; 225 int error;
229 226
230 stats = this_cpu_ptr(dp->stats_percpu); 227 stats = this_cpu_ptr(dp->stats_percpu);
@@ -237,7 +234,7 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
237 } 234 }
238 235
239 /* Look up flow. */ 236 /* Look up flow. */
240 flow = ovs_flow_lookup(rcu_dereference(dp->table), &key); 237 flow = ovs_flow_tbl_lookup(&dp->table, &key, &n_mask_hit);
241 if (unlikely(!flow)) { 238 if (unlikely(!flow)) {
242 struct dp_upcall_info upcall; 239 struct dp_upcall_info upcall;
243 240
@@ -262,6 +259,7 @@ out:
262 /* Update datapath statistics. */ 259 /* Update datapath statistics. */
263 u64_stats_update_begin(&stats->sync); 260 u64_stats_update_begin(&stats->sync);
264 (*stats_counter)++; 261 (*stats_counter)++;
262 stats->n_mask_hit += n_mask_hit;
265 u64_stats_update_end(&stats->sync); 263 u64_stats_update_end(&stats->sync);
266} 264}
267 265
@@ -435,7 +433,7 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex,
435 upcall->dp_ifindex = dp_ifindex; 433 upcall->dp_ifindex = dp_ifindex;
436 434
437 nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY); 435 nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_KEY);
438 ovs_flow_to_nlattrs(upcall_info->key, upcall_info->key, user_skb); 436 ovs_nla_put_flow(upcall_info->key, upcall_info->key, user_skb);
439 nla_nest_end(user_skb, nla); 437 nla_nest_end(user_skb, nla);
440 438
441 if (upcall_info->userdata) 439 if (upcall_info->userdata)
@@ -455,398 +453,6 @@ out:
455 return err; 453 return err;
456} 454}
457 455
458/* Called with ovs_mutex. */
459static int flush_flows(struct datapath *dp)
460{
461 struct flow_table *old_table;
462 struct flow_table *new_table;
463
464 old_table = ovsl_dereference(dp->table);
465 new_table = ovs_flow_tbl_alloc(TBL_MIN_BUCKETS);
466 if (!new_table)
467 return -ENOMEM;
468
469 rcu_assign_pointer(dp->table, new_table);
470
471 ovs_flow_tbl_destroy(old_table, true);
472 return 0;
473}
474
475static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa, int attr_len)