aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/datapath.c
diff options
context:
space:
mode:
authorNeil McKee <neil.mckee@inmon.com>2015-05-26 23:59:43 -0400
committerDavid S. Miller <davem@davemloft.net>2015-06-01 18:05:40 -0400
commitccea74457bbdafe33dce8bffcb5cb183aeb5f2bb (patch)
treeb8c195485a704d7360a59f6a42c02f820c2c4a46 /net/openvswitch/datapath.c
parentbdef7de4b8d9be4cf7bf5aea977f827310ab3ff0 (diff)
openvswitch: include datapath actions with sampled-packet upcall to userspace
If new optional attribute OVS_USERSPACE_ATTR_ACTIONS is added to an OVS_ACTION_ATTR_USERSPACE action, then include the datapath actions in the upcall. This Directly associates the sampled packet with the path it takes through the virtual switch. Path information currently includes mangling, encapsulation and decapsulation actions for tunneling protocols GRE, VXLAN, Geneve, MPLS and QinQ, but this extension requires no further changes to accommodate datapath actions that may be added in the future. Adding path information enhances visibility into complex virtual networks. Signed-off-by: Neil McKee <neil.mckee@inmon.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r--net/openvswitch/datapath.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 3b90461317ec..ff8c4a4c1609 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -272,10 +272,9 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
272 struct dp_upcall_info upcall; 272 struct dp_upcall_info upcall;
273 int error; 273 int error;
274 274
275 memset(&upcall, 0, sizeof(upcall));
275 upcall.cmd = OVS_PACKET_CMD_MISS; 276 upcall.cmd = OVS_PACKET_CMD_MISS;
276 upcall.userdata = NULL;
277 upcall.portid = ovs_vport_find_upcall_portid(p, skb); 277 upcall.portid = ovs_vport_find_upcall_portid(p, skb);
278 upcall.egress_tun_info = NULL;
279 error = ovs_dp_upcall(dp, skb, key, &upcall); 278 error = ovs_dp_upcall(dp, skb, key, &upcall);
280 if (unlikely(error)) 279 if (unlikely(error))
281 kfree_skb(skb); 280 kfree_skb(skb);
@@ -397,6 +396,10 @@ static size_t upcall_msg_size(const struct dp_upcall_info *upcall_info,
397 if (upcall_info->egress_tun_info) 396 if (upcall_info->egress_tun_info)
398 size += nla_total_size(ovs_tun_key_attr_size()); 397 size += nla_total_size(ovs_tun_key_attr_size());
399 398
399 /* OVS_PACKET_ATTR_ACTIONS */
400 if (upcall_info->actions_len)
401 size += nla_total_size(upcall_info->actions_len);
402
400 return size; 403 return size;
401} 404}
402 405
@@ -478,6 +481,17 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
478 nla_nest_end(user_skb, nla); 481 nla_nest_end(user_skb, nla);
479 } 482 }
480 483
484 if (upcall_info->actions_len) {
485 nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_ACTIONS);
486 err = ovs_nla_put_actions(upcall_info->actions,
487 upcall_info->actions_len,
488 user_skb);
489 if (!err)
490 nla_nest_end(user_skb, nla);
491 else
492 nla_nest_cancel(user_skb, nla);
493 }
494
481 /* Only reserve room for attribute header, packet data is added 495 /* Only reserve room for attribute header, packet data is added
482 * in skb_zerocopy() */ 496 * in skb_zerocopy() */
483 if (!(nla = nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, 0))) { 497 if (!(nla = nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, 0))) {