diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c index fb7589fda..60e1b4e0a 100644 --- a/ofproto/ofproto-dpif-sflow.c +++ b/ofproto/ofproto-dpif-sflow.c @@ -961,7 +961,7 @@ sflow_read_set_action(const struct nlattr *attr, } else { dpif_sflow_read_actions(NULL, nl_attr_get(attr), nl_attr_get_size(attr), - sflow_actions); + sflow_actions, true); } break; case OVS_KEY_ATTR_PRIORITY: @@ -1088,8 +1088,9 @@ dpif_sflow_capture_input_mpls(const struct flow *flow, void dpif_sflow_read_actions(const struct flow *flow, - const struct nlattr *actions, size_t actions_len, - struct dpif_sflow_actions *sflow_actions) + const struct nlattr *actions, size_t actions_len, + struct dpif_sflow_actions *sflow_actions, + bool capture_mpls) { const struct nlattr *a; unsigned int left; @@ -1099,7 +1100,7 @@ dpif_sflow_read_actions(const struct flow *flow, return; } - if (flow != NULL) { + if (flow != NULL && capture_mpls == true) { /* Make sure the MPLS output stack * is seeded with the input stack. */ @@ -1198,8 +1199,13 @@ dpif_sflow_read_actions(const struct flow *flow, * structure to report this. */ break; + case OVS_ACTION_ATTR_CLONE: + if (flow != NULL) { + dpif_sflow_read_actions(flow, nl_attr_get(a), nl_attr_get_size(a), + sflow_actions, false); + } + break; case OVS_ACTION_ATTR_SAMPLE: - case OVS_ACTION_ATTR_CLONE: case OVS_ACTION_ATTR_PUSH_NSH: case OVS_ACTION_ATTR_POP_NSH: case OVS_ACTION_ATTR_UNSPEC: diff --git a/ofproto/ofproto-dpif-sflow.h b/ofproto/ofproto-dpif-sflow.h index 74fe58007..c5d9b8aad 100644 --- a/ofproto/ofproto-dpif-sflow.h +++ b/ofproto/ofproto-dpif-sflow.h @@ -71,7 +71,7 @@ void dpif_sflow_wait(struct dpif_sflow *); void dpif_sflow_read_actions(const struct flow *, const struct nlattr *actions, size_t actions_len, - struct dpif_sflow_actions *); + struct dpif_sflow_actions *, bool capture_mpls); void dpif_sflow_received(struct dpif_sflow *, const struct dp_packet *, const struct flow *, odp_port_t odp_port, diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index cb5018d99..5ddf08a75 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -1330,7 +1330,7 @@ dpif_read_actions(struct udpif *udpif, struct upcall *upcall, switch (type) { case SFLOW_UPCALL: - dpif_sflow_read_actions(flow, actions, actions_len, upcall_data); + dpif_sflow_read_actions(flow, actions, actions_len, upcall_data, true); break; case FLOW_SAMPLE_UPCALL: case IPFIX_UPCALL: diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index aee18bf33..b85bcacae 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -3264,6 +3264,9 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport, char buf_sip6[INET6_ADDRSTRLEN]; char buf_dip6[INET6_ADDRSTRLEN]; + /* Store sFlow data. */ + uint32_t sflow_n_outputs = ctx->sflow_n_outputs; + /* Structures to backup Ethernet and IP of base_flow. */ struct flow old_base_flow; struct flow old_flow; @@ -3415,6 +3418,10 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport, /* Restore the flows after the translation. */ memcpy(&ctx->xin->flow, &old_flow, sizeof ctx->xin->flow); memcpy(&ctx->base_flow, &old_base_flow, sizeof ctx->base_flow); + + /* Restore sFlow data. */ + ctx->sflow_n_outputs = sflow_n_outputs; + return 0; } diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index a582aaf39..1945d222e 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -6336,7 +6336,7 @@ AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 br0], [0], [OK AT_CHECK([ovs-ofctl add-flow br0 action=normal]) dnl Prime ARP Cache for 1.1.2.92 -AT_CHECK([ovs-appctl netdev-dummy/receive br0 'recirc_id(0),in_port(100),eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00)']) +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'recirc_id(0),in_port(1),eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00)']) dnl configure sflow on int-br only ovs-vsctl \