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

systemd / systemd / 19397511130

15 Nov 2025 09:47PM UTC coverage: 72.518% (+0.1%) from 72.37%
19397511130

push

github

web-flow
sd-event: several follow-ups for recent change (#39743)

3 of 4 new or added lines in 2 files covered. (75.0%)

1869 existing lines in 55 files now uncovered.

308519 of 425439 relevant lines covered (72.52%)

1258617.71 hits per line

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

83.72
/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,451✔
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) {
26,093✔
53
        const char *kind_string;
26,093✔
54
        NetDev *netdev;
26,093✔
55
        int r;
26,093✔
56

57
        /* For test-networkd-conf, the check must be earlier than the assertions. */
58
        if (!name)
26,093✔
59
                return 0;
26,093✔
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,474✔
102
        void *name, *kind;
6,474✔
103
        int r;
6,474✔
104

105
        assert(network);
6,474✔
106

107
        HASHMAP_FOREACH_KEY(kind, name, network->stacked_netdev_names) {
6,671✔
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,474✔
124
}
125

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

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

133
        if (net_match_is_empty(&network->match) && !network->conditions)
7,524✔
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,524✔
141
                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
1,050✔
142
                                       "%s: Conditions in the file do not match the system environment, skipping.",
143
                                       network->filename);
144

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

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

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

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

