aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/datapath.c
diff options
context:
space:
mode:
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