• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 16458254342

22 Jul 2025 11:49PM UTC coverage: 72.173% (+0.05%) from 72.121%
16458254342

push

github

yuwata
meson: prepend sys_root to bpf isystem

These sort of absolute include paths are generally unsafe when cross compiling.

302515 of 419153 relevant lines covered (72.17%)

734662.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.66
/src/network/networkd-network.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <unistd.h>
4

5
#include "alloc-util.h"
6
#include "condition.h"
7
#include "conf-files.h"
8
#include "conf-parser.h"
9
#include "in-addr-util.h"
10
#include "net-condition.h"
11
#include "netdev/macvlan.h"
12
#include "netif-sriov.h"
13
#include "network-util.h"
14
#include "networkd-address.h"
15
#include "networkd-address-label.h"
16
#include "networkd-bridge-fdb.h"
17
#include "networkd-bridge-mdb.h"
18
#include "networkd-dhcp-common.h"
19
#include "networkd-dhcp-server-static-lease.h"
20
#include "networkd-ipv6-proxy-ndp.h"
21
#include "networkd-manager.h"
22
#include "networkd-ndisc.h"
23
#include "networkd-neighbor.h"
24
#include "networkd-network.h"
25
#include "networkd-nexthop.h"
26
#include "networkd-radv.h"
27
#include "networkd-route.h"
28
#include "networkd-routing-policy-rule.h"
29
#include "ordered-set.h"
30
#include "parse-util.h"
31
#include "path-util.h"
32
#include "qdisc.h"
33
#include "radv-internal.h"
34
#include "set.h"
35
#include "socket-util.h"
36
#include "stat-util.h"
37
#include "string-table.h"
38
#include "string-util.h"
39
#include "strv.h"
40
#include "tclass.h"
41

42
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
6,381✔
43
                network_hash_ops,
44
                char, string_hash_func, string_compare_func,
45
                Network, network_unref);
46

47
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
196✔
48
                stacked_netdevs_hash_ops,
49
                char, string_hash_func, string_compare_func,
50
                NetDev, netdev_unref);
51

52
static int network_resolve_netdev_one(Network *network, const char *name, NetDevKind kind, NetDev **ret) {
25,813✔
53
        const char *kind_string;
25,813✔
54
        NetDev *netdev;
25,813✔
55
        int r;
25,813✔
56

57
        /* For test-networkd-conf, the check must be earlier than the assertions. */
58
        if (!name)
25,813✔
59
                return 0;
25,813✔
60

61
        assert(network);
239✔
62
        assert(network->manager);
239✔
63
        assert(network->filename);
239✔
64
        assert(ret);
239✔
65

66
        if (kind == _NETDEV_KIND_TUNNEL)
239✔
67
                kind_string = "tunnel";
68
        else {
69
                kind_string = netdev_kind_to_string(kind);
89✔
70
                if (!kind_string)
89✔
71
                        return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
×
72
                                                 "%s: Invalid NetDev kind of %s, ignoring assignment.",
73
                                                 network->filename, name);
74
        }
75

76
        r = netdev_get(network->manager, name, &netdev);
239✔
77
        if (r < 0)
239✔
78
                return log_warning_errno(r, "%s: %s NetDev could not be found, ignoring assignment.",
1✔
79
                                         network->filename, name);
80

81
        if (netdev->kind != kind && !(kind == _NETDEV_KIND_TUNNEL &&
238✔
82
                                      IN_SET(netdev->kind,
149✔
83
                                             NETDEV_KIND_ERSPAN,
84
                                             NETDEV_KIND_GRE,
85
                                             NETDEV_KIND_GRETAP,
86
                                             NETDEV_KIND_IP6GRE,
87
                                             NETDEV_KIND_IP6GRETAP,
88
                                             NETDEV_KIND_IP6TNL,
89
                                             NETDEV_KIND_IPIP,
90
                                             NETDEV_KIND_SIT,
91
                                             NETDEV_KIND_VTI,
92
                                             NETDEV_KIND_VTI6)))
93
                return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
×
94
                                         "%s: NetDev %s is not a %s, ignoring assignment",
95
                                         network->filename, name, kind_string);
96

97
        *ret = netdev_ref(netdev);
238✔
98
        return 1;
238✔
99
}
100

101
static int network_resolve_stacked_netdevs(Network *network) {
6,404✔
102
        void *name, *kind;
6,404✔
103
        int r;
6,404✔
104

105
        assert(network);
6,404✔
106

107
        HASHMAP_FOREACH_KEY(kind, name, network->stacked_netdev_names) {
6,601✔
108
                _cleanup_(netdev_unrefp) NetDev *netdev = NULL;
×
109

110
                if (network_resolve_netdev_one(network, name, PTR_TO_INT(kind), &netdev) <= 0)
197✔
111
                        continue;
1✔
112

113
                r = hashmap_ensure_put(&network->stacked_netdevs, &stacked_netdevs_hash_ops, netdev->ifname, netdev);
196✔
114
                if (r == -ENOMEM)
196✔
115
                        return log_oom();
×
116
                if (r < 0)
196✔
117
                        log_warning_errno(r, "%s: Failed to add NetDev '%s' to network, ignoring: %m",
×
118
                                          network->filename, (const char *) name);
119

120
                TAKE_PTR(netdev);
196✔
121
        }
122

123
        return 0;
6,404✔
124
}
125

126
int network_verify(Network *network) {
7,446✔
127
        int r;
7,446✔
128

129
        assert(network);
7,446✔
130
        assert(network->manager);
7,446✔
131
        assert(network->filename);
7,446✔
132

133
        if (net_match_is_empty(&network->match) && !network->conditions)
7,446✔
134
                return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
×
135
                                         "%s: No valid settings found in the [Match] section, ignoring file. "
136
                                         "To match all interfaces, add Name=* in the [Match] section.",
137
                                         network->filename);
138

139
        /* skip out early if configuration does not match the environment */
140
        if (!condition_test_list(network->conditions, environ, NULL, NULL, NULL))
7,446✔
141
                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
1,042✔
142
                                       "%s: Conditions in the file do not match the system environment, skipping.",
143
                                       network->filename);
144

145
        if (network->keep_master) {
6,404✔
146
                if (network->batadv_name)
593✔
147
                        log_warning("%s: BatmanAdvanced= set with KeepMaster= enabled, ignoring BatmanAdvanced=.",
×
148
                                    network->filename);
149
                if (network->bond_name)
593✔
150
                        log_warning("%s: Bond= set with KeepMaster= enabled, ignoring Bond=.",
×
151
                                    network->filename);
152
                if (network->bridge_name)
593✔
153
                        log_warning("%s: Bridge= set with KeepMaster= enabled, ignoring Bridge=.",
×
154
                                    network->filename);
155
                if (network->vrf_name)
593✔
156
                        log_warning("%s: VRF= set with KeepMaster= enabled, ignoring VRF=.",
×
157
                                    network->filename);
158

159
                network->batadv_name = mfree(network->batadv_name);
593✔
160
                network->bond_name = mfree(network->bond_name);
593✔
161
                network->bridge_name = mfree(network->bridge_name);
593✔
162
                network->vrf_name = mfree(network->vrf_name);
593✔
163
        }
164

165
        (void) network_resolve_netdev_one(network, network->batadv_name, NETDEV_KIND_BATADV, &network->batadv);
6,404✔
166
        (void) network_resolve_netdev_one(network, network->bond_name, NETDEV_KIND_BOND, &network->bond);
6,404✔
167
        (void) network_resolve_netdev_one(network, network->bridge_name, NETDEV_KIND_BRIDGE, &network->bridge);
6,404✔
168
        (void) network_resolve_netdev_one(network, network->vrf_name, NETDEV_KIND_VRF, &network->vrf);
6,404✔
169
        r = network_resolve_stacked_netdevs(network);
6,404✔
170
        if (r < 0)
6,404✔
171
                return r;
172

173
        /* Free unnecessary entries. */
174
        network->batadv_name = mfree(network->batadv_name);
6,404✔
175
        network->bond_name = mfree(network->bond_name);
6,404✔
176
        network->bridge_name = mfree(network->bridge_name);
6,404✔
177
        network->vrf_name = mfree(network->vrf_name);
6,404✔
178
        network->stacked_netdev_names = hashmap_free(network->stacked_netdev_names);
6,404✔
179

180
        if (network->bond) {
6,404✔
181
                /* Bonding slave does not support addressing. */
182
                if (network->link_local >= 0 && network->link_local != ADDRESS_FAMILY_NO) {
9✔
183
                        log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
2✔
184
                                    network->filename);
185
                        network->link_local = ADDRESS_FAMILY_NO;
2✔
186
                }
187
                if (!ordered_hashmap_isempty(network->addresses_by_section))
9✔
188
                        log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
2✔
189
                                    network->filename);
190
                if (!hashmap_isempty(network->routes_by_section))
9✔
191
                        log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
2✔
192
                                    network->filename);
193

194
                network->addresses_by_section = ordered_hashmap_free(network->addresses_by_section);
9✔
195
                network->routes_by_section = hashmap_free(network->routes_by_section);
9✔
196
        }
197

198
        if (network->link_local < 0) {
6,404✔
199
                network->link_local = ADDRESS_FAMILY_IPV6;
1,862✔
200

201
                if (network->keep_master || network->bridge)
1,862✔
202
                        network->link_local = ADDRESS_FAMILY_NO;
28✔
203
                else {
204
                        NetDev *netdev;
1,834✔
205

206
                        HASHMAP_FOREACH(netdev, network->stacked_netdevs) {
2,008✔
207
                                MacVlan *m;
190✔
208

209
                                if (netdev->kind == NETDEV_KIND_MACVLAN)
190✔
210
                                        m = MACVLAN(netdev);
8✔
211
                                else if (netdev->kind == NETDEV_KIND_MACVTAP)
182✔
212
                                        m = MACVTAP(netdev);
8✔
213
                                else
214
                                        continue;
174✔
215

216
                                if (m->mode == NETDEV_MACVLAN_MODE_PASSTHRU)
16✔
217
                                        network->link_local = ADDRESS_FAMILY_NO;
4✔
218

219
                                /* There won't be a passthru MACVLAN/MACVTAP if there's already one in another mode */
220
                                break;
221
                        }
222
                }
223
        }
224

225
        if (network->ipv6ll_address_gen_mode == IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE)
6,404✔
226
                SET_FLAG(network->link_local, ADDRESS_FAMILY_IPV6, false);
×
227

228
        if (in6_addr_is_set(&network->ipv6ll_stable_secret) &&
6,404✔
229
            network->ipv6ll_address_gen_mode < 0)
230
                network->ipv6ll_address_gen_mode = IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY;
1✔
231

232
        network_adjust_ipv6_proxy_ndp(network);
6,404✔
233
        network_adjust_ndisc(network);
6,404✔
234
        network_adjust_dhcp(network);
6,404✔
235
        network_adjust_radv(network);
6,404✔
236
        network_adjust_bridge_vlan(network);
6,404✔
237

238
        if (network->mtu > 0 && network->dhcp_use_mtu) {
6,404✔
239
                log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
×
240
                            "Disabling UseMTU=.", network->filename);
241
                network->dhcp_use_mtu = false;
×
242
        }
243

244
        if (network->dhcp_critical >= 0) {
6,404✔
245
                if (network->keep_configuration >= 0) {
23✔
246
                        if (network->manager->keep_configuration < 0)
23✔
247
                                log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
23✔
248
                                            "Ignoring CriticalConnection=.", network->filename);
249
                } else if (network->dhcp_critical)
×
250
                        /* CriticalConnection=yes also preserve foreign static configurations. */
251
                        network->keep_configuration = KEEP_CONFIGURATION_YES;
×
252
                else
253
                        network->keep_configuration = KEEP_CONFIGURATION_NO;
×
254
        }
255

256
        if (!strv_isempty(network->bind_carrier)) {
6,404✔
257
                if (!IN_SET(network->activation_policy, _ACTIVATION_POLICY_INVALID, ACTIVATION_POLICY_BOUND))
8✔
258
                        log_warning("%s: ActivationPolicy=bound is required with BindCarrier=. "
×
259
                                    "Setting ActivationPolicy=bound.", network->filename);
260
                network->activation_policy = ACTIVATION_POLICY_BOUND;
8✔
261
        } else if (network->activation_policy == ACTIVATION_POLICY_BOUND) {
6,396✔
262
                log_warning("%s: ActivationPolicy=bound requires BindCarrier=. "
×
263
                            "Ignoring ActivationPolicy=bound.", network->filename);
264
                network->activation_policy = ACTIVATION_POLICY_UP;
×
265
        }
266

267
        if (network->activation_policy == _ACTIVATION_POLICY_INVALID)
6,404✔
268
                network->activation_policy = ACTIVATION_POLICY_UP;
6,346✔
269

270
        if (network->activation_policy == ACTIVATION_POLICY_ALWAYS_UP) {
6,404✔
271
                if (network->ignore_carrier_loss_set && network->ignore_carrier_loss_usec < USEC_INFINITY)
5✔
272
                        log_warning("%s: IgnoreCarrierLoss=no or finite timespan conflicts with ActivationPolicy=always-up. "
×
273
                                    "Setting IgnoreCarrierLoss=yes.", network->filename);
274
                network->ignore_carrier_loss_set = true;
5✔
275
                network->ignore_carrier_loss_usec = USEC_INFINITY;
5✔
276
        }
