From: Numan Siddique <[email protected]> These actions are very similar to ct_dnat and ct_snat respectively with one difference. These new actions use the same zone id for natting. Upcoming patch will make use of these actions.
Acked-by: Mark Michelson <[email protected]> Signed-off-by: Numan Siddique <[email protected]> --- v2 -> v3 ---- * Added Mark's Ack v1 -> v2 ---- * No changes. include/ovn/actions.h | 2 ++ include/ovn/logical-fields.h | 2 ++ lib/actions.c | 59 +++++++++++++++++++++++++----- ovn-sb.xml | 44 +++++++++++++++++++++++ tests/ovn.at | 69 ++++++++++++++++++++++++++++++++++++ utilities/ovn-trace.c | 18 ++++++++-- 6 files changed, 184 insertions(+), 10 deletions(-) diff --git a/include/ovn/actions.h b/include/ovn/actions.h index f023a37b9..ede5eb93c 100644 --- a/include/ovn/actions.h +++ b/include/ovn/actions.h @@ -66,6 +66,8 @@ struct ovn_extend_table; OVNACT(CT_COMMIT_V2, ovnact_nest) \ OVNACT(CT_DNAT, ovnact_ct_nat) \ OVNACT(CT_SNAT, ovnact_ct_nat) \ + OVNACT(CT_DNAT_IN_CZONE, ovnact_ct_nat) \ + OVNACT(CT_SNAT_IN_CZONE, ovnact_ct_nat) \ OVNACT(CT_LB, ovnact_ct_lb) \ OVNACT(SELECT, ovnact_select) \ OVNACT(CT_CLEAR, ovnact_null) \ diff --git a/include/ovn/logical-fields.h b/include/ovn/logical-fields.h index ef97117b9..c9675f81c 100644 --- a/include/ovn/logical-fields.h +++ b/include/ovn/logical-fields.h @@ -36,6 +36,8 @@ enum ovn_controller_event { * (32 bits). */ #define MFF_LOG_SNAT_ZONE MFF_REG12 /* conntrack snat zone for gateway router * (32 bits). */ +#define MFF_LOG_NAT_ZONE MFF_LOG_DNAT_ZONE /* conntrack zone for both snat + * and dnat. */ #define MFF_LOG_CT_ZONE MFF_REG13 /* Logical conntrack zone for lports * (32 bits). */ #define MFF_LOG_INPORT MFF_REG14 /* Logical input port (32 bits). */ diff --git a/lib/actions.c b/lib/actions.c index 7cf6be308..6b9a426ae 100644 --- a/lib/actions.c +++ b/lib/actions.c @@ -917,6 +917,20 @@ parse_CT_SNAT(struct action_context *ctx) parse_ct_nat(ctx, "ct_snat", ovnact_put_CT_SNAT(ctx->ovnacts)); } +static void +parse_CT_DNAT_IN_CZONE(struct action_context *ctx) +{ + parse_ct_nat(ctx, "ct_dnat_in_czone", + ovnact_put_CT_DNAT_IN_CZONE(ctx->ovnacts)); +} + +static void +parse_CT_SNAT_IN_CZONE(struct action_context *ctx) +{ + parse_ct_nat(ctx, "ct_snat_in_czone", + ovnact_put_CT_SNAT_IN_CZONE(ctx->ovnacts)); +} + static void format_ct_nat(const struct ovnact_ct_nat *cn, const char *name, struct ds *s) { @@ -954,21 +968,30 @@ format_CT_SNAT(const struct ovnact_ct_nat *cn, struct ds *s) format_ct_nat(cn, "ct_snat", s); } +static void +format_CT_DNAT_IN_CZONE(const struct ovnact_ct_nat *cn, struct ds *s) +{ + format_ct_nat(cn, "ct_dnat_in_czone", s); +} + +static void +format_CT_SNAT_IN_CZONE(const struct ovnact_ct_nat *cn, struct ds *s) +{ + format_ct_nat(cn, "ct_snat_in_czone", s); +} + static void encode_ct_nat(const struct ovnact_ct_nat *cn, const struct ovnact_encode_params *ep, - bool snat, struct ofpbuf *ofpacts) + bool snat, enum mf_field_id zone_src, + struct ofpbuf *ofpacts) { const size_t ct_offset = ofpacts->size; ofpbuf_pull(ofpacts, ct_offset); struct ofpact_conntrack *ct = ofpact_put_CT(ofpacts); ct->recirc_table = cn->ltable + first_ptable(ep, ep->pipeline); - if (snat) { - ct->zone_src.field = mf_from_id(MFF_LOG_SNAT_ZONE); - } else { - ct->zone_src.field = mf_from_id(MFF_LOG_DNAT_ZONE); - } + ct->zone_src.field = mf_from_id(zone_src); ct->zone_src.ofs = 0; ct->zone_src.n_bits = 16; ct->flags = 0; @@ -1020,7 +1043,7 @@ encode_CT_DNAT(const struct ovnact_ct_nat *cn, const struct ovnact_encode_params *ep, struct ofpbuf *ofpacts) { - encode_ct_nat(cn, ep, false, ofpacts); + encode_ct_nat(cn, ep, false, MFF_LOG_DNAT_ZONE, ofpacts); } static void @@ -1028,7 +1051,23 @@ encode_CT_SNAT(const struct ovnact_ct_nat *cn, const struct ovnact_encode_params *ep, struct ofpbuf *ofpacts) { - encode_ct_nat(cn, ep, true, ofpacts); + encode_ct_nat(cn, ep, true, MFF_LOG_SNAT_ZONE, ofpacts); +} + +static void +encode_CT_DNAT_IN_CZONE(const struct ovnact_ct_nat *cn, + const struct ovnact_encode_params *ep, + struct ofpbuf *ofpacts) +{ + encode_ct_nat(cn, ep, false, MFF_LOG_NAT_ZONE, ofpacts); +} + +static void +encode_CT_SNAT_IN_CZONE(const struct ovnact_ct_nat *cn, + const struct ovnact_encode_params *ep, + struct ofpbuf *ofpacts) +{ + encode_ct_nat(cn, ep, true, MFF_LOG_NAT_ZONE, ofpacts); } static void @@ -4017,6 +4056,10 @@ parse_action(struct action_context *ctx) parse_CT_DNAT(ctx); } else if (lexer_match_id(ctx->lexer, "ct_snat")) { parse_CT_SNAT(ctx); + } else if (lexer_match_id(ctx->lexer, "ct_dnat_in_czone")) { + parse_CT_DNAT_IN_CZONE(ctx); + } else if (lexer_match_id(ctx->lexer, "ct_snat_in_czone")) { + parse_CT_SNAT_IN_CZONE(ctx); } else if (lexer_match_id(ctx->lexer, "ct_lb")) { parse_ct_lb_action(ctx); } else if (lexer_match_id(ctx->lexer, "ct_clear")) { diff --git a/ovn-sb.xml b/ovn-sb.xml index 150051f26..9ddacdf09 100644 --- a/ovn-sb.xml +++ b/ovn-sb.xml @@ -1383,6 +1383,50 @@ </p> </dd> + <dt><code>ct_dnat_in_czone;</code></dt> + <dt><code>ct_dnat_in_czone(<var>IP</var>);</code></dt> + <dd> + <p> + <code>ct_dnat_in_czone</code> sends the packet through the common + NAT zone (used for both DNAT and SNAT) in connection tracking table + to unDNAT any packet that was DNATed in the opposite direction. + The packet is then automatically sent to to the next tables as if + followed by <code>next;</code> action. The next tables will see + the changes in the packet caused by the connection tracker. + </p> + <p> + <code>ct_dnat_in_czone(<var>IP</var>)</code> sends the packet + through the common NAT zone to change the destination IP address + of the packet to the one provided inside the parentheses and + commits the connection. The packet is then automatically sent to + the next tables as if followed by <code>next;</code> action. The + next tables will see the changes in the packet caused by the + connection tracker. + </p> + </dd> + + <dt><code>ct_snat_in_czone;</code></dt> + <dt><code>ct_snat_in_czone(<var>IP</var>);</code></dt> + <dd> + <p> + <code>ct_snat_in_czone</code> sends the packet through the common + NAT zone to unSNAT any packet that was SNATed in the opposite + direction. The packet is automatically sent to the next tables as + if followed by the <code>next;</code> action. The next tables + will see the changes in the packet caused by the connection + tracker. + </p> + <p> + <code>ct_snat_in_czone(<var>IP</var>)</code> sends the packet\ + through the common NAT zone to change the source IP address of + the packet to the one provided inside the parenthesis and commits + the connection. The packet is then automatically sent to the next + tables as if followed by <code>next;</code> action. The next + tables will see the changes in the packet caused by the connection + tracker. + </p> + </dd> + <dt><code>ct_clear;</code></dt> <dd> Clears connection tracking state. diff --git a/tests/ovn.at b/tests/ovn.at index ae832918c..0d606b42f 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -1193,6 +1193,40 @@ ct_dnat(192.168.1.2, 1000); ct_dnat(192.168.1.2, 1000-100); Syntax error at `100' range high should be greater than range low. +# ct_dnat_in_czone +ct_dnat_in_czone; + encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat) + has prereqs ip +ct_dnat_in_czone(192.168.1.2); + encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2)) + has prereqs ip +ct_dnat_in_czone(fd11::2); + encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=fd11::2)) + has prereqs ip +ct_dnat_in_czone(192.168.1.2, 1-3000); + formats as ct_dnat_in_czone(192.168.1.2,1-3000); + encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2:1-3000)) + has prereqs ip + +ct_dnat_in_czone(192.168.1.2, 192.168.1.3); + Syntax error at `192.168.1.3' expecting Integer for port range. +ct_dnat_in_czone(foo); + Syntax error at `foo' expecting IPv4 or IPv6 address. +ct_dnat_in_czone(foo, bar); + Syntax error at `foo' expecting IPv4 or IPv6 address. +ct_dnat_in_czone(); + Syntax error at `)' expecting IPv4 or IPv6 address. +ct_dnat_in_czone(192.168.1.2, foo); + Syntax error at `foo' expecting Integer for port range. +ct_dnat_in_czone(192.168.1.2, 1000-foo); + Syntax error at `foo' expecting Integer for port range. +ct_dnat_in_czone(192.168.1.2, 1000); + formats as ct_dnat_in_czone(192.168.1.2,1000); + encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2:1000)) + has prereqs ip +ct_dnat_in_czone(192.168.1.2, 1000-100); + Syntax error at `100' range high should be greater than range low. + # ct_snat ct_snat; encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat) @@ -1226,6 +1260,41 @@ ct_snat(192.168.1.2, 1000); has prereqs ip ct_snat(192.168.1.2, 1000-100); Syntax error at `100' range high should be greater than range low. + +# ct_snat_in_czone +ct_snat_in_czone; + encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat) + has prereqs ip +ct_snat_in_czone(192.168.1.2); + encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(src=192.168.1.2)) + has prereqs ip +ct_snat_in_czone(fd11::2); + encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(src=fd11::2)) + has prereqs ip +ct_snat_in_czone(192.168.1.2, 1-3000); + formats as ct_snat_in_czone(192.168.1.2,1-3000); + encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(src=192.168.1.2:1-3000)) + has prereqs ip + +ct_snat_in_czone(192.168.1.2, 192.168.1.3); + Syntax error at `192.168.1.3' expecting Integer for port range. +ct_snat_in_czone(foo); + Syntax error at `foo' expecting IPv4 or IPv6 address. +ct_snat_in_czone(foo, bar); + Syntax error at `foo' expecting IPv4 or IPv6 address. +ct_snat_in_czone(); + Syntax error at `)' expecting IPv4 or IPv6 address. +ct_snat_in_czone(192.168.1.2, foo); + Syntax error at `foo' expecting Integer for port range. +ct_snat_in_czone(192.168.1.2, 1000-foo); + Syntax error at `foo' expecting Integer for port range. +ct_snat_in_czone(192.168.1.2, 1000); + formats as ct_snat_in_czone(192.168.1.2,1000); + encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(src=192.168.1.2:1000)) + has prereqs ip +ct_snat_in_czone(192.168.1.2, 1000-100); + Syntax error at `100' range high should be greater than range low. + # ct_clear ct_clear; encodes as ct_clear diff --git a/utilities/ovn-trace.c b/utilities/ovn-trace.c index 65a1822ea..617ad834c 100644 --- a/utilities/ovn-trace.c +++ b/utilities/ovn-trace.c @@ -2286,7 +2286,10 @@ execute_ct_nat(const struct ovnact_ct_nat *ct_nat, const struct ovntrace_datapath *dp, struct flow *uflow, enum ovnact_pipeline pipeline, struct ovs_list *super) { - bool is_dst = ct_nat->ovnact.type == OVNACT_CT_DNAT; + bool is_dst = (ct_nat->ovnact.type == OVNACT_CT_DNAT || + ct_nat->ovnact.type == OVNACT_CT_DNAT_IN_CZONE); + bool nat_in_czone = (ct_nat->ovnact.type == OVNACT_CT_DNAT_IN_CZONE || + ct_nat->ovnact.type == OVNACT_CT_SNAT_IN_CZONE); if (!is_dst && dp->has_local_l3gateway && ct_nat->family == AF_UNSPEC) { /* "ct_snat;" has no visible effect in a gateway router. */ return; @@ -2297,7 +2300,8 @@ execute_ct_nat(const struct ovnact_ct_nat *ct_nat, * and figure out the changes if any. */ struct flow ct_flow = *uflow; struct ds s = DS_EMPTY_INITIALIZER; - ds_put_format(&s, "ct_%cnat", direction[0]); + ds_put_format(&s, "ct_%cnat%s", direction[0], + nat_in_czone ? "in_czone" : ""); if (ct_nat->family != AF_UNSPEC) { if (ct_nat->family == AF_INET) { ds_put_format(&s, "(ip4.%s="IP_FMT")", direction, @@ -2610,6 +2614,16 @@ trace_actions(const struct ovnact *ovnacts, size_t ovnacts_len, execute_ct_nat(ovnact_get_CT_SNAT(a), dp, uflow, pipeline, super); break; + case OVNACT_CT_DNAT_IN_CZONE: + execute_ct_nat(ovnact_get_CT_DNAT_IN_CZONE(a), dp, uflow, + pipeline, super); + break; + + case OVNACT_CT_SNAT_IN_CZONE: + execute_ct_nat(ovnact_get_CT_SNAT_IN_CZONE(a), dp, uflow, + pipeline, super); + break; + case OVNACT_CT_LB: execute_ct_lb(ovnact_get_CT_LB(a), dp, uflow, pipeline, super); break; -- 2.33.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
