X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=datapath%2Fdatapath.c;h=c756e2f5c436e000761e84c931251a45a2d76ee0;hb=1e827902be9194d71ea851c9ce2676f65eeed33a;hp=b42fd8bd4ab1ed0cfd98c3862cbc30ab32ec9800;hpb=1d04cd4e722c63e8d5564c6c993b04a891f1e867;p=sliver-openvswitch.git diff --git a/datapath/datapath.c b/datapath/datapath.c index b42fd8bd4..c756e2f5c 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -56,6 +56,7 @@ #include "datapath.h" #include "flow.h" +#include "flow_table.h" #include "flow_netlink.h" #include "vlan.h" #include "vport-internal_dev.h" @@ -162,7 +163,6 @@ static void destroy_dp_rcu(struct rcu_head *rcu) { struct datapath *dp = container_of(rcu, struct datapath, rcu); - ovs_flow_tbl_destroy(&dp->table); free_percpu(dp->stats_percpu); release_net(ovs_dp_get_net(dp)); kfree(dp->ports); @@ -400,7 +400,7 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, #endif .snd_portid = upcall_info->portid, }; - size_t len; + size_t len, plen; unsigned int hlen; int err, dp_ifindex; @@ -471,6 +471,11 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, skb_zerocopy(user_skb, skb, skb->len, hlen); + /* Pad OVS_PACKET_ATTR_PACKET if linear copy was performed */ + if (!(dp->user_features & OVS_DP_F_UNALIGNED) && + (plen = (ALIGN(user_skb->len, NLA_ALIGNTO) - user_skb->len)) > 0) + memset(skb_put(user_skb, plen), 0, plen); + ((struct nlmsghdr *) user_skb->data)->nlmsg_len = user_skb->len; err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid); @@ -1278,7 +1283,7 @@ err_destroy_ports_array: err_destroy_percpu: free_percpu(dp->stats_percpu); err_destroy_table: - ovs_flow_tbl_destroy(&dp->table); + ovs_flow_tbl_destroy(&dp->table, false); err_free_dp: release_net(ovs_dp_get_net(dp)); kfree(dp); @@ -1305,10 +1310,13 @@ static void __dp_destroy(struct datapath *dp) list_del_rcu(&dp->list_node); /* OVSP_LOCAL is datapath internal port. We need to make sure that - * all port in datapath are destroyed first before freeing datapath. - */ + * all ports in datapath are destroyed first before freeing datapath. + */ ovs_dp_detach_port(ovs_vport_ovsl(dp, OVSP_LOCAL)); + /* RCU destroy the flow table */ + ovs_flow_tbl_destroy(&dp->table, true); + call_rcu(&dp->rcu, destroy_dp_rcu); }