[ovs-dev] [PATCH v2 2/2] OVN: Add support for periodic router advertisements.
Mark Michelson
mmichels at redhat.com
Fri Nov 3 16:24:23 UTC 2017
Thanks for the reviews Jakub. I've added an in-line comment below.
Otherwise consider that there is an implicit "Will do!" on all of your
other suggestions.
On Fri, Nov 3, 2017 at 11:04 AM Jakub Sitnicki <jkbs at redhat.com> wrote:
> Hi again Mark,
>
> A batch of nit-picks/suggestions & a question that I've collected so far
> when reading through this patch. Please apply as you see fit.
>
> On Thu, Nov 02, 2017 at 08:47 PM GMT, Mark Michelson wrote:
> > This change adds three new options to the Northbound
> > Logical_Router_Port's ipv6_ra_configs option:
> >
> > * send_periodic: If set to "true", then OVN will send periodic router
> > advertisements out of this router port.
> > * max_interval: The maximum amount of time to wait between sending
> > periodic router advertisements.
> > * min_interval: The minimum amount of time to wait between sending
> > periodic router advertisements.
> >
> > When send_periodic is true, then IPv6 RA configs, as well as some layer
> > 2 and layer 3 information about the router port, are copied to the
> > southbound database. From there, ovn-controller can use this information
> > to know when to send periodic RAs and what to send in them.
> >
> > Because periodic RAs originate from each ovn-controller, the new
> > keep-local flag is set on the packet so that ports don't receive an
> > overabundance of RAs.
> >
> > Signed-off-by: Mark Michelson <mmichels at redhat.com>
> > ---
> > lib/packets.h | 4 +
> > ovn/controller/pinctrl.c | 349
> +++++++++++++++++++++++++++++++++++++++++++++++
> > ovn/northd/ovn-northd.c | 65 +++++++++
> > ovn/ovn-nb.xml | 19 +++
> > tests/ovn-northd.at | 110 +++++++++++++++
> > tests/ovn.at | 150 ++++++++++++++++++++
> > 6 files changed, 697 insertions(+)
> >
> > diff --git a/lib/packets.h b/lib/packets.h
> > index 057935cbf..9d69b93d0 100644
> > --- a/lib/packets.h
> > +++ b/lib/packets.h
> > @@ -976,6 +976,7 @@ BUILD_ASSERT_DECL(ND_PREFIX_OPT_LEN == sizeof(struct
> ovs_nd_prefix_opt));
> >
> > /* Neighbor Discovery option: MTU. */
> > #define ND_MTU_OPT_LEN 8
> > +#define ND_MTU_DEFAULT 0
> > struct ovs_nd_mtu_opt {
> > uint8_t type; /* ND_OPT_MTU */
> > uint8_t len; /* Always 1. */
> > @@ -1015,6 +1016,9 @@ BUILD_ASSERT_DECL(RA_MSG_LEN == sizeof(struct
> ovs_ra_msg));
> > #define ND_RA_MANAGED_ADDRESS 0x80
> > #define ND_RA_OTHER_CONFIG 0x40
> >
> > +#define ND_RA_MAX_INTERVAL_DEFAULT 600
> > +#define ND_RA_MIN_INTERVAL_DEFAULT(max) (max) >= 9 ? (max) / 3 : (max)
> * 3 / 4
> > +
>
> I don't understand the formula. It generates a sequence that is not
> always increasing but takes a dip when max == 9. What is the reasoning
> behind it?
>
It's based on RFC 4861 section 6.2.1.
MinRtrAdvInterval
The minimum time allowed between sending
unsolicited multicast Router Advertisements from
the interface, in seconds. MUST be no less than 3
seconds and no greater than .75 *
MaxRtrAdvInterval.
Default: 0.33 * MaxRtrAdvInterval If
MaxRtrAdvInterval >= 9 seconds; otherwise, the
Default is 0.75 * MaxRtrAdvInterval.
Note that this is not the exact quote from the RFC. I have altered the
default text to include the suggested change from Errata 3154. Does that
explain the formula better?
I can add the citation to the code so that it makes more sense for someone
skimming the code.
>
> Also, you probably want to put the expression in parenthesis to avoid
> surprises in evalution like: ND_RA_MIN_INTERVAL_DEFAULT(max)*1000.
>
> > /*
> > * Use the same struct for MLD and MLD2, naming members as the defined
> fields in
> > * in the corresponding version of the protocol, though they are
> reserved in the
> > diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c
> > index 29b2dde0c..f97eba4d5 100644
> > --- a/ovn/controller/pinctrl.c
> > +++ b/ovn/controller/pinctrl.c
> > @@ -48,6 +48,7 @@
> > #include "socket-util.h"
> > #include "timeval.h"
> > #include "vswitch-idl.h"
> > +#include "lflow.h"
> >
> > VLOG_DEFINE_THIS_MODULE(pinctrl);
> >
> > @@ -88,6 +89,11 @@ static void pinctrl_handle_put_nd_ra_opts(
> > static void pinctrl_handle_nd_ns(const struct flow *ip_flow,
> > const struct match *md,
> > struct ofpbuf *userdata);
> > +static void init_ipv6_ras(void);
> > +static void destroy_ipv6_ras(void);
> > +static void ipv6_ra_wait(void);
> > +static void send_ipv6_ras(const struct controller_ctx *ctx,
> > + struct hmap *local_datapaths);
> >
> > COVERAGE_DEFINE(pinctrl_drop_put_mac_binding);
> >
> > @@ -98,6 +104,7 @@ pinctrl_init(void)
> > conn_seq_no = 0;
> > init_put_mac_bindings();
> > init_send_garps();
> > + init_ipv6_ras();
> > }
> >
> > static ovs_be32
> > @@ -1083,8 +1090,348 @@ pinctrl_run(struct controller_ctx *ctx,
> > run_put_mac_bindings(ctx);
> > send_garp_run(ctx, br_int, chassis, chassis_index, local_datapaths,
> > active_tunnels);
> > + send_ipv6_ras(ctx, local_datapaths);
> > }
> >
> > +/* Table of ipv6_ra_state structures, keyed on logical port name */
> > +static struct shash ipv6_ras;
> > +
> > +/* Next IPV6 RA in seconds. */
> > +static long long int send_ipv6_ra_time;
> > +
> > +struct ipv6_network_prefix {
> > + struct in6_addr addr;
> > + unsigned int prefix_len;
> > +};
> > +
> > +struct ipv6_ra_config {
> > + time_t min_interval;
> > + time_t max_interval;
> > + struct eth_addr eth_src;
> > + struct eth_addr eth_dst;
> > + struct in6_addr ipv6_src;
> > + struct in6_addr ipv6_dst;
> > + ovs_be32 mtu;
> > + uint8_t mo_flags;
>
> Maybe annotate? For example /* Managed/Other RA flags */
>
> > + uint8_t la_flags;
>
> Maybe annotate? For example /* SLLAO flags */
>
> > + struct ipv6_network_prefix *prefixes;
> > + int n_prefixes;
> > +};
> > +
> > +struct ipv6_ra_state {
> > + long long int next_announce;
> > + struct ipv6_ra_config *config;
> > + int64_t port_key;
> > + int64_t metadata;
> > + bool deleteme;
> > +};
> > +
> > +static void
> > +init_ipv6_ras(void)
> > +{
> > + shash_init(&ipv6_ras);
> > + send_ipv6_ra_time = LLONG_MAX;
> > +}
> > +
> > +static void ipv6_ra_config_delete(struct ipv6_ra_config *config)
>
> Function return type not on a separate line.
>
> > +{
> > + if (config) {
> > + free(config->prefixes);
> > + }
> > + free(config);
> > +}
> > +
> > +static void
> > +ipv6_ra_delete(struct ipv6_ra_state *ra)
> > +{
> > + ipv6_ra_config_delete(ra->config);
> > + free(ra);
> > +}
>
> Would consider making the destructor NULL-friendly.
>
> [...]
>
> > diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml
> > index 8ad53cd7d..cddd5f6f2 100644
> > --- a/ovn/ovn-nb.xml
> > +++ b/ovn/ovn-nb.xml
> > @@ -1369,6 +1369,25 @@
> > Per RFC 2460, the mtu value is recommended no less than 1280, so
> > any mtu value less than 1280 will be considered as no MTU
> Option.
> > </column>
> > +
> > + <column name="ipv6_ra_configs" key="send_periodic">
> > + Should the router port send periodic router advertisements? If
> set to
> > + true, then this router interface will send router advertisements
> > + out periodically. The default is false.
> > + </column>
> > +
> > + <column name="ipv6_ra_configs" key="max_interval">
> > + The maximum number of seconds to wait between sending periodic
> router
> > + advertisements. This option has no effect if the
> "send_periodic" value
> > + is set to false. The default is 600.
> > + </column>
> > +
> > + <column name="ipv6_ra_configs" key="min_interval">
> > + The minimum number of seconds to wait between sending periodic
> router
> > + advertisements. This option has no effect if the
> "send_periodic" value
> > + is set to "false". The default is 0.33 * max_interval. If
> max_interval
> > + is set to its defaul, then min_interval will be 200.
>
> Lost a letter there. Should read "default."
>
> > + </column>
> > </group>
> >
> > <group title="Options">
>
> [...]
>
> Thanks,
> Jakub
>
More information about the dev
mailing list