aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/datapath.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-02-20 01:50:32 -0500
committerTakashi Iwai <tiwai@suse.de>2014-02-20 01:50:32 -0500
commitf31f40be8f82d5eeb4ca084f9ac0f11ca265876b (patch)
tree6fce9ac78045249084d641945e094dcaea72d265 /net/openvswitch/datapath.c
parent13c12dbe3a2ce17227f7ddef652b6a53c78fa51f (diff)
parent895be5b31e5175bef575008aadb4f0a27b850daa (diff)
Merge tag 'asoc-v3.14-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Fixes for v3.14 A few fixes, all driver speccific ones. The DaVinci ones aren't as clear as they should be from the subject lines on the commits but they fix issues which will prevent correct operation in some use cases and only affect that particular driver so are reasonably safe.
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r--net/openvswitch/datapath.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index df4692826ead..e9a48baf8551 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -55,6 +55,7 @@
55 55
56#include "datapath.h" 56#include "datapath.h"
57#include "flow.h" 57#include "flow.h"
58#include "flow_table.h"
58#include "flow_netlink.h" 59#include "flow_netlink.h"
59#include "vport-internal_dev.h" 60#include "vport-internal_dev.h"
60#include "vport-netdev.h" 61#include "vport-netdev.h"
@@ -160,7 +161,6 @@ static void destroy_dp_rcu(struct rcu_head *rcu)
160{ 161{
161 struct datapath *dp = container_of(rcu, struct datapath, rcu); 162 struct datapath *dp = container_of(rcu, struct datapath, rcu);
162 163
163 ovs_flow_tbl_destroy(&dp->table);
164 free_percpu(dp->stats_percpu); 164 free_percpu(dp->stats_percpu);
165 release_net(ovs_dp_get_net(dp)); 165 release_net(ovs_dp_get_net(dp));
166 kfree(dp->ports); 166 kfree(dp->ports);
@@ -466,6 +466,14 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
466 466
467 skb_zerocopy(user_skb, skb, skb->len, hlen); 467 skb_zerocopy(user_skb, skb, skb->len, hlen);
468 468
469 /* Pad OVS_PACKET_ATTR_PACKET if linear copy was performed */
470 if (!(dp->user_features & OVS_DP_F_UNALIGNED)) {
471 size_t plen = NLA_ALIGN(user_skb->len) - user_skb->len;
472
473 if (plen > 0)
474 memset(skb_put(user_skb, plen), 0, plen);
475 }
476
469 ((struct nlmsghdr *) user_skb->data)->nlmsg_len = user_skb->len; 477 ((struct nlmsghdr *) user_skb->data)->nlmsg_len = user_skb->len;
470 478
471 err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid); 479 err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid);
@@ -852,11 +860,8 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
852 goto err_unlock_ovs; 860 goto err_unlock_ovs;
853 861
854 /* The unmasked key has to be the same for flow updates. */ 862 /* The unmasked key has to be the same for flow updates. */
855 error = -EINVAL; 863 if (!ovs_flow_cmp_unmasked_key(flow, &match))
856 if (!ovs_flow_cmp_unmasked_key(flow, &match)) {
857 OVS_NLERR("Flow modification message rejected, unmasked key does not match.\n");
858 goto err_unlock_ovs; 864 goto err_unlock_ovs;
859 }
860 865
861 /* Update actions. */ 866 /* Update actions. */
862 old_acts = ovsl_dereference(flow->sf_acts); 867 old_acts = ovsl_dereference(flow->sf_acts);
@@ -1079,6 +1084,7 @@ static size_t ovs_dp_cmd_msg_size(void)
1079 msgsize += nla_total_size(IFNAMSIZ); 1084 msgsize += nla_total_size(IFNAMSIZ);
1080 msgsize += nla_total_size(sizeof(struct ovs_dp_stats)); 1085 msgsize += nla_total_size(sizeof(struct ovs_dp_stats));
1081 msgsize += nla_total_size(sizeof(struct ovs_dp_megaflow_stats)); 1086 msgsize += nla_total_size(sizeof(struct ovs_dp_megaflow_stats));
1087 msgsize += nla_total_size(sizeof(u32)); /* OVS_DP_ATTR_USER_FEATURES */
1082 1088
1083 return msgsize; 1089 return msgsize;
1084} 1090}
@@ -1279,7 +1285,7 @@ err_destroy_ports_array:
1279err_destroy_percpu: 1285err_destroy_percpu:
1280 free_percpu(dp->stats_percpu); 1286 free_percpu(dp->stats_percpu);
1281err_destroy_table: 1287err_destroy_table:
1282 ovs_flow_tbl_destroy(&dp->table); 1288 ovs_flow_tbl_destroy(&dp->table, false);
1283err_free_dp: 1289err_free_dp:
1284 release_net(ovs_dp_get_net(dp)); 1290 release_net(ovs_dp_get_net(dp));
1285 kfree(dp); 1291 kfree(dp);
@@ -1306,10 +1312,13 @@ static void __dp_destroy(struct datapath *dp)
1306 list_del_rcu(&dp->list_node); 1312 list_del_rcu(&dp->list_node);
1307 1313
1308 /* OVSP_LOCAL is datapath internal port. We need to make sure that 1314 /* OVSP_LOCAL is datapath internal port. We need to make sure that
1309 * all port in datapath are destroyed first before freeing datapath. 1315 * all ports in datapath are destroyed first before freeing datapath.
1310 */ 1316 */
1311 ovs_dp_detach_port(ovs_vport_ovsl(dp, OVSP_LOCAL)); 1317 ovs_dp_detach_port(ovs_vport_ovsl(dp, OVSP_LOCAL));
1312 1318
1319 /* RCU destroy the flow table */
1320 ovs_flow_tbl_destroy(&dp->table, true);
1321
1313 call_rcu(&dp->rcu, destroy_dp_rcu); 1322 call_rcu(&dp->rcu, destroy_dp_rcu);
1314} 1323}
1315 1324