]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: manage route and nexthop flags 21341/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 12 Nov 2021 06:26:06 +0000 (15:26 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 12 Nov 2021 23:16:06 +0000 (08:16 +0900)
src/network/networkd-nexthop.c
src/network/networkd-nexthop.h
src/network/networkd-route.c
src/network/networkd-route.h

index 55fad8a63685e34caf09504bd1d045877d57a52e..7ae43a00bd62fdb6f90f16d8d61929a6f072b8cc 100644 (file)
@@ -483,11 +483,9 @@ static int nexthop_configure(
                         if (r < 0)
                                 return log_link_error_errno(link, r, "Could not append NHA_GATEWAY attribute: %m");
 
-                        if (nexthop->onlink > 0) {
-                                r = sd_rtnl_message_nexthop_set_flags(req, RTNH_F_ONLINK);
-                                if (r < 0)
-                                        return log_link_error_errno(link, r, "Failed to set RTNH_F_ONLINK flag: %m");
-                        }
+                        r = sd_rtnl_message_nexthop_set_flags(req, nexthop->flags & RTNH_F_ONLINK);
+                        if (r < 0)
+                                return log_link_error_errno(link, r, "Failed to set nexthop flags: %m");
                 }
         }
 
@@ -801,7 +799,7 @@ static bool nexthop_is_ready_to_configure(Link *link, const NextHop *nexthop) {
                 }
         }
 
-        return gateway_is_ready(link, nexthop->onlink, nexthop->family, &nexthop->gw);
+        return gateway_is_ready(link, FLAGS_SET(nexthop->flags, RTNH_F_ONLINK), nexthop->family, &nexthop->gw);
 }
 
 int request_process_nexthop(Request *req) {
@@ -890,6 +888,12 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
                 return 0;
         }
 
