diff options
author | Dumitru Ceara <dceara@redhat.com> | 2020-01-10 10:34:43 +0100 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2020-06-16 15:07:31 -0700 |
commit | d072d2de011b5874e16a0fe81953c2448658746a (patch) | |
tree | d2c16ac540c49e40fee5df443b0fa6aa81d3d587 /ofproto/ofproto-dpif-xlate.c | |
parent | 29b1dd934f8d0c4cf3d58abc2c10aa9d0ae68277 (diff) | |
download | openvswitch-d072d2de011b5874e16a0fe81953c2448658746a.tar.gz |
ofproto-dpif-trace: Improve NAT tracing.
When ofproto/trace detects a recirc action it resumes execution at the
specified next table. However, if the ct action performs SNAT/DNAT,
e.g., ct(commit,nat(src=1.1.1.1:4000),table=42), the src/dst IPs and
ports in the oftrace_recirc_node->flow field are not updated. This leads
to misleading outputs from ofproto/trace as real packets would actually
first get NATed and might match different flows when recirculated.
Assume the first IP/port from the NAT src/dst action will be used by
conntrack for the translation and update the oftrace_recirc_node->flow
accordingly. This is not entirely correct as conntrack might choose a
different IP/port but the result is more realistic than before.
This fix covers new connections. However, for reply traffic that executes
actions of the form ct(nat, table=42) we still don't update the flow as
we don't have any information about conntrack state when tracing.
Also move the oftrace_recirc_node processing out of ofproto_trace()
and to its own function, ofproto_trace_recirc_node() for better
readability/
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'ofproto/ofproto-dpif-xlate.c')
-rw-r--r-- | ofproto/ofproto-dpif-xlate.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 80fba84cb..e64c6d477 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -4999,7 +4999,8 @@ compose_recirculate_and_fork(struct xlate_ctx *ctx, uint8_t table, if (OVS_UNLIKELY(ctx->xin->trace) && recirc_id) { if (oftrace_add_recirc_node(ctx->xin->recirc_queue, OFT_RECIRC_CONNTRACK, &ctx->xin->flow, - ctx->xin->packet, recirc_id, zone)) { + ctx->ct_nat_action, ctx->xin->packet, + recirc_id, zone)) { xlate_report(ctx, OFT_DETAIL, "A clone of the packet is forked to " "recirculate. The forked pipeline will be resumed at " "table %u.", table); @@ -6205,7 +6206,6 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, put_ct_label(&ctx->xin->flow, ctx->odp_actions, ctx->wc); put_ct_helper(ctx, ctx->odp_actions, ofc); put_ct_nat(ctx); - ctx->ct_nat_action = NULL; nl_msg_end_nested(ctx->odp_actions, ct_offset); ctx->wc->masks.ct_mark = old_ct_mark_mask; @@ -6216,6 +6216,8 @@ compose_conntrack_action(struct xlate_ctx *ctx, struct ofpact_conntrack *ofc, compose_recirculate_and_fork(ctx, ofc->recirc_table, zone); } + ctx->ct_nat_action = NULL; + /* The ct_* fields are only available in the scope of the 'recirc_table' * call chain. */ flow_clear_conntrack(&ctx->xin->flow); |