On Thu, Sep 7, 2017 at 8:12 AM Jakub Sitnicki <j...@redhat.com> wrote:

> Hi Mark,
>
> On Wed,  6 Sep 2017 16:08:37 -0500
> Mark Michelson <mmich...@redhat.com> wrote:
>
> > The ct_lb action previously assumed that any address arguments were
> > IPv4. This patch expands the parsing, formatting, and encoding of ct_lb
> > to be amenable to IPv6 addresses as well.
> >
> > Signed-off-by: Mark Michelson <mmich...@redhat.com>
> > ---
> >  include/ovn/actions.h |  4 ++-
> >  ovn/lib/actions.c     | 99
> ++++++++++++++++++++++++++++++++++++++++-----------
> >  tests/ovn.at          |  8 ++++-
> >  3 files changed, 89 insertions(+), 22 deletions(-)
> >
> > diff --git a/include/ovn/actions.h b/include/ovn/actions.h
> > index 0a04af7aa..ec0063efc 100644
> > --- a/include/ovn/actions.h
> > +++ b/include/ovn/actions.h
> > @@ -200,7 +200,9 @@ struct ovnact_ct_nat {
> >  };
> >
> >  struct ovnact_ct_lb_dst {
> > -    ovs_be32 ip;
> > +    int family;
> > +    struct in6_addr ipv6;
> > +    ovs_be32 ipv4;
> >      uint16_t port;
> >  };
> >
>
> Do you think it would make sense to put 'ipv6' and 'ipv4' in an
> anonymous union to emphasize the fact that we're using only one or the
> other? Similar to how it was done in flow_hash_symmetric_l4():
>
>
Sure, I can do that. I think I'm going to wait for more feedback on the
patchset before posting new revisions, though.

Thanks for giving this a look!



