Signed-off-by: Jarno Rajahalme <[email protected]>
---
datapath/datapath.c | 75 ++++++++++++++++++++++++++-------------------------
1 file changed, 39 insertions(+), 36 deletions(-)
diff --git a/datapath/datapath.c b/datapath/datapath.c
index 452b889..cbdd68f 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -655,7 +655,7 @@ static size_t ovs_flow_cmd_msg_size(const struct
sw_flow_actions *acts)
}
/* Called with ovs_mutex or RCU read lock. */
-static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
+static int ovs_flow_cmd_fill_info(struct sw_flow *flow, int dp_ifindex,
struct sk_buff *skb, u32 portid,
u32 seq, u32 flags, u8 cmd)
{
@@ -672,7 +672,7 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow,
struct datapath *dp,
if (!ovs_header)
return -EMSGSIZE;
- ovs_header->dp_ifindex = get_dpifindex(dp);
+ ovs_header->dp_ifindex = dp_ifindex;
/* Fill flow key. */
nla = nla_nest_start(skb, OVS_FLOW_ATTR_KEY);
@@ -758,9 +758,8 @@ static struct sk_buff *ovs_flow_cmd_alloc_info(struct
sw_flow *flow,
/* Must be called with ovs_mutex. */
static struct sk_buff *ovs_flow_cmd_build_info(struct sw_flow *flow,
- struct datapath *dp,
- struct genl_info *info,
- u8 cmd)
+ int dp_ifindex,
+ struct genl_info *info, u8 cmd)
{
struct sk_buff *skb;
int retval;
@@ -769,8 +768,9 @@ static struct sk_buff *ovs_flow_cmd_build_info(struct
sw_flow *flow,
if (!skb)
return ERR_PTR(-ENOMEM);
- retval = ovs_flow_cmd_fill_info(flow, dp, skb, info->snd_portid,
- info->snd_seq, 0, cmd);
+ retval = ovs_flow_cmd_fill_info(flow, dp_ifindex, skb,
+ info->snd_portid, info->snd_seq, 0,
+ cmd);
BUG_ON(retval < 0);
return skb;
}
@@ -857,7 +857,8 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb,
struct genl_info *info)
goto err_flow_free;
}
- reply = ovs_flow_cmd_build_info(flow, dp, info,
OVS_FLOW_CMD_NEW);
+ reply = ovs_flow_cmd_build_info(flow, ovs_header->dp_ifindex,
+ info, OVS_FLOW_CMD_NEW);
} else {
/* We found a matching flow. */
struct sw_flow_actions *old_acts;
@@ -882,8 +883,8 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb,
struct genl_info *info)
rcu_assign_pointer(flow->sf_acts, acts);
ovs_nla_free_flow_actions(old_acts);
- reply = ovs_flow_cmd_build_info(flow, dp, info,
OVS_FLOW_CMD_NEW);
-
+ reply = ovs_flow_cmd_build_info(flow, ovs_header->dp_ifindex,
+ info, OVS_FLOW_CMD_NEW);
/* Clear stats. */
if (a[OVS_FLOW_ATTR_CLEAR])
ovs_flow_stats_clear(flow);
@@ -941,7 +942,8 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct
genl_info *info)
goto unlock;
}
- reply = ovs_flow_cmd_build_info(flow, dp, info, OVS_FLOW_CMD_NEW);
+ reply = ovs_flow_cmd_build_info(flow, ovs_header->dp_ifindex, info,
+ OVS_FLOW_CMD_NEW);
if (IS_ERR(reply)) {
err = PTR_ERR(reply);
goto unlock;
@@ -965,47 +967,48 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct
genl_info *info)
struct sw_flow_match match;
int err;
+ if (a[OVS_FLOW_ATTR_KEY]) {
+ ovs_match_init(&match, &key, NULL);
+ err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL);
+ if (err)
+ return err;
+ }
+
ovs_lock();
dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
if (!dp) {
err = -ENODEV;
- goto unlock;
+ goto ovs_unlock;
}
-
if (!a[OVS_FLOW_ATTR_KEY]) {
err = ovs_flow_tbl_flush(&dp->table);
- goto unlock;
+ /* No reply in this case, so any existing stats are lost. */
+ goto ovs_unlock;
}
-
- ovs_match_init(&match, &key, NULL);
- err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL);
- if (err)
- goto unlock;
-
flow = ovs_flow_tbl_lookup(&dp->table, &key);
if (!flow || !ovs_flow_cmp_unmasked_key(flow, &match)) {
err = -ENOENT;
- goto unlock;
+ goto ovs_unlock;
}
+ ovs_flow_tbl_remove(&dp->table, flow);
+ ovs_unlock();
reply = ovs_flow_cmd_alloc_info(flow, info);
- if (!reply) {
- err = -ENOMEM;
- goto unlock;
+ /* XXX: We may skip sending a response if kernel is out of memory.
+ * We could do the allocation before locking if we did not need
+ * to return the actions (which are useless in this case anyway). */
+ if (reply) {
+ err = ovs_flow_cmd_fill_info(flow, ovs_header->dp_ifindex,
+ reply, info->snd_portid,
+ info->snd_seq, 0,
+ OVS_FLOW_CMD_DEL);
+ BUG_ON(err < 0);
+ ovs_notify(reply, info, &ovs_dp_flow_multicast_group);
}
-
- ovs_flow_tbl_remove(&dp->table, flow);
-
- err = ovs_flow_cmd_fill_info(flow, dp, reply, info->snd_portid,
- info->snd_seq, 0, OVS_FLOW_CMD_DEL);
- BUG_ON(err < 0);
-
ovs_flow_free(flow, true);
- ovs_unlock();
-
- ovs_notify(reply, info, &ovs_dp_flow_multicast_group);
return 0;
-unlock:
+
+ovs_unlock:
ovs_unlock();
return err;
}
@@ -1034,7 +1037,7 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct
netlink_callback *cb)
if (!flow)
break;
- if (ovs_flow_cmd_fill_info(flow, dp, skb,
+ if (ovs_flow_cmd_fill_info(flow, ovs_header->dp_ifindex, skb,
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, NLM_F_MULTI,
OVS_FLOW_CMD_NEW) < 0)
--
1.7.10.4
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev