In order to have the SNAT action available for related traffic store the flag in CT register.
Extend the ct_lb and ct_lb_mark action to allow additional parameter that sets the corresponding flag if needed in ct_label/ct_mark register. This allows us to later on match on it for related traffic and set the corresponding flags fro additional flows. Currently only two flags are supported "skip_snat" and "force_snat" which are mutually exclusive. Reported-at: https://bugzilla.redhat.com/2126083 Signed-off-by: Ales Musil <[email protected]> --- include/ovn/actions.h | 7 +++ include/ovn/logical-fields.h | 4 ++ lib/actions.c | 57 ++++++++++++++++++---- lib/logical-fields.c | 20 ++++++++ northd/northd.c | 55 ++++++++++++++++++--- northd/ovn-northd.8.xml | 4 +- ovn-sb.xml | 9 ++-- tests/ovn-northd.at | 87 +++++++++++++++++++++------------ tests/ovn.at | 93 ++++++++++++++++++++++++++---------- tests/system-ovn.at | 51 +++++++++++++++----- 10 files changed, 300 insertions(+), 87 deletions(-) diff --git a/include/ovn/actions.h b/include/ovn/actions.h index a56351081..7bbcabc30 100644 --- a/include/ovn/actions.h +++ b/include/ovn/actions.h @@ -284,6 +284,12 @@ struct ovnact_ct_nat { uint8_t ltable; /* Logical table ID of next table. */ }; +enum ovnact_ct_lb_flag { + OVNACT_CT_LB_FLAG_NONE, + OVNACT_CT_LB_FLAG_SKIP_SNAT, + OVNACT_CT_LB_FLAG_FORCE_SNAT, +}; + struct ovnact_ct_lb_dst { int family; union { @@ -300,6 +306,7 @@ struct ovnact_ct_lb { size_t n_dsts; uint8_t ltable; /* Logical table ID of next table. */ char *hash_fields; + enum ovnact_ct_lb_flag ct_flag; }; struct ovnact_select_dst { diff --git a/include/ovn/logical-fields.h b/include/ovn/logical-fields.h index 8060488f9..a7b64ef67 100644 --- a/include/ovn/logical-fields.h +++ b/include/ovn/logical-fields.h @@ -182,9 +182,13 @@ const struct ovn_field *ovn_field_from_name(const char *name); #define OVN_CT_BLOCKED_BIT 0 #define OVN_CT_NATTED_BIT 1 +#define OVN_CT_LB_SKIP_SNAT_BIT 2 +#define OVN_CT_LB_FORCE_SNAT_BIT 3 #define OVN_CT_BLOCKED 1 #define OVN_CT_NATTED 2 +#define OVN_CT_LB_SKIP_SNAT 4 +#define OVN_CT_LB_FORCE_SNAT 8 #define OVN_CT_ECMP_ETH_1ST_BIT 32 #define OVN_CT_ECMP_ETH_END_BIT 79 diff --git a/lib/actions.c b/lib/actions.c index 47ec654e1..a5cba994c 100644 --- a/lib/actions.c +++ b/lib/actions.c @@ -1200,6 +1200,7 @@ parse_ct_lb_action(struct action_context *ctx, bool ct_lb_mark) size_t allocated_dsts = 0; size_t n_dsts = 0; char *hash_fields = NULL; + enum ovnact_ct_lb_flag ct_flag = OVNACT_CT_LB_FLAG_NONE; if (lexer_match(ctx->lexer, LEX_T_LPAREN) && !lexer_match(ctx->lexer, LEX_T_RPAREN)) { @@ -1280,8 +1281,7 @@ parse_ct_lb_action(struct action_context *ctx, bool ct_lb_mark) if (lexer_match_id(ctx->lexer, "hash_fields")) { if (!lexer_match(ctx->lexer, LEX_T_EQUALS) || - ctx->lexer->token.type != LEX_T_STRING || - lexer_lookahead(ctx->lexer) != LEX_T_RPAREN) { + ctx->lexer->token.type != LEX_T_STRING) { lexer_syntax_error(ctx->lexer, "invalid hash_fields"); free(dsts); return; @@ -1289,6 +1289,16 @@ parse_ct_lb_action(struct action_context *ctx, bool ct_lb_mark) hash_fields = xstrdup(ctx->lexer->token.s); lexer_get(ctx->lexer); + if (!lexer_match(ctx->lexer, LEX_T_SEMICOLON)) { + lexer_get(ctx->lexer); + } + } + + if (lexer_match_id(ctx->lexer, "skip_snat")) { + ct_flag = OVNACT_CT_LB_FLAG_SKIP_SNAT; + lexer_get(ctx->lexer); + } else if (lexer_match_id(ctx->lexer, "force_snat")) { + ct_flag = OVNACT_CT_LB_FLAG_FORCE_SNAT; lexer_get(ctx->lexer); } } @@ -1299,6 +1309,7 @@ parse_ct_lb_action(struct action_context *ctx, bool ct_lb_mark) cl->dsts = dsts; cl->n_dsts = n_dsts; cl->hash_fields = hash_fields; + cl->ct_flag = ct_flag; } static void @@ -1332,12 +1343,23 @@ format_ct_lb(const struct ovnact_ct_lb *cl, struct ds *s, bool ct_lb_mark) } } } - ds_put_char(s, ')'); if (cl->hash_fields) { - ds_chomp(s, ')'); - ds_put_format(s, "; hash_fields=\"%s\")", cl->hash_fields); + ds_put_format(s, "; hash_fields=\"%s\"", cl->hash_fields); + } + + switch (cl->ct_flag) { + case OVNACT_CT_LB_FLAG_SKIP_SNAT: + ds_put_cstr(s, "; skip_snat"); + break; + case OVNACT_CT_LB_FLAG_FORCE_SNAT: + ds_put_cstr(s, "; force_snat"); + break; + case OVNACT_CT_LB_FLAG_NONE: + /* None is the default value not shown in the output. */ + break; } + ds_put_char(s, ')'); } ds_put_char(s, ';'); @@ -1397,6 +1419,21 @@ encode_ct_lb(const struct ovnact_ct_lb *cl, struct ofpact_group *og; uint32_t zone_reg = ep->is_switch ? MFF_LOG_CT_ZONE - MFF_REG0 : MFF_LOG_DNAT_ZONE - MFF_REG0; + const char *flag_reg = ct_lb_mark ? "ct_mark" : "ct_label"; + + const char *ct_flag_value; + switch (cl->ct_flag) { + case OVNACT_CT_LB_FLAG_SKIP_SNAT: + ct_flag_value = OVN_CT_MASKED_STR(OVN_CT_LB_SKIP_SNAT); + break; + case OVNACT_CT_LB_FLAG_FORCE_SNAT: + ct_flag_value = OVN_CT_MASKED_STR(OVN_CT_LB_FORCE_SNAT); + break; + case OVNACT_CT_LB_FLAG_NONE: + default: + ct_flag_value = NULL; + break; + } struct ds ds = DS_EMPTY_INITIALIZER; ds_put_format(&ds, "type=select,selection_method=%s", @@ -1428,9 +1465,13 @@ encode_ct_lb(const struct ovnact_ct_lb *cl, ds_put_format(&ds, "),commit,table=%d,zone=NXM_NX_REG%d[0..15]," "exec(set_field:" OVN_CT_MASKED_STR(OVN_CT_NATTED) - "->%s))", - recirc_table, zone_reg, - ct_lb_mark ? "ct_mark" : "ct_label"); + "->%s", + recirc_table, zone_reg, flag_reg); + if (ct_flag_value) { + ds_put_format(&ds, ",set_field:%s->%s", ct_flag_value, flag_reg); + } + + ds_put_cstr(&ds, "))"); } table_id = ovn_extend_table_assign_id(ep->group_table, ds_cstr(&ds), diff --git a/lib/logical-fields.c b/lib/logical-fields.c index fc131791e..fd509d9ee 100644 --- a/lib/logical-fields.c +++ b/lib/logical-fields.c @@ -145,6 +145,16 @@ ovn_init_symtab(struct shash *symtab) WR_CT_COMMIT); expr_symtab_add_subfield_scoped(symtab, "ct_mark.ecmp_reply_port", NULL, "ct_mark[16..31]", WR_CT_COMMIT); + expr_symtab_add_subfield_scoped(symtab, "ct_mark.skip_snat", NULL, + "ct_mark[" + OVN_CT_STR(OVN_CT_LB_SKIP_SNAT_BIT) + "]", + WR_CT_COMMIT); + expr_symtab_add_subfield_scoped(symtab, "ct_mark.force_snat", NULL, + "ct_mark[" + OVN_CT_STR(OVN_CT_LB_FORCE_SNAT_BIT) + "]", + WR_CT_COMMIT); expr_symtab_add_field_scoped(symtab, "ct_label", MFF_CT_LABEL, NULL, false, WR_CT_COMMIT); @@ -167,6 +177,16 @@ ovn_init_symtab(struct shash *symtab) "ct_label[80..95]", WR_CT_COMMIT); expr_symtab_add_subfield_scoped(symtab, "ct_label.label", NULL, "ct_label[96..127]", WR_CT_COMMIT); + expr_symtab_add_subfield_scoped(symtab, "ct_label.skip_snat", NULL, + "ct_label[" + OVN_CT_STR(OVN_CT_LB_SKIP_SNAT_BIT) + "]", + WR_CT_COMMIT); + expr_symtab_add_subfield_scoped(symtab, "ct_label.force_snat", NULL, + "ct_label[" + OVN_CT_STR(OVN_CT_LB_FORCE_SNAT_BIT) + "]", + WR_CT_COMMIT); expr_symtab_add_field(symtab, "ct_state", MFF_CT_STATE, NULL, false); diff --git a/northd/northd.c b/northd/northd.c index a16e8a8a7..cb5b14181 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -6973,12 +6973,12 @@ build_lb_rules_pre_stateful(struct hmap *lflows, struct ovn_northd_lb *lb, * match=(REGBIT_KNOWN_LB_SESSION == 1 && ct.new && ip4 * && REG_LB_AFF_BACKEND_IP4 == B1 && REG_LB_AFF_MATCH_PORT == BP1) * action=(REG_NEXT_HOP_IPV4 = V; lb_action; - * ct_lb_mark(backends=B1:BP1);) + * ct_lb_mark(backends=B1:BP1; ct_flag);) * table=lr_in_dnat, priority=150 * match=(REGBIT_KNOWN_LB_SESSION == 1 && ct.new && ip4 * && REG_LB_AFF_BACKEND_IP4 == B2 && REG_LB_AFF_MATCH_PORT == BP2) * action=(REG_NEXT_HOP_IPV4 = V; lb_action; - * ct_lb_mark(backends=B2:BP2);) + * ct_lb_mark(backends=B2:BP2; ct_flag);) * * - load balancing affinity learn: * table=lr_in_lb_aff_learn, priority=100 @@ -7036,6 +7036,13 @@ build_lb_affinity_lr_flows(struct hmap *lflows, struct ovn_northd_lb *lb, const char *reg_vip = ipv6 ? REG_NEXT_HOP_IPV6 : REG_NEXT_HOP_IPV4; const char *reg_backend = ipv6 ? REG_LB_L3_AFF_BACKEND_IP6 : REG_LB_AFF_BACKEND_IP4; + const char *ct_flag = NULL; + if (lb_action && !strcmp(lb_action, "flags.skip_snat_for_lb = 1; ")) { + ct_flag = "; skip_snat"; + } else if (lb_action && + !strcmp(lb_action, "flags.force_snat_for_lb = 1; ")) { + ct_flag = "; force_snat"; + } /* Prepare common part of affinity LB and affinity learn action. */ ds_put_format(&aff_action, "%s = %s; ", reg_vip, lb_vip->vip_str); @@ -7099,6 +7106,10 @@ build_lb_affinity_lr_flows(struct hmap *lflows, struct ovn_northd_lb *lb, ds_put_cstr(&aff_action_learn, backend->ip_str); } + if (ct_flag) { + ds_put_cstr(&aff_action, ct_flag); + } + ds_put_cstr(&aff_action, ");"); ds_put_char(&aff_action_learn, '"'); @@ -10411,6 +10422,11 @@ build_lrouter_nat_flows_for_lb(struct ovn_lb_vip *lb_vip, bool reject = build_lb_vip_actions(lb_vip, vips_nb, action, lb->selection_fields, false, ct_lb_mark); + bool drop = !!strncmp(ds_cstr(action), "ct_lb", strlen("ct_lb")); + if (!drop) { + /* Remove the trailing ");". */ + ds_truncate(action, action->length - 2); + } /* Higher priority rules are added for load-balancing in DNAT * table. For every match (on a VIP[:port]), we add two flows. @@ -10427,8 +10443,9 @@ build_lrouter_nat_flows_for_lb(struct ovn_lb_vip *lb_vip, } if (lb->skip_snat) { - skip_snat_new_action = xasprintf("flags.skip_snat_for_lb = 1; %s", - ds_cstr(action)); + skip_snat_new_action = xasprintf("flags.skip_snat_for_lb = 1; %s%s", + ds_cstr(action), + drop ? "" : "; skip_snat);"); skip_snat_est_action = xasprintf("flags.skip_snat_for_lb = 1; " "next;"); } @@ -10561,8 +10578,9 @@ build_lrouter_nat_flows_for_lb(struct ovn_lb_vip *lb_vip, skip_snat_new_action, est_match, skip_snat_est_action, lflows, prio, meter_groups); - char *new_actions = xasprintf("flags.force_snat_for_lb = 1; %s", - ds_cstr(action)); + char *new_actions = xasprintf("flags.force_snat_for_lb = 1; %s%s", + ds_cstr(action), + drop ? "" : "; force_snat);"); build_gw_lrouter_nat_flows_for_lb(lb, gw_router_force_snat, n_gw_router_force_snat, reject, new_match, new_actions, est_match, @@ -10577,6 +10595,10 @@ build_lrouter_nat_flows_for_lb(struct ovn_lb_vip *lb_vip, lb_aff_force_snat_router, n_lb_aff_force_snat_router); + if (!drop) { + ds_put_cstr(action, ");"); + } + build_gw_lrouter_nat_flows_for_lb(lb, gw_router, n_gw_router, reject, new_match, ds_cstr(action), est_match, "next;", lflows, prio, meter_groups); @@ -14142,7 +14164,7 @@ build_lrouter_nat_defrag_and_lb(struct ovn_datapath *od, struct hmap *lflows, ovn_lflow_add(lflows, od, S_ROUTER_OUT_EGR_LOOP, 0, "1", "next;"); ovn_lflow_add(lflows, od, S_ROUTER_IN_ECMP_STATEFUL, 0, "1", "next;"); - /* Ingress DNAT and DEFRAG Table (Priority 50). + /* Ingress DNAT and DEFRAG Table (Priority 50/70). * * The defrag stage needs to have flows for ICMP in order to get * the correct ct_state that can be used by DNAT stage. @@ -14155,10 +14177,29 @@ build_lrouter_nat_defrag_and_lb(struct ovn_datapath *od, struct hmap *lflows, * related traffic such as an ICMP Port Unreachable through * that's generated from a non-listening UDP port. */ if (od->has_lb_vip) { + ds_clear(match); + const char *ct_flag_reg = ct_lb_mark ? "ct_mark" : "ct_label"; + + ds_put_cstr(match, "ct.rel && !ct.est && !ct.new"); + size_t match_len = match->length; + ovn_lflow_add(lflows, od, S_ROUTER_IN_DEFRAG, 50, "icmp || icmp6", "ct_dnat;"); + + ds_put_format(match, " && %s.skip_snat == 1", ct_flag_reg); + ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 70, ds_cstr(match), + "flags.skip_snat_for_lb = 1; ct_commit_nat;"); + + ds_truncate(match, match_len); + ds_put_format(match, " && %s.force_snat == 1", ct_flag_reg); + ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 70, ds_cstr(match), + "flags.force_snat_for_lb = 1; ct_commit_nat;"); + + ds_truncate(match, match_len); ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 50, "ct.rel && !ct.est && !ct.new", "ct_commit_nat;"); + + ds_clear(match); } /* If the router has load balancer or DNAT rules, re-circulate every packet diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml index 4d455e0f3..058cbf71a 100644 --- a/northd/ovn-northd.8.xml +++ b/northd/ovn-northd.8.xml @@ -3495,7 +3495,9 @@ icmp6 { For the related traffic, a priority 50 flow that matches <code>ct.rel && !ct.est && !ct.new </code> with an action of <code>ct_commit_nat;</code>, if the router - has load balancer assigned to it. + has load balancer assigned to it. Along with two priority 70 flows + that match <code>skip_snat</code> and <code>force_snat</code> + flags. </p> </li> </ul> diff --git a/ovn-sb.xml b/ovn-sb.xml index 4f485b860..d5287e3c2 100644 --- a/ovn-sb.xml +++ b/ovn-sb.xml @@ -2033,7 +2033,7 @@ </dd> <dt><code>ct_lb;</code></dt> - <dt><code>ct_lb(backends=<var>ip</var>[:<var>port</var>][,...][; hash_fields=<var>field1</var>,<var>field2</var>,...]);</code></dt> + <dt><code>ct_lb(backends=<var>ip</var>[:<var>port</var>][,...][; hash_fields=<var>field1</var>,<var>field2</var>,...][; ct_flag]);</code></dt> <dd> <p> With arguments, <code>ct_lb</code> commits the packet @@ -2045,7 +2045,10 @@ <code>dp_hash</code> is used as the OpenFlow group selection method, but if <code>hash_fields</code> is specified, <code>hash</code> is used as the selection method, and the fields - listed are used as the hash fields. + listed are used as the hash fields. The <code>ct_flag</code> + field represents one of supported flag: <code>skip_snat</code> or + <code>force_snat</code>, this flag will be stored in + <code>ct_label</code> register. </p> <p> Without arguments, <code>ct_lb</code> sends the packet to the @@ -2067,7 +2070,7 @@ </dd> <dt><code>ct_lb_mark;</code></dt> - <dt><code>ct_lb_mark(backends=<var>ip</var>[:<var>port</var>][,...][; hash_fields=<var>field1</var>,<var>field2</var>,...]);</code></dt> + <dt><code>ct_lb_mark(backends=<var>ip</var>[:<var>port</var>][,...][; hash_fields=<var>field1</var>,<var>field2</var>,...][; ct_flag]);</code></dt> <dd> <p> Same as <code>ct_lb</code>, except that it internally uses ct_mark diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 7cc53e367..cf06ce7f9 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -3679,6 +3679,8 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(ct_lb_mark(backends=10.0.0.4:8080);) table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(ct_lb_mark(backends=10.0.0.40:8080);) table=7 (lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; ct_commit_nat;) ]) AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl @@ -3714,9 +3716,11 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=7 (lr_in_dnat ), priority=0 , match=(1), action=(next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080);) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080; force_snat);) table=7 (lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; ct_commit_nat;) ]) AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl @@ -3762,9 +3766,11 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=7 (lr_in_dnat ), priority=0 , match=(1), action=(next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080);) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080; force_snat);) table=7 (lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; ct_commit_nat;) ]) AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl @@ -3824,9 +3830,11 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=7 (lr_in_dnat ), priority=0 , match=(1), action=(next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080);) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080; force_snat);) table=7 (lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; ct_commit_nat;) ]) AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl @@ -3871,7 +3879,8 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl AT_CHECK([grep "lr_in_dnat" lr0flows | grep skip_snat_for_lb | sort], [0], [dnl table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 10.0.0.20 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.skip_snat_for_lb = 1; next;) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.20 && tcp && reg9[[16..31]] == 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.20 && tcp && reg9[[16..31]] == 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080; skip_snat);) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; ct_commit_nat;) ]) AT_CHECK([grep "lr_out_snat" lr0flows | grep skip_snat_for_lb | sed 's/table=./table=?/' | sort], [0], [dnl @@ -5135,6 +5144,8 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);) table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);) table=7 (lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; ct_commit_nat;) ]) AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl @@ -5206,6 +5217,8 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082), action=(ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);) table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);) table=7 (lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; ct_commit_nat;) ]) AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl @@ -5261,14 +5274,16 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=7 (lr_in_dnat ), priority=0 , match=(1), action=(next;) table=7 (lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);) table=7 (lr_in_dnat ), priority=110 , match=(ct.est && !ct.rel && ip4 && reg0 == 172.168.0.200 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) - table=7 (lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.80,10.0.0.81);) + table=7 (lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.80,10.0.0.81; force_snat);) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080);) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82; force_snat);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062; force_snat);) table=7 (lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; ct_commit_nat;) ]) AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl @@ -5327,16 +5342,18 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=7 (lr_in_dnat ), priority=0 , match=(1), action=(next;) table=7 (lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);) table=7 (lr_in_dnat ), priority=110 , match=(ct.est && !ct.rel && ip4 && reg0 == 172.168.0.200 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) - table=7 (lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.80,10.0.0.81);) + table=7 (lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.80,10.0.0.81; force_snat);) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080);) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82; force_snat);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82; force_snat);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062; force_snat);) table=7 (lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; ct_commit_nat;) ]) AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl @@ -5406,18 +5423,20 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=7 (lr_in_dnat ), priority=0 , match=(1), action=(next;) table=7 (lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);) table=7 (lr_in_dnat ), priority=110 , match=(ct.est && !ct.rel && ip4 && reg0 == 172.168.0.200 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) - table=7 (lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.80,10.0.0.81);) + table=7 (lr_in_dnat ), priority=110 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.80,10.0.0.81; force_snat);) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip6 && xxreg0 == def0::2 && tcp && reg9[[16..31]] == 8000 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080);) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip6 && xxreg0 == def0::2 && tcp && reg9[[16..31]] == 8000), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=[[aef0::2]]:80,[[aef0::3]]:80);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080; force_snat);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82; force_snat);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82; force_snat);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062; force_snat);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip6 && xxreg0 == def0::2 && tcp && reg9[[16..31]] == 8000), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=[[aef0::2]]:80,[[aef0::3]]:80; force_snat);) table=7 (lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; ct_commit_nat;) ]) AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl @@ -5476,9 +5495,11 @@ AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl table=7 (lr_in_dnat ), priority=0 , match=(1), action=(next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 172.168.0.210 && tcp && reg9[[16..31]] == 60 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.210 && tcp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.210 && tcp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062; force_snat);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062; force_snat);) table=7 (lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; ct_commit_nat;) ]) AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl @@ -8053,6 +8074,8 @@ AT_CHECK([grep "lr_in_dnat " R1flows | sort], [0], [dnl table=7 (lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; ct_lb_mark(backends=10.0.0.2:80);) table=7 (lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; ct_lb_mark(backends=20.0.0.2:80);) table=7 (lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; ct_commit_nat;) ]) AT_CHECK([grep "lr_in_lb_aff_learn" R1flows | sort], [0], [dnl table=8 (lr_in_lb_aff_learn ), priority=0 , match=(1), action=(next;) @@ -8069,10 +8092,12 @@ AT_CAPTURE_FILE([R1flows_skip_snat]) AT_CHECK([grep "lr_in_dnat " R1flows_skip_snat | sort], [0], [dnl table=7 (lr_in_dnat ), priority=0 , match=(1), action=(next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 172.16.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.skip_snat_for_lb = 1; next;) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.16.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80);) - table=7 (lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80);) - table=7 (lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.16.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; skip_snat);) + table=7 (lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80; skip_snat);) + table=7 (lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80; skip_snat);) table=7 (lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; ct_commit_nat;) ]) check ovn-nbctl remove load_balancer lb0 options skip_snat @@ -8086,10 +8111,12 @@ AT_CAPTURE_FILE([R1flows_force_snat]) AT_CHECK([grep "lr_in_dnat " R1flows_force_snat | sort], [0], [dnl table=7 (lr_in_dnat ), priority=0 , match=(1), action=(next;) table=7 (lr_in_dnat ), priority=120 , match=(ct.est && !ct.rel && ip4 && reg0 == 172.16.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) - table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.16.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80);) - table=7 (lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80);) - table=7 (lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.force_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80);) + table=7 (lr_in_dnat ), priority=120 , match=(ct.new && !ct.rel && ip4 && reg0 == 172.16.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; force_snat);) + table=7 (lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80; force_snat);) + table=7 (lr_in_dnat ), priority=150 , match=(reg9[[6]] == 1 && ct.new && ip4 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 = 172.16.0.10; flags.force_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80; force_snat);) table=7 (lr_in_dnat ), priority=50 , match=(ct.rel && !ct.est && !ct.new), action=(ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; ct_commit_nat;) + table=7 (lr_in_dnat ), priority=70 , match=(ct.rel && !ct.est && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1; ct_commit_nat;) ]) AT_CLEANUP diff --git a/tests/ovn.at b/tests/ovn.at index f3bd53242..2ac002804 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -309,12 +309,16 @@ ct_label = NXM_NX_CT_LABEL ct_label.blocked = ct_label[0] ct_label.ecmp_reply_eth = ct_label[32..79] ct_label.ecmp_reply_port = ct_label[80..95] +ct_label.force_snat = ct_label[3] ct_label.label = ct_label[96..127] ct_label.natted = ct_label[1] +ct_label.skip_snat = ct_label[2] ct_mark = NXM_NX_CT_MARK ct_mark.blocked = ct_mark[0] ct_mark.ecmp_reply_port = ct_mark[16..31] +ct_mark.force_snat = ct_mark[3] ct_mark.natted = ct_mark[1] +ct_mark.skip_snat = ct_mark[2] ct_state = NXM_NX_CT_STATE ]]) AT_CLEANUP @@ -1123,15 +1127,23 @@ ct_lb(backends=192.168.1.2:80,192.168.1.3:80); encodes as group:1 uses group: id(1), name(type=select,selection_method=dp_hash,bucket=bucket_id=0,weight:100,actions=ct(nat(dst=192.168.1.2:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=192.168.1.3:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label))) has prereqs ip +ct_lb(backends=192.168.1.2:80,192.168.1.3:80; skip_snat); + encodes as group:2 + uses group: id(2), name(type=select,selection_method=dp_hash,bucket=bucket_id=0,weight:100,actions=ct(nat(dst=192.168.1.2:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label,set_field:4/4->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=192.168.1.3:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label,set_field:4/4->ct_label))) + has prereqs ip +ct_lb(backends=192.168.1.2:80,192.168.1.3:80; force_snat); + encodes as group:3 + uses group: id(3), name(type=select,selection_method=dp_hash,bucket=bucket_id=0,weight:100,actions=ct(nat(dst=192.168.1.2:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label,set_field:8/8->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=192.168.1.3:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label,set_field:8/8->ct_label))) + has prereqs ip ct_lb(backends=192.168.1.2, 192.168.1.3, ); formats as ct_lb(backends=192.168.1.2,192.168.1.3); - encodes as group:2 - uses group: id(2), name(type=select,selection_method=dp_hash,bucket=bucket_id=0,weight:100,actions=ct(nat(dst=192.168.1.2),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=192.168.1.3),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label))) + encodes as group:4 + uses group: id(4), name(type=select,selection_method=dp_hash,bucket=bucket_id=0,weight:100,actions=ct(nat(dst=192.168.1.2),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=192.168.1.3),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label))) has prereqs ip ct_lb(backends=fd0f::2, fd0f::3, ); formats as ct_lb(backends=fd0f::2,fd0f::3); - encodes as group:3 - uses group: id(3), name(type=select,selection_method=dp_hash,bucket=bucket_id=0,weight:100,actions=ct(nat(dst=fd0f::2),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=fd0f::3),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label))) + encodes as group:5 + uses group: id(5), name(type=select,selection_method=dp_hash,bucket=bucket_id=0,weight:100,actions=ct(nat(dst=fd0f::2),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=fd0f::3),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label))) has prereqs ip ct_lb(backends=192.168.1.2:); @@ -1146,30 +1158,59 @@ ct_lb(backends=[192.168.1.2]); ct_lb(backends=192.168.1.2:80,192.168.1.3:80; hash_fields=eth_src,eth_dst,ip_src); Syntax error at `eth_src' invalid hash_fields. ct_lb(backends=192.168.1.2:80,192.168.1.3:80; hash_fields="eth_src,eth_dst,ip_src"); - encodes as group:4 - uses group: id(4), name(type=select,selection_method=hash,fields(eth_src,eth_dst,ip_src),bucket=bucket_id=0,weight:100,actions=ct(nat(dst=192.168.1.2:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=192.168.1.3:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label))) + encodes as group:6 + uses group: id(6), name(type=select,selection_method=hash,fields(eth_src,eth_dst,ip_src),bucket=bucket_id=0,weight:100,actions=ct(nat(dst=192.168.1.2:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=192.168.1.3:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label))) has prereqs ip ct_lb(backends=fd0f::2,fd0f::3; hash_fields="eth_src,eth_dst,ip_src,ip_dst,tp_src,tp_dst"); - encodes as group:5 - uses group: id(5), name(type=select,selection_method=hash,fields(eth_src,eth_dst,ip_src,ip_dst,tp_src,tp_dst),bucket=bucket_id=0,weight:100,actions=ct(nat(dst=fd0f::2),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=fd0f::3),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label))) + encodes as group:7 + uses group: id(7), name(type=select,selection_method=hash,fields(eth_src,eth_dst,ip_src,ip_dst,tp_src,tp_dst),bucket=bucket_id=0,weight:100,actions=ct(nat(dst=fd0f::2),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=fd0f::3),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label))) has prereqs ip ct_lb(backends=fd0f::2,fd0f::3; hash_fields="eth_src,eth_dst,ip_src,ip_dst,tcp_src,tcp_dst"); - encodes as group:6 - uses group: id(6), name(type=select,selection_method=hash,fields(eth_src,eth_dst,ip_src,ip_dst,tcp_src,tcp_dst),bucket=bucket_id=0,weight:100,actions=ct(nat(dst=fd0f::2),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=fd0f::3),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label))) + encodes as group:8 + uses group: id(8), name(type=select,selection_method=hash,fields(eth_src,eth_dst,ip_src,ip_dst,tcp_src,tcp_dst),bucket=bucket_id=0,weight:100,actions=ct(nat(dst=fd0f::2),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=fd0f::3),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label))) has prereqs ip ct_lb(backends=fd0f::2,fd0f::3; hash_fields="eth_src,eth_dst,ip_src,ip_dst,udp_src,udp_dst"); - encodes as group:7 - uses group: id(7), name(type=select,selection_method=hash,fields(eth_src,eth_dst,ip_src,ip_dst,udp_src,udp_dst),bucket=bucket_id=0,weight:100,actions=ct(nat(dst=fd0f::2),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=fd0f::3),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label))) + encodes as group:9 + uses group: id(9), name(type=select,selection_method=hash,fields(eth_src,eth_dst,ip_src,ip_dst,udp_src,udp_dst),bucket=bucket_id=0,weight:100,actions=ct(nat(dst=fd0f::2),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=fd0f::3),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label))) has prereqs ip ct_lb(backends=fd0f::2,fd0f::3; hash_fields="eth_src,eth_dst,ip_src,ip_dst,sctp_src,sctp_dst"); - encodes as group:8 - uses group: id(8), name(type=select,selection_method=hash,fields(eth_src,eth_dst,ip_src,ip_dst,sctp_src,sctp_dst),bucket=bucket_id=0,weight:100,actions=ct(nat(dst=fd0f::2),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=fd0f::3),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label))) + encodes as group:10 + uses group: id(10), name(type=select,selection_method=hash,fields(eth_src,eth_dst,ip_src,ip_dst,sctp_src,sctp_dst),bucket=bucket_id=0,weight:100,actions=ct(nat(dst=fd0f::2),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=fd0f::3),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label))) + has prereqs ip +ct_lb(backends=fd0f::2,fd0f::3; hash_fields="eth_src,eth_dst,ip_src,ip_dst,sctp_src,sctp_dst"; skip_snat); + encodes as group:11 + uses group: id(11), name(type=select,selection_method=hash,fields(eth_src,eth_dst,ip_src,ip_dst,sctp_src,sctp_dst),bucket=bucket_id=0,weight:100,actions=ct(nat(dst=fd0f::2),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label,set_field:4/4->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=fd0f::3),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label,set_field:4/4->ct_label))) + has prereqs ip +ct_lb(backends=fd0f::2,fd0f::3; hash_fields="eth_src,eth_dst,ip_src,ip_dst,sctp_src,sctp_dst"; force_snat); + encodes as group:12 + uses group: id(12), name(type=select,selection_method=hash,fields(eth_src,eth_dst,ip_src,ip_dst,sctp_src,sctp_dst),bucket=bucket_id=0,weight:100,actions=ct(nat(dst=fd0f::2),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label,set_field:8/8->ct_label)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=fd0f::3),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_label,set_field:8/8->ct_label))) has prereqs ip ct_lb_mark(backends=192.168.1.2:80,192.168.1.3:80); - encodes as group:9 - uses group: id(9), name(type=select,selection_method=dp_hash,bucket=bucket_id=0,weight:100,actions=ct(nat(dst=192.168.1.2:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_mark)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=192.168.1.3:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_mark))) + encodes as group:13 + uses group: id(13), name(type=select,selection_method=dp_hash,bucket=bucket_id=0,weight:100,actions=ct(nat(dst=192.168.1.2:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_mark)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=192.168.1.3:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_mark))) + has prereqs ip +ct_lb_mark(backends=192.168.1.2:80,192.168.1.3:80; skip_snat); + encodes as group:14 + uses group: id(14), name(type=select,selection_method=dp_hash,bucket=bucket_id=0,weight:100,actions=ct(nat(dst=192.168.1.2:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_mark,set_field:4/4->ct_mark)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=192.168.1.3:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_mark,set_field:4/4->ct_mark))) + has prereqs ip +ct_lb_mark(backends=192.168.1.2:80,192.168.1.3:80; force_snat); + encodes as group:15 + uses group: id(15), name(type=select,selection_method=dp_hash,bucket=bucket_id=0,weight:100,actions=ct(nat(dst=192.168.1.2:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_mark,set_field:8/8->ct_mark)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=192.168.1.3:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_mark,set_field:8/8->ct_mark))) + has prereqs ip +ct_lb_mark(backends=192.168.1.2:80,192.168.1.3:80; hash_fields="eth_src,eth_dst,ip_src,ip_dst,sctp_src,sctp_dst"); + encodes as group:16 + uses group: id(16), name(type=select,selection_method=hash,fields(eth_src,eth_dst,ip_src,ip_dst,sctp_src,sctp_dst),bucket=bucket_id=0,weight:100,actions=ct(nat(dst=192.168.1.2:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_mark)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=192.168.1.3:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_mark))) has prereqs ip +ct_lb_mark(backends=192.168.1.2:80,192.168.1.3:80; hash_fields="eth_src,eth_dst,ip_src,ip_dst,sctp_src,sctp_dst"; skip_snat); + encodes as group:17 + uses group: id(17), name(type=select,selection_method=hash,fields(eth_src,eth_dst,ip_src,ip_dst,sctp_src,sctp_dst),bucket=bucket_id=0,weight:100,actions=ct(nat(dst=192.168.1.2:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_mark,set_field:4/4->ct_mark)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=192.168.1.3:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_mark,set_field:4/4->ct_mark))) + has prereqs ip +ct_lb_mark(backends=192.168.1.2:80,192.168.1.3:80; hash_fields="eth_src,eth_dst,ip_src,ip_dst,sctp_src,sctp_dst"; force_snat); + encodes as group:18 + uses group: id(18), name(type=select,selection_method=hash,fields(eth_src,eth_dst,ip_src,ip_dst,sctp_src,sctp_dst),bucket=bucket_id=0,weight:100,actions=ct(nat(dst=192.168.1.2:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_mark,set_field:8/8->ct_mark)),bucket=bucket_id=1,weight:100,actions=ct(nat(dst=192.168.1.3:80),commit,table=19,zone=NXM_NX_REG13[0..15],exec(set_field:2/2->ct_mark,set_field:8/8->ct_mark))) + has prereqs ip + # ct_next ct_next; encodes as ct(table=19,zone=NXM_NX_REG13[0..15]) @@ -1927,13 +1968,13 @@ handle_svc_check(reg0); # select reg9[16..31] = select(1=50, 2=100, 3, ); formats as reg9[16..31] = select(1=50, 2=100, 3=100); - encodes as group:10 - uses group: id(10), name(type=select,selection_method=dp_hash,bucket=bucket_id=0,weight:50,actions=load:1->xreg4[16..31],resubmit(,19),bucket=bucket_id=1,weight:100,actions=load:2->xreg4[16..31],resubmit(,19),bucket=bucket_id=2,weight:100,actions=load:3->xreg4[16..31],resubmit(,19)) + encodes as group:19 + uses group: id(19), name(type=select,selection_method=dp_hash,bucket=bucket_id=0,weight:50,actions=load:1->xreg4[16..31],resubmit(,19),bucket=bucket_id=1,weight:100,actions=load:2->xreg4[16..31],resubmit(,19),bucket=bucket_id=2,weight:100,actions=load:3->xreg4[16..31],resubmit(,19)) reg0 = select(1, 2); formats as reg0 = select(1=100, 2=100); - encodes as group:11 - uses group: id(11), name(type=select,selection_method=dp_hash,bucket=bucket_id=0,weight:100,actions=load:1->xxreg0[96..127],resubmit(,19),bucket=bucket_id=1,weight:100,actions=load:2->xxreg0[96..127],resubmit(,19)) + encodes as group:20 + uses group: id(20), name(type=select,selection_method=dp_hash,bucket=bucket_id=0,weight:100,actions=load:1->xxreg0[96..127],resubmit(,19),bucket=bucket_id=1,weight:100,actions=load:2->xxreg0[96..127],resubmit(,19)) reg0 = select(1=, 2); Syntax error at `,' expecting weight. @@ -1950,12 +1991,12 @@ reg0[0..14] = select(1, 2, 3); fwd_group(liveness=true, childports="eth0", "lsp1"); formats as fwd_group(liveness="true", childports="eth0", "lsp1"); - encodes as group:12 - uses group: id(12), name(type=select,selection_method=dp_hash,bucket=watch_port:5,load=0x5->NXM_NX_REG15[0..15],resubmit(,64),bucket=watch_port:17,load=0x17->NXM_NX_REG15[0..15],resubmit(,64)) + encodes as group:21 + uses group: id(21), name(type=select,selection_method=dp_hash,bucket=watch_port:5,load=0x5->NXM_NX_REG15[0..15],resubmit(,64),bucket=watch_port:17,load=0x17->NXM_NX_REG15[0..15],resubmit(,64)) fwd_group(childports="eth0", "lsp1"); - encodes as group:13 - uses group: id(13), name(type=select,selection_method=dp_hash,bucket=load=0x5->NXM_NX_REG15[0..15],resubmit(,64),bucket=load=0x17->NXM_NX_REG15[0..15],resubmit(,64)) + encodes as group:22 + uses group: id(22), name(type=select,selection_method=dp_hash,bucket=load=0x5->NXM_NX_REG15[0..15],resubmit(,64),bucket=load=0x17->NXM_NX_REG15[0..15],resubmit(,64)) fwd_group(childports=eth0); Syntax error at `eth0' expecting logical switch port. @@ -1964,8 +2005,8 @@ fwd_group(); Syntax error at `)' expecting `;'. fwd_group(childports="eth0", "lsp1"); - encodes as group:13 - uses group: id(13), name(type=select,selection_method=dp_hash,bucket=load=0x5->NXM_NX_REG15[0..15],resubmit(,64),bucket=load=0x17->NXM_NX_REG15[0..15],resubmit(,64)) + encodes as group:22 + uses group: id(22), name(type=select,selection_method=dp_hash,bucket=load=0x5->NXM_NX_REG15[0..15],resubmit(,64),bucket=load=0x17->NXM_NX_REG15[0..15],resubmit(,64)) fwd_group(liveness=xyzzy, childports="eth0", "lsp1"); Syntax error at `xyzzy' expecting true or false. diff --git a/tests/system-ovn.at b/tests/system-ovn.at index e3325acae..99ad14aa5 100644 --- a/tests/system-ovn.at +++ b/tests/system-ovn.at @@ -2197,6 +2197,7 @@ grep 'nat(dst=192.168.2.2:80)']) OVS_START_L7([foo1], [http]) OVS_START_L7([bar1], [http]) +check ovs-appctl dpctl/flush-conntrack dnl Should work with the virtual IP address through NAT for i in `seq 1 20`; do echo Request $i @@ -2210,6 +2211,7 @@ tcp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(sr tcp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) ]) +check ovs-appctl dpctl/flush-conntrack dnl Test load-balancing that includes L4 ports in NAT. for i in `seq 1 20`; do echo Request $i @@ -2253,6 +2255,7 @@ ovn-sbctl dump-flows R2 OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-flows br-int table=43 | \ grep 'nat(src=20.0.0.2)']) +check ovs-appctl dpctl/flush-conntrack dnl Test load-balancing that includes L4 ports in NAT. for i in `seq 1 20`; do echo Request $i @@ -2262,8 +2265,8 @@ done dnl Each server should have at least one connection. AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl -tcp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) -tcp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10,protoinfo=(state=<cleared>) +tcp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10,protoinfo=(state=<cleared>) ]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0.2) | @@ -2293,6 +2296,7 @@ grep 'nat(src=20.0.0.2)']) rm -f wget*.log +check ovs-appctl dpctl/flush-conntrack dnl Test load-balancing that includes L4 ports in NAT. for i in `seq 1 20`; do echo Request $i @@ -2302,8 +2306,8 @@ done dnl Each server should have at least one connection. AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl -tcp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) -tcp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10,protoinfo=(state=<cleared>) +tcp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10,protoinfo=(state=<cleared>) ]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0.2) | @@ -2731,8 +2735,8 @@ done dnl Each server should have at least one connection. AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl -tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) -tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10,protoinfo=(state=<cleared>) +tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10,protoinfo=(state=<cleared>) ]) dnl Force SNAT should have worked. @@ -2904,8 +2908,8 @@ done dnl Each server should have at least one connection. AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd30::1) | grep -v fe80 | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl -tcp,orig=(src=fd72::3,dst=fd30::1,sport=<cleared>,dport=<cleared>),reply=(src=fd11::2,dst=fd72::3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) -tcp,orig=(src=fd72::3,dst=fd30::1,sport=<cleared>,dport=<cleared>),reply=(src=fd12::2,dst=fd72::3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=fd72::3,dst=fd30::1,sport=<cleared>,dport=<cleared>),reply=(src=fd11::2,dst=fd72::3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10,protoinfo=(state=<cleared>) +tcp,orig=(src=fd72::3,dst=fd30::1,sport=<cleared>,dport=<cleared>),reply=(src=fd12::2,dst=fd72::3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10,protoinfo=(state=<cleared>) ]) dnl Force SNAT should have worked. @@ -3120,13 +3124,13 @@ done dnl Each server should have at least one connection. AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl -tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) -tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10,protoinfo=(state=<cleared>) +tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10,protoinfo=(state=<cleared>) ]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fd30::1) | grep -v fe80 | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl -tcp,orig=(src=fd72::3,dst=fd30::1,sport=<cleared>,dport=<cleared>),reply=(src=fd11::2,dst=fd72::3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) -tcp,orig=(src=fd72::3,dst=fd30::1,sport=<cleared>,dport=<cleared>),reply=(src=fd12::2,dst=fd72::3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=fd72::3,dst=fd30::1,sport=<cleared>,dport=<cleared>),reply=(src=fd11::2,dst=fd72::3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10,protoinfo=(state=<cleared>) +tcp,orig=(src=fd72::3,dst=fd30::1,sport=<cleared>,dport=<cleared>),reply=(src=fd12::2,dst=fd72::3,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10,protoinfo=(state=<cleared>) ]) dnl Force SNAT should have worked. @@ -9352,6 +9356,29 @@ udp,orig=(src=192.168.10.10,dst=192.168.20.20,sport=<cleared>,dport=<cleared>),r check ovn-nbctl lr-lb-del lr check ovn-nbctl lb-del lb0 +AS_BOX([ICMP related force SNAT]) +check ovn-nbctl lb-add lb0 192.168.20.20 192.168.20.10 +check ovn-nbctl lr-lb-add lr lb0 + +check ovn-nbctl --wait=sb set logical_router lr options:lb_force_snat_ip="router_ip" + +# Change the expected packets on server to be with source IP from router +server_udp_expected=00000000201000000000200008004500001c000040000911c875c0a8\ +1401c0a8140a0001000200080000 +icmp_expected=000000002010000000002000080045000038011f0000fe01124ac0a81401c0\ +a8140a0304f778000005784500001c000040000911c875c0a8140ac0a814010002000100080000 + +# Server should respond to the router IP +server_udp=00000000200000000000201008004500001C000040000A11C775C0A8140AC0A8\ +14010002000100080000 + +test_related_traffic + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.20.20) | \ +sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +udp,orig=(src=192.168.10.10,dst=192.168.20.20,sport=<cleared>,dport=<cleared>),reply=(src=192.168.20.10,dst=192.168.10.10,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=10 +]) + OVS_APP_EXIT_AND_WAIT([ovn-controller]) as ovn-sb -- 2.38.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
