[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