Hi Mike, Thanks for the patch!. I took your patch and tried running the OVN unit test for the 'both' direction packets mirroring check using the ovsmirrortest.diff attached in the BZ (2155579 <https://bugzilla.redhat.com/show_bug.cgi?id=2155579>) It passed with your patch.
Thanks & Regards, Abhiram R N On Fri, Feb 17, 2023 at 1:37 AM Mike Pattrick <m...@redhat.com> wrote: > Currently OVS keeps track of which mirrors that each packet has been > sent to for the purpose of deduplication. However, this doesn't consider > that openflow rules can make significant changes to packets after > ingress. > > For example, OVN can create OpenFlow rules that turn an echo request > into an echo response by flipping source/destination addresses and > setting the ICMP type to Reply. When a mirror is configured, only the > request gets mirrored even though a response is recieved. > > This can cause a false impression of the actual traffic on wire if > someone inspects the mirror and doesn't see an echo reply even though > one has been sent. > > This patch resets the mirrors every time a packet is modified, so > mirrors will recieve every copy of a packet that is sent for output. > > Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2155579 > Signed-off-by: Mike Pattrick <m...@redhat.com> > --- > ofproto/ofproto-dpif-xlate.c | 37 +++++++++++++++++++++++++++++++----- > tests/ofproto-dpif.at | 6 +++--- > 2 files changed, 35 insertions(+), 8 deletions(-) > > diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c > index a9cf3cbee..34b4b4018 100644 > --- a/ofproto/ofproto-dpif-xlate.c > +++ b/ofproto/ofproto-dpif-xlate.c > @@ -7078,6 +7078,7 @@ do_xlate_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > break; > > case OFPACT_SET_VLAN_VID: > + ctx->mirrors = 0; > wc->masks.vlans[0].tci |= htons(VLAN_VID_MASK | VLAN_CFI); > if (flow->vlans[0].tci & htons(VLAN_CFI) || > ofpact_get_SET_VLAN_VID(a)->push_vlan_if_needed) { > @@ -7092,6 +7093,7 @@ do_xlate_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > break; > > case OFPACT_SET_VLAN_PCP: > + ctx->mirrors = 0; > wc->masks.vlans[0].tci |= htons(VLAN_PCP_MASK | VLAN_CFI); > if (flow->vlans[0].tci & htons(VLAN_CFI) || > ofpact_get_SET_VLAN_PCP(a)->push_vlan_if_needed) { > @@ -7106,27 +7108,32 @@ do_xlate_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > break; > > case OFPACT_STRIP_VLAN: > + ctx->mirrors = 0; > flow_pop_vlan(flow, wc); > break; > > case OFPACT_PUSH_VLAN: > + ctx->mirrors = 0; > flow_push_vlan_uninit(flow, wc); > flow->vlans[0].tpid = ofpact_get_PUSH_VLAN(a)->ethertype; > flow->vlans[0].tci = htons(VLAN_CFI); > break; > > case OFPACT_SET_ETH_SRC: > + ctx->mirrors = 0; > WC_MASK_FIELD(wc, dl_src); > flow->dl_src = ofpact_get_SET_ETH_SRC(a)->mac; > break; > > case OFPACT_SET_ETH_DST: > + ctx->mirrors = 0; > WC_MASK_FIELD(wc, dl_dst); > flow->dl_dst = ofpact_get_SET_ETH_DST(a)->mac; > break; > > case OFPACT_SET_IPV4_SRC: > if (flow->dl_type == htons(ETH_TYPE_IP)) { > + ctx->mirrors = 0; > memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src); > flow->nw_src = ofpact_get_SET_IPV4_SRC(a)->ipv4; > } > @@ -7134,6 +7141,7 @@ do_xlate_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > > case OFPACT_SET_IPV4_DST: > if (flow->dl_type == htons(ETH_TYPE_IP)) { > + ctx->mirrors = 0; > memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst); > flow->nw_dst = ofpact_get_SET_IPV4_DST(a)->ipv4; > } > @@ -7141,6 +7149,7 @@ do_xlate_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > > case OFPACT_SET_IP_DSCP: > if (is_ip_any(flow)) { > + ctx->mirrors = 0; > wc->masks.nw_tos |= IP_DSCP_MASK; > flow->nw_tos &= ~IP_DSCP_MASK; > flow->nw_tos |= ofpact_get_SET_IP_DSCP(a)->dscp; > @@ -7149,6 +7158,7 @@ do_xlate_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > > case OFPACT_SET_IP_ECN: > if (is_ip_any(flow)) { > + ctx->mirrors = 0; > wc->masks.nw_tos |= IP_ECN_MASK; > flow->nw_tos &= ~IP_ECN_MASK; > flow->nw_tos |= ofpact_get_SET_IP_ECN(a)->ecn; > @@ -7157,6 +7167,7 @@ do_xlate_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > > case OFPACT_SET_IP_TTL: > if (is_ip_any(flow)) { > + ctx->mirrors = 0; > wc->masks.nw_ttl = 0xff; > flow->nw_ttl = ofpact_get_SET_IP_TTL(a)->ttl; > } > @@ -7164,6 +7175,7 @@ do_xlate_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > > case OFPACT_SET_L4_SRC_PORT: > if (is_ip_any(flow) && !(flow->nw_frag & FLOW_NW_FRAG_LATER)) > { > + ctx->mirrors = 0; > memset(&wc->masks.nw_proto, 0xff, sizeof > wc->masks.nw_proto); > memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src); > flow->tp_src = htons(ofpact_get_SET_L4_SRC_PORT(a)->port); > @@ -7172,6 +7184,7 @@ do_xlate_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > > case OFPACT_SET_L4_DST_PORT: > if (is_ip_any(flow) && !(flow->nw_frag & FLOW_NW_FRAG_LATER)) > { > + ctx->mirrors = 0; > memset(&wc->masks.nw_proto, 0xff, sizeof > wc->masks.nw_proto); > memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst); > flow->tp_dst = htons(ofpact_get_SET_L4_DST_PORT(a)->port); > @@ -7224,6 +7237,7 @@ do_xlate_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > > /* Set the field only if the packet actually has it. */ > if (mf_are_prereqs_ok(mf, flow, wc)) { > + ctx->mirrors = 0; > mf_mask_field_masked(mf, > ofpact_set_field_mask(set_field), wc); > mf_set_flow_value_masked(mf, set_field->value, > ofpact_set_field_mask(set_field), > @@ -7246,39 +7260,47 @@ do_xlate_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > break; > > case OFPACT_PUSH_MPLS: > + ctx->mirrors = 0; > compose_mpls_push_action(ctx, ofpact_get_PUSH_MPLS(a)); > break; > > case OFPACT_POP_MPLS: > + ctx->mirrors = 0; > compose_mpls_pop_action(ctx, > ofpact_get_POP_MPLS(a)->ethertype); > break; > > case OFPACT_SET_MPLS_LABEL: > + ctx->mirrors = 0; > compose_set_mpls_label_action( > ctx, ofpact_get_SET_MPLS_LABEL(a)->label); > break; > > case OFPACT_SET_MPLS_TC: > + ctx->mirrors = 0; > compose_set_mpls_tc_action(ctx, > ofpact_get_SET_MPLS_TC(a)->tc); > break; > > case OFPACT_SET_MPLS_TTL: > + ctx->mirrors = 0; > compose_set_mpls_ttl_action(ctx, > ofpact_get_SET_MPLS_TTL(a)->ttl); > break; > > case OFPACT_DEC_MPLS_TTL: > + ctx->mirrors = 0; > if (compose_dec_mpls_ttl_action(ctx)) { > return; > } > break; > > case OFPACT_DEC_NSH_TTL: > + ctx->mirrors = 0; > if (compose_dec_nsh_ttl_action(ctx)) { > return; > } > break; > > case OFPACT_DEC_TTL: > + ctx->mirrors = 0; > wc->masks.nw_ttl = 0xff; > if (compose_dec_ttl(ctx, ofpact_get_DEC_TTL(a))) { > return; > @@ -7370,17 +7392,21 @@ do_xlate_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > break; > > case OFPACT_ENCAP: > + ctx->mirrors = 0; > xlate_generic_encap_action(ctx, ofpact_get_ENCAP(a)); > break; > > case OFPACT_DECAP: { > bool recirc_needed = > xlate_generic_decap_action(ctx, ofpact_get_DECAP(a)); > - if (!ctx->error && recirc_needed) { > - /* Recirculate for parsing of inner packet. */ > - ctx_trigger_freeze(ctx); > - /* Then continue with next action. */ > - a = ofpact_next(a); > + if (!ctx->error) { > + ctx->mirrors = 0; > + if (recirc_needed) { > + /* Recirculate for parsing of inner packet. */ > + ctx_trigger_freeze(ctx); > + /* Then continue with next action. */ > + a = ofpact_next(a); > + } > } > break; > } > @@ -7397,6 +7423,7 @@ do_xlate_actions(const struct ofpact *ofpacts, > size_t ofpacts_len, > > case OFPACT_NAT: > /* This will be processed by compose_conntrack_action(). */ > + ctx->mirrors = 0; > ctx->ct_nat_action = ofpact_get_NAT(a); > break; > > diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at > index 222415ac0..b027e8c2c 100644 > --- a/tests/ofproto-dpif.at > +++ b/tests/ofproto-dpif.at > @@ -5349,7 +5349,7 @@ AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) > > > flow="in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)" > AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow"], [0], [stdout]) > AT_CHECK_UNQUOTED([tail -1 stdout], [0], > - [Datapath actions: 3,push_vlan(vid=17,pcp=0),2 > + [Datapath actions: 3,push_vlan(vid=17,pcp=0),2,3 > ]) > > > > flow="in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)" > @@ -5388,7 +5388,7 @@ > flow="in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x080 > AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow"], [0], [stdout]) > actual=`tail -1 stdout | sed 's/Datapath actions: //'` > > > -expected="push_vlan(vid=17,pcp=0),1,pop_vlan,push_vlan(vid=12,pcp=0),1,2,100" > > +expected="push_vlan(vid=12,pcp=0),100,2,1,pop_vlan,push_vlan(vid=17,pcp=0),1,pop_vlan,push_vlan(vid=12,pcp=0),100,2,1" > AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout]) > mv stdout expout > AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout]) > @@ -5656,7 +5656,7 @@ AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) > > > flow="in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)" > AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow"], [0], [stdout]) > AT_CHECK_UNQUOTED([tail -1 stdout], [0], > - [Datapath actions: trunc(100),3,push_vlan(vid=17,pcp=0),2 > + [Datapath actions: trunc(100),3,push_vlan(vid=17,pcp=0),2,trunc(100),3 > ]) > > > > flow="in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)" > -- > 2.31.1 > > _______________________________________________ > dev mailing list > d...@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > -- Always put yourself in others' shoes. If you feel that it hurts you, it probably hurts the other person, too. Regards ABHIRAM _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev