LCOV - code coverage report
Current view: top level - udev/net - link-config.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 2 264 0.8 %
Date: 2019-08-23 13:36:53 Functions: 4 20 20.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 8 395 2.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <linux/netdevice.h>
       4                 :            : #include <netinet/ether.h>
       5                 :            : 
       6                 :            : #include "sd-device.h"
       7                 :            : #include "sd-netlink.h"
       8                 :            : 
       9                 :            : #include "alloc-util.h"
      10                 :            : #include "conf-files.h"
      11                 :            : #include "conf-parser.h"
      12                 :            : #include "def.h"
      13                 :            : #include "device-util.h"
      14                 :            : #include "ethtool-util.h"
      15                 :            : #include "fd-util.h"
      16                 :            : #include "link-config.h"
      17                 :            : #include "log.h"
      18                 :            : #include "memory-util.h"
      19                 :            : #include "naming-scheme.h"
      20                 :            : #include "netlink-util.h"
      21                 :            : #include "network-internal.h"
      22                 :            : #include "parse-util.h"
      23                 :            : #include "path-util.h"
      24                 :            : #include "proc-cmdline.h"
      25                 :            : #include "random-util.h"
      26                 :            : #include "stat-util.h"
      27                 :            : #include "string-table.h"
      28                 :            : #include "string-util.h"
      29                 :            : #include "strv.h"
      30                 :            : 
      31                 :            : struct link_config_ctx {
      32                 :            :         LIST_HEAD(link_config, links);
      33                 :            : 
      34                 :            :         int ethtool_fd;
      35                 :            : 
      36                 :            :         bool enable_name_policy;
      37                 :            : 
      38                 :            :         sd_netlink *rtnl;
      39                 :            : 
      40                 :            :         usec_t network_dirs_ts_usec;
      41                 :            : };
      42                 :            : 
      43                 :          0 : static void link_config_free(link_config *link) {
      44         [ #  # ]:          0 :         if (!link)
      45                 :          0 :                 return;
      46                 :            : 
      47                 :          0 :         free(link->filename);
      48                 :            : 
      49                 :          0 :         set_free_free(link->match_mac);
      50                 :          0 :         strv_free(link->match_path);
      51                 :          0 :         strv_free(link->match_driver);
      52                 :          0 :         strv_free(link->match_type);
      53                 :          0 :         strv_free(link->match_name);
      54                 :          0 :         strv_free(link->match_property);
      55                 :          0 :         condition_free_list(link->conditions);
      56                 :            : 
      57                 :          0 :         free(link->description);
      58                 :          0 :         free(link->mac);
      59                 :          0 :         free(link->name_policy);
      60                 :          0 :         free(link->name);
      61                 :          0 :         free(link->alias);
      62                 :            : 
      63                 :          0 :         free(link);
      64                 :            : }
      65                 :            : 
      66         [ #  # ]:          0 : DEFINE_TRIVIAL_CLEANUP_FUNC(link_config*, link_config_free);
      67                 :            : 
      68                 :          0 : static void link_configs_free(link_config_ctx *ctx) {
      69                 :            :         link_config *link, *link_next;
      70                 :            : 
      71         [ #  # ]:          0 :         if (!ctx)
      72                 :          0 :                 return;
      73                 :            : 
      74         [ #  # ]:          0 :         LIST_FOREACH_SAFE(links, link, link_next, ctx->links)
      75                 :          0 :                 link_config_free(link);
      76                 :            : }
      77                 :            : 
      78                 :          0 : void link_config_ctx_free(link_config_ctx *ctx) {
      79         [ #  # ]:          0 :         if (!ctx)
      80                 :          0 :                 return;
      81                 :            : 
      82                 :          0 :         safe_close(ctx->ethtool_fd);
      83                 :            : 
      84                 :          0 :         sd_netlink_unref(ctx->rtnl);
      85                 :            : 
      86                 :          0 :         link_configs_free(ctx);
      87                 :            : 
      88                 :          0 :         free(ctx);
      89                 :            : 
      90                 :          0 :         return;
      91                 :            : }
      92                 :            : 
      93                 :          0 : int link_config_ctx_new(link_config_ctx **ret) {
      94                 :          0 :         _cleanup_(link_config_ctx_freep) link_config_ctx *ctx = NULL;
      95                 :            : 
      96         [ #  # ]:          0 :         if (!ret)
      97                 :          0 :                 return -EINVAL;
      98                 :            : 
      99                 :          0 :         ctx = new0(link_config_ctx, 1);
     100         [ #  # ]:          0 :         if (!ctx)
     101                 :          0 :                 return -ENOMEM;
     102                 :            : 
     103                 :          0 :         LIST_HEAD_INIT(ctx->links);
     104                 :            : 
     105                 :          0 :         ctx->ethtool_fd = -1;
     106                 :            : 
     107                 :          0 :         ctx->enable_name_policy = true;
     108                 :            : 
     109                 :          0 :         *ret = TAKE_PTR(ctx);
     110                 :            : 
     111                 :          0 :         return 0;
     112                 :            : }
     113                 :            : 
     114                 :          0 : int link_load_one(link_config_ctx *ctx, const char *filename) {
     115                 :          0 :         _cleanup_(link_config_freep) link_config *link = NULL;
     116                 :          0 :         _cleanup_fclose_ FILE *file = NULL;
     117                 :          0 :         _cleanup_free_ char *name = NULL;
     118                 :            :         size_t i;
     119                 :            :         int r;
     120                 :            : 
     121         [ #  # ]:          0 :         assert(ctx);
     122         [ #  # ]:          0 :         assert(filename);
     123                 :            : 
     124                 :          0 :         file = fopen(filename, "re");
     125         [ #  # ]:          0 :         if (!file)
     126         [ #  # ]:          0 :                 return errno == ENOENT ? 0 : -errno;
     127                 :            : 
     128         [ #  # ]:          0 :         if (null_or_empty_fd(fileno(file))) {
     129         [ #  # ]:          0 :                 log_debug("Skipping empty file: %s", filename);
     130                 :          0 :                 return 0;
     131                 :            :         }
     132                 :            : 
     133                 :          0 :         name = strdup(filename);
     134         [ #  # ]:          0 :         if (!name)
     135                 :          0 :                 return -ENOMEM;
     136                 :            : 
     137                 :          0 :         link = new(link_config, 1);
     138         [ #  # ]:          0 :         if (!link)
     139                 :          0 :                 return -ENOMEM;
     140                 :            : 
     141                 :          0 :         *link = (link_config) {
     142                 :          0 :                 .filename = TAKE_PTR(name),
     143                 :            :                 .mac_address_policy = _MAC_ADDRESS_POLICY_INVALID,
     144                 :            :                 .wol = _WOL_INVALID,
     145                 :            :                 .duplex = _DUP_INVALID,
     146                 :            :                 .port = _NET_DEV_PORT_INVALID,
     147                 :            :                 .autonegotiation = -1,
     148                 :            :         };
     149                 :            : 
     150         [ #  # ]:          0 :         for (i = 0; i < ELEMENTSOF(link->features); i++)
     151                 :          0 :                 link->features[i] = -1;
     152                 :            : 
     153                 :          0 :         r = config_parse(NULL, filename, file,
     154                 :            :                          "Match\0Link\0",
     155                 :            :                          config_item_perf_lookup, link_config_gperf_lookup,
     156                 :            :                          CONFIG_PARSE_WARN, link);
     157         [ #  # ]:          0 :         if (r < 0)
     158                 :          0 :                 return r;
     159                 :            : 
     160         [ #  # ]:          0 :         if (link->speed > UINT_MAX)
     161                 :          0 :                 return -ERANGE;
     162                 :            : 
     163   [ #  #  #  #  :          0 :         if (set_isempty(link->match_mac) && strv_isempty(link->match_path) &&
                   #  # ]
     164   [ #  #  #  # ]:          0 :             strv_isempty(link->match_driver) && strv_isempty(link->match_type) &&
     165   [ #  #  #  # ]:          0 :             strv_isempty(link->match_name) && strv_isempty(link->match_property) && !link->conditions)
     166         [ #  # ]:          0 :                 log_warning("%s: No valid settings found in the [Match] section. "
     167                 :            :                             "The file will match all interfaces. "
     168                 :            :                             "If that is intended, please add OriginalName=* in the [Match] section.",
     169                 :            :                             filename);
     170                 :            : 
     171         [ #  # ]:          0 :         if (!condition_test_list(link->conditions, NULL, NULL, NULL)) {
     172         [ #  # ]:          0 :                 log_debug("%s: Conditions do not match the system environment, skipping.", filename);
     173                 :          0 :                 return 0;
     174                 :            :         }
     175                 :            : 
     176         [ #  # ]:          0 :         log_debug("Parsed configuration file %s", filename);
     177                 :            : 
     178   [ #  #  #  # ]:          0 :         LIST_PREPEND(links, ctx->links, TAKE_PTR(link));
     179                 :          0 :         return 0;
     180                 :            : }
     181                 :            : 
     182                 :          0 : static bool enable_name_policy(void) {
     183                 :            :         bool b;
     184                 :            : 
     185   [ #  #  #  # ]:          0 :         return proc_cmdline_get_bool("net.ifnames", &b) <= 0 || b;
     186                 :            : }
     187                 :            : 
     188                 :          0 : static int link_unsigned_attribute(sd_device *device, const char *attr, unsigned *type) {
     189                 :            :         const char *s;
     190                 :            :         int r;
     191                 :            : 
     192                 :          0 :         r = sd_device_get_sysattr_value(device, attr, &s);
     193         [ #  # ]:          0 :         if (r < 0)
     194   [ #  #  #  #  :          0 :                 return log_device_debug_errno(device, r, "Failed to query %s: %m", attr);
                   #  # ]
     195                 :            : 
     196                 :          0 :         r = safe_atou(s, type);
     197         [ #  # ]:          0 :         if (r < 0)
     198   [ #  #  #  #  :          0 :                 return log_device_warning_errno(device, r, "Failed to parse %s \"%s\": %m", attr, s);
                   #  # ]
     199                 :            : 
     200   [ #  #  #  #  :          0 :         log_device_debug(device, "Device has %s=%u", attr, *type);
                   #  # ]
     201                 :          0 :         return 0;
     202                 :            : }
     203                 :            : 
     204                 :          0 : int link_config_load(link_config_ctx *ctx) {
     205                 :          0 :         _cleanup_strv_free_ char **files;
     206                 :            :         char **f;
     207                 :            :         int r;
     208                 :            : 
     209                 :          0 :         link_configs_free(ctx);
     210                 :            : 
     211         [ #  # ]:          0 :         if (!enable_name_policy()) {
     212                 :          0 :                 ctx->enable_name_policy = false;
     213         [ #  # ]:          0 :                 log_info("Network interface NamePolicy= disabled on kernel command line, ignoring.");
     214                 :            :         }
     215                 :            : 
     216                 :            :         /* update timestamp */
     217                 :          0 :         paths_check_timestamp(NETWORK_DIRS, &ctx->network_dirs_ts_usec, true);
     218                 :            : 
     219                 :          0 :         r = conf_files_list_strv(&files, ".link", NULL, 0, NETWORK_DIRS);
     220         [ #  # ]:          0 :         if (r < 0)
     221         [ #  # ]:          0 :                 return log_error_errno(r, "failed to enumerate link files: %m");
     222                 :            : 
     223   [ #  #  #  #  :          0 :         STRV_FOREACH_BACKWARDS(f, files) {
                   #  # ]
     224                 :          0 :                 r = link_load_one(ctx, *f);
     225         [ #  # ]:          0 :                 if (r < 0)
     226         [ #  # ]:          0 :                         log_error_errno(r, "Failed to load %s, ignoring: %m", *f);
     227                 :            :         }
     228                 :            : 
     229                 :          0 :         return 0;
     230                 :            : }
     231                 :            : 
     232                 :          0 : bool link_config_should_reload(link_config_ctx *ctx) {
     233                 :          0 :         return paths_check_timestamp(NETWORK_DIRS, &ctx->network_dirs_ts_usec, false);
     234                 :            : }
     235                 :            : 
     236                 :          0 : int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret) {
     237                 :            :         link_config *link;
     238                 :            : 
     239         [ #  # ]:          0 :         assert(ctx);
     240         [ #  # ]:          0 :         assert(device);
     241         [ #  # ]:          0 :         assert(ret);
     242                 :            : 
     243         [ #  # ]:          0 :         LIST_FOREACH(links, link, ctx->links) {
     244         [ #  # ]:          0 :                 if (net_match_config(link->match_mac, link->match_path, link->match_driver,
     245                 :          0 :                                      link->match_type, link->match_name, link->match_property,
     246                 :            :                                      device, NULL, NULL)) {
     247   [ #  #  #  # ]:          0 :                         if (link->match_name && !strv_contains(link->match_name, "*")) {
     248                 :          0 :                                 unsigned name_assign_type = NET_NAME_UNKNOWN;
     249                 :            : 
     250                 :          0 :                                 (void) link_unsigned_attribute(device, "name_assign_type", &name_assign_type);
     251                 :            : 
     252         [ #  # ]:          0 :                                 if (name_assign_type == NET_NAME_ENUM) {
     253   [ #  #  #  #  :          0 :                                         log_device_warning(device, "Config file %s applies to device based on potentially unpredictable interface name",
                   #  # ]
     254                 :            :                                                            link->filename);
     255                 :          0 :                                         *ret = link;
     256                 :            : 
     257                 :          0 :                                         return 0;
     258         [ #  # ]:          0 :                                 } else if (name_assign_type == NET_NAME_RENAMED) {
     259   [ #  #  #  #  :          0 :                                         log_device_warning(device, "Config file %s matches device based on renamed interface name, ignoring",
                   #  # ]
     260                 :            :                                                            link->filename);
     261                 :            : 
     262                 :          0 :                                         continue;
     263                 :            :                                 }
     264                 :            :                         }
     265                 :            : 
     266   [ #  #  #  #  :          0 :                         log_device_debug(device, "Config file %s is applied", link->filename);
                   #  # ]
     267                 :            : 
     268                 :          0 :                         *ret = link;
     269                 :          0 :                         return 0;
     270                 :            :                 }
     271                 :            :         }
     272                 :            : 
     273                 :          0 :         *ret = NULL;
     274                 :          0 :         return -ENOENT;
     275                 :            : }
     276                 :            : 
     277                 :          0 : static int get_mac(sd_device *device, MACAddressPolicy policy, struct ether_addr *mac) {
     278                 :            :         unsigned addr_type;
     279                 :          0 :         bool want_random = policy == MAC_ADDRESS_POLICY_RANDOM;
     280                 :            :         int r;
     281                 :            : 
     282   [ #  #  #  # ]:          0 :         assert(IN_SET(policy, MAC_ADDRESS_POLICY_RANDOM, MAC_ADDRESS_POLICY_PERSISTENT));
     283                 :            : 
     284                 :          0 :         r = link_unsigned_attribute(device, "addr_assign_type", &addr_type);
     285         [ #  # ]:          0 :         if (r < 0)
     286                 :          0 :                 return r;
     287   [ #  #  #  # ]:          0 :         switch (addr_type) {
     288                 :          0 :         case NET_ADDR_SET:
     289   [ #  #  #  #  :          0 :                 return log_device_debug(device, "MAC on the device already set by userspace");
                   #  # ]
     290                 :          0 :         case NET_ADDR_STOLEN:
     291   [ #  #  #  #  :          0 :                 return log_device_debug(device, "MAC on the device already set based on another device");
                   #  # ]
     292                 :          0 :         case NET_ADDR_RANDOM:
     293                 :            :         case NET_ADDR_PERM:
     294                 :          0 :                 break;
     295                 :          0 :         default:
     296   [ #  #  #  #  :          0 :                 return log_device_warning(device, "Unknown addr_assign_type %u, ignoring", addr_type);
                   #  # ]
     297                 :            :         }
     298                 :            : 
     299         [ #  # ]:          0 :         if (want_random == (addr_type == NET_ADDR_RANDOM))
     300   [ #  #  #  #  :          0 :                 return log_device_debug(device, "MAC on the device already matches policy *%s*",
                   #  # ]
     301                 :            :                                         mac_address_policy_to_string(policy));
     302                 :            : 
     303         [ #  # ]:          0 :         if (want_random) {
     304   [ #  #  #  #  :          0 :                 log_device_debug(device, "Using random bytes to generate MAC");
                   #  # ]
     305                 :          0 :                 random_bytes(mac->ether_addr_octet, ETH_ALEN);
     306                 :            :         } else {
     307                 :            :                 uint64_t result;
     308                 :            : 
     309                 :          0 :                 r = net_get_unique_predictable_data(device,
     310                 :          0 :                                                     naming_scheme_has(NAMING_STABLE_VIRTUAL_MACS),
     311                 :            :                                                     &result);
     312         [ #  # ]:          0 :                 if (r < 0)
     313   [ #  #  #  #  :          0 :                         return log_device_warning_errno(device, r, "Could not generate persistent MAC: %m");
                   #  # ]
     314                 :            : 
     315   [ #  #  #  #  :          0 :                 log_device_debug(device, "Using generated persistent MAC address");
                   #  # ]
     316                 :            :                 assert_cc(ETH_ALEN <= sizeof(result));
     317                 :          0 :                 memcpy(mac->ether_addr_octet, &result, ETH_ALEN);
     318                 :            :         }
     319                 :            : 
     320                 :            :         /* see eth_random_addr in the kernel */
     321                 :          0 :         mac->ether_addr_octet[0] &= 0xfe;  /* clear multicast bit */
     322                 :          0 :         mac->ether_addr_octet[0] |= 0x02;  /* set local assignment bit (IEEE802) */
     323                 :          0 :         return 1;
     324                 :            : }
     325                 :            : 
     326                 :          0 : int link_config_apply(link_config_ctx *ctx, link_config *config,
     327                 :            :                       sd_device *device, const char **name) {
     328                 :            :         struct ether_addr generated_mac;
     329                 :          0 :         struct ether_addr *mac = NULL;
     330                 :          0 :         const char *new_name = NULL;
     331                 :            :         const char *old_name;
     332                 :          0 :         unsigned speed, name_type = NET_NAME_UNKNOWN;
     333                 :            :         NamePolicy policy;
     334                 :            :         int r, ifindex;
     335                 :            : 
     336         [ #  # ]:          0 :         assert(ctx);
     337         [ #  # ]:          0 :         assert(config);
     338         [ #  # ]:          0 :         assert(device);
     339         [ #  # ]:          0 :         assert(name);
     340                 :            : 
     341                 :          0 :         r = sd_device_get_sysname(device, &old_name);
     342         [ #  # ]:          0 :         if (r < 0)
     343                 :          0 :                 return r;
     344                 :            : 
     345                 :          0 :         r = ethtool_set_glinksettings(&ctx->ethtool_fd, old_name,
     346                 :          0 :                                       config->autonegotiation, config->advertise,
     347                 :            :                                       config->speed, config->duplex, config->port);
     348         [ #  # ]:          0 :         if (r < 0) {
     349                 :            : 
     350         [ #  # ]:          0 :                 if (config->port != _NET_DEV_PORT_INVALID)
     351         [ #  # ]:          0 :                         log_warning_errno(r, "Could not set port (%s) of %s: %m", port_to_string(config->port), old_name);
     352                 :            : 
     353         [ #  # ]:          0 :                 if (!eqzero(config->advertise))
     354         [ #  # ]:          0 :                         log_warning_errno(r, "Could not set advertise mode: %m"); /* TODO: include modes in the log message. */
     355                 :            : 
     356         [ #  # ]:          0 :                 if (config->speed) {
     357                 :          0 :                         speed = DIV_ROUND_UP(config->speed, 1000000);
     358         [ #  # ]:          0 :                         if (r == -EOPNOTSUPP) {
     359                 :          0 :                                 r = ethtool_set_speed(&ctx->ethtool_fd, old_name, speed, config->duplex);
     360         [ #  # ]:          0 :                                 if (r < 0)
     361         [ #  # ]:          0 :                                         log_warning_errno(r, "Could not set speed of %s to %u Mbps: %m", old_name, speed);
     362                 :            :                         }
     363                 :            :                 }
     364                 :            : 
     365         [ #  # ]:          0 :                 if (config->duplex !=_DUP_INVALID)
     366         [ #  # ]:          0 :                         log_warning_errno(r, "Could not set duplex of %s to (%s): %m", old_name, duplex_to_string(config->duplex));
     367                 :            :         }
     368                 :            : 
     369                 :          0 :         r = ethtool_set_wol(&ctx->ethtool_fd, old_name, config->wol);
     370         [ #  # ]:          0 :         if (r < 0)
     371         [ #  # ]:          0 :                 log_warning_errno(r, "Could not set WakeOnLan of %s to %s: %m",
     372                 :            :                                   old_name, wol_to_string(config->wol));
     373                 :            : 
     374                 :          0 :         r = ethtool_set_features(&ctx->ethtool_fd, old_name, config->features);
     375         [ #  # ]:          0 :         if (r < 0)
     376         [ #  # ]:          0 :                 log_warning_errno(r, "Could not set offload features of %s: %m", old_name);
     377                 :            : 
     378   [ #  #  #  #  :          0 :         if (config->channels.rx_count_set || config->channels.tx_count_set || config->channels.other_count_set || config->channels.combined_count_set) {
             #  #  #  # ]
     379                 :          0 :                 r = ethtool_set_channels(&ctx->ethtool_fd, old_name, &config->channels);
     380         [ #  # ]:          0 :                 if (r < 0)
     381         [ #  # ]:          0 :                         log_warning_errno(r, "Could not set channels of %s: %m", old_name);
     382                 :            :         }
     383                 :            : 
     384                 :          0 :         r = sd_device_get_ifindex(device, &ifindex);
     385         [ #  # ]:          0 :         if (r < 0)
     386   [ #  #  #  #  :          0 :                 return log_device_warning_errno(device, r, "Could not find ifindex: %m");
                   #  # ]
     387                 :            : 
     388                 :          0 :         (void) link_unsigned_attribute(device, "name_assign_type", &name_type);
     389                 :            : 
     390   [ #  #  #  # ]:          0 :         if (IN_SET(name_type, NET_NAME_USER, NET_NAME_RENAMED)
     391         [ #  # ]:          0 :             && !naming_scheme_has(NAMING_ALLOW_RERENAMES)) {
     392   [ #  #  #  #  :          0 :                 log_device_debug(device, "Device already has a name given by userspace, not renaming.");
                   #  # ]
     393                 :          0 :                 goto no_rename;
     394                 :            :         }
     395                 :            : 
     396   [ #  #  #  # ]:          0 :         if (ctx->enable_name_policy && config->name_policy)
     397   [ #  #  #  # ]:          0 :                 for (NamePolicy *p = config->name_policy; !new_name && *p != _NAMEPOLICY_INVALID; p++) {
     398                 :          0 :                         policy = *p;
     399                 :            : 
     400   [ #  #  #  #  :          0 :                         switch (policy) {
             #  #  #  # ]
     401                 :          0 :                         case NAMEPOLICY_KERNEL:
     402         [ #  # ]:          0 :                                 if (name_type != NET_NAME_PREDICTABLE)
     403                 :          0 :                                         continue;
     404                 :            : 
     405                 :            :                                 /* The kernel claims to have given a predictable name, keep it. */
     406   [ #  #  #  #  :          0 :                                 log_device_debug(device, "Policy *%s*: keeping predictable kernel name",
                   #  # ]
     407                 :            :                                                  name_policy_to_string(policy));
     408                 :          0 :                                 goto no_rename;
     409                 :          0 :                         case NAMEPOLICY_KEEP:
     410   [ #  #  #  # ]:          0 :                                 if (!IN_SET(name_type, NET_NAME_USER, NET_NAME_RENAMED))
     411                 :          0 :                                         continue;
     412                 :            : 
     413   [ #  #  #  #  :          0 :                                 log_device_debug(device, "Policy *%s*: keeping existing userspace name",
                   #  # ]
     414                 :            :                                                  name_policy_to_string(policy));
     415                 :          0 :                                 goto no_rename;
     416                 :          0 :                         case NAMEPOLICY_DATABASE:
     417                 :          0 :                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE", &new_name);
     418                 :          0 :                                 break;
     419                 :          0 :                         case NAMEPOLICY_ONBOARD:
     420                 :          0 :                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_ONBOARD", &new_name);
     421                 :          0 :                                 break;
     422                 :          0 :                         case NAMEPOLICY_SLOT:
     423                 :          0 :                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_SLOT", &new_name);
     424                 :          0 :                                 break;
     425                 :          0 :                         case NAMEPOLICY_PATH:
     426                 :          0 :                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_PATH", &new_name);
     427                 :          0 :                                 break;
     428                 :          0 :                         case NAMEPOLICY_MAC:
     429                 :          0 :                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_MAC", &new_name);
     430                 :          0 :                                 break;
     431                 :          0 :                         default:
     432                 :          0 :                                 assert_not_reached("invalid policy");
     433                 :            :                         }
     434                 :            :                 }
     435                 :            : 
     436         [ #  # ]:          0 :         if (new_name)
     437   [ #  #  #  #  :          0 :                 log_device_debug(device, "Policy *%s* yields \"%s\".", name_policy_to_string(policy), new_name);
                   #  # ]
     438         [ #  # ]:          0 :         else if (config->name) {
     439                 :          0 :                 new_name = config->name;
     440   [ #  #  #  #  :          0 :                 log_device_debug(device, "Policies didn't yield a name, using specified Name=%s.", new_name);
                   #  # ]
     441                 :            :         } else
     442   [ #  #  #  #  :          0 :                 log_device_debug(device, "Policies didn't yield a name and Name= is not given, not renaming.");
                   #  # ]
     443                 :          0 :  no_rename:
     444                 :            : 
     445   [ #  #  #  # ]:          0 :         if (IN_SET(config->mac_address_policy, MAC_ADDRESS_POLICY_PERSISTENT, MAC_ADDRESS_POLICY_RANDOM)) {
     446         [ #  # ]:          0 :                 if (get_mac(device, config->mac_address_policy, &generated_mac) > 0)
     447                 :          0 :                         mac = &generated_mac;
     448                 :            :         } else
     449                 :          0 :                 mac = config->mac;
     450                 :            : 
     451                 :          0 :         r = rtnl_set_link_properties(&ctx->rtnl, ifindex, config->alias, mac, config->mtu);
     452         [ #  # ]:          0 :         if (r < 0)
     453         [ #  # ]:          0 :                 return log_warning_errno(r, "Could not set Alias=, MACAddress= or MTU= on %s: %m", old_name);
     454                 :            : 
     455                 :          0 :         *name = new_name;
     456                 :            : 
     457                 :          0 :         return 0;
     458                 :            : }
     459                 :            : 
     460                 :          0 : int link_get_driver(link_config_ctx *ctx, sd_device *device, char **ret) {
     461                 :            :         const char *name;
     462                 :          0 :         char *driver = NULL;
     463                 :            :         int r;
     464                 :            : 
     465                 :          0 :         r = sd_device_get_sysname(device, &name);
     466         [ #  # ]:          0 :         if (r < 0)
     467                 :          0 :                 return r;
     468                 :            : 
     469                 :          0 :         r = ethtool_get_driver(&ctx->ethtool_fd, name, &driver);
     470         [ #  # ]:          0 :         if (r < 0)
     471                 :          0 :                 return r;
     472                 :            : 
     473                 :          0 :         *ret = driver;
     474                 :          0 :         return 0;
     475                 :            : }
     476                 :            : 
     477                 :            : static const char* const mac_address_policy_table[_MAC_ADDRESS_POLICY_MAX] = {
     478                 :            :         [MAC_ADDRESS_POLICY_PERSISTENT] = "persistent",
     479                 :            :         [MAC_ADDRESS_POLICY_RANDOM] = "random",
     480                 :            :         [MAC_ADDRESS_POLICY_NONE] = "none",
     481                 :            : };
     482                 :            : 
     483   [ +  +  +  + ]:         40 : DEFINE_STRING_TABLE_LOOKUP(mac_address_policy, MACAddressPolicy);
     484   [ #  #  #  #  :          0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_mac_address_policy, mac_address_policy, MACAddressPolicy,
          #  #  #  #  #  
                #  #  # ]
     485                 :            :                          "Failed to parse MAC address policy");
     486                 :            : 
     487                 :            : static const char* const name_policy_table[_NAMEPOLICY_MAX] = {
     488                 :            :         [NAMEPOLICY_KERNEL] = "kernel",
     489                 :            :         [NAMEPOLICY_KEEP] = "keep",
     490                 :            :         [NAMEPOLICY_DATABASE] = "database",
     491                 :            :         [NAMEPOLICY_ONBOARD] = "onboard",
     492                 :            :         [NAMEPOLICY_SLOT] = "slot",
     493                 :            :         [NAMEPOLICY_PATH] = "path",
     494                 :            :         [NAMEPOLICY_MAC] = "mac",
     495                 :            : };
     496                 :            : 
     497   [ +  +  +  + ]:         72 : DEFINE_STRING_TABLE_LOOKUP(name_policy, NamePolicy);
     498   [ #  #  #  #  :          0 : DEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy, name_policy, NamePolicy,
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     499                 :            :                           _NAMEPOLICY_INVALID,
     500                 :            :                           "Failed to parse interface name policy");

Generated by: LCOV version 1.14