Skip to content

Commit ccea744

Browse files
sflowdavem330
authored andcommitted
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>
1 parent bdef7de commit ccea744

File tree

4 files changed

+37
-10
lines changed

4 files changed

+37
-10
lines changed

include/uapi/linux/openvswitch.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ enum ovs_packet_cmd {
153153
* flow key against the kernel's.
154154
* @OVS_PACKET_ATTR_ACTIONS: Contains actions for the packet. Used
155155
* for %OVS_PACKET_CMD_EXECUTE. It has nested %OVS_ACTION_ATTR_* attributes.
156+
* Also used in upcall when %OVS_ACTION_ATTR_USERSPACE has optional
157+
* %OVS_USERSPACE_ATTR_ACTIONS attribute.
156158
* @OVS_PACKET_ATTR_USERDATA: Present for an %OVS_PACKET_CMD_ACTION
157159
* notification if the %OVS_ACTION_ATTR_USERSPACE action specified an
158160
* %OVS_USERSPACE_ATTR_USERDATA attribute, with the same length and content
@@ -528,13 +530,15 @@ enum ovs_sample_attr {
528530
* copied to the %OVS_PACKET_CMD_ACTION message as %OVS_PACKET_ATTR_USERDATA.
529531
* @OVS_USERSPACE_ATTR_EGRESS_TUN_PORT: If present, u32 output port to get
530532
* tunnel info.
533+
* @OVS_USERSPACE_ATTR_ACTIONS: If present, send actions with upcall.
531534
*/
532535
enum ovs_userspace_attr {
533536
OVS_USERSPACE_ATTR_UNSPEC,
534537
OVS_USERSPACE_ATTR_PID, /* u32 Netlink PID to receive upcalls. */
535538
OVS_USERSPACE_ATTR_USERDATA, /* Optional user-specified cookie. */
536539
OVS_USERSPACE_ATTR_EGRESS_TUN_PORT, /* Optional, u32 output port
537540
* to get tunnel info. */
541+
OVS_USERSPACE_ATTR_ACTIONS, /* Optional flag to get actions. */
538542
__OVS_USERSPACE_ATTR_MAX
539543
};
540544

net/openvswitch/actions.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -608,17 +608,16 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port)
608608
}
609609

610610
static int output_userspace(struct datapath *dp, struct sk_buff *skb,
611-
struct sw_flow_key *key, const struct nlattr *attr)
611+
struct sw_flow_key *key, const struct nlattr *attr,
612+
const struct nlattr *actions, int actions_len)
612613
{
613614
struct ovs_tunnel_info info;
614615
struct dp_upcall_info upcall;
615616
const struct nlattr *a;
616617
int rem;
617618

619+
memset(&upcall, 0, sizeof(upcall));
618620
upcall.cmd = OVS_PACKET_CMD_ACTION;
619-
upcall.userdata = NULL;
620-
upcall.portid = 0;
621-
upcall.egress_tun_info = NULL;
622621

623622
for (a = nla_data(attr), rem = nla_len(attr); rem > 0;
624623
a = nla_next(a, &rem)) {
@@ -647,14 +646,22 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
647646
break;
648647
}
649648

649+
case OVS_USERSPACE_ATTR_ACTIONS: {
650+
/* Include actions. */
651+
upcall.actions = actions;
652+
upcall.actions_len = actions_len;
653+
break;
654+
}
655+
650656
} /* End of switch. */
651657
}
652658

653659
return ovs_dp_upcall(dp, skb, key, &upcall);
654660
}
655661

656662
static int sample(struct datapath *dp, struct sk_buff *skb,
657-
struct sw_flow_key *key, const struct nlattr *attr)
663+
struct sw_flow_key *key, const struct nlattr *attr,
664+
const struct nlattr *actions, int actions_len)
658665
{
659666
const struct nlattr *acts_list = NULL;
660667
const struct nlattr *a;
@@ -688,7 +695,7 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
688695
*/
689696
if (likely(nla_type(a) == OVS_ACTION_ATTR_USERSPACE &&
690697
nla_is_last(a, rem)))
691-
return output_userspace(dp, skb, key, a);
698+
return output_userspace(dp, skb, key, a, actions, actions_len);
692699

693700
skb = skb_clone(skb, GFP_ATOMIC);
694701
if (!skb)
@@ -872,7 +879,7 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
872879
break;
873880

874881
case OVS_ACTION_ATTR_USERSPACE:
875-
output_userspace(dp, skb, key, a);
882+
output_userspace(dp, skb, key, a, attr, len);
876883
break;
877884

878885
case OVS_ACTION_ATTR_HASH:
@@ -916,7 +923,7 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
916923
break;
917924

918925
case OVS_ACTION_ATTR_SAMPLE:
919-
err = sample(dp, skb, key, a);
926+
err = sample(dp, skb, key, a, attr, len);
920927
break;
921928
}
922929

net/openvswitch/datapath.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,10 +272,9 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
272272
struct dp_upcall_info upcall;
273273
int error;
274274

275+
memset(&upcall, 0, sizeof(upcall));
275276
upcall.cmd = OVS_PACKET_CMD_MISS;
276-
upcall.userdata = NULL;
277277
upcall.portid = ovs_vport_find_upcall_portid(p, skb);
278-
upcall.egress_tun_info = NULL;
279278
error = ovs_dp_upcall(dp, skb, key, &upcall);
280279
if (unlikely(error))
281280
kfree_skb(skb);
@@ -397,6 +396,10 @@ static size_t upcall_msg_size(const struct dp_upcall_info *upcall_info,
397396
if (upcall_info->egress_tun_info)
398397
size += nla_total_size(ovs_tun_key_attr_size());
399398

399+
/* OVS_PACKET_ATTR_ACTIONS */
400+
if (upcall_info->actions_len)
401+
size += nla_total_size(upcall_info->actions_len);
402+
400403
return size;
401404
}
402405

@@ -478,6 +481,17 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
478481
nla_nest_end(user_skb, nla);
479482
}
480483

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+
481495
/* Only reserve room for attribute header, packet data is added
482496
* in skb_zerocopy() */
483497
if (!(nla = nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, 0))) {

net/openvswitch/datapath.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ struct ovs_skb_cb {
116116
struct dp_upcall_info {
117117
const struct ovs_tunnel_info *egress_tun_info;
118118
const struct nlattr *userdata;
119+
const struct nlattr *actions;
120+
int actions_len;
119121
u32 portid;
120122
u8 cmd;
121123
};

0 commit comments

Comments
 (0)