chiark / gitweb /
networkd: set route protocol
authorDan Williams <dcbw@redhat.com>
Tue, 22 Jul 2014 21:54:47 +0000 (16:54 -0500)
committerTom Gundersen <teg@jklm.no>
Wed, 23 Jul 2014 07:19:32 +0000 (09:19 +0200)
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?).

[tomegun: fixup
src/network/networkd-link.c:972:33: error: too few arguments to function 'route_new_dynamic']

src/libsystemd/sd-rtnl/rtnl-message.c
src/libsystemd/sd-rtnl/test-rtnl.c
src/network/networkd-link.c
src/network/networkd-route.c
src/network/networkd.h
src/systemd/sd-rtnl.h

index 7f2e398b7494ab10cd45f77e74b9029cbae11bb4..c50d0ea9824089995d7562fe88785f5ac6e9256d 100644 (file)
@@ -133,7 +133,8 @@ int sd_rtnl_message_route_set_scope(sd_rtnl_message *m, unsigned char scope) {
 }
 
 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;
 
@@ -154,7 +155,7 @@ int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret,
         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;
 }
index 082c9e4a01a946469b2fc05b1fbc236e903cfe57..4b6e5339d9ec05807d87f21df460e997df2ad01a 100644 (file)
@@ -132,7 +132,7 @@ static void test_route(void) {
         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;
index 0a6f52408f458b66694969029623a9e4aec0ee47..86d4b83d3b98cb1568b2b64432bc9f787e401c8a 100644 (file)
@@ -415,7 +415,7 @@ static int link_set_dhcp_routes(Link *link) {
         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));
@@ -481,7 +481,7 @@ static int link_enter_set_routes(Link *link) {
                 }
 
                 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));
@@ -517,14 +517,14 @@ static int link_enter_set_routes(Link *link) {
                 }
 
                 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));
@@ -969,7 +969,7 @@ static int dhcp_lease_lost(Link *link) {
                         for (i = 0; i < n; i++) {
                                 _cleanup_route_free_ Route *route = NULL;
 
-                                r = route_new_dynamic(&route);
+                                r = route_new_dynamic(&route, RTPROT_UNSPEC);
                                 if (r >= 0) {
                                         route->family = AF_INET;
                                         route->in_addr.in = routes[i].gw_addr;
@@ -989,7 +989,7 @@ static int dhcp_lease_lost(Link *link) {
                         _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;
@@ -999,7 +999,7 @@ static int dhcp_lease_lost(Link *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;
@@ -1316,7 +1316,7 @@ static int ipv4ll_address_lost(Link *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));
index 8949299409f476aead74fca52037049b309a60fd..00fd9528c48586dee2cef4daa9e2efa3a208fe43 100644 (file)
@@ -49,6 +49,7 @@ int route_new_static(Network *network, unsigned section, Route **ret) {
 
         route->family = AF_UNSPEC;
         route->scope = RT_SCOPE_UNIVERSE;
+        route->protocol = RTPROT_STATIC;
 
         route->network = network;
 
@@ -65,7 +66,7 @@ int route_new_static(Network *network, unsigned section, Route **ret) {
         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);
@@ -74,6 +75,7 @@ int route_new_dynamic(Route **ret) {
 
         route->family = AF_UNSPEC;
         route->scope = RT_SCOPE_UNIVERSE;
+        route->protocol = rtm_protocol;
 
         *ret = route;
         route = NULL;
@@ -108,7 +110,8 @@ int route_drop(Route *route, Link *link,
         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;
@@ -181,7 +184,8 @@ int route_configure(Route *route, Link *link,
         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;
index f1c7f204ea862af7b4404abdbdf3b258c99f60ba..7d291e5ea34244dacad7fc5d334d08f4deb9e9b5 100644 (file)
@@ -137,6 +137,7 @@ struct Route {
         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;
@@ -305,7 +306,7 @@ const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, unsig
 
 /* 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);
index 5cd26d98cdf0c6e9def4f3bd79ea48d8fb38e41d..47bb232ff15b89d13aee57b9bb2f5fcf1cad24db 100644 (file)
@@ -72,7 +72,7 @@ int sd_rtnl_message_new_addr_update(sd_rtnl *rtnl, sd_rtnl_message **ret, int in
 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);