180
        if (network->bond) {
6,474✔
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,474✔
199
                network->link_local = ADDRESS_FAMILY_IPV6;
1,886✔
200

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

206
                        HASHMAP_FOREACH(netdev, network->stacked_netdevs) {
2,032✔
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,474✔
226
                SET_FLAG(network->link_local, ADDRESS_FAMILY_IPV6, false);
×
227

228
        if (in6_addr_is_set(&network->ipv6ll_stable_secret) &&
6,474✔
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,474✔
233
        network_adjust_ndisc(network);
6,474✔
234
        network_adjust_dhcp(network);
6,474✔
235
        network_adjust_radv(network);
6,474✔
236
        network_adjust_bridge_vlan(network);
6,474✔
237

238
        if (network->mtu > 0 && network->dhcp_use_mtu) {
6,474✔
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,474✔
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,474✔
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,466✔
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,474✔
268
                network->activation_policy = ACTIVATION_POLICY_UP;
6,416✔
269

270
        if (network->activation_policy == ACTIVATION_POLICY_ALWAYS_UP) {
6,474✔
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,474✔
279
                network->ignore_carrier_loss_usec = network->configure_without_carrier ? USEC_INFINITY : 0;
12,928✔
280

281
        if (IN_SET(network->activation_policy, ACTIVATION_POLICY_DOWN, ACTIVATION_POLICY_ALWAYS_DOWN, ACTIVATION_POLICY_MANUAL)) {
6,474✔
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,474✔
294
                network->required_for_online = true;
2,842✔
295

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

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

320
        return 0;
6,474✔
321
}
322

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

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

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

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

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

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

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

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

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

361
        *network = (Network) {
7,501✔
362
                .filename = TAKE_PTR(fname),
7,501✔
363
                .name = TAKE_PTR(name),
7,501✔
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,501✔
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(
15,002✔
518
                        STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname, /* root = */ NULL,
7,501✔
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,501✔
582
        if (r < 0)
7,501✔
583
                return r; /* config_parse_many() logs internally. */
584

585
        r = network_add_ipv4ll_route(network);
7,501✔
586
        if (r < 0)
7,501✔
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,501✔
590
        if (r < 0)
7,501✔
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,501✔
595
        if (r < 0)
7,501✔
596
                return r; /* network_verify() logs internally. */
597

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

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

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

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

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

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

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

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

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

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

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

645
        return true;
1,571✔
646
}
647

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

653
        assert(manager);
154✔
654

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

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

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

671
                if (!network_netdev_equal(n, old)) {
1,615✔
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,571✔
678
                if (r < 0)
1,571✔
679
                        return r;
×
680

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

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

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

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

695
        return 0;
696
}
697

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

702
        assert(manager);
597✔
703

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

706
        ORDERED_HASHMAP_FOREACH(n, manager->networks) {
7,048✔
707
                if (n->unmanaged)
6,451✔
708
                        continue;
360✔
709

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

713
                if (n->dhcp_pd_subnet_id < 0)
613✔
714
                        continue;
599✔
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;
597✔
722
}
723

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

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

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

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

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

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

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

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

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

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

797
        /* Router advertisement */
798
        ordered_set_free(network->router_search_domains);
7,524✔
799
        free(network->router_dns);
7,524✔
800
        free(network->router_uplink_name);
7,524✔
801

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

813
        /* LLDP */
814
        free(network->lldp_mudurl);
7,524✔
815

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

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

845
        return mfree(network);
7,524✔
846
}
847

848
DEFINE_TRIVIAL_REF_UNREF_FUNC(Network, network, network_free);
16,480✔
849

850
int network_get_by_name(Manager *manager, const char *name, Network **ret) {
1,745✔
851
        Network *network;
1,745✔
852

853
        assert(manager);
1,745✔
854
        assert(name);
1,745✔
855
        assert(ret);
1,745✔
856

857
        network = ordered_hashmap_get(manager->networks, name);
1,745✔
858
        if (!network)
1,745✔
859
                return -ENOENT;
860

861
        *ret = network;
1,712✔
862

863
        return 0;
1,712✔
864
}
865

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

873
        assert(network);
120✔
874

875
        ORDERED_HASHMAP_FOREACH(address, network->addresses_by_section)
125✔
876
                if (address->family == AF_INET6)
48✔
877
                        return true;
43✔
878

879
        HASHMAP_FOREACH(route, network->routes_by_section)
77✔
880
                if (route->family == AF_INET6)
×
UNCOV
881
                        return true;
×
882

883
        HASHMAP_FOREACH(fdb, network->bridge_fdb_entries_by_section)
77✔
884
                if (fdb->family == AF_INET6)
×
UNCOV
885
                        return true;
×
886

887
        HASHMAP_FOREACH(mdb, network->bridge_mdb_entries_by_section)
77✔
888
                if (mdb->family == AF_INET6)
1✔
889
                        return true;
1✔
890

891
        ORDERED_HASHMAP_FOREACH(neighbor, network->neighbors_by_section)
78✔
892
                if (neighbor->dst_addr.family == AF_INET6)
2✔
UNCOV
893
                        return true;
×
894

895
        if (!hashmap_isempty(network->address_labels_by_section))
76✔
896
                return true;
897

898
        if (!hashmap_isempty(network->prefixes_by_section))
76✔
899
                return true;
900

901
        if (!hashmap_isempty(network->route_prefixes_by_section))
76✔
902
                return true;
903

904
        if (!hashmap_isempty(network->pref64_prefixes_by_section))
76✔
UNCOV
905
                return true;
×
906

907
        return false;
908
}
909

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

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

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

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

948
        name = strdup(rvalue);
197✔
949
        if (!name)
197✔
UNCOV
950
                return log_oom();
×
951

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

964
        return 0;
965
}
966

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

979
        Network *network = ASSERT_PTR(userdata);
3,599✔
980
        int r;
3,599✔
981

982
        assert(filename);
3,599✔
983
        assert(lvalue);
3,599✔
984
        assert(rvalue);
3,599✔
985

986
        if (isempty(rvalue)) {
3,599✔
987
                network->required_for_online = -1;
×
988
                network->required_operstate_for_online = LINK_OPERSTATE_RANGE_INVALID;
×
UNCOV
989
                return 0;
×
990
        }
991

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

1002
                network->required_for_online = r;
3,598✔
1003
                network->required_operstate_for_online = LINK_OPERSTATE_RANGE_DEFAULT;
3,598✔
1004
                return 0;
3,598✔
1005
        }
1006

1007
        network->required_for_online = true;
1✔
1008
        return 0;
1✔
1009
}
1010

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

1023
        Network *network = ASSERT_PTR(userdata);
×
1024
        int r;
×
UNCOV
1025
        int32_t group;
×
1026

1027
        assert(filename);
×
1028
        assert(lvalue);
×
UNCOV
1029
        assert(rvalue);
×
1030

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

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

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

1049
        network->group = group;
×
UNCOV
1050
        return 0;
×
1051
}
1052

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

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

1069
        assert(filename);
3✔
1070
        assert(lvalue);
3✔
1071
        assert(rvalue);
3✔
1072

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

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

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

1092
        network->ignore_carrier_loss_set = true;
×
1093
        network->ignore_carrier_loss_usec = usec;
×
UNCOV
1094
        return 0;
×
1095
}
1096

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

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

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

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

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

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

1132
        *k = t;
10✔
1133
        return 0;
10✔
1134
}
1135

1136
DEFINE_CONFIG_PARSE_ENUM(config_parse_required_family_for_online, link_required_address_family, AddressFamily);
1✔
1137

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

1146
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration, KeepConfiguration, KEEP_CONFIGURATION_YES);
10✔
1147

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

1157
DEFINE_STRING_TABLE_LOOKUP(activation_policy, ActivationPolicy);
5,568✔
1158
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