> uint32_t
> flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis)
> {
>     struct {
>         union {
>             ovs_be32 ipv4_addr;
>             struct in6_addr ipv6_addr;
>         };
>         ovs_be16 eth_type;
>         ovs_be16 vlan_tci;
>         ovs_be16 tp_port;
>         struct eth_addr eth_addr;
>         uint8_t ip_proto;
>     } fields;
>     /* ... */
> }
>
> -Jakub
>
> > diff --git a/ovn/lib/actions.c b/ovn/lib/actions.c
> > index d0d73b69c..8d60529cb 100644
> > --- a/ovn/lib/actions.c
> > +++ b/ovn/lib/actions.c
> > @@ -883,23 +883,63 @@ parse_ct_lb_action(struct action_context *ctx)
> >
> >      if (lexer_match(ctx->lexer, LEX_T_LPAREN)) {
> >          while (!lexer_match(ctx->lexer, LEX_T_RPAREN)) {
> > -            if (ctx->lexer->token.type != LEX_T_INTEGER
> > -                || mf_subvalue_width(&ctx->lexer->token.value) > 32) {
> > -                free(dsts);
> > -                lexer_syntax_error(ctx->lexer, "expecting IPv4
> address");
> > -                return;
> > -            }
> > +            struct ovnact_ct_lb_dst dst;
> > +            if (lexer_match(ctx->lexer, LEX_T_LSQUARE)) {
> > +                /* IPv6 address and port */
> > +                if (ctx->lexer->token.type != LEX_T_INTEGER
> > +                    || ctx->lexer->token.format != LEX_F_IPV6) {
> > +                    free(dsts);
> > +                    lexer_syntax_error(ctx->lexer, "expecting IPv6
> address");
> > +                    return;
> > +                }
> > +                dst.family = AF_INET6;
> > +                dst.ipv6 = ctx->lexer->token.value.ipv6;
> >
> > -            /* Parse IP. */
> > -            ovs_be32 ip = ctx->lexer->token.value.ipv4;
> > -            lexer_get(ctx->lexer);
> > +                lexer_get(ctx->lexer);
> > +                if (!lexer_match(ctx->lexer, LEX_T_RSQUARE)) {
> > +                    free(dsts);
> > +                    lexer_syntax_error(ctx->lexer, "no closing square "
> > +                                                   "bracket");
> > +                    return;
> > +                }
> > +                dst.port = 0;
> > +                if (lexer_match(ctx->lexer, LEX_T_COLON)
> > +                    && !action_parse_port(ctx, &dst.port)) {
> > +                    free(dsts);
> > +                    return;
> > +                }
> > +            } else {
> > +                if (ctx->lexer->token.type != LEX_T_INTEGER
> > +                    || (ctx->lexer->token.format != LEX_F_IPV4
> > +                    && ctx->lexer->token.format != LEX_F_IPV6)) {
> > +                    free(dsts);
> > +                    lexer_syntax_error(ctx->lexer, "expecting IP
> address");
> > +                    return;
> > +                }
> >
> > -            /* Parse optional port. */
> > -            uint16_t port = 0;
> > -            if (lexer_match(ctx->lexer, LEX_T_COLON)
> > -                && !action_parse_port(ctx, &port)) {
> > -                free(dsts);
> > -                return;
> > +                /* Parse IP. */
> > +                struct ovnact_ct_lb_dst dst;
> > +                if (ctx->lexer->token.format == LEX_F_IPV4) {
> > +                    dst.family = AF_INET;
> > +                    dst.ipv4 = ctx->lexer->token.value.ipv4;
> > +                } else {
> > +                    dst.family = AF_INET6;
> > +                    dst.ipv6 = ctx->lexer->token.value.ipv6;
> > +                }
> > +
> > +                lexer_get(ctx->lexer);
> > +                dst.port = 0;
> > +                if (lexer_match(ctx->lexer, LEX_T_COLON)) {
> > +                    if (dst.family == AF_INET6) {
> > +                        free(dsts);
> > +                        lexer_syntax_error(ctx->lexer, "IPv6 address
> needs "
> > +                                "square brackets if port is included");
> > +                        return;
> > +                    } else if (!action_parse_port(ctx, &dst.port)) {
> > +                        free(dsts);
> > +                        return;
> > +                    }
> > +                }
> >              }
> >              lexer_match(ctx->lexer, LEX_T_COMMA);
> >
> > @@ -907,7 +947,7 @@ parse_ct_lb_action(struct action_context *ctx)
> >              if (n_dsts >= allocated_dsts) {
> >                  dsts = x2nrealloc(dsts, &allocated_dsts, sizeof *dsts);
> >              }
> > -            dsts[n_dsts++] = (struct ovnact_ct_lb_dst) { ip, port };
> > +            dsts[n_dsts++] = dst;
> >          }
> >      }
> >
> > @@ -929,9 +969,19 @@ format_CT_LB(const struct ovnact_ct_lb *cl, struct
> ds *s)
> >              }
> >
> >              const struct ovnact_ct_lb_dst *dst = &cl->dsts[i];
> > -            ds_put_format(s, IP_FMT, IP_ARGS(dst->ip));
> > -            if (dst->port) {
> > -                ds_put_format(s, ":%"PRIu16, dst->port);
> > +            if (dst->family == AF_INET) {
> > +                ds_put_format(s, IP_FMT, IP_ARGS(dst->ipv4));
> > +                if (dst->port) {
> > +                    ds_put_format(s, ":%"PRIu16, dst->port);
> > +                }
> > +            } else {
> > +                if (dst->port) {
> > +                    ds_put_char(s, '[');
> > +                }
> > +                ipv6_format_addr(&dst->ipv6, s);
> > +                if (dst->port) {
> > +                    ds_put_format(s, "]:%"PRIu16, dst->port);
> > +                }
> >              }
> >          }
> >          ds_put_char(s, ')');
> > @@ -991,8 +1041,17 @@ encode_CT_LB(const struct ovnact_ct_lb *cl,
> >      BUILD_ASSERT(MFF_LOG_DNAT_ZONE < MFF_REG0 + FLOW_N_REGS);
> >      for (size_t bucket_id = 0; bucket_id < cl->n_dsts; bucket_id++) {
> >          const struct ovnact_ct_lb_dst *dst = &cl->dsts[bucket_id];
> > +        char ip_addr[INET6_ADDRSTRLEN];
> > +        if (dst->family == AF_INET) {
> > +            inet_ntop(AF_INET, &dst->ipv4, ip_addr, sizeof ip_addr);
> > +        } else {
> > +            inet_ntop(AF_INET6, &dst->ipv6, ip_addr, sizeof ip_addr);
> > +        }
> >          ds_put_format(&ds,
> ",bucket=bucket_id=%"PRIuSIZE",weight:100,actions="
> > -                      "ct(nat(dst="IP_FMT, bucket_id, IP_ARGS(dst->ip));
> > +                      "ct(nat(dst=%s%s%s", bucket_id,
> > +                      dst->family == AF_INET6 && dst->port ? "[" : "",
> > +                      ip_addr,
> > +                      dst->family == AF_INET6 && dst->port ? "]" : "");
> >          if (dst->port) {
> >              ds_put_format(&ds, ":%"PRIu16, dst->port);
> >          }
> > diff --git a/tests/ovn.at b/tests/ovn.at
> > index fb9fc7352..9118f2839 100644
> > --- a/tests/ovn.at
> > +++ b/tests/ovn.at
> > @@ -793,13 +793,19 @@ ct_lb(192.168.1.2, 192.168.1.3, );
> >      formats as ct_lb(192.168.1.2, 192.168.1.3);
> >      encodes as group:2
> >      has prereqs ip
> > +ct_lb(fd0f::2, fd0f::3, );
> > +    formats as ct_lb(fd0f::2, fd0f::3);
> > +    encodes as group:3
> > +    has prereqs ip
> >
> >  ct_lb(192.168.1.2:);
> >      Syntax error at `)' expecting port number.
> >  ct_lb(192.168.1.2:123456);
> >      Syntax error at `123456' expecting port number.
> >  ct_lb(foo);
> > -    Syntax error at `foo' expecting IPv4 address.
> > +    Syntax error at `foo' expecting IP address.
> > +ct_lb([192.168.1.2]);
> > +    Syntax error at `192.168.1.2' expecting IPv6 address.
> >
> >  # ct_next
> >  ct_next;
>
>
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to