277

278
        if (!network->ignore_carrier_loss_set) /* Set implied default. */
6,404✔
279
                network->ignore_carrier_loss_usec = network->configure_without_carrier ? USEC_INFINITY : 0;
12,788✔
280

281
        if (IN_SET(network->activation_policy, ACTIVATION_POLICY_DOWN, ACTIVATION_POLICY_ALWAYS_DOWN, ACTIVATION_POLICY_MANUAL)) {
6,404✔
282
                if (network->required_for_online < 0 ||
16✔
283
                    (network->required_for_online == true && network->activation_policy == ACTIVATION_POLICY_ALWAYS_DOWN)) {
3✔
284
                        log_debug("%s: Setting RequiredForOnline=no because ActivationPolicy=%s.", network->filename,
11✔
285
                                  activation_policy_to_string(network->activation_policy));
286
                        network->required_for_online = false;
11✔
287
                } else if (network->required_for_online == true)
5✔
288
                        log_warning("%s: RequiredForOnline=yes and ActivationPolicy=%s, "
2✔
289
                                    "this may cause a delay at boot.", network->filename,
290
                                    activation_policy_to_string(network->activation_policy));
291
        }
292

293
        if (network->required_for_online < 0)
6,404✔
294
                network->required_for_online = true;
2,808✔
295

296
        if (network->keep_configuration < 0)
6,404✔
297
                network->keep_configuration = KEEP_CONFIGURATION_NO;
6,371✔
298

299
        r = network_drop_invalid_addresses(network);
6,404✔
300
        if (r < 0)
6,404✔
301
                return r; /* network_drop_invalid_addresses() logs internally. */
302
        network_drop_invalid_routes(network);
6,404✔
303
        r = network_drop_invalid_nexthops(network);
6,404✔
304
        if (r < 0)
6,404✔
305
                return r;
306
        network_drop_invalid_bridge_fdb_entries(network);
6,404✔
307
        network_drop_invalid_bridge_mdb_entries(network);
6,404✔
308
        r = network_drop_invalid_neighbors(network);
6,404✔
309
        if (r < 0)
6,404✔
310
                return r;
311
        network_drop_invalid_address_labels(network);
6,404✔
312
        network_drop_invalid_routing_policy_rules(network);
6,404✔
313
        network_drop_invalid_qdisc(network);
6,404✔
314
        network_drop_invalid_tclass(network);
6,404✔
315
        r = sr_iov_drop_invalid_sections(UINT32_MAX, network->sr_iov_by_section);
6,404✔
316
        if (r < 0)
6,404✔
317
                return r; /* sr_iov_drop_invalid_sections() logs internally. */
318
        network_drop_invalid_static_leases(network);
6,404✔
319

320
        return 0;
6,404✔
321
}
322