+        r = sd_rtnl_message_nexthop_get_flags(message, &tmp->flags);
+        if (r < 0) {
+                log_link_warning_errno(link, r, "rtnl: could not get nexthop flags, ignoring: %m");
+                return 0;
+        }
+
         r = sd_netlink_message_read_data(message, NHA_GROUP, &raw_group_size, &raw_group);
         if (r < 0 && r != -ENODATA) {
                 log_link_warning_errno(link, r, "rtnl: could not get NHA_GROUP attribute, ignoring: %m");
@@ -971,6 +975,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
         switch (type) {
         case RTM_NEWNEXTHOP:
                 if (nexthop) {
+                        nexthop->flags = tmp->flags;
                         nexthop_enter_configured(nexthop);
                         log_nexthop_debug(tmp, "Received remembered", link);
                 } else {
@@ -1048,6 +1053,9 @@ static int nexthop_section_verify(NextHop *nh) {
                 nh->onlink = true;
         }
 
+        if (nh->onlink >= 0)
+                SET_FLAG(nh->flags, RTNH_F_ONLINK, nh->onlink);
+
         return 0;
 }
 
index 3cc177fc54a7da3a1163f9d808990036b7203f7b..7a8920238c0bc64556097571072506b24719d809 100644 (file)
@@ -32,7 +32,8 @@ typedef struct NextHop {
         bool blackhole;
         int family;
         union in_addr_union gw;
-        int onlink;
+        uint8_t flags;
+        int onlink; /* Only used in conf parser and nexthop_section_verify(). */
         Hashmap *group;
 } NextHop;
 
index 1df67b160126d7ade61b106362ae2d4a789cb12b..ed8c113a546d6162d8a8f888945dbf5404f752d4 100644 (file)
@@ -863,7 +863,6 @@ static void log_route_debug(const Route *route, const char *str, const Link *lin
 }
 
 static int route_set_netlink_message(const Route *route, sd_netlink_message *req, Link *link) {
-        unsigned flags;
         int r;
 
         assert(route);
@@ -918,11 +917,7 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
         if (r < 0)
                 return log_link_error_errno(link, r, "Could not set scope: %m");
 
-        flags = route->flags;
-        if (route->gateway_onlink >= 0)
-                SET_FLAG(flags, RTNH_F_ONLINK, route->gateway_onlink);
-
-        r = sd_rtnl_message_route_set_flags(req, flags);
+        r = sd_rtnl_message_route_set_flags(req, route->flags & RTNH_F_ONLINK);
         if (r < 0)
                 return log_link_error_errno(link, r, "Could not set flags: %m");
 
@@ -1633,11 +1628,11 @@ int link_request_static_routes(Link *link, bool only_ipv4) {
         return 0;
 }
 
-bool gateway_is_ready(Link *link, int onlink, int family, const union in_addr_union *gw) {
+bool gateway_is_ready(Link *link, bool onlink, int family, const union in_addr_union *gw) {
         assert(link);
         assert(gw);
 
-        if (onlink > 0)
+        if (onlink)
                 return true;
 
         if (!in_addr_is_set(family, gw))
@@ -1688,7 +1683,7 @@ static int route_is_ready_to_configure(const Route *route, Link *link) {
                         return r;
         }
 
-        if (!gateway_is_ready(link, route->gateway_onlink, route->gw_family, &route->gw))
+        if (!gateway_is_ready(link, FLAGS_SET(route->flags, RTNH_F_ONLINK), route->gw_family, &route->gw))
                 return false;
 
         MultipathRoute *m;
@@ -1706,7 +1701,7 @@ static int route_is_ready_to_configure(const Route *route, Link *link) {
                         m->ifindex = l->ifindex;
                 }
 
-                if (!gateway_is_ready(l ?: link, route->gateway_onlink, m->gateway.family, &a))
+                if (!gateway_is_ready(l ?: link, FLAGS_SET(route->flags, RTNH_F_ONLINK), m->gateway.family, &a))
                         return false;
         }
 
@@ -1802,6 +1797,7 @@ static int process_route_one(
         switch (type) {
         case RTM_NEWROUTE:
                 if (route) {
+                        route->flags = tmp->flags;
                         route_enter_configured(route);
                         log_route_debug(route, "Received remembered", link, manager);
 
@@ -1924,6 +1920,12 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, Ma
                 return 0;
         }
 
+        r = sd_rtnl_message_route_get_flags(message, &tmp->flags);
+        if (r < 0) {
+                log_warning_errno(r, "rtnl: received route message without route flags, ignoring: %m");
+                return 0;
+        }
+
         r = netlink_message_read_in_addr_union(message, RTA_DST, tmp->family, &tmp->dst);
         if (r < 0 && r != -ENODATA) {
                 log_link_warning_errno(link, r, "rtnl: received route message without valid destination, ignoring: %m");
@@ -3159,6 +3161,9 @@ static int route_section_verify(Route *route, Network *network) {
                 route->gateway_onlink = true;
         }
 
+        if (route->gateway_onlink >= 0)
+                SET_FLAG(route->flags, RTNH_F_ONLINK, route->gateway_onlink);
+
         if (route->family == AF_INET6) {
                 MultipathRoute *m;
 
index c9144702268a1fce5a37f217cff60cdd3be9af67..f6066d9601af497ff6c5ab2142ab51d6f26ef2a5 100644 (file)
@@ -45,7 +45,7 @@ typedef struct Route {
         uint32_t advmss;
         unsigned char pref;
         unsigned flags;
-        int gateway_onlink;
+        int gateway_onlink; /* Only used in conf parser and route_section_verify(). */
         uint32_t nexthop_id;
 
         bool scope_set:1;
@@ -81,7 +81,7 @@ int route_remove(Route *route);
 
 int route_get(Manager *manager, Link *link, const Route *in, Route **ret);
 int manager_find_uplink(Manager *m, int family, Link *exclude, Link **ret);
-bool gateway_is_ready(Link *link, int onlink, int family, const union in_addr_union *gw);
+bool gateway_is_ready(Link *link, bool onlink, int family, const union in_addr_union *gw);
 
 int link_drop_routes(Link *link);
 int link_drop_foreign_routes(Link *link);