]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #17357 from yuwata/network-dhcp6-pd-announce-17353
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 23 Oct 2020 03:57:58 +0000 (12:57 +0900)
committerGitHub <noreply@github.com>
Fri, 23 Oct 2020 03:57:58 +0000 (12:57 +0900)
network: add an option to control announcement of delegated prefix

1  2 
src/network/networkd-address.c
src/network/networkd-dhcp4.c
src/network/networkd-radv.c

index 636812b5560234b40a49185e4f0506e8233647af,ebb9d43371eff748a5feb09ccdcc2d8ed8d22dc3..9130fae77830f32bc60a763cc6034d7d60b1c16c
@@@ -980,6 -980,7 +980,7 @@@ static int static_address_configure(con
  
  int link_set_addresses(Link *link) {
          Address *ad;
+         Prefix *p;
          int r;
  
          assert(link);
                          return r;
          }
  
-         if (link->network->router_prefix_delegation & RADV_PREFIX_DELEGATION_STATIC) {
-                 Prefix *p;
+         HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
+                 _cleanup_(address_freep) Address *address = NULL;
  
-                 HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
-                         _cleanup_(address_freep) Address *address = NULL;
-                         if (!p->assign)
-                                 continue;
+                 if (!p->assign)
+                         continue;
  
-                         r = address_new(&address);
-                         if (r < 0)
-                                 return log_oom();
+                 r = address_new(&address);
+                 if (r < 0)
+                         return log_oom();
  
-                         r = sd_radv_prefix_get_prefix(p->radv_prefix, &address->in_addr.in6, &address->prefixlen);
-                         if (r < 0)
-                                 return log_link_warning_errno(link, r, "Could not get RA prefix: %m");
+                 r = sd_radv_prefix_get_prefix(p->radv_prefix, &address->in_addr.in6, &address->prefixlen);
+                 if (r < 0)
+                         return log_link_warning_errno(link, r, "Could not get RA prefix: %m");
  
-                         r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
-                         if (r < 0)
-                                 return log_link_warning_errno(link, r, "Could not generate EUI64 address: %m");
+                 r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
+                 if (r < 0)
+                         return log_link_warning_errno(link, r, "Could not generate EUI64 address: %m");
  
-                         address->family = AF_INET6;
-                         r = static_address_configure(address, link, true);
-                         if (r < 0)
-                                 return r;
-                 }
+                 address->family = AF_INET6;
+                 r = static_address_configure(address, link, true);
+                 if (r < 0)
+                         return r;
          }
  
          if (link->address_messages == 0) {
@@@ -1341,7 -1338,7 +1338,7 @@@ static void static_address_on_acd(sd_ip
                  assert_not_reached("Invalid IPv4ACD event.");
          }
  
 -        sd_ipv4acd_stop(acd);
 +        (void) sd_ipv4acd_stop(acd);
  
          return;
  }
@@@ -1402,9 -1399,11 +1399,9 @@@ static int ipv4_dad_update_mac_one(Addr
  
          running = sd_ipv4acd_is_running(address->acd);
  
 -        if (running) {
 -                r = sd_ipv4acd_stop(address->acd);
 -                if (r < 0)
 -                        return r;
 -        }
 +        r = sd_ipv4acd_stop(address->acd);
 +        if (r < 0)
 +                return r;
  
          r = sd_ipv4acd_set_mac(address->acd, &address->link->mac);
          if (r < 0)
@@@ -1441,6 -1440,9 +1438,6 @@@ int ipv4_dad_stop(Link *link) 
          assert(link);
  
          SET_FOREACH(address, link->addresses) {
 -                if (!address->acd)
 -                        continue;
 -
                  k = sd_ipv4acd_stop(address->acd);
                  if (k < 0 && r >= 0)
                          r = k;
          return r;
  }
  
 +void ipv4_dad_unref(Link *link) {
 +        Address *address;
 +
 +        assert(link);
 +
 +        SET_FOREACH(address, link->addresses)
 +                address->acd = sd_ipv4acd_unref(address->acd);
 +}
 +
  int config_parse_broadcast(
                  const char *unit,
                  const char *filename,
index a881df8bb43e3a17da3502548bf959dda188c4bc,28e2e4275c52d1ead342c71e65ddbae74bd20e9b..bb8c34f7cc5959c048e21a3a6b61c73cb54453ec
@@@ -570,7 -570,8 +570,7 @@@ static int dhcp_lease_lost(Link *link) 
          link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
          link_dirty(link);
  
 -        if (link->dhcp_acd)
 -                (void) sd_ipv4acd_stop(link->dhcp_acd);
 +        (void) sd_ipv4acd_stop(link->dhcp_acd);
  
          return r;
  }
@@@ -1457,8 -1458,8 +1457,8 @@@ int dhcp4_configure(Link *link) 
                          return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set max attempts: %m");
          }
  
-         if (link->network->ip_service_type > 0) {
-                 r = sd_dhcp_client_set_service_type(link->dhcp_client, link->network->ip_service_type);
+         if (link->network->dhcp_ip_service_type > 0) {
+                 r = sd_dhcp_client_set_service_type(link->dhcp_client, link->network->dhcp_ip_service_type);
                  if (r < 0)
                          return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set IP service type: %m");
          }
index bb80e91b6c1e289b11b358ff681c2c4f7894041a,b9979f957a57516763f02cb77e0ea05496f9d75b..eb10f21cbd456602720043e8a934f8610e91dfdc
@@@ -180,6 -180,35 +180,35 @@@ void network_drop_invalid_route_prefixe
                          route_prefix_free(prefix);
  }
  
+ void network_adjust_radv(Network *network) {
+         assert(network);
+         /* After this function is called, network->router_prefix_delegation can be treated as a boolean. */
+         if (network->dhcp6_pd < 0)
+                 /* For backward compatibility. */
+                 network->dhcp6_pd = FLAGS_SET(network->router_prefix_delegation, RADV_PREFIX_DELEGATION_DHCP6);
+         if (!FLAGS_SET(network->link_local, ADDRESS_FAMILY_IPV6)) {
+                 if (network->router_prefix_delegation != RADV_PREFIX_DELEGATION_NONE)
+                         log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
+                                     "Disabling IPv6PrefixDelegation=.", network->filename);
+                 network->router_prefix_delegation = RADV_PREFIX_DELEGATION_NONE;
+         }
+         if (network->router_prefix_delegation == RADV_PREFIX_DELEGATION_NONE) {
+                 network->n_router_dns = 0;
+                 network->router_dns = mfree(network->router_dns);
+                 network->router_search_domains = ordered_set_free(network->router_search_domains);
+         }
+         if (!FLAGS_SET(network->router_prefix_delegation, RADV_PREFIX_DELEGATION_STATIC)) {
+                 network->prefixes_by_section = hashmap_free_with_destructor(network->prefixes_by_section, prefix_free);
+                 network->route_prefixes_by_section = hashmap_free_with_destructor(network->route_prefixes_by_section, route_prefix_free);
+         }
+ }
  int config_parse_prefix(
                  const char *unit,
                  const char *filename,
@@@ -608,10 -637,12 +637,12 @@@ static bool link_radv_enabled(Link *lin
          if (!link_ipv6ll_enabled(link))
                  return false;
  
-         return link->network->router_prefix_delegation != RADV_PREFIX_DELEGATION_NONE;
+         return link->network->router_prefix_delegation;
  }
  
  int radv_configure(Link *link) {
+         RoutePrefix *q;
+         Prefix *p;
          int r;
  
          assert(link);
                          return r;
          }
  
-         if (link->network->router_prefix_delegation & RADV_PREFIX_DELEGATION_STATIC) {
-                 RoutePrefix *q;
-                 Prefix *p;
-                 HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
-                         r = sd_radv_add_prefix(link->radv, p->radv_prefix, false);
-                         if (r == -EEXIST)
-                                 continue;
-                         if (r == -ENOEXEC) {
-                                 log_link_warning_errno(link, r, "[IPv6Prefix] section configured without Prefix= setting, ignoring section.");
-                                 continue;
-                         }
-                         if (r < 0)
-                                 return r;
+         HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
+                 r = sd_radv_add_prefix(link->radv, p->radv_prefix, false);
+                 if (r == -EEXIST)
+                         continue;
+                 if (r == -ENOEXEC) {
+                         log_link_warning_errno(link, r, "[IPv6Prefix] section configured without Prefix= setting, ignoring section.");
+                         continue;
                  }
+                 if (r < 0)
+                         return r;
+         }
  
-                 HASHMAP_FOREACH(q, link->network->route_prefixes_by_section) {
-                         r = sd_radv_add_route_prefix(link->radv, q->radv_route_prefix, false);
-                         if (r == -EEXIST)
-                                 continue;
-                         if (r < 0)
-                                 return r;
-                 }
+         HASHMAP_FOREACH(q, link->network->route_prefixes_by_section) {
+                 r = sd_radv_add_route_prefix(link->radv, q->radv_route_prefix, false);
+                 if (r == -EEXIST)
+                         continue;
+                 if (r < 0)
+                         return r;
          }
  
          return 0;
@@@ -697,9 -723,11 +723,9 @@@ int radv_update_mac(Link *link) 
  
          restart = sd_radv_is_running(link->radv);
  
 -        if (restart) {
 -                r = sd_radv_stop(link->radv);
 -                if (r < 0)
 -                        return r;
 -        }
 +        r = sd_radv_stop(link->radv);
 +        if (r < 0)
 +                return r;
  
          r = sd_radv_set_mac(link->radv, &link->mac);
          if (r < 0)
@@@ -771,6 -799,12 +797,12 @@@ int config_parse_radv_dns
          assert(lvalue);
          assert(rvalue);
  
+         if (isempty(rvalue)) {
+                 n->n_router_dns = 0;
+                 n->router_dns = mfree(n->router_dns);
+                 return 0;
+         }
          for (const char *p = rvalue;;) {
                  _cleanup_free_ char *w = NULL;
                  union in_addr_union a;
@@@ -832,6 -866,11 +864,11 @@@ int config_parse_radv_search_domains
          assert(lvalue);
          assert(rvalue);
  
+         if (isempty(rvalue)) {
+                 n->router_search_domains = ordered_set_free(n->router_search_domains);
+                 return 0;
+         }
          for (const char *p = rvalue;;) {
                  _cleanup_free_ char *w = NULL, *idna = NULL;
  
                          /* transfer ownership to simplify subsequent operations */
                          idna = TAKE_PTR(w);
  
-                 r = ordered_set_ensure_allocated(&n->router_search_domains, &string_hash_ops);
+                 r = ordered_set_ensure_allocated(&n->router_search_domains, &string_hash_ops_free);
                  if (r < 0)
                          return log_oom();
  
@@@ -877,11 -916,51 +914,51 @@@ DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN
                  RADVPrefixDelegation,
                  RADV_PREFIX_DELEGATION_BOTH);
  
- DEFINE_CONFIG_PARSE_ENUM(
-                 config_parse_router_prefix_delegation,
-                 radv_prefix_delegation,
-                 RADVPrefixDelegation,
-                 "Invalid router prefix delegation");
+ int config_parse_router_prefix_delegation(
+                 const char *unit,
+                 const char *filename,
+                 unsigned line,
+                 const char *section,
+                 unsigned section_line,
+                 const char *lvalue,
+                 int ltype,
+                 const char *rvalue,
+                 void *data,
+                 void *userdata) {
+         RADVPrefixDelegation val, *ra = data;
+         int r;
+         assert(filename);
+         assert(lvalue);
+         assert(rvalue);
+         assert(data);
+         if (streq(lvalue, "IPv6SendRA")) {
+                 r = parse_boolean(rvalue);
+                 if (r < 0) {
+                         log_syntax(unit, LOG_WARNING, filename, line, r,
+                                    "Invalid %s= setting, ignoring assignment: %s", lvalue, rvalue);
+                         return 0;
+                 }
+                 /* When IPv6SendRA= is enabled, only static prefixes are sent by default, and users
+                  * need to explicitly enable DHCPv6PrefixDelegation=. */
+                 *ra = r ? RADV_PREFIX_DELEGATION_STATIC : RADV_PREFIX_DELEGATION_NONE;
+                 return 0;
+         }
+         /* For backward compatibility */
+         val = radv_prefix_delegation_from_string(rvalue);
+         if (val < 0) {
+                 log_syntax(unit, LOG_WARNING, filename, line, 0,
+                            "Invalid %s= setting, ignoring assignment: %s", lvalue, rvalue);
+                 return 0;
+         }
+         *ra = val;
+         return 0;
+ }
  
  int config_parse_router_preference(
                  const char *unit,