323
int network_load_one(Manager *manager, OrderedHashmap **networks, const char *filename) {
7,425✔
324
        _cleanup_free_ char *fname = NULL, *name = NULL;
7,425✔
325
        _cleanup_(network_unrefp) Network *network = NULL;
7,425✔
326
        const char *dropin_dirname;
7,425✔
327
        char *d;
7,425✔
328
        int r;
7,425✔
329

330
        assert(manager);
7,425✔
331
        assert(filename);
7,425✔
332

333
        r = null_or_empty_path(filename);
7,425✔
334
        if (r < 0)
7,425✔
335
                return log_warning_errno(r, "Failed to check if \"%s\" is empty: %m", filename);
×
336
        if (r > 0) {
7,425✔
337
                log_debug("Skipping empty file: %s", filename);
2✔
338
                return 0;
2✔
339
        }
340

341
        fname = strdup(filename);
7,423✔
342
        if (!fname)
7,423✔
343
                return log_oom();
×
344

345
        r = path_extract_filename(filename, &name);
7,423✔
346
        if (r < 0)
7,423✔
347
                return log_warning_errno(r, "Failed to extract file name of \"%s\": %m", filename);
×
348

349
        d = strrchr(name, '.');
7,423✔
350
        if (!d)
7,423✔
351
                return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid file name: %s", filename);
×
352

353
        *d = '\0';
7,423✔
354

355
        dropin_dirname = strjoina(name, ".network.d");
37,115✔
356

357
        network = new(Network, 1);
7,423✔
358
        if (!network)
7,423✔
359
                return log_oom();
×
360

361
        *network = (Network) {
7,423✔
362
                .filename = TAKE_PTR(fname),
7,423✔
363
                .name = TAKE_PTR(name),
7,423✔
364

365
                .manager = manager,
366
                .n_ref = 1,
367

368
                .required_for_online = -1,
369
                .required_operstate_for_online = LINK_OPERSTATE_RANGE_INVALID,
370
                .activation_policy = _ACTIVATION_POLICY_INVALID,
371
                .group = -1,
372
                .arp = -1,
373
                .multicast = -1,
374
                .allmulticast = -1,
375
                .promiscuous = -1,
376

377
                .keep_configuration = manager->keep_configuration,
7,423✔
378

379
                .use_domains = _USE_DOMAINS_INVALID,
380

381
                .compat_dhcp_use_domains = _USE_DOMAINS_INVALID,
382
                .compat_dhcp_use_dns = -1,
383
                .compat_dhcp_use_ntp = -1,
384

385
                .dhcp_duid.type = _DUID_TYPE_INVALID,
386
                .dhcp_critical = -1,
387
                .dhcp_use_ntp = -1,
388
                .dhcp_routes_to_ntp = true,
389
                .dhcp_use_sip = true,
390
                .dhcp_use_captive_portal = true,
391
                .dhcp_use_dns = -1,
392
                .dhcp_use_dnr = -1,
393
                .dhcp_routes_to_dns = true,
394
                .dhcp_use_domains = _USE_DOMAINS_INVALID,
395
                .dhcp_use_hostname = true,
396
                .dhcp_use_routes = true,
397
                .dhcp_use_gateway = -1,
398
                .dhcp_send_hostname = true,
399
                .dhcp_send_release = true,
400
                .dhcp_route_metric = DHCP_ROUTE_METRIC,
401
                .dhcp_use_rapid_commit = -1,
402
                .dhcp_client_identifier = _DHCP_CLIENT_ID_INVALID,
403
                .dhcp_route_table = RT_TABLE_MAIN,
404
                .dhcp_ip_service_type = -1,
405
                .dhcp_broadcast = -1,
406
                .dhcp_ipv6_only_mode = -1,
407
                .dhcp_6rd_prefix_route_type = RTN_UNREACHABLE,
408

409
                .dhcp6_use_address = true,
410
                .dhcp6_use_pd_prefix = true,
411
                .dhcp6_use_dns = -1,
412
                .dhcp6_use_dnr = -1,
413
                .dhcp6_use_domains = _USE_DOMAINS_INVALID,
414
                .dhcp6_use_hostname = true,
415
                .dhcp6_use_ntp = -1,
416
                .dhcp6_use_sip = true,
417
                .dhcp6_use_captive_portal = true,
418
                .dhcp6_use_rapid_commit = true,
419
                .dhcp6_send_hostname = true,
420
                .dhcp6_duid.type = _DUID_TYPE_INVALID,
421
                .dhcp6_client_start_mode = _DHCP6_CLIENT_START_MODE_INVALID,
422
                .dhcp6_send_release = true,
423
                .dhcp6_pd_prefix_route_type = RTN_UNREACHABLE,
424

425
                .dhcp_pd = -1,
426
                .dhcp_pd_announce = true,
427
                .dhcp_pd_assign = true,
428
                .dhcp_pd_manage_temporary_address = true,
429
                .dhcp_pd_subnet_id = -1,
430
                .dhcp_pd_route_metric = DHCP6PD_ROUTE_METRIC,
431

432
                .dhcp_server_bind_to_interface = true,
433
                .dhcp_server_emit[SD_DHCP_LEASE_DNS].emit = true,
434
                .dhcp_server_emit[SD_DHCP_LEASE_NTP].emit = true,
435
                .dhcp_server_emit[SD_DHCP_LEASE_SIP].emit = true,
436
                .dhcp_server_emit_router = true,
437
                .dhcp_server_emit_timezone = true,
438
                .dhcp_server_rapid_commit = true,
439
                .dhcp_server_persist_leases = _DHCP_SERVER_PERSIST_LEASES_INVALID,
440

441
                .router_lifetime_usec = RADV_DEFAULT_ROUTER_LIFETIME_USEC,
442
                .router_dns_lifetime_usec = RADV_DEFAULT_VALID_LIFETIME_USEC,
443
                .router_emit_dns = true,
444
                .router_emit_domains = true,
445

446
                .use_bpdu = -1,
447
                .hairpin = -1,
448
                .isolated = -1,
449
                .fast_leave = -1,
450
                .allow_port_to_be_root = -1,
451
                .unicast_flood = -1,
452
                .multicast_flood = -1,
453
                .multicast_to_unicast = -1,
454
                .neighbor_suppression = -1,
455
                .learning = -1,
456
                .bridge_proxy_arp = -1,
457
                .bridge_proxy_arp_wifi = -1,
458
                .priority = LINK_BRIDGE_PORT_PRIORITY_INVALID,
459
                .multicast_router = _MULTICAST_ROUTER_INVALID,
460
                .bridge_locked = -1,
461
                .bridge_mac_authentication_bypass = -1,
462
                .bridge_vlan_tunnel = -1,
463

464
                .bridge_vlan_pvid = BRIDGE_VLAN_KEEP_PVID,
465

466
                .lldp_mode = LLDP_MODE_ROUTERS_ONLY,
467
                .lldp_multicast_mode = _SD_LLDP_MULTICAST_MODE_INVALID,
468

469
                .dns_default_route = -1,
470
                .llmnr = RESOLVE_SUPPORT_YES,
471
                .mdns = RESOLVE_SUPPORT_NO,
472
                .dnssec_mode = _DNSSEC_MODE_INVALID,
473
                .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
474

475
                /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
476
                .link_local = _ADDRESS_FAMILY_INVALID,
477
                .ipv6ll_address_gen_mode = _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID,
478

479
                .ip_forwarding = { -1, -1, },
480
                .ipv4_accept_local = -1,
481
                .ipv4_route_localnet = -1,
482
                .ipv6_privacy_extensions = _IPV6_PRIVACY_EXTENSIONS_INVALID,
483
                .ipv6_dad_transmits = -1,
484
                .ipv6_proxy_ndp = -1,
485
                .proxy_arp = -1,
486
                .proxy_arp_pvlan = -1,
487
                .ipv4_rp_filter = _IP_REVERSE_PATH_FILTER_INVALID,
488
                .ipv4_force_igmp_version = _IPV4_FORCE_IGMP_VERSION_INVALID,
489
                .mpls_input = -1,
490

491
                .ndisc = -1,
492
                .ndisc_use_redirect = true,
493
                .ndisc_use_dns = -1,
494
                .ndisc_use_dnr = -1,
495
                .ndisc_use_gateway = true,
496
                .ndisc_use_captive_portal = true,
497
                .ndisc_use_route_prefix = true,
498
                .ndisc_use_autonomous_prefix = true,
499
                .ndisc_use_onlink_prefix = true,
500
                .ndisc_use_mtu = true,
501
                .ndisc_use_hop_limit = true,
502
                .ndisc_use_reachable_time = true,
503
                .ndisc_use_retransmission_time = true,
504
                .ndisc_use_domains = _USE_DOMAINS_INVALID,
505
                .ndisc_route_table = RT_TABLE_MAIN,
506
                .ndisc_route_metric_high = IPV6RA_ROUTE_METRIC_HIGH,
507
                .ndisc_route_metric_medium = IPV6RA_ROUTE_METRIC_MEDIUM,
508
                .ndisc_route_metric_low = IPV6RA_ROUTE_METRIC_LOW,
509
                .ndisc_start_dhcp6_client = IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES,
510

511
                .can_termination = -1,
512

513
                .ipoib_mode = _IP_OVER_INFINIBAND_MODE_INVALID,
514
                .ipoib_umcast = -1,
515
        };
516

517
        r = config_parse_many(
14,846✔
518
                        STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname, /* root = */ NULL,
7,423✔
519
                        "Match\0"
520
                        "Link\0"
521
                        "SR-IOV\0"
522
                        "Network\0"
523
                        "Address\0"
524
                        "Neighbor\0"
525
                        "IPv6AddressLabel\0"
526
                        "RoutingPolicyRule\0"
527
                        "Route\0"
528
                        "NextHop\0"
529
                        "DHCP\0" /* compat */
530
                        "DHCPv4\0"
531
                        "DHCPv6\0"
532
                        "DHCPv6PrefixDelegation\0" /* compat */
533
                        "DHCPPrefixDelegation\0"
534
                        "DHCPServer\0"
535
                        "DHCPServerStaticLease\0"
536
                        "IPv6AcceptRA\0"
537
                        "IPv6NDPProxyAddress\0"
538
                        "Bridge\0"
539
                        "BridgeFDB\0"
540
                        "BridgeMDB\0"
541
                        "BridgeVLAN\0"
542
                        "IPv6SendRA\0"
543
                        "IPv6PrefixDelegation\0"
544
                        "IPv6Prefix\0"
545
                        "IPv6RoutePrefix\0"
546
                        "IPv6PREF64Prefix\0"
547
                        "LLDP\0"
548
                        "TrafficControlQueueingDiscipline\0"
549
                        "CAN\0"
550
                        "QDisc\0"
551
                        "BFIFO\0"
552
                        "CAKE\0"
553
                        "ControlledDelay\0"
554
                        "DeficitRoundRobinScheduler\0"
555
                        "DeficitRoundRobinSchedulerClass\0"
556
                        "EnhancedTransmissionSelection\0"
557
                        "FairQueueing\0"
558
                        "FairQueueingControlledDelay\0"
559
                        "FlowQueuePIE\0"
560
                        "GenericRandomEarlyDetection\0"
561
                        "HeavyHitterFilter\0"
562
                        "HierarchyTokenBucket\0"
563
                        "HierarchyTokenBucketClass\0"
564
                        "ClassfulMultiQueueing\0"
565
                        "BandMultiQueueing\0"
566
                        "NetworkEmulator\0"
567
                        "PFIFO\0"
568
                        "PFIFOFast\0"
569
                        "PFIFOHeadDrop\0"
570
                        "PIE\0"
571
                        "QuickFairQueueing\0"
572
                        "QuickFairQueueingClass\0"
573
                        "StochasticFairBlue\0"
574
                        "StochasticFairnessQueueing\0"
575
                        "TokenBucketFilter\0"
576
                        "TrivialLinkEqualizer\0",
577
                        config_item_perf_lookup, network_network_gperf_lookup,
578
                        CONFIG_PARSE_WARN,
579
                        network,
580
                        &network->stats_by_path,
581
                        &network->dropins);
7,423✔
582
        if (r < 0)
7,423✔
583
                return r; /* config_parse_many() logs internally. */
584

585
        r = network_add_ipv4ll_route(network);
7,423✔
586
        if (r < 0)
7,423✔
587
                return log_warning_errno(r, "%s: Failed to add IPv4LL route: %m", network->filename);
×
588

589
        r = network_add_default_route_on_device(network);
7,423✔
590
        if (r < 0)
7,423✔
591
                return log_warning_errno(r, "%s: Failed to add default route on device: %m",
×
592
                                         network->filename);
593

594
        r = network_verify(network);
7,423✔
595
        if (r < 0)
7,423✔
596
                return r; /* network_verify() logs internally. */
597

598
        r = ordered_hashmap_ensure_put(networks, &network_hash_ops, network->name, network);
6,381✔
599
        if (r < 0)
6,381✔
600
                return log_warning_errno(r, "%s: Failed to store configuration into hashmap: %m", filename);
×
601

602
        TAKE_PTR(network);
6,381✔
603
        log_syntax(/* unit = */ NULL, LOG_DEBUG, filename, /* config_line = */ 0, /* error = */ 0, "Successfully loaded.");
6,381✔
604
        return 0;
605
}
606

