On Fri, Jan 3, 2025 at 6:10 PM Eelco Chaudron <[email protected]> wrote:
>
> On 18 Dec 2024, at 20:12, Frode Nordahl wrote:
>
> > Along with dependent data structures these functions are useful
> > for programs that build against OVS private library sources,
> > allowing them to make use of functionality provided by the
> > route-table module.
> >
> > A test program to be run as part of the system tests that
> > exercise the exported interfaces will be added in a subsequent
> > patch.
> >
> > Signed-off-by: Frode Nordahl <[email protected]>
>
> This patch looks good to me with one small nit below.
>
> //Eelco
>
> > ---
> >  lib/route-table.c |  60 ++-------------------
> >  lib/route-table.h | 133 ++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 136 insertions(+), 57 deletions(-)
> >
> > diff --git a/lib/route-table.c b/lib/route-table.c
> > index 30c96b116..36d5c8620 100644
> > --- a/lib/route-table.c
> > +++ b/lib/route-table.c
> > @@ -48,56 +48,6 @@ VLOG_DEFINE_THIS_MODULE(route_table);
> >
> >  COVERAGE_DEFINE(route_table_dump);
> >
> > -struct route_data_nexthop {
> > -    struct ovs_list nexthop_node;
> > -
> > -    sa_family_t family;
> > -    struct in6_addr addr;
> > -    char ifname[IFNAMSIZ]; /* Interface name. */
> > -};
> > -
> > -struct route_data {
> > -    /* Routes can have multiple next hops per destination.
> > -     *
> > -     * Each next hop has its own set of attributes such as address family,
> > -     * interface and IP address.
> > -     *
> > -     * When retrieving information about a route from the kernel, in the 
> > case
> > -     * of multiple next hops, information is provided as nested attributes.
> > -     *
> > -     * A linked list with struct route_data_nexthop entries is used to 
> > store
> > -     * this information as we parse each attribute.
> > -     *
> > -     * For the common case of one next hop, the nexthops list will contain 
> > a
> > -     * single entry pointing to the struct route_data _primary_next_hop
> > -     * element.
> > -     *
> > -     * Any dynamically allocated list elements can be freed with a call to 
> > the
> > -     * route_data_destroy function. */
> > -    struct ovs_list nexthops;
> > -    struct route_data_nexthop _primary_next_hop;
> > -
> > -    /* Copied from struct rtmsg. */
> > -    unsigned char rtm_dst_len;
> > -    unsigned char rtm_protocol;
> > -    bool rtn_local;
> > -
> > -    /* Extracted from Netlink attributes. */
> > -    struct in6_addr rta_dst;     /* 0 if missing. */
> > -    struct in6_addr rta_prefsrc; /* 0 if missing. */
> > -    uint32_t rta_mark;           /* 0 if missing. */
> > -    uint32_t rta_table_id;       /* 0 if missing. */
> > -    uint32_t rta_priority;       /* 0 if missing. */
> > -};
> > -
> > -/* A digested version of a route message sent down by the kernel to 
> > indicate
> > - * that a route has changed. */
> > -struct route_table_msg {
> > -    bool relevant;        /* Should this message be processed? */
> > -    uint16_t nlmsg_type;  /* e.g. RTM_NEWROUTE, RTM_DELROUTE. */
> > -    struct route_data rd; /* Data parsed from this message. */
> > -};
> > -
> >  static struct ovs_mutex route_table_mutex = OVS_MUTEX_INITIALIZER;
> >  static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
> >
> > @@ -115,14 +65,13 @@ static bool route_table_valid = false;
> >
> >  static void route_table_reset(void);
> >  static void route_table_handle_msg(const struct route_table_msg *, void 
> > *aux);
> > -static int route_table_parse(struct ofpbuf *, void *change);
> >  static void route_table_change(struct route_table_msg *, void *aux);
> >  static void route_map_clear(void);
> >
> >  static void name_table_init(void);
> >  static void name_table_change(const struct rtnetlink_change *, void *);
> >
> > -static void
> > +void
> >  route_data_destroy(struct route_data *rd)
> >  {
> >      struct route_data_nexthop *rdnh;
> > @@ -197,10 +146,7 @@ route_table_wait(void)
> >      ovs_mutex_unlock(&route_table_mutex);
> >  }
> >
> > -typedef void route_table_handle_msg_callback(const struct route_table_msg 
> > *,
> > -                                             void *aux);
> > -
> > -static bool
> > +bool
> >  route_table_dump_one_table(uint32_t id,
> >                             route_table_handle_msg_callback *handle_msg_cb,
> >                             void *aux)
> > @@ -461,7 +407,7 @@ error_out:
> >   * responsibility to free it with a call to route_data_destroy.
> >   *
> >   * In case of error, any allocated memory will be freed before return. */
> > -static int
> > +int
> >  route_table_parse(struct ofpbuf *buf, void *change)
> >  {
> >      struct nlmsghdr *nlmsg;
> > diff --git a/lib/route-table.h b/lib/route-table.h
> > index 3a02d737a..493864e10 100644
> > --- a/lib/route-table.h
> > +++ b/lib/route-table.h
> > @@ -24,8 +24,132 @@
> >  #include <stdbool.h>
> >  #include <stdint.h>
> >
> > +#include "openvswitch/list.h"
> > +#include "openvswitch/ofpbuf.h"
> >  #include "openvswitch/types.h"
> >
> > +/*
> > + * route-table, system route table synchronization for Open vSwitch.
> > + *
> > + * Overview
> > + * ========
> > + *
> > + * The route-table module has two use cases:
> > + *
> > + * 1) Internal use by Open vSwitch which together with the ovs-router 
> > module
> > + *    implement route lookup for features such as flow based tunneling,
> > + *    userspace tunneling, and sFlow.
> > + *
> > + * 2) External use by projects such as Open Virtual Network (OVN), that use
> > + *    Open vSwitch as a compile time library.
> > + *
> > + * Typical External Usage
> > + * ======================
> > + *
> > + * static void
> > + * my_handle_msg(const struct route_table_msg *change, void *data)
> > + * {
> > + *     struct my_data *aux = data;
> > + *
> > + *     if (data) {
> > + *         aux->rta_dst = change->rd.rta_dst;
> > + *     }
> > + * }
> > + *
> > + * static void
> > + * my_route_table_dump(void)
> > + * {
> > + *     struct my_data *aux;
> > + *
> > + *     route_table_dump_one_table(RT_TABLE_MAIN, my_handle_msg, aux);
> > + * }
> > + *
> > + * static void
> > + * my_route_table_change(struct route_table_msg *change, void *aux 
> > OVS_UNUSED);
> > + * {
> > + *     my_handle_msg(change, NULL);
> > + *     route_data_destroy(&change->rd);
> > + * }
> > + *
> > + * static void
> > + * my_init(void)
> > + * {
> > + *     static struct nln *nln = NULL;
> > + *     static struct nln_notifier *route_notifier = NULL;
> > + *     static struct nln_notifier *route6_notifier = NULL;
> > + *     static struct route_table_msg nln_change;
>
> This is not real code, but I would move nln here to adhere to revere 
> Christmas tree.

Done, thanks!

--
Frode Nordahl

> > + *
> > + *     nln = nln_create(NETLINK_ROUTE, route_table_parse, NULL);
> > + *
> > + *     route_notifier =
> > + *        nln_notifier_create(nln, RTNLGRP_IPV4_ROUTE,
> > + *                            (nln_notify_func *) 
> > test_lib_route_table_change,
> > + *                            NULL);
> > + *     route6_notifier =
> > + *        nln_notifier_create(nln, RTNLGRP_IPV6_ROUTE,
> > + *                            (nln_notify_func *) 
> > test_lib_route_table_change,
> > + *                            NULL);
> > + * }
> > + *
> > + * Thread-safety
> > + * =============
> > + *
> > + * Assuming thread safe initialization of dependencies such as netlink 
> > socket,
> > + * netlink notifier and so on, the functions in this module are thread 
> > safe.
> > + */
> > +
> > +/* Information about a next hop stored in a linked list with base in struct
> > + * route_data.  Please refer to comment in struct route_data for details. 
> > */
> > +struct route_data_nexthop {
> > +    struct ovs_list nexthop_node;
> > +
> > +    sa_family_t family;
> > +    struct in6_addr addr;
> > +    char ifname[IFNAMSIZ]; /* Interface name. */
> > +};
> > +
> > +struct route_data {
> > +    /* Routes can have multiple next hops per destination.
> > +     *
> > +     * Each next hop has its own set of attributes such as address family,
> > +     * interface and IP address.
> > +     *
> > +     * When retrieving information about a route from the kernel, in the 
> > case
> > +     * of multiple next hops, information is provided as nested attributes.
> > +     *
> > +     * A linked list with struct route_data_nexthop entries is used to 
> > store
> > +     * this information as we parse each attribute.
> > +     *
> > +     * For the common case of one next hop, the nexthops list will contain 
> > a
> > +     * single entry pointing to the struct route_data _primary_next_hop
> > +     * element.
> > +     *
> > +     * Any dynamically allocated list elements can be freed with a call to 
> > the
> > +     * route_data_destroy function. */
> > +    struct ovs_list nexthops;
> > +    struct route_data_nexthop _primary_next_hop;
> > +
> > +    /* Copied from struct rtmsg. */
> > +    unsigned char rtm_dst_len;
> > +    unsigned char rtm_protocol;
> > +    bool rtn_local;
> > +
> > +    /* Extracted from Netlink attributes. */
> > +    struct in6_addr rta_dst;     /* 0 if missing. */
> > +    struct in6_addr rta_prefsrc; /* 0 if missing. */
> > +    uint32_t rta_mark;           /* 0 if missing. */
> > +    uint32_t rta_table_id;       /* 0 if missing. */
> > +    uint32_t rta_priority;       /* 0 if missing. */
> > +};
> > +
> > +/* A digested version of a route message sent down by the kernel to 
> > indicate
> > + * that a route has changed. */
> > +struct route_table_msg {
> > +    bool relevant;        /* Should this message be processed? */
> > +    uint16_t nlmsg_type;  /* e.g. RTM_NEWROUTE, RTM_DELROUTE. */
> > +    struct route_data rd; /* Data parsed from this message. */
> > +};
> > +
> >  uint64_t route_table_get_change_seq(void);
> >  void route_table_init(void);
> >  void route_table_run(void);
> > @@ -33,4 +157,13 @@ void route_table_wait(void);
> >  bool route_table_fallback_lookup(const struct in6_addr *ip6_dst,
> >                                   char name[],
> >                                   struct in6_addr *gw6);
> > +
> > +typedef void route_table_handle_msg_callback(const struct route_table_msg 
> > *,
> > +                                             void *aux);
> > +
> > +bool route_table_dump_one_table(uint32_t id,
> > +                                route_table_handle_msg_callback *,
> > +                                void *aux);
> > +int route_table_parse(struct ofpbuf *buf, void *change);
> > +void route_data_destroy(struct route_data *rd);
> >  #endif /* route-table.h */
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to