Re: [ovs-dev] [PATCH ovn v2 4/7] actions: Add new actions chk_lb_hairpin, chk_lb_hairpin_reply and ct_snat_to_vip.

2020-10-29 Thread Dumitru Ceara
On 10/27/20 6:19 PM, num...@ovn.org wrote:
> From: Numan Siddique 
> 
> The action - chk_lb_hairpin checks if the packet destined to a load balancer 
> VIP
> is to be hairpinned back to the same destination and if so, sets the 
> destination register
> bit to 1.
> 
> The action - chk_lb_hairpin_reply checks if the packet is a reply of the 
> hairpinned
> packet. If so, it sets the destination register bit to 1.
> 
> The action ct_snat_to_vip snats the source IP to the load balancer VIP if 
> chk_lb_hairpin()
> returned true.
> 
> These actions will be used in the upcoming patch by ovn-northd in the hairpin 
> logical flows.
> This helps in reducing lots of hairpin logical flows.
> 
> Signed-off-by: Numan Siddique 
> ---
>  controller/lflow.c|   3 ++
>  include/ovn/actions.h |  15 --
>  lib/actions.c | 116 ++
>  ovn-sb.xml|  37 ++
>  tests/ovn.at  |  39 ++
>  tests/test-ovn.c  |   3 ++
>  utilities/ovn-trace.c |  65 ++-
>  7 files changed, 265 insertions(+), 13 deletions(-)
> 
> diff --git a/controller/lflow.c b/controller/lflow.c
> index 657482626d..588c72dc22 100644
> --- a/controller/lflow.c
> +++ b/controller/lflow.c
> @@ -698,6 +698,9 @@ add_matches_to_flow_table(const struct sbrec_logical_flow 
> *lflow,
>  .output_ptable = output_ptable,
>  .mac_bind_ptable = OFTABLE_MAC_BINDING,
>  .mac_lookup_ptable = OFTABLE_MAC_LOOKUP,
> +.lb_hairpin_ptable = OFTABLE_CHK_LB_HAIRPIN,
> +.lb_hairpin_reply_ptable = OFTABLE_CHK_LB_HAIRPIN_REPLY,
> +.ct_snat_vip_ptable = OFTABLE_CT_SNAT_FOR_VIP,
>  };
>  ovnacts_encode(ovnacts->data, ovnacts->size, , );
>  
> diff --git a/include/ovn/actions.h b/include/ovn/actions.h
> index b4e5acabb9..32f9c53dfc 100644
> --- a/include/ovn/actions.h
> +++ b/include/ovn/actions.h
> @@ -83,7 +83,7 @@ struct ovn_extend_table;
>  OVNACT(PUT_DHCPV4_OPTS,   ovnact_put_opts)\
>  OVNACT(PUT_DHCPV6_OPTS,   ovnact_put_opts)\
>  OVNACT(SET_QUEUE, ovnact_set_queue)   \
> -OVNACT(DNS_LOOKUP,ovnact_dns_lookup)  \
> +OVNACT(DNS_LOOKUP,ovnact_result)  \

Nit: indent.

Thanks,
Dumitru

