By avoiding Tx recirculation and embracing tnl_push action within clone, the tunnel metadata is not propagated. Unless clone action is handled in the dpif_sflow_read_actions() function as well. This commit resolves this issue. In addition, some sflow data needs to be stored and restored in ofproto-dpif-xlate when native_tunnel_output() is invoked. Otherwise the output action of underlay bridge is getting counted as well if sFlow is set on the overlay bridge.
Signed-off-by: Zoltan Balogh <zoltan.bal...@ericsson.com> --- ofproto/ofproto-dpif-sflow.c | 31 ++++++++++++++++++++----------- ofproto/ofproto-dpif-sflow.h | 4 ++-- ofproto/ofproto-dpif-upcall.c | 2 +- ofproto/ofproto-dpif-xlate.c | 7 +++++++ tests/ofproto-dpif.at | 2 +- 5 files changed, 31 insertions(+), 15 deletions(-) diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c index ccf89645b..0948551d3 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. */ @@ -1197,8 +1198,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_ENCAP_NSH: case OVS_ACTION_ATTR_DECAP_NSH: case OVS_ACTION_ATTR_UNSPEC: @@ -1266,6 +1272,7 @@ dpif_sflow_received(struct dpif_sflow *ds, const struct dp_packet *packet, struct dpif_sflow_port *in_dsp; struct dpif_sflow_port *out_dsp; ovs_be16 vlan_tci; + uint32_t num_outputs; ovs_mutex_lock(&mutex); sampler = ds->sflow_agent->samplers; @@ -1333,11 +1340,13 @@ dpif_sflow_received(struct dpif_sflow *ds, const struct dp_packet *packet, } } + num_outputs = dpif_sflow_cookie_num_outputs(cookie); /* Output tunnel. */ if (sflow_actions - && sflow_actions->encap_depth == 1 - && !sflow_actions->tunnel_err - && dpif_sflow_cookie_num_outputs(cookie) == 1) { + && sflow_actions->encap_depth == 1 + && !sflow_actions->tunnel_err + && (num_outputs == 1 /* push_tnl or */ + || num_outputs == 2)) { /* clone + push_tnl */ tnlOutProto = sflow_actions->tunnel_ipproto; if (tnlOutProto == 0) { /* Try to infer the ip-protocol from the output port. */ @@ -1365,9 +1374,9 @@ dpif_sflow_received(struct dpif_sflow *ds, const struct dp_packet *packet, /* MPLS output label stack. */ if (sflow_actions - && sflow_actions->mpls_stack_depth > 0 - && !sflow_actions->mpls_err - && dpif_sflow_cookie_num_outputs(cookie) == 1) { + && sflow_actions->mpls_stack_depth > 0 + && !sflow_actions->mpls_err + && num_outputs == 1) { memset(&mplsElem, 0, sizeof(mplsElem)); mplsElem.tag = SFLFLOW_EX_MPLS; dpif_sflow_encode_mpls_stack(&mplsElem.flowType.mpls.out_stack, diff --git a/ofproto/ofproto-dpif-sflow.h b/ofproto/ofproto-dpif-sflow.h index 014e6cce3..87ed93c6e 100644 --- a/ofproto/ofproto-dpif-sflow.h +++ b/ofproto/ofproto-dpif-sflow.h @@ -70,8 +70,8 @@ void dpif_sflow_run(struct dpif_sflow *); 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 *); + const struct nlattr *actions, size_t actions_len, + 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 02cf5415b..dc496344f 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -1317,7 +1317,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 9b3a2f28a..9be0bbd84 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -3259,6 +3259,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; @@ -3410,6 +3413,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 9a51a1364..cdf48f4de 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -6286,7 +6286,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 \ -- 2.14.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev