From: Yu Watanabe Date: Mon, 11 Dec 2023 17:29:25 +0000 (+0900) Subject: network/nexthop: introduce ManageForeignNextHops= boolean setting X-Git-Tag: v256-rc1~1502^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bbc05bec9854a644eb591b3507ae22bbaa14ee73;p=thirdparty%2Fsystemd.git network/nexthop: introduce ManageForeignNextHops= boolean setting Closes #29034. --- diff --git a/man/networkd.conf.xml b/man/networkd.conf.xml index 018bde0fbfa..6d1dfc78cee 100644 --- a/man/networkd.conf.xml +++ b/man/networkd.conf.xml @@ -90,6 +90,17 @@ + + ManageForeignNextHops= + A boolean. When true, systemd-networkd will remove nexthops + that are not configured in .network files (except for routes with protocol + kernel). When false, it will + not remove any foreign nexthops, keeping them even if they are not configured in a .network file. + Defaults to yes. + + + + RouteTable= Defines the route table name. Takes a whitespace-separated list of the pairs of diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 3436a32b115..0bad731b0d7 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1715,8 +1715,10 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix Id= - The id of the next hop. Takes an integer in the range 1…4294967295. If unspecified, - then automatically chosen by kernel. + The id of the next hop. Takes an integer in the range 1…4294967295. + This is mandatory if ManageForeignNextHops=no is specified in + networkd.conf5. + Otherwise, if unspecified, an unused ID will be automatically picked. diff --git a/src/network/networkd-gperf.gperf b/src/network/networkd-gperf.gperf index 8542ffa6b5d..c9e3c937f47 100644 --- a/src/network/networkd-gperf.gperf +++ b/src/network/networkd-gperf.gperf @@ -25,6 +25,7 @@ Network.SpeedMeter, config_parse_bool, Network.SpeedMeterIntervalSec, config_parse_sec, 0, offsetof(Manager, speed_meter_interval_usec) Network.ManageForeignRoutingPolicyRules, config_parse_bool, 0, offsetof(Manager, manage_foreign_rules) Network.ManageForeignRoutes, config_parse_bool, 0, offsetof(Manager, manage_foreign_routes) +Network.ManageForeignNextHops, config_parse_bool, 0, offsetof(Manager, manage_foreign_nexthops) Network.RouteTable, config_parse_route_table_names, 0, 0 Network.IPv6PrivacyExtensions, config_parse_ipv6_privacy_extensions, 0, offsetof(Manager, ipv6_privacy_extensions) DHCPv4.DUIDType, config_parse_duid_type, 0, offsetof(Manager, dhcp_duid) diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index fca5d766184..6ee01b28e07 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -591,6 +591,7 @@ int manager_new(Manager **ret, bool test_mode) { .online_state = _LINK_ONLINE_STATE_INVALID, .manage_foreign_routes = true, .manage_foreign_rules = true, + .manage_foreign_nexthops = true, .ethtool_fd = -EBADF, .dhcp_duid.type = DUID_TYPE_EN, .dhcp6_duid.type = DUID_TYPE_EN, @@ -867,6 +868,9 @@ static int manager_enumerate_nexthop(Manager *m) { assert(m); assert(m->rtnl); + if (!m->manage_foreign_nexthops) + return 0; + r = sd_rtnl_message_new_nexthop(m->rtnl, &req, RTM_GETNEXTHOP, 0, 0); if (r < 0) return r; diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h index fbef5289d28..a4eb7d78afa 100644 --- a/src/network/networkd-manager.h +++ b/src/network/networkd-manager.h @@ -38,6 +38,7 @@ struct Manager { bool restarting; bool manage_foreign_routes; bool manage_foreign_rules; + bool manage_foreign_nexthops; Set *dirty_links; Set *new_wlan_ifindices; diff --git a/src/network/networkd-nexthop.c b/src/network/networkd-nexthop.c index e2ded28197b..442e16b0260 100644 --- a/src/network/networkd-nexthop.c +++ b/src/network/networkd-nexthop.c @@ -318,6 +318,10 @@ static int nexthop_acquire_id(Manager *manager, NextHop *nexthop) { if (nexthop->id > 0) return 0; + /* If ManageForeignNextHops=no, nexthop with id == 0 should be already filtered by + * nexthop_section_verify(). */ + assert(manager->manage_foreign_nexthops); + /* Find the lowest unused ID. */ ORDERED_HASHMAP_FOREACH(network, manager->networks) { @@ -988,6 +992,13 @@ static int nexthop_section_verify(NextHop *nh) { if (section_is_invalid(nh->section)) return -EINVAL; + if (!nh->network->manager->manage_foreign_nexthops && nh->id == 0) + return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), + "%s: [NextHop] section without specifying Id= is not supported " + "if ManageForeignNextHops=no is set in networkd.conf. " + "Ignoring [NextHop] section from line %u.", + nh->section->filename, nh->section->line); + if (!hashmap_isempty(nh->group)) { if (in_addr_is_set(nh->family, &nh->gw)) return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), diff --git a/src/network/networkd.conf b/src/network/networkd.conf index e5a5e889262..2994b8b70c1 100644 --- a/src/network/networkd.conf +++ b/src/network/networkd.conf @@ -21,6 +21,7 @@ #SpeedMeterIntervalSec=10sec #ManageForeignRoutingPolicyRules=yes #ManageForeignRoutes=yes +#ManageForeignNextHops=yes #RouteTable= #IPv6PrivacyExtensions=no