diff options
| author | David S. Miller <davem@davemloft.net> | 2013-11-04 16:25:04 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2013-11-04 16:25:04 -0500 |
| commit | 6fcf018ae4491dc11b080892fa9f3dbd928fdbb9 (patch) | |
| tree | f28592676e295183581d59149fd1eac913b229a2 | |
| parent | 5a6e55c461db3364aa5be919101db972bc859133 (diff) | |
| parent | 8ddd094675cfd453fc9838caa46ea108a4107183 (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.h | 18 | ||||
| -rw-r--r-- | net/openvswitch/Makefile | 2 | ||||
| -rw-r--r-- | net/openvswitch/datapath.c | 668 | ||||
| -rw-r--r-- | net/openvswitch/datapath.h | 9 | ||||
| -rw-r--r-- | net/openvswitch/flow.c | 1605 | ||||
| -rw-r--r-- | net/openvswitch/flow.h | 132 | ||||
| -rw-r--r-- | net/openvswitch/flow_netlink.c | 1630 | ||||
| -rw-r--r-- | net/openvswitch/flow_netlink.h | 60 | ||||
| -rw-r--r-- | net/openvswitch/flow_table.c | 592 | ||||
| -rw-r--r-- | net/openvswitch/flow_table.h | 81 | ||||
| -rw-r--r-- | net/openvswitch/vport-gre.c | 2 | ||||
| -rw-r--r-- | net/openvswitch/vport-internal_dev.c | 2 | ||||
| -rw-r--r-- | net/openvswitch/vport-vxlan.c | 1 |
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 | */ |
| 70 | enum ovs_datapath_attr { | 72 | enum 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 | ||
| 90 | struct 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 | |||
| 87 | struct ovs_vport_stats { | 98 | struct 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) | ||
| 63 | static void rehash_flow_table(struct work_struct *work); | ||
| 64 | static DECLARE_DELAYED_WORK(rehash_flow_wq, rehash_flow_table); | ||
| 65 | |||
| 66 | int ovs_net_id __read_mostly; | 62 | int ovs_net_id __read_mostly; |
| 67 | 63 | ||
| 68 | static void ovs_notify(struct sk_buff *skb, struct genl_info *info, | 64 | static 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. */ | ||
| 459 | static 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 | |||
| 475 | static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa, int attr_len) | ||
