[systemd-devel] [PATCH v2] networkd: set route protocol

Tom Gundersen teg at jklm.no
Wed Jul 23 00:34:33 PDT 2014


On Tue, Jul 22, 2014 at 11:54 PM, Dan Williams <dcbw at redhat.com> wrote:
> All routes added by networkd are currently set RTPROT_BOOT, which according
> to the kernel means "Route installed during boot" (rtnetlink.h).  But this
> is not always the case as networkd changes routing after boot too.  Since
> the kernel gives more detailed protocols, use them.
>
> With this patch, user-configured static routes now use RTPROT_STATIC (which
> they are) and DHCP routes use RTPROT_DHCP.  There is no define for IPv4LL
> yet, so those are installed as RTPROT_STATIC (though perhaps RTPROT_RA is
> better?).

Nice. Applied.

Thanks!

Tom

> Signed-off-by: Dan Williams <dcbw at redhat.com>

Btw, we don't do sob, so I dropped this when applying.

> ---
> v2: rebase missed one case of RTPROT_DHCP; now fixed
>
>  src/libsystemd/sd-rtnl/rtnl-message.c |  5 +++--
>  src/libsystemd/sd-rtnl/test-rtnl.c    |  2 +-
>  src/network/networkd-link.c           | 14 +++++++-------
>  src/network/networkd-route.c          | 10 +++++++---
>  src/network/networkd.h                |  3 ++-
>  src/systemd/sd-rtnl.h                 |  2 +-
>  6 files changed, 21 insertions(+), 15 deletions(-)
>
> diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
> index 7f2e398..c50d0ea 100644
> --- a/src/libsystemd/sd-rtnl/rtnl-message.c
> +++ b/src/libsystemd/sd-rtnl/rtnl-message.c
> @@ -129,15 +129,16 @@ int sd_rtnl_message_route_set_scope(sd_rtnl_message *m, unsigned char scope) {
>
>          rtm->rtm_scope = scope;
>
>          return 0;
>  }
>
>  int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
> -                              uint16_t nlmsg_type, int rtm_family) {
> +                              uint16_t nlmsg_type, int rtm_family,
> +                              unsigned char rtm_protocol) {
>          struct rtmsg *rtm;
>          int r;
>
>          assert_return(rtnl_message_type_is_route(nlmsg_type), -EINVAL);
>          assert_return(rtm_family == AF_INET || rtm_family == AF_INET6, -EINVAL);
>          assert_return(ret, -EINVAL);
>
> @@ -150,15 +151,15 @@ int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
>
>          rtm = NLMSG_DATA((*ret)->hdr);
>
>          rtm->rtm_family = rtm_family;
>          rtm->rtm_scope = RT_SCOPE_UNIVERSE;
>          rtm->rtm_type = RTN_UNICAST;
>          rtm->rtm_table = RT_TABLE_MAIN;
> -        rtm->rtm_protocol = RTPROT_BOOT;
> +        rtm->rtm_protocol = rtm_protocol;
>
>          return 0;
>  }
>
>  int sd_rtnl_message_link_set_flags(sd_rtnl_message *m, unsigned flags, unsigned change) {
>          struct ifinfomsg *ifi;
>
> diff --git a/src/libsystemd/sd-rtnl/test-rtnl.c b/src/libsystemd/sd-rtnl/test-rtnl.c
> index 082c9e4..4b6e533 100644
> --- a/src/libsystemd/sd-rtnl/test-rtnl.c
> +++ b/src/libsystemd/sd-rtnl/test-rtnl.c
> @@ -128,15 +128,15 @@ static void test_address_get(sd_rtnl *rtnl, int ifindex) {
>
>  static void test_route(void) {
>          _cleanup_rtnl_message_unref_ sd_rtnl_message *req;
>          struct in_addr addr, addr_data;
>          uint32_t index = 2, u32_data;
>          int r;
>
> -        r = sd_rtnl_message_new_route(NULL, &req, RTM_NEWROUTE, AF_INET);
> +        r = sd_rtnl_message_new_route(NULL, &req, RTM_NEWROUTE, AF_INET, RTPROT_STATIC);
>          if (r < 0) {
>                  log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
>                  return;
>          }
>
>          addr.s_addr = htonl(INADDR_LOOPBACK);
>
> diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
> index 0a6f524..5b70578 100644
> --- a/src/network/networkd-link.c
> +++ b/src/network/networkd-link.c
> @@ -411,15 +411,15 @@ static int link_set_dhcp_routes(Link *link) {
>                          log_warning_link(link, "DHCP error: could not get routes: %s", strerror(-n));
>                  return n;
>          }
>
>          for (i = 0; i < n; i++) {
>                  _cleanup_route_free_ Route *route = NULL;
>
> -                r = route_new_dynamic(&route);
> +                r = route_new_dynamic(&route, RTPROT_DHCP);
>                  if (r < 0) {
>                          log_error_link(link, "Could not allocate route: %s",
>                                         strerror(-r));
>                          return r;
>                  }
>
>                  route->family = AF_INET;
> @@ -477,15 +477,15 @@ static int link_enter_set_routes(Link *link) {
>                  if (r < 0 && r != -ENOENT) {
>                          log_warning_link(link, "IPV4LL error: no address: %s",
>                                          strerror(-r));
>                          return r;
>                  }
>
>                  if (r != -ENOENT) {
> -                        r = route_new_dynamic(&route);
> +                        r = route_new_dynamic(&route, RTPROT_STATIC);
>                          if (r < 0) {
>                                  log_error_link(link, "Could not allocate route: %s",
>                                                 strerror(-r));
>                                  return r;
>                          }
>
>                          route->family = AF_INET;
> @@ -513,22 +513,22 @@ static int link_enter_set_routes(Link *link) {
>                  if (r < 0 && r != -ENOENT) {
>                          log_warning_link(link, "DHCP error: could not get gateway: %s",
>                                           strerror(-r));
>                          return r;
>                  }
>
>                  if (r >= 0) {
> -                        r = route_new_dynamic(&route);
> +                        r = route_new_dynamic(&route, RTPROT_DHCP);
>                          if (r < 0) {
>                                  log_error_link(link, "Could not allocate route: %s",
>                                                 strerror(-r));
>                                  return r;
>                          }
>
> -                        r = route_new_dynamic(&route_gw);
> +                        r = route_new_dynamic(&route_gw, RTPROT_DHCP);
>                          if (r < 0) {
>                                  log_error_link(link, "Could not allocate route: %s",
>                                                 strerror(-r));
>                                  return r;
>                          }
>
>                          /* The dhcp netmask may mask out the gateway. Add an explicit
> @@ -985,25 +985,25 @@ static int dhcp_lease_lost(Link *link) {
>          r = address_new_dynamic(&address);
>          if (r >= 0) {
>                  r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
>                  if (r >= 0) {
>                          _cleanup_route_free_ Route *route_gw = NULL;
>                          _cleanup_route_free_ Route *route = NULL;
>
> -                        r = route_new_dynamic(&route_gw);
> +                        r = route_new_dynamic(&route_gw, RTPROT_UNSPEC);
>                          if (r >= 0) {
>                                  route_gw->family = AF_INET;
>                                  route_gw->dst_addr.in = gateway;
>                                  route_gw->dst_prefixlen = 32;
>                                  route_gw->scope = RT_SCOPE_LINK;
>
>                                  route_drop(route_gw, link, &route_drop_handler);
>                          }
>
> -                        r = route_new_dynamic(&route);
> +                        r = route_new_dynamic(&route, RTPROT_UNSPEC);
>                          if (r >= 0) {
>                                  route->family = AF_INET;
>                                  route->in_addr.in = gateway;
>
>                                  route_drop(route, link, &route_drop_handler);
>                          }
>                  }
> @@ -1312,15 +1312,15 @@ static int ipv4ll_address_lost(Link *link) {
>                  address->family = AF_INET;
>                  address->in_addr.in = addr;
>                  address->prefixlen = 16;
>                  address->scope = RT_SCOPE_LINK;
>
>                  address_drop(address, link, &address_drop_handler);
>
> -                r = route_new_dynamic(&route);
> +                r = route_new_dynamic(&route, RTPROT_UNSPEC);
>                  if (r < 0) {
>                          log_error_link(link, "Could not allocate route: %s",
>                                         strerror(-r));
>                          return r;
>                  }
>
>                  route->family = AF_INET;
> diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
> index 8949299..00fd952 100644
> --- a/src/network/networkd-route.c
> +++ b/src/network/networkd-route.c
> @@ -45,14 +45,15 @@ int route_new_static(Network *network, unsigned section, Route **ret) {
>
>          route = new0(Route, 1);
>          if (!route)
>                  return -ENOMEM;
>
>          route->family = AF_UNSPEC;
>          route->scope = RT_SCOPE_UNIVERSE;
> +        route->protocol = RTPROT_STATIC;
>
>          route->network = network;
>
>          LIST_PREPEND(routes, network->static_routes, route);
>
>          if (section) {
>                  route->section = section;
> @@ -61,23 +62,24 @@ int route_new_static(Network *network, unsigned section, Route **ret) {
>
>          *ret = route;
>          route = NULL;
>
>          return 0;
>  }
>
> -int route_new_dynamic(Route **ret) {
> +int route_new_dynamic(Route **ret, unsigned char rtm_protocol) {
>          _cleanup_route_free_ Route *route = NULL;
>
>          route = new0(Route, 1);
>          if (!route)
>                  return -ENOMEM;
>
>          route->family = AF_UNSPEC;
>          route->scope = RT_SCOPE_UNIVERSE;
> +        route->protocol = rtm_protocol;
>
>          *ret = route;
>          route = NULL;
>
>          return 0;
>  }
>
> @@ -104,15 +106,16 @@ int route_drop(Route *route, Link *link,
>          assert(link);
>          assert(link->manager);
>          assert(link->manager->rtnl);
>          assert(link->ifindex > 0);
>          assert(route->family == AF_INET || route->family == AF_INET6);
>
>          r = sd_rtnl_message_new_route(link->manager->rtnl, &req,
> -                                      RTM_DELROUTE, route->family);
> +                                      RTM_DELROUTE, route->family,
> +                                      route->protocol);
>          if (r < 0) {
>                  log_error("Could not create RTM_DELROUTE message: %s", strerror(-r));
>                  return r;
>          }
>
>          if (route->family == AF_INET)
>                  r = sd_rtnl_message_append_in_addr(req, RTA_GATEWAY, &route->in_addr.in);
> @@ -177,15 +180,16 @@ int route_configure(Route *route, Link *link,
>          assert(link);
>          assert(link->manager);
>          assert(link->manager->rtnl);
>          assert(link->ifindex > 0);
>          assert(route->family == AF_INET || route->family == AF_INET6);
>
>          r = sd_rtnl_message_new_route(link->manager->rtnl, &req,
> -                                      RTM_NEWROUTE, route->family);
> +                                      RTM_NEWROUTE, route->family,
> +                                      route->protocol);
>          if (r < 0) {
>                  log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
>                  return r;
>          }
>
>          if (route->family == AF_INET)
>                  r = sd_rtnl_message_append_in_addr(req, RTA_GATEWAY, &route->in_addr.in);
> diff --git a/src/network/networkd.h b/src/network/networkd.h
> index f1c7f20..7d291e5 100644
> --- a/src/network/networkd.h
> +++ b/src/network/networkd.h
> @@ -133,14 +133,15 @@ struct Route {
>          Network *network;
>          uint64_t section;
>
>          int family;
>          unsigned char dst_prefixlen;
>          unsigned char scope;
>          uint32_t metrics;
> +        unsigned char protocol;  /* RTPROT_* */
>
>          union in_addr_union in_addr;
>          union in_addr_union dst_addr;
>
>          LIST_FIELDS(Route, routes);
>  };
>
> @@ -301,15 +302,15 @@ int config_parse_tunnel_address(const char *unit,
>                                  void *userdata);
>
>  /* gperf */
>  const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, unsigned length);
>
>  /* Route */
>  int route_new_static(Network *network, unsigned section, Route **ret);
> -int route_new_dynamic(Route **ret);
> +int route_new_dynamic(Route **ret, unsigned char rtm_protocol);
>  void route_free(Route *route);
>  int route_configure(Route *route, Link *link, sd_rtnl_message_handler_t callback);
>  int route_drop(Route *route, Link *link, sd_rtnl_message_handler_t callback);
>
>
>  DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free);
>  #define _cleanup_route_free_ _cleanup_(route_freep)
> diff --git a/src/systemd/sd-rtnl.h b/src/systemd/sd-rtnl.h
> index 5cd26d9..47bb232 100644
> --- a/src/systemd/sd-rtnl.h
> +++ b/src/systemd/sd-rtnl.h
> @@ -68,15 +68,15 @@ int sd_rtnl_detach_event(sd_rtnl *nl);
>
>  /* messages */
>  int sd_rtnl_message_new_link(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t msg_type, int index);
>  int sd_rtnl_message_new_addr_update(sd_rtnl *rtnl, sd_rtnl_message **ret, int index, int family);
>  int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t msg_type, int index,
>                               int family);
>  int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t nlmsg_type,
> -                              int rtm_family);
> +                              int rtm_family, unsigned char rtm_protocol);
>
>  sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m);
>  sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m);
>
>  int sd_rtnl_message_request_dump(sd_rtnl_message *m, int dump);
>  int sd_rtnl_message_get_errno(sd_rtnl_message *m);
>  int sd_rtnl_message_get_type(sd_rtnl_message *m, uint16_t *type);
> --
> 1.9.3
>
>
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel


More information about the systemd-devel mailing list