607
int network_load(Manager *manager, OrderedHashmap **ret) {
591✔
608
        _cleanup_strv_free_ char **files = NULL;
591✔
609
        OrderedHashmap *networks = NULL;
591✔
610
        int r;
591✔
611

612
        assert(manager);
591✔
613
        assert(ret);
591✔
614

615
        r = conf_files_list_strv(&files, ".network", NULL, 0, NETWORK_DIRS);
591✔
616
        if (r < 0)
591✔
617
                return log_error_errno(r, "Failed to enumerate network files: %m");
×
618

619
        STRV_FOREACH(f, files)
8,016✔
620
                (void) network_load_one(manager, &networks, *f);
7,425✔
621

622
        *ret = TAKE_PTR(networks);
591✔
623
        return 0;
591✔
624
}
625

626
static bool network_netdev_equal(Network *a, Network *b) {
1,591✔
627
        assert(a);
1,591✔
628
        assert(b);
1,591✔
629

630
        if (a->batadv != b->batadv ||
1,591✔
631
            a->bridge != b->bridge ||
1,591✔
632
            a->bond != b->bond ||
1,591✔
633
            a->vrf != b->vrf ||
1,591✔
634
            a->xfrm != b->xfrm)
1,591✔
635
                return false;
1,591✔
636

637
        if (hashmap_size(a->stacked_netdevs) != hashmap_size(b->stacked_netdevs))
1,591✔
638
                return false;
639

640
        NetDev *n;
1,591✔
641
        HASHMAP_FOREACH(n, a->stacked_netdevs)
1,592✔
642
                if (hashmap_get(b->stacked_netdevs, n->ifname) != n)
45✔
643
                        return false;
44✔
644

645
        return true;
1,547✔
646
}
647

648
int network_reload(Manager *manager) {
152✔
649
        _cleanup_ordered_hashmap_free_ OrderedHashmap *new_networks = NULL;
152✔
650
        Network *n, *old;
152✔
651
        int r;
152✔
652

653
        assert(manager);
152✔
654

655
        r = network_load(manager, &new_networks);
152✔
656
        if (r < 0)
152✔
657
                return r;
658

659
        ORDERED_HASHMAP_FOREACH(n, new_networks) {
1,861✔
660
                r = network_get_by_name(manager, n->name, &old);
1,709✔
661
                if (r < 0) {
1,709✔
662
                        log_debug("%s: Found new .network file.", n->filename);
31✔
663
                        continue;
31✔
664
                }
665

666
                if (!stats_by_path_equal(n->stats_by_path, old->stats_by_path)) {
1,678✔
667
                        log_debug("%s: Found updated .network file.", n->filename);
87✔
668
                        continue;
87✔
669
                }
670

671
                if (!network_netdev_equal(n, old)) {
1,591✔
672
                        log_debug("%s: Detected update of referenced .netdev file(s).", n->filename);
44✔
673
                        continue;
44✔
674
                }
675

676
                /* Nothing updated, use the existing Network object, and drop the new one. */
677
                r = ordered_hashmap_replace(new_networks, old->name, old);
1,547✔
678
                if (r < 0)
1,547✔
679
                        return r;
×
680

681
                network_ref(old);
1,547✔
682
                network_unref(n);
1,547✔
683
        }
684

685
        ordered_hashmap_free_and_replace(manager->networks, new_networks);
152✔
686

687
        r = manager_build_dhcp_pd_subnet_ids(manager);
152✔
688
        if (r < 0)
152✔
689
                return r;
690

691
        r = manager_build_nexthop_ids(manager);
152✔
692
        if (r < 0)
152✔
693
                return r;
×
694

695
        return 0;
696
}
697

698
int manager_build_dhcp_pd_subnet_ids(Manager *manager) {
591✔
699
        Network *n;
591✔
700
        int r;
591✔
701

702
        assert(manager);
591✔
703

704
        set_clear(manager->dhcp_pd_subnet_ids);
591✔
705

706
        ORDERED_HASHMAP_FOREACH(n, manager->networks) {
6,972✔
707
                if (n->unmanaged)
6,381✔
708
                        continue;
357✔
709

710
                if (!n->dhcp_pd)
6,024✔
711
                        continue;
5,417✔
712

713
                if (n->dhcp_pd_subnet_id < 0)
607✔
714
                        continue;
593✔
715

716
                r = set_ensure_put(&manager->dhcp_pd_subnet_ids, &uint64_hash_ops, &n->dhcp_pd_subnet_id);
14✔
717
                if (r < 0)
14✔
718
                        return r;
×
719
        }
720

721
        return 0;
591✔
722
}
723

724
static Network *network_free(Network *network) {
7,446✔
725
        if (!network)
7,446✔
726
                return NULL;
727

728
        free(network->name);
7,446✔
729
        free(network->filename);
7,446✔
730
        free(network->description);
7,446✔
731
        strv_free(network->dropins);
7,446✔
732
        hashmap_free(network->stats_by_path);
7,446✔
733

734
        /* conditions */
735
        net_match_clear(&network->match);
7,446✔
736
        condition_free_list(network->conditions);
7,446✔
737

738
        /* link settings */
739
        strv_free(network->bind_carrier);
7,446✔
740

741
        /* NTP */
742
        strv_free(network->ntp);
7,446✔
743

744
        /* DNS */
745
        for (unsigned i = 0; i < network->n_dns; i++)
7,455✔
746
                in_addr_full_free(network->dns[i]);
9✔
747
        free(network->dns);
7,446✔
748
        ordered_set_free(network->search_domains);
7,446✔
749
        ordered_set_free(network->route_domains);
7,446✔
750
        set_free(network->dnssec_negative_trust_anchors);
7,446✔
751

752
        /* DHCP server */
753
        free(network->dhcp_server_relay_agent_circuit_id);
7,446✔
754
        free(network->dhcp_server_relay_agent_remote_id);
7,446✔
755
        free(network->dhcp_server_boot_server_name);
7,446✔
756
        free(network->dhcp_server_boot_filename);
7,446✔
757
        free(network->dhcp_server_timezone);
7,446✔
758
        free(network->dhcp_server_uplink_name);
7,446✔
759
        for (sd_dhcp_lease_server_type_t t = 0; t < _SD_DHCP_LEASE_SERVER_TYPE_MAX; t++)
52,122✔
760
                free(network->dhcp_server_emit[t].addresses);
44,676✔
761
        ordered_hashmap_free(network->dhcp_server_send_options);
7,446✔
762
        ordered_hashmap_free(network->dhcp_server_send_vendor_options);
7,446✔
763

764
        /* DHCP client */
765
        free(network->dhcp_vendor_class_identifier);
7,446✔
766
        free(network->dhcp_mudurl);
7,446✔
767
        free(network->dhcp_hostname);
7,446✔
768
        free(network->dhcp_label);
7,446✔
769
        set_free(network->dhcp_deny_listed_ip);
7,446✔
770
        set_free(network->dhcp_allow_listed_ip);
7,446✔
771
        strv_free(network->dhcp_user_class);
7,446✔
772
        set_free(network->dhcp_request_options);
7,446✔
773
        ordered_hashmap_free(network->dhcp_client_send_options);
7,446✔
774
        ordered_hashmap_free(network->dhcp_client_send_vendor_options);
7,446✔
775
        free(network->dhcp_netlabel);
7,446✔
776
        nft_set_context_clear(&network->dhcp_nft_set_context);
7,446✔
777

778
        /* DHCPv6 client */
779
        free(network->dhcp6_mudurl);
7,446✔
780
        free(network->dhcp6_hostname);
7,446✔
781
        strv_free(network->dhcp6_user_class);
7,446✔
782
        strv_free(network->dhcp6_vendor_class);
7,446✔
783
        set_free(network->dhcp6_request_options);
7,446✔
784
        ordered_hashmap_free(network->dhcp6_client_send_options);
7,446✔
785
        ordered_hashmap_free(network->dhcp6_client_send_vendor_options);
7,446✔
786
        free(network->dhcp6_netlabel);
7,446✔
787
        nft_set_context_clear(&network->dhcp6_nft_set_context);
7,446✔
788

789
        /* DHCP PD */
790
        free(network->dhcp_pd_uplink_name);
7,446✔
791
        set_free(network->dhcp_pd_tokens);
7,446✔
792
        free(network->dhcp_pd_netlabel);
7,446✔
793
        nft_set_context_clear(&network->dhcp_pd_nft_set_context);
7,446✔
794

795
        /* Router advertisement */
796
        ordered_set_free(network->router_search_domains);
7,446✔
797
        free(network->router_dns);
7,446✔
798
        free(network->router_uplink_name);
7,446✔
799

800
        /* NDisc */
801
        set_free(network->ndisc_deny_listed_router);
7,446✔
802
        set_free(network->ndisc_allow_listed_router);
7,446✔
803
        set_free(network->ndisc_deny_listed_prefix);
7,446✔
804
        set_free(network->ndisc_allow_listed_prefix);
7,446✔
805
        set_free(network->ndisc_deny_listed_route_prefix);
7,446✔
806
        set_free(network->ndisc_allow_listed_route_prefix);
7,446✔
807
        set_free(network->ndisc_tokens);
7,446✔
808
        free(network->ndisc_netlabel);
7,446✔
809
        nft_set_context_clear(&network->ndisc_nft_set_context);
7,446✔
810

811
        /* LLDP */
812
        free(network->lldp_mudurl);
7,446✔
813

814
        /* netdev */
815
        free(network->batadv_name);
7,446✔
816
        free(network->bridge_name);
7,446✔
817
        free(network->bond_name);
7,446✔
818
        free(network->vrf_name);
7,446✔
819
        hashmap_free(network->stacked_netdev_names);
7,446✔
820
        netdev_unref(network->bridge);
7,446✔
821
        netdev_unref(network->bond);
7,446✔
822
        netdev_unref(network->vrf);
7,446✔
823
        hashmap_free(network->stacked_netdevs);
7,446✔
824

825
        /* static configs */
826
        set_free(network->ipv6_proxy_ndp_addresses);
7,446✔
827
        ordered_hashmap_free(network->addresses_by_section);
7,446✔
828
        hashmap_free(network->routes_by_section);
7,446✔
829
        ordered_hashmap_free(network->nexthops_by_section);
7,446✔
830
        hashmap_free(network->bridge_fdb_entries_by_section);
7,446✔
831
        hashmap_free(network->bridge_mdb_entries_by_section);
7,446✔
832
        ordered_hashmap_free(network->neighbors_by_section);
7,446✔
833
        hashmap_free(network->address_labels_by_section);
7,446✔
834
        hashmap_free(network->prefixes_by_section);
7,446✔
835
        hashmap_free(network->route_prefixes_by_section);
7,446✔
836
        hashmap_free(network->pref64_prefixes_by_section);
7,446✔
837
        hashmap_free(network->rules_by_section);
7,446✔
838
        hashmap_free(network->dhcp_static_leases_by_section);
7,446✔
839
        ordered_hashmap_free(network->sr_iov_by_section);
7,446✔
840
        hashmap_free(network->qdiscs_by_section);
7,446✔
841
        hashmap_free(network->tclasses_by_section);
7,446✔
842

843
        return mfree(network);
7,446✔
844
}
845

846
DEFINE_TRIVIAL_REF_UNREF_FUNC(Network, network, network_free);
16,296✔
847

848
int network_get_by_name(Manager *manager, const char *name, Network **ret) {
1,720✔
849
        Network *network;
1,720✔
850

851
        assert(manager);
1,720✔
852
        assert(name);
1,720✔
853
        assert(ret);
1,720✔
854

855
        network = ordered_hashmap_get(manager->networks, name);
1,720✔
856
        if (!network)
1,720✔
857
                return -ENOENT;
858

859
        *ret = network;
1,688✔
860

861
        return 0;
1,688✔
862
}
863

864
bool network_has_static_ipv6_configurations(Network *network) {
117✔
865
        Address *address;
117✔
866
        Route *route;
117✔
867
        BridgeFDB *fdb;
117✔
868
        BridgeMDB *mdb;
117✔
869
        Neighbor *neighbor;
117✔
870

871
        assert(network);
117✔
872

873
        ORDERED_HASHMAP_FOREACH(address, network->addresses_by_section)
122✔
874
                if (address->family == AF_INET6)
48✔
875
                        return true;
43✔
876

877
        HASHMAP_FOREACH(route, network->routes_by_section)
74✔
878
                if (route->family == AF_INET6)
×
879
                        return true;
×
880

881
        HASHMAP_FOREACH(fdb, network->bridge_fdb_entries_by_section)
74✔
882
                if (fdb->family == AF_INET6)
×
883
                        return true;
×
884

885
        HASHMAP_FOREACH(mdb, network->bridge_mdb_entries_by_section)
74✔
886
                if (mdb->family == AF_INET6)
1✔
887
                        return true;
1✔
888

889
        ORDERED_HASHMAP_FOREACH(neighbor, network->neighbors_by_section)
75✔
890
                if (neighbor->dst_addr.family == AF_INET6)
2✔
891
                        return true;
×
892

893
        if (!hashmap_isempty(network->address_labels_by_section))
73✔
894
                return true;
895

896
        if (!hashmap_isempty(network->prefixes_by_section))
73✔
897
                return true;
898

899
        if (!hashmap_isempty(network->route_prefixes_by_section))
73✔
900
                return true;
901

902
        if (!hashmap_isempty(network->pref64_prefixes_by_section))
73✔
903
                return true;
×
904

905
        return false;
906
}
907

908
int config_parse_stacked_netdev(
197✔
909
                const char *unit,
910
                const char *filename,
911
                unsigned line,
912
                const char *section,
913
                unsigned section_line,
914
                const char *lvalue,
915
                int ltype,
916
                const char *rvalue,
917
                void *data,
918
                void *userdata) {
919

920
        _cleanup_free_ char *name = NULL;
197✔
921
        NetDevKind kind = ltype;
197✔
922
        Hashmap **h = ASSERT_PTR(data);
197✔
923
        int r;
197✔
924

925
        assert(filename);
197✔
926
        assert(lvalue);
197✔
927
        assert(rvalue);
197✔
928
        assert(IN_SET(kind,
197✔
929
                      NETDEV_KIND_IPOIB,
930
                      NETDEV_KIND_IPVLAN,
931
                      NETDEV_KIND_IPVTAP,
932
                      NETDEV_KIND_MACSEC,
933
                      NETDEV_KIND_MACVLAN,
934
                      NETDEV_KIND_MACVTAP,
935
                      NETDEV_KIND_VLAN,
936
                      NETDEV_KIND_VXLAN,
937
                      NETDEV_KIND_XFRM,
938
                      _NETDEV_KIND_TUNNEL));
939

940
        if (!ifname_valid(rvalue)) {
197✔
941
                log_syntax(unit, LOG_WARNING, filename, line, 0,
×
942
                           "Invalid netdev name in %s=, ignoring assignment: %s", lvalue, rvalue);
943
                return 0;
×
944
        }
945

946
        name = strdup(rvalue);
197✔
947
        if (!name)
197✔
948
                return log_oom();
×
949

950
        r = hashmap_ensure_put(h, &string_hash_ops_free, name, INT_TO_PTR(kind));
197✔
951
        if (r == -ENOMEM)
197✔
952
                return log_oom();
×
953
        if (r < 0)
197✔
954
                log_syntax(unit, LOG_WARNING, filename, line, r,
×
955
                           "Cannot add NetDev '%s' to network, ignoring assignment: %m", name);
956
        else if (r == 0)
197✔
957
                log_syntax(unit, LOG_DEBUG, filename, line, r,
×
958
                           "NetDev '%s' specified twice, ignoring.", name);
959
        else
960
                TAKE_PTR(name);
961

962
        return 0;
963
}
964

965
int config_parse_required_for_online(
3,563✔
966
                const char *unit,
967
                const char *filename,
968
                unsigned line,
969
                const char *section,
970
                unsigned section_line,
971
                const char *lvalue,
972
                int ltype,
973
                const char *rvalue,
974
                void *data,
975
                void *userdata) {
976

977
        Network *network = ASSERT_PTR(userdata);
3,563✔
978
        int r;
3,563✔
979

980
        assert(filename);
3,563✔
981
        assert(lvalue);
3,563✔
982
        assert(rvalue);
3,563✔
983

984
        if (isempty(rvalue)) {
3,563✔
985
                network->required_for_online = -1;
×
986
                network->required_operstate_for_online = LINK_OPERSTATE_RANGE_INVALID;
×
987
                return 0;
×
988
        }
989

990
        r = parse_operational_state_range(rvalue, &network->required_operstate_for_online);
3,563✔
991
        if (r < 0) {
3,563✔
992
                r = parse_boolean(rvalue);
3,562✔
993
                if (r < 0) {
3,562✔
994
                        log_syntax(unit, LOG_WARNING, filename, line, r,
×
995
                                   "Failed to parse %s= setting, ignoring assignment: %s",
996
                                   lvalue, rvalue);
997
                        return 0;
×
998
                }
999

1000
                network->required_for_online = r;
3,562✔
1001
                network->required_operstate_for_online = LINK_OPERSTATE_RANGE_DEFAULT;
3,562✔
1002
                return 0;
3,562✔
1003
        }
1004

1005
        network->required_for_online = true;
1✔
1006
        return 0;
1✔
1007
}
1008

