On Mon, Aug 1, 2016 at 7:16 PM, Zong Kai LI <zealo...@gmail.com> wrote:

> This patch tries to implement Router Advertisement (RA) responder for SLAAC
> on ovn-northd side.
>
> It tries to build lflows per each Logical Router Port, who have IPv6
> networks
> and set their 'slaac' column to true.
>
> The lflows will look like:
>  match=(inport == "lrp-32a71e0b-8b19-4c52-8cde-058325e4df5d" &&
>         ip6.dst == ff02::2 && nd_rs)
>  action=(nd_ra{slaac(fd80:a123:b345::/64,1450,fa:16:3e:62:f1:e6);
>          outport = inport; flags.loopback = 1; output;};)
> while:
>  - nd_rs is a new symbol stands for
>    "icmp6.type == 133 && icmp6.code == 0 && ttl == 255"
>  - slaac is a new action which accepts ordered parameter list:
>      - one or more IPv6 prefixes: such as fd80:a123:b345::/64.
>      - MTU: logical switch MTU, such as 1450.
>      - MAC address: router port mac address, such as fa:16:3e:62:f1:e6.
>  - nd_ra is a new action which stands for RA responder, it will compose a
> RA
>    packet per parameters in slaac, and eth.src and ip6.src from packet
> being
>    processed.
>
This would be a router solicitation responder, since it responds to router
solicitation messages by sending router advertisement messages.

>
> Logical_Router_Port.slaac column will only tell whether ovn should reply a
> RA
> packet for Router solicitation packet received from the lrp port. To
> respond
> a RA packet for other scenario will be a future work.
> ---
>  ovn/northd/ovn-northd.c |  94 ++++++++++++++++++++++++++++++++++++----
>  ovn/ovn-nb.ovsschema    |   6 ++-
>  ovn/ovn-nb.xml          |  11 +++++
>  tests/ovn.at            | 111 ++++++++++++++++++++++++++++++
> ++++++++++++++++++
>  4 files changed, 213 insertions(+), 9 deletions(-)
>
> diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
> index d6c14cf..98db819 100644
> --- a/ovn/northd/ovn-northd.c
> +++ b/ovn/northd/ovn-northd.c
> @@ -126,9 +126,10 @@ enum ovn_stage {
>      PIPELINE_STAGE(ROUTER, IN,  IP_INPUT,    1, "lr_in_ip_input")     \
>      PIPELINE_STAGE(ROUTER, IN,  UNSNAT,      2, "lr_in_unsnat")       \
>      PIPELINE_STAGE(ROUTER, IN,  DNAT,        3, "lr_in_dnat")         \
> -    PIPELINE_STAGE(ROUTER, IN,  IP_ROUTING,  4, "lr_in_ip_routing")   \
> -    PIPELINE_STAGE(ROUTER, IN,  ARP_RESOLVE, 5, "lr_in_arp_resolve")  \
> -    PIPELINE_STAGE(ROUTER, IN,  ARP_REQUEST, 6, "lr_in_arp_request")  \
> +    PIPELINE_STAGE(ROUTER, IN,  RA_RSP,      4, "lr_in_ra_rsp")      \

Since this is responding to router solicitation messages, should this be
RS_RSP?

> +    PIPELINE_STAGE(ROUTER, IN,  IP_ROUTING,  5, "lr_in_ip_routing")   \
> +    PIPELINE_STAGE(ROUTER, IN,  ARP_RESOLVE, 6, "lr_in_arp_resolve")  \
> +    PIPELINE_STAGE(ROUTER, IN,  ARP_REQUEST, 7, "lr_in_arp_request")  \
>                                                                        \
>      /* Logical router egress stages. */                               \
>      PIPELINE_STAGE(ROUTER, OUT, SNAT,      0, "lr_out_snat")          \
> @@ -3409,7 +3443,51 @@ build_lrouter_flows(struct hmap *datapaths, struct
> hmap *ports,
>                        "ip", "flags.loopback = 1; ct_dnat;");
>      }
>
> -    /* Logical router ingress table 4: IP Routing.
> +    /* Logical router ingress table 5: RA responder, by default goto next.
>
Isn't this table 4 now?

> +     * (priority 0)*/
> +    HMAP_FOR_EACH (od, key_node, datapaths) {
> +        if (!od->nbr) {
> +            continue;
> +        }
> +
> +        ovn_lflow_add(lflows, od, S_ROUTER_IN_RA_RSP, 0, "1", "next;");
> +    }
> +
> +    /* Logical router ingress table 5: RA responder, reply for 'slaac'
> enabled
> +     * router port. (priority 50)*/
> +    HMAP_FOR_EACH (op, key_node, ports) {
> +        if (!op->nbrp || op->nbrp->peer
> +            || !op->peer
> +            || !op->nbrp->slaac
> +            || !*op->nbrp->slaac) {
> +            continue;
> +        }
> +
> +        ds_clear(&match);
> +        ds_put_format(&match, "inport == %s", op->json_key);
> +        ds_put_cstr(&match,  " && ip6.dst == ff02::2 && nd_rs");
> +        ds_clear(&actions);
> +        ds_put_format(&actions, "nd_ra{slaac(");
> +        size_t actions_len = actions.length;
> +        for (size_t i = 0; i != op->lrp_networks.n_ipv6_addrs; i++) {
> +            if (in6_is_lla(&op->lrp_networks.ipv6_addrs[i].network)) {
> +                continue;
> +            }
> +            ds_put_format(&actions, "%s/%u,",
> +                          op->lrp_networks.ipv6_addrs[i].network_s,
> +                          op->lrp_networks.ipv6_addrs[i].plen);
> +        }
> +        if (actions.length != actions_len) {
> +            ds_put_format(&actions, "%ld,", op->peer->od->nbs->mtu);
> +            ds_put_cstr(&actions, op->lrp_networks.ea_s);
> +            ds_put_cstr(&actions, "); outport = inport; flags.loopback =
> 1;"
> +                                  " output;};");
> +            ovn_lflow_add(lflows, op->od, S_ROUTER_IN_RA_RSP, 50,
> +                          ds_cstr(&match), ds_cstr(&actions));
> +        }
> +    }
> +
> +    /* Logical router ingress table 5: IP Routing.
>       *
>       * A packet that arrives at this table is an IP packet that should be
>       * routed to the address in 'ip[46].dst'. This table sets outport to
> diff --git a/ovn/ovn-nb.ovsschema b/ovn/ovn-nb.ovsschema
> index 660db76..f4d57a1 100644
> --- a/ovn/ovn-nb.ovsschema
> +++ b/ovn/ovn-nb.ovsschema
> @@ -34,6 +34,9 @@
>                  "other_config": {
>                      "type": {"key": "string", "value": "string",
>                               "min": 0, "max": "unlimited"}},
> +                "mtu": {"type": {"key": {"type": "integer",
> +                                         "minInteger": 0,
> +                                         "maxInteger": 65535}}},
>
IPv6 specifies a minimum MTU of 1280, unless 0 is a sentinel value to not
include MTU options in router advertisements (which I didn't see code to
implement), we should not permit invalid MTUs in the database schema.

>                  "external_ids": {
>                      "type": {"key": "string", "value": "string",
>                               "min": 0, "max": "unlimited"}}},
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to