>  OVNACT(LOG,   ovnact_log) \
>  OVNACT(PUT_ND_RA_OPTS,ovnact_put_opts)\
>  OVNACT(ND_NS, ovnact_nest)\
> @@ -97,6 +97,9 @@ struct ovn_extend_table;
>  OVNACT(DHCP6_REPLY,   ovnact_null)\
>  OVNACT(ICMP6_ERROR,   ovnact_nest)\
>  OVNACT(REJECT,ovnact_nest)\
> +OVNACT(CHK_LB_HAIRPIN,ovnact_result)  \
> +OVNACT(CHK_LB_HAIRPIN_REPLY, ovnact_result)   \
> +OVNACT(CT_SNAT_TO_VIP,ovnact_null)\
>  
>  /* enum ovnact_type, with a member OVNACT_ for each action. */
>  enum OVS_PACKED_ENUM ovnact_type {
> @@ -338,8 +341,8 @@ struct ovnact_set_queue {
>  uint16_t queue_id;
>  };
>  
> -/* OVNACT_DNS_LOOKUP. */
> -struct ovnact_dns_lookup {
> +/* OVNACT_DNS_LOOKUP, OVNACT_CHK_LB_HAIRPIN, OVNACT_CHK_LB_HAIRPIN_REPLY. */
> +struct ovnact_result {
>  struct ovnact ovnact;
>  struct expr_field dst;  /* 1-bit destination field. */
>  };
> @@ -727,6 +730,12 @@ struct ovnact_encode_params {
> resubmit. */
>  uint8_t mac_lookup_ptable;  /* OpenFlow table for
> 'lookup_arp'/'lookup_nd' to resubmit. */
> +uint8_t lb_hairpin_ptable;  /* OpenFlow table for
> + * 'chk_lb_hairpin' to resubmit. */
> +uint8_t lb_hairpin_reply_ptable;  /* OpenFlow table for
> +   * 'chk_lb_hairpin_reply' to resubmit. 
> */
> +uint8_t ct_snat_vip_ptable;  /* OpenFlow table for
> +  * 'ct_snat_to_vip' to resubmit. */
>  };
>  
>  void ovnacts_encode(const struct ovnact[], size_t ovnacts_len,
> diff --git a/lib/actions.c b/lib/actions.c
> index 23e54ef2a6..015bcbc4dc 100644
> --- a/lib/actions.c
> +++ b/lib/actions.c
> @@ -2655,13 +2655,14 @@ ovnact_set_queue_free(struct ovnact_set_queue *a 
> OVS_UNUSED)
>  }
>  
>  static void
> -parse_dns_lookup(struct action_context *ctx, const struct expr_field *dst,
> - struct ovnact_dns_lookup *dl)
> +parse_ovnact_result(struct action_context *ctx, const char *name,
> +const char *prereq, const struct expr_field *dst,
> +struct ovnact_result *res)
>  {
> -lexer_get(ctx->lexer); /* Skip dns_lookup. */
> +lexer_get(ctx->lexer); /* Skip action name. */
>  lexer_get(ctx->lexer); /* Skip '('. */
>  if (!lexer_match(ctx->lexer, LEX_T_RPAREN)) {
> -lexer_error(ctx->lexer, "dns_lookup doesn't take any parameters");
> +lexer_error(ctx->lexer, "%s doesn't take any parameters", name);
>  return;
>  }
>  /* 

[ovs-dev] [PATCH ovn v2 4/7] actions: Add new actions chk_lb_hairpin, chk_lb_hairpin_reply and ct_snat_to_vip.

2020-10-27 Thread numans
From: Numan Siddique 

The action - chk_lb_hairpin checks if the packet destined to a load balancer VIP
is to be hairpinned back to the same destination and if so, sets the 
destination register
bit to 1.

The action - chk_lb_hairpin_reply checks if the packet is a reply of the 
hairpinned
packet. If so, it sets the destination register bit to 1.

The action ct_snat_to_vip snats the source IP to the load balancer VIP if 
chk_lb_hairpin()
returned true.

These actions will be used in the upcoming patch by ovn-northd in the hairpin 
logical flows.
This helps in reducing lots of hairpin logical flows.

Signed-off-by: Numan Siddique 
---
 controller/lflow.c|   3 ++
 include/ovn/actions.h |  15 --
 lib/actions.c | 116 ++
 ovn-sb.xml|  37 ++
 tests/ovn.at  |  39 ++
 tests/test-ovn.c  |   3 ++
 utilities/ovn-trace.c |  65 ++-
 7 files changed, 265 insertions(+), 13 deletions(-)

diff --git a/controller/lflow.c b/controller/lflow.c
index 657482626d..588c72dc22 100644
--- a/controller/lflow.c
+++ b/controller/lflow.c
@@ -698,6 +698,9 @@ add_matches_to_flow_table(const struct sbrec_logical_flow 
*lflow,
 .output_ptable = output_ptable,
 .mac_bind_ptable = OFTABLE_MAC_BINDING,
 .mac_lookup_ptable = OFTABLE_MAC_LOOKUP,
+.lb_hairpin_ptable = OFTABLE_CHK_LB_HAIRPIN,
+.lb_hairpin_reply_ptable = OFTABLE_CHK_LB_HAIRPIN_REPLY,
+.ct_snat_vip_ptable = OFTABLE_CT_SNAT_FOR_VIP,
 };
 ovnacts_encode(ovnacts->data, ovnacts->size, , );
 
diff --git a/include/ovn/actions.h b/include/ovn/actions.h
index b4e5acabb9..32f9c53dfc 100644
--- a/include/ovn/actions.h
+++ b/include/ovn/actions.h
@@ -83,7 +83,7 @@ struct ovn_extend_table;
 OVNACT(PUT_DHCPV4_OPTS,   ovnact_put_opts)\
 OVNACT(PUT_DHCPV6_OPTS,   ovnact_put_opts)\
 OVNACT(SET_QUEUE, ovnact_set_queue)   \
-OVNACT(DNS_LOOKUP,ovnact_dns_lookup)  \
+OVNACT(DNS_LOOKUP,ovnact_result)  \
 OVNACT(LOG,   ovnact_log) \
 OVNACT(PUT_ND_RA_OPTS,ovnact_put_opts)\
 OVNACT(ND_NS, ovnact_nest)\
@@ -97,6 +97,9 @@ struct ovn_extend_table;
 OVNACT(DHCP6_REPLY,   ovnact_null)\
 OVNACT(ICMP6_ERROR,   ovnact_nest)\
 OVNACT(REJECT,ovnact_nest)\
+OVNACT(CHK_LB_HAIRPIN,ovnact_result)  \
+OVNACT(CHK_LB_HAIRPIN_REPLY, ovnact_result)   \
+OVNACT(CT_SNAT_TO_VIP,ovnact_null)\
 
 /* enum ovnact_type, with a member OVNACT_ for each action. */
 enum OVS_PACKED_ENUM ovnact_type {
@@ -338,8 +341,8 @@ struct ovnact_set_queue {
 uint16_t queue_id;
 };
 
-/* OVNACT_DNS_LOOKUP. */
-struct ovnact_dns_lookup {
+/* OVNACT_DNS_LOOKUP, OVNACT_CHK_LB_HAIRPIN, OVNACT_CHK_LB_HAIRPIN_REPLY. */
+struct ovnact_result {
 struct ovnact ovnact;
 struct expr_field dst;  /* 1-bit destination field. */
 };
@@ -727,6 +730,12 @@ struct ovnact_encode_params {
resubmit. */
 uint8_t mac_lookup_ptable;  /* OpenFlow table for
'lookup_arp'/'lookup_nd' to resubmit. */
+uint8_t lb_hairpin_ptable;  /* OpenFlow table for
+ * 'chk_lb_hairpin' to resubmit. */
+uint8_t lb_hairpin_reply_ptable;  /* OpenFlow table for
+   * 'chk_lb_hairpin_reply' to resubmit. */
+uint8_t ct_snat_vip_ptable;  /* OpenFlow table for
+  * 'ct_snat_to_vip' to resubmit. */
 };
 
 void ovnacts_encode(const struct ovnact[], size_t ovnacts_len,
diff --git a/lib/actions.c b/lib/actions.c
index 23e54ef2a6..015bcbc4dc 100644
--- a/lib/actions.c
+++ b/lib/actions.c
@@ -2655,13 +2655,14 @@ ovnact_set_queue_free(struct ovnact_set_queue *a 
OVS_UNUSED)
 }
 
 static void
-parse_dns_lookup(struct action_context *ctx, const struct expr_field *dst,
- struct ovnact_dns_lookup *dl)
+parse_ovnact_result(struct action_context *ctx, const char *name,
+const char *prereq, const struct expr_field *dst,
+struct ovnact_result *res)
 {
-lexer_get(ctx->lexer); /* Skip dns_lookup. */
+lexer_get(ctx->lexer); /* Skip action name. */
 lexer_get(ctx->lexer); /* Skip '('. */
 if (!lexer_match(ctx->lexer, LEX_T_RPAREN)) {
-lexer_error(ctx->lexer, "dns_lookup doesn't take any parameters");
+lexer_error(ctx->lexer, "%s doesn't take any parameters", name);
 return;
 }
 /* Validate that the destination is a 1-bit, modifiable field. */
@@ -2671,19 +2672,29 @@ parse_dns_lookup(struct action_context *ctx, const 
struct expr_field *dst,
 free(error);
 return;
 }
-dl->dst = *dst;
-add_prerequisite(ctx, "udp");
+res->dst = *dst;
+
+if (prereq) {
+