1009
int config_parse_link_group(
×
1010
                const char *unit,
1011
                const char *filename,
1012
                unsigned line,
1013
                const char *section,
1014
                unsigned section_line,
1015
                const char *lvalue,
1016
                int ltype,
1017
                const char *rvalue,
1018
                void *data,
1019
                void *userdata) {
1020

1021
        Network *network = ASSERT_PTR(userdata);
×
1022
        int r;
×
1023
        int32_t group;
×
1024

1025
        assert(filename);
×
1026
        assert(lvalue);
×
1027
        assert(rvalue);
×
1028

1029
        if (isempty(rvalue)) {
×
1030
                network->group = -1;
×
1031
                return 0;
×
1032
        }
1033

1034
        r = safe_atoi32(rvalue, &group);
×
1035
        if (r < 0) {
×
1036
                log_syntax(unit, LOG_WARNING, filename, line, r,
×
1037
                           "Failed to parse Group=, ignoring assignment: %s", rvalue);
1038
                return 0;
×
1039
        }
1040

1041
        if (group < 0) {
×
1042
                log_syntax(unit, LOG_WARNING, filename, line, r,
×
1043
                           "Value of Group= must be in the range 0…2147483647, ignoring assignment: %s", rvalue);
1044
                return 0;
×
1045
        }
1046

1047
        network->group = group;
×
1048
        return 0;
×
1049
}
1050

1051
int config_parse_ignore_carrier_loss(
3✔
1052
                const char *unit,
1053
                const char *filename,
1054
                unsigned line,
1055
                const char *section,
1056
                unsigned section_line,
1057
                const char *lvalue,
1058
                int ltype,
1059
                const char *rvalue,
1060
                void *data,
1061
                void *userdata) {
1062

1063
        Network *network = ASSERT_PTR(userdata);
3✔
1064
        usec_t usec;
3✔
1065
        int r;
3✔
1066

1067
        assert(filename);
3✔
1068
        assert(lvalue);
3✔
1069
        assert(rvalue);
3✔
1070

1071
        if (isempty(rvalue)) {
3✔
1072
                network->ignore_carrier_loss_set = false;
×
1073
                return 0;
×
1074
        }
1075

1076
        r = parse_boolean(rvalue);
3✔
1077
        if (r >= 0) {
3✔
1078
                network->ignore_carrier_loss_set = true;
3✔
1079
                network->ignore_carrier_loss_usec = r > 0 ? USEC_INFINITY : 0;
3✔
1080
                return 0;
3✔
1081
        }
1082

1083
        r = parse_sec(rvalue, &usec);
×
1084
        if (r < 0) {
×
1085
                log_syntax(unit, LOG_WARNING, filename, line, r,
×
1086
                           "Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
1087
                return 0;
×
1088
        }
1089

1090
        network->ignore_carrier_loss_set = true;
×
1091
        network->ignore_carrier_loss_usec = usec;
×
1092
        return 0;
×
1093
}
1094

1095
int config_parse_keep_configuration(
10✔
1096
                const char *unit,
1097
                const char *filename,
1098
                unsigned line,
1099
                const char *section,
1100
                unsigned section_line,
1101
                const char *lvalue,
1102
                int ltype,
1103
                const char *rvalue,
1104
                void *data,
1105
                void *userdata) {
1106

1107
        KeepConfiguration t, *k = ASSERT_PTR(data);
10✔
1108
        Network *network = ASSERT_PTR(userdata);
10✔
1109

1110
        if (isempty(rvalue)) {
10✔
1111
                *k = ASSERT_PTR(network->manager)->keep_configuration;
×
1112
                return 0;
×
1113
        }
1114

1115
        /* backward compatibility */
1116
        if (streq(rvalue, "dhcp")) {
10✔
1117
                *k = KEEP_CONFIGURATION_DYNAMIC;
×
1118
                return 0;
×
1119
        }
1120

1121
        if (streq(rvalue, "dhcp-on-stop")) {
10✔
1122
                *k = KEEP_CONFIGURATION_DYNAMIC_ON_STOP;
×
1123
                return 0;
×
1124
        }
1125

1126
        t = keep_configuration_from_string(rvalue);
10✔
1127
        if (t < 0)
10✔
1128
                return log_syntax_parse_error(unit, filename, line, t, lvalue, rvalue);
×
1129

1130
        *k = t;
10✔
1131
        return 0;
10✔
1132
}
1133

1134
DEFINE_CONFIG_PARSE_ENUM(config_parse_required_family_for_online, link_required_address_family, AddressFamily);
1✔
1135

1136
static const char* const keep_configuration_table[_KEEP_CONFIGURATION_MAX] = {
1137
        [KEEP_CONFIGURATION_NO]              = "no",
1138
        [KEEP_CONFIGURATION_DYNAMIC_ON_STOP] = "dynamic-on-stop",
1139
        [KEEP_CONFIGURATION_DYNAMIC]         = "dynamic",
1140
        [KEEP_CONFIGURATION_STATIC]          = "static",
1141
        [KEEP_CONFIGURATION_YES]             = "yes",
1142
};
1143

1144
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration, KeepConfiguration, KEEP_CONFIGURATION_YES);
10✔
1145

1146
static const char* const activation_policy_table[_ACTIVATION_POLICY_MAX] = {
1147
        [ACTIVATION_POLICY_UP]          = "up",
1148
        [ACTIVATION_POLICY_ALWAYS_UP]   = "always-up",
1149
        [ACTIVATION_POLICY_MANUAL]      = "manual",
1150
        [ACTIVATION_POLICY_ALWAYS_DOWN] = "always-down",
1151
        [ACTIVATION_POLICY_DOWN]        = "down",
1152
        [ACTIVATION_POLICY_BOUND]       = "bound",
1153
};
1154

1155
DEFINE_STRING_TABLE_LOOKUP(activation_policy, ActivationPolicy);
5,505✔
1156
DEFINE_CONFIG_PARSE_ENUM(config_parse_activation_policy, activation_policy, ActivationPolicy);
30✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc