Bug Summary

File:build-scan/../src/network/netdev/netdev.c
Warning:line 117, column 17
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name netdev.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/network/libnetworkd-core.a.p -I src/network -I ../src/network -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I . -I .. -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/network/netdev/netdev.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <net/if.h>
4
5#include "alloc-util.h"
6#include "conf-files.h"
7#include "conf-parser.h"
8#include "fd-util.h"
9#include "list.h"
10#include "netlink-util.h"
11#include "network-internal.h"
12#include "netdev/netdev.h"
13#include "networkd-manager.h"
14#include "networkd-link.h"
15#include "siphash24.h"
16#include "stat-util.h"
17#include "string-table.h"
18#include "string-util.h"
19
20#include "netdev/bridge.h"
21#include "netdev/bond.h"
22#include "netdev/geneve.h"
23#include "netdev/vlan.h"
24#include "netdev/macvlan.h"
25#include "netdev/ipvlan.h"
26#include "netdev/vxlan.h"
27#include "netdev/tunnel.h"
28#include "netdev/tuntap.h"
29#include "netdev/veth.h"
30#include "netdev/dummy.h"
31#include "netdev/vrf.h"
32#include "netdev/vcan.h"
33#include "netdev/vxcan.h"
34#include "netdev/wireguard.h"
35#include "netdev/netdevsim.h"
36
37const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
38 [NETDEV_KIND_BRIDGE] = &bridge_vtable,
39 [NETDEV_KIND_BOND] = &bond_vtable,
40 [NETDEV_KIND_VLAN] = &vlan_vtable,
41 [NETDEV_KIND_MACVLAN] = &macvlan_vtable,
42 [NETDEV_KIND_MACVTAP] = &macvtap_vtable,
43 [NETDEV_KIND_IPVLAN] = &ipvlan_vtable,
44 [NETDEV_KIND_VXLAN] = &vxlan_vtable,
45 [NETDEV_KIND_IPIP] = &ipip_vtable,
46 [NETDEV_KIND_GRE] = &gre_vtable,
47 [NETDEV_KIND_GRETAP] = &gretap_vtable,
48 [NETDEV_KIND_IP6GRE] = &ip6gre_vtable,
49 [NETDEV_KIND_IP6GRETAP] = &ip6gretap_vtable,
50 [NETDEV_KIND_SIT] = &sit_vtable,
51 [NETDEV_KIND_VTI] = &vti_vtable,
52 [NETDEV_KIND_VTI6] = &vti6_vtable,
53 [NETDEV_KIND_VETH] = &veth_vtable,
54 [NETDEV_KIND_DUMMY] = &dummy_vtable,
55 [NETDEV_KIND_TUN] = &tun_vtable,
56 [NETDEV_KIND_TAP] = &tap_vtable,
57 [NETDEV_KIND_IP6TNL] = &ip6tnl_vtable,
58 [NETDEV_KIND_VRF] = &vrf_vtable,
59 [NETDEV_KIND_VCAN] = &vcan_vtable,
60 [NETDEV_KIND_GENEVE] = &geneve_vtable,
61 [NETDEV_KIND_VXCAN] = &vxcan_vtable,
62 [NETDEV_KIND_WIREGUARD] = &wireguard_vtable,
63 [NETDEV_KIND_NETDEVSIM] = &netdevsim_vtable,
64};
65
66static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
67 [NETDEV_KIND_BRIDGE] = "bridge",
68 [NETDEV_KIND_BOND] = "bond",
69 [NETDEV_KIND_VLAN] = "vlan",
70 [NETDEV_KIND_MACVLAN] = "macvlan",
71 [NETDEV_KIND_MACVTAP] = "macvtap",
72 [NETDEV_KIND_IPVLAN] = "ipvlan",
73 [NETDEV_KIND_VXLAN] = "vxlan",
74 [NETDEV_KIND_IPIP] = "ipip",
75 [NETDEV_KIND_GRE] = "gre",
76 [NETDEV_KIND_GRETAP] = "gretap",
77 [NETDEV_KIND_IP6GRE] = "ip6gre",
78 [NETDEV_KIND_IP6GRETAP] = "ip6gretap",
79 [NETDEV_KIND_SIT] = "sit",
80 [NETDEV_KIND_VETH] = "veth",
81 [NETDEV_KIND_VTI] = "vti",
82 [NETDEV_KIND_VTI6] = "vti6",
83 [NETDEV_KIND_DUMMY] = "dummy",
84 [NETDEV_KIND_TUN] = "tun",
85 [NETDEV_KIND_TAP] = "tap",
86 [NETDEV_KIND_IP6TNL] = "ip6tnl",
87 [NETDEV_KIND_VRF] = "vrf",
88 [NETDEV_KIND_VCAN] = "vcan",
89 [NETDEV_KIND_GENEVE] = "geneve",
90 [NETDEV_KIND_VXCAN] = "vxcan",
91 [NETDEV_KIND_WIREGUARD] = "wireguard",
92 [NETDEV_KIND_NETDEVSIM] = "netdevsim",
93};
94
95DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind)const char *netdev_kind_to_string(NetDevKind i) { if (i < 0
|| i >= (NetDevKind) __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(netdev_kind_table), typeof
(&*(netdev_kind_table))), sizeof(netdev_kind_table)/sizeof
((netdev_kind_table)[0]), ((void)0)))) return ((void*)0); return
netdev_kind_table[i]; } NetDevKind netdev_kind_from_string(const
char *s) { return (NetDevKind) string_table_lookup(netdev_kind_table
, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(netdev_kind_table), typeof(&*(netdev_kind_table))
), sizeof(netdev_kind_table)/sizeof((netdev_kind_table)[0]), (
(void)0))), s); }
;
96DEFINE_CONFIG_PARSE_ENUM(config_parse_netdev_kind, netdev_kind, NetDevKind, "Failed to parse netdev kind")int config_parse_netdev_kind(const char *unit, const char *filename
, unsigned line, const char *section, unsigned section_line, const
char *lvalue, int ltype, const char *rvalue, void *data, void
*userdata) { NetDevKind *i = data, x; do { if ((__builtin_expect
(!!(!(filename)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("filename"), "../src/network/netdev/netdev.c", 96, __PRETTY_FUNCTION__
); } while (0); do { if ((__builtin_expect(!!(!(lvalue)),0)))
log_assert_failed_realm(LOG_REALM_SYSTEMD, ("lvalue"), "../src/network/netdev/netdev.c"
, 96, __PRETTY_FUNCTION__); } while (0); do { if ((__builtin_expect
(!!(!(rvalue)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("rvalue"), "../src/network/netdev/netdev.c", 96, __PRETTY_FUNCTION__
); } while (0); do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("data"), "../src/network/netdev/netdev.c"
, 96, __PRETTY_FUNCTION__); } while (0); x = netdev_kind_from_string
(rvalue); if (x < 0) { ({ int _level = (3), _e = (0); (log_get_max_level_realm
(LOG_REALM_SYSTEMD) >= ((_level) & 0x07)) ? log_syntax_internal
(unit, _level, filename, line, _e, "../src/network/netdev/netdev.c"
, 96, __func__, "Failed to parse netdev kind" ", ignoring: %s"
, rvalue) : -abs(_e); }); return 0; } *i = x; return 0; }
;
97
98static void netdev_cancel_callbacks(NetDev *netdev) {
99 _cleanup_(sd_netlink_message_unrefp)__attribute__((cleanup(sd_netlink_message_unrefp))) sd_netlink_message *m = NULL((void*)0);
100 netdev_join_callback *callback;
101
102 if (!netdev
10.1
'netdev' is non-null
|| !netdev->manager)
11
Assuming field 'manager' is non-null
12
Taking false branch
103 return;
104
105 rtnl_message_new_synthetic_error(netdev->manager->rtnl, -ENODEV19, 0, &m);
106
107 while ((callback = netdev->callbacks)) {
13
Loop condition is true. Entering loop body
24
Loop condition is true. Entering loop body
108 if (m
24.1
'm' is null
) {
14
Assuming 'm' is null
15
Taking false branch
25
Taking false branch
109 assert(callback->link)do { if ((__builtin_expect(!!(!(callback->link)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("callback->link"), "../src/network/netdev/netdev.c"
, 109, __PRETTY_FUNCTION__); } while (0)
;
110 assert(callback->callback)do { if ((__builtin_expect(!!(!(callback->callback)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("callback->callback"), "../src/network/netdev/netdev.c"
, 110, __PRETTY_FUNCTION__); } while (0)
;
111 assert(netdev->manager)do { if ((__builtin_expect(!!(!(netdev->manager)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev->manager"), "../src/network/netdev/netdev.c"
, 111, __PRETTY_FUNCTION__); } while (0)
;
112 assert(netdev->manager->rtnl)do { if ((__builtin_expect(!!(!(netdev->manager->rtnl))
,0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("netdev->manager->rtnl"
), "../src/network/netdev/netdev.c", 112, __PRETTY_FUNCTION__
); } while (0)
;
113
114 callback->callback(netdev->manager->rtnl, m, callback->link);
115 }
116
117 LIST_REMOVE(callbacks, netdev->callbacks, callback)do { typeof(*(netdev->callbacks)) **_head = &(netdev->
callbacks), *_item = (callback); do { if ((__builtin_expect(!
!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, (
"_item"), "../src/network/netdev/netdev.c", 117, __PRETTY_FUNCTION__
); } while (0); if (_item->callbacks_next) _item->callbacks_next
->callbacks_prev = _item->callbacks_prev; if (_item->
callbacks_prev) _item->callbacks_prev->callbacks_next =
_item->callbacks_next; else { do { if ((__builtin_expect(
!!(!(*_head == _item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("*_head == _item"), "../src/network/netdev/netdev.c", 117,
__PRETTY_FUNCTION__); } while (0); *_head = _item->callbacks_next
; } _item->callbacks_next = _item->callbacks_prev = ((void
*)0); } while (0)
;
16
Taking false branch
17
Loop condition is false. Exiting loop
18
Assuming field 'callbacks_next' is null
19
Taking false branch
20
Assuming field 'callbacks_prev' is non-null
21
Taking true branch
22
Loop condition is false. Exiting loop
26
Taking false branch
27
Loop condition is false. Exiting loop
28
Use of memory after it is freed
118 link_unref(callback->link);
119 free(callback);
23
Memory is released
120 }
121}
122
123static void netdev_free(NetDev *netdev) {
124 if (!netdev
8.1
'netdev' is non-null
)
9
Taking false branch
125 return;
126
127 netdev_cancel_callbacks(netdev);
10
Calling 'netdev_cancel_callbacks'
128
129 if (netdev->ifname && netdev->manager)
130 hashmap_remove(netdev->manager->netdevs, netdev->ifname);
131
132 free(netdev->filename);
133
134 free(netdev->description);
135 free(netdev->ifname);
136 free(netdev->mac);
137
138 condition_free_list(netdev->match_host);
139 condition_free_list(netdev->match_virt);
140 condition_free_list(netdev->match_kernel_cmdline);
141 condition_free_list(netdev->match_kernel_version);
142 condition_free_list(netdev->match_arch);
143
144 /* Invoke the per-kind done() destructor, but only if the state field is initialized. We conditionalize that
145 * because we parse .netdev files twice: once to determine the kind (with a short, minimal NetDev structure
146 * allocation, with no room for per-kind fields), and once to read the kind's properties (with a full,
147 * comprehensive NetDev structure allocation with enough space for whatever the specific kind needs). Now, in
148 * the first case we shouldn't try to destruct the per-kind NetDev fields on destruction, in the second case we
149 * should. We use the state field to discern the two cases: it's _NETDEV_STATE_INVALID on the first "raw"
150 * call. */
151 if (netdev->state != _NETDEV_STATE_INVALID &&
152 NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
&&
153 NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
->done)
154 NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
->done(netdev);
155
156 free(netdev);
157}
158
159NetDev *netdev_unref(NetDev *netdev) {
160 if (netdev
5.1
'netdev' is non-null
&& (-- netdev->n_ref <= 0))
6
Assuming the condition is true
7
Taking true branch
161 netdev_free(netdev);
8
Calling 'netdev_free'
162
163 return NULL((void*)0);
164}
165
166NetDev *netdev_ref(NetDev *netdev) {
167 if (netdev)
168 assert_se(++ netdev->n_ref >= 2)do { if ((__builtin_expect(!!(!(++ netdev->n_ref >= 2))
,0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("++ netdev->n_ref >= 2"
), "../src/network/netdev/netdev.c", 168, __PRETTY_FUNCTION__
); } while (0)
;
169
170 return netdev;
171}
172
173void netdev_drop(NetDev *netdev) {
174 if (!netdev || netdev->state == NETDEV_STATE_LINGER)
175 return;
176
177 netdev->state = NETDEV_STATE_LINGER;
178
179 log_netdev_debug(netdev, "netdev removed")({ const NetDev *_n = (netdev); _n ? log_object_internal(7, 0
, "../src/network/netdev/netdev.c", 179, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "netdev removed") : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/network/netdev/netdev.c"
, 179, __func__, "netdev removed"); })
;
180
181 netdev_cancel_callbacks(netdev);
182
183 netdev_unref(netdev);
184
185 return;
186}
187
188int netdev_get(Manager *manager, const char *name, NetDev **ret) {
189 NetDev *netdev;
190
191 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("manager"), "../src/network/netdev/netdev.c"
, 191, __PRETTY_FUNCTION__); } while (0)
;
192 assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("name"), "../src/network/netdev/netdev.c"
, 192, __PRETTY_FUNCTION__); } while (0)
;
193 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/network/netdev/netdev.c"
, 193, __PRETTY_FUNCTION__); } while (0)
;
194
195 netdev = hashmap_get(manager->netdevs, name);
196 if (!netdev) {
197 *ret = NULL((void*)0);
198 return -ENOENT2;
199 }
200
201 *ret = netdev;
202
203 return 0;
204}
205
206static int netdev_enter_failed(NetDev *netdev) {
207 netdev->state = NETDEV_STATE_FAILED;
208
209 netdev_cancel_callbacks(netdev);
210
211 return 0;
212}
213
214static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_netlink_message_handler_t callback) {
215 _cleanup_(sd_netlink_message_unrefp)__attribute__((cleanup(sd_netlink_message_unrefp))) sd_netlink_message *req = NULL((void*)0);
216 int r;
217
218 assert(netdev)do { if ((__builtin_expect(!!(!(netdev)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev"), "../src/network/netdev/netdev.c"
, 218, __PRETTY_FUNCTION__); } while (0)
;
219 assert(netdev->state == NETDEV_STATE_READY)do { if ((__builtin_expect(!!(!(netdev->state == NETDEV_STATE_READY
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("netdev->state == NETDEV_STATE_READY"
), "../src/network/netdev/netdev.c", 219, __PRETTY_FUNCTION__
); } while (0)
;
220 assert(netdev->manager)do { if ((__builtin_expect(!!(!(netdev->manager)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev->manager"), "../src/network/netdev/netdev.c"
, 220, __PRETTY_FUNCTION__); } while (0)
;
221 assert(netdev->manager->rtnl)do { if ((__builtin_expect(!!(!(netdev->manager->rtnl))
,0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("netdev->manager->rtnl"
), "../src/network/netdev/netdev.c", 221, __PRETTY_FUNCTION__
); } while (0)
;
222 assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF
})/sizeof(int)]; switch(netdev->kind) { case NETDEV_KIND_BRIDGE
: case NETDEV_KIND_BOND: case NETDEV_KIND_VRF: _found = 1; break
; default: break; } _found; }))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF)"
), "../src/network/netdev/netdev.c", 222, __PRETTY_FUNCTION__
); } while (0)
;
223 assert(link)do { if ((__builtin_expect(!!(!(link)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("link"), "../src/network/netdev/netdev.c"
, 223, __PRETTY_FUNCTION__); } while (0)
;
224 assert(callback)do { if ((__builtin_expect(!!(!(callback)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("callback"), "../src/network/netdev/netdev.c"
, 224, __PRETTY_FUNCTION__); } while (0)
;
225
226 if (link->flags & IFF_UPIFF_UP && netdev->kind == NETDEV_KIND_BOND) {
227 log_netdev_debug(netdev, "Link '%s' was up when attempting to enslave it. Bringing link down.", link->ifname)({ const NetDev *_n = (netdev); _n ? log_object_internal(7, 0
, "../src/network/netdev/netdev.c", 227, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Link '%s' was up when attempting to enslave it. Bringing link down."
, link->ifname) : log_internal_realm(((LOG_REALM_SYSTEMD) <<
10 | ((7))), 0, "../src/network/netdev/netdev.c", 227, __func__
, "Link '%s' was up when attempting to enslave it. Bringing link down."
, link->ifname); })
;
228 r = link_down(link);
229 if (r < 0)
230 return log_netdev_error_errno(netdev, r, "Could not bring link down: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 230, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not bring link down: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 230, __func__, "Could not bring link down: %m"
); })
;
231 }
232
233 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_SETLINKRTM_SETLINK, link->ifindex);
234 if (r < 0)
235 return log_netdev_error_errno(netdev, r, "Could not allocate RTM_SETLINK message: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 235, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not allocate RTM_SETLINK message: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 235, __func__, "Could not allocate RTM_SETLINK message: %m"
); })
;
236
237 r = sd_netlink_message_append_u32(req, IFLA_MASTERIFLA_MASTER, netdev->ifindex);
238 if (r < 0)
239 return log_netdev_error_errno(netdev, r, "Could not append IFLA_MASTER attribute: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 239, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not append IFLA_MASTER attribute: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 239, __func__, "Could not append IFLA_MASTER attribute: %m"
); })
;
240
241 r = sd_netlink_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL((void*)0));
242 if (r < 0)
243 return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 243, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not send rtnetlink message: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 243, __func__, "Could not send rtnetlink message: %m"
); })
;
244
245 link_ref(link);
246
247 log_netdev_debug(netdev, "Enslaving link '%s'", link->ifname)({ const NetDev *_n = (netdev); _n ? log_object_internal(7, 0
, "../src/network/netdev/netdev.c", 247, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Enslaving link '%s'"
, link->ifname) : log_internal_realm(((LOG_REALM_SYSTEMD) <<
10 | ((7))), 0, "../src/network/netdev/netdev.c", 247, __func__
, "Enslaving link '%s'", link->ifname); })
;
248
249 return 0;
250}
251
252static int netdev_enter_ready(NetDev *netdev) {
253 netdev_join_callback *callback, *callback_next;
254 int r;
255
256 assert(netdev)do { if ((__builtin_expect(!!(!(netdev)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev"), "../src/network/netdev/netdev.c"
, 256, __PRETTY_FUNCTION__); } while (0)
;
257 assert(netdev->ifname)do { if ((__builtin_expect(!!(!(netdev->ifname)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev->ifname"), "../src/network/netdev/netdev.c"
, 257, __PRETTY_FUNCTION__); } while (0)
;
258
259 if (netdev->state != NETDEV_STATE_CREATING)
260 return 0;
261
262 netdev->state = NETDEV_STATE_READY;
263
264 log_netdev_info(netdev, "netdev ready")({ const NetDev *_n = (netdev); _n ? log_object_internal(6, 0
, "../src/network/netdev/netdev.c", 264, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "netdev ready") : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((6))), 0, "../src/network/netdev/netdev.c"
, 264, __func__, "netdev ready"); })
;
265
266 LIST_FOREACH_SAFE(callbacks, callback, callback_next, netdev->callbacks)for ((callback) = (netdev->callbacks); (callback) &&
(((callback_next) = (callback)->callbacks_next), 1); (callback
) = (callback_next))
{
267 /* enslave the links that were attempted to be enslaved before the
268 * link was ready */
269 r = netdev_enslave_ready(netdev, callback->link, callback->callback);
270 if (r < 0)
271 return r;
272
273 LIST_REMOVE(callbacks, netdev->callbacks, callback)do { typeof(*(netdev->callbacks)) **_head = &(netdev->
callbacks), *_item = (callback); do { if ((__builtin_expect(!
!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, (
"_item"), "../src/network/netdev/netdev.c", 273, __PRETTY_FUNCTION__
); } while (0); if (_item->callbacks_next) _item->callbacks_next
->callbacks_prev = _item->callbacks_prev; if (_item->
callbacks_prev) _item->callbacks_prev->callbacks_next =
_item->callbacks_next; else { do { if ((__builtin_expect(
!!(!(*_head == _item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("*_head == _item"), "../src/network/netdev/netdev.c", 273,
__PRETTY_FUNCTION__); } while (0); *_head = _item->callbacks_next
; } _item->callbacks_next = _item->callbacks_prev = ((void
*)0); } while (0)
;
274 link_unref(callback->link);
275 free(callback);
276 }
277
278 if (NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
->post_create)
279 NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
->post_create(netdev, NULL((void*)0), NULL((void*)0));
280
281 return 0;
282}
283
284/* callback for netdev's created without a backing Link */
285static int netdev_create_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
286 _cleanup_(netdev_unrefp)__attribute__((cleanup(netdev_unrefp))) NetDev *netdev = userdata;
287 int r;
288
289 assert(netdev->state != _NETDEV_STATE_INVALID)do { if ((__builtin_expect(!!(!(netdev->state != _NETDEV_STATE_INVALID
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("netdev->state != _NETDEV_STATE_INVALID"
), "../src/network/netdev/netdev.c", 289, __PRETTY_FUNCTION__
); } while (0)
;
290
291 r = sd_netlink_message_get_errno(m);
292 if (r == -EEXIST17)
293 log_netdev_info(netdev, "netdev exists, using existing without changing its parameters")({ const NetDev *_n = (netdev); _n ? log_object_internal(6, 0
, "../src/network/netdev/netdev.c", 293, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "netdev exists, using existing without changing its parameters"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((6
))), 0, "../src/network/netdev/netdev.c", 293, __func__, "netdev exists, using existing without changing its parameters"
); })
;
294 else if (r < 0) {
295 log_netdev_warning_errno(netdev, r, "netdev could not be created: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(4, r
, "../src/network/netdev/netdev.c", 295, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "netdev could not be created: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/netdev/netdev.c", 295, __func__, "netdev could not be created: %m"
); })
;
296 netdev_drop(netdev);
297
298 return 1;
299 }
300
301 log_netdev_debug(netdev, "Created")({ const NetDev *_n = (netdev); _n ? log_object_internal(7, 0
, "../src/network/netdev/netdev.c", 301, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Created") : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/network/netdev/netdev.c"
, 301, __func__, "Created"); })
;
302
303 return 1;
304}
305
306int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler_t callback) {
307 int r;
308
309 assert(netdev)do { if ((__builtin_expect(!!(!(netdev)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev"), "../src/network/netdev/netdev.c"
, 309, __PRETTY_FUNCTION__); } while (0)
;
310 assert(netdev->manager)do { if ((__builtin_expect(!!(!(netdev->manager)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev->manager"), "../src/network/netdev/netdev.c"
, 310, __PRETTY_FUNCTION__); } while (0)
;
311 assert(netdev->manager->rtnl)do { if ((__builtin_expect(!!(!(netdev->manager->rtnl))
,0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("netdev->manager->rtnl"
), "../src/network/netdev/netdev.c", 311, __PRETTY_FUNCTION__
); } while (0)
;
312 assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF
})/sizeof(int)]; switch(netdev->kind) { case NETDEV_KIND_BRIDGE
: case NETDEV_KIND_BOND: case NETDEV_KIND_VRF: _found = 1; break
; default: break; } _found; }))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF)"
), "../src/network/netdev/netdev.c", 312, __PRETTY_FUNCTION__
); } while (0)
;
313
314 if (netdev->state == NETDEV_STATE_READY) {
315 r = netdev_enslave_ready(netdev, link, callback);
316 if (r < 0)
317 return r;
318 } else if (IN_SET(netdev->state, NETDEV_STATE_LINGER, NETDEV_STATE_FAILED)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){NETDEV_STATE_LINGER, NETDEV_STATE_FAILED
})/sizeof(int)]; switch(netdev->state) { case NETDEV_STATE_LINGER
: case NETDEV_STATE_FAILED: _found = 1; break; default: break
; } _found; })
) {
319 _cleanup_(sd_netlink_message_unrefp)__attribute__((cleanup(sd_netlink_message_unrefp))) sd_netlink_message *m = NULL((void*)0);
320
321 r = rtnl_message_new_synthetic_error(netdev->manager->rtnl, -ENODEV19, 0, &m);
322 if (r >= 0)
323 callback(netdev->manager->rtnl, m, link);
324 } else {
325 /* the netdev is not yet read, save this request for when it is */
326 netdev_join_callback *cb;
327
328 cb = new0(netdev_join_callback, 1)((netdev_join_callback*) calloc((1), sizeof(netdev_join_callback
)))
;
329 if (!cb)
330 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/netdev/netdev.c"
, 330, __func__)
;
331
332 cb->callback = callback;
333 cb->link = link;
334 link_ref(link);
335
336 LIST_PREPEND(callbacks, netdev->callbacks, cb)do { typeof(*(netdev->callbacks)) **_head = &(netdev->
callbacks), *_item = (cb); do { if ((__builtin_expect(!!(!(_item
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_item"),
"../src/network/netdev/netdev.c", 336, __PRETTY_FUNCTION__);
} while (0); if ((_item->callbacks_next = *_head)) _item->
callbacks_next->callbacks_prev = _item; _item->callbacks_prev
= ((void*)0); *_head = _item; } while (0)
;
337
338 log_netdev_debug(netdev, "Will enslave '%s', when ready", link->ifname)({ const NetDev *_n = (netdev); _n ? log_object_internal(7, 0
, "../src/network/netdev/netdev.c", 338, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Will enslave '%s', when ready"
, link->ifname) : log_internal_realm(((LOG_REALM_SYSTEMD) <<
10 | ((7))), 0, "../src/network/netdev/netdev.c", 338, __func__
, "Will enslave '%s', when ready", link->ifname); })
;
339 }
340
341 return 0;
342}
343
344int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *message) {
345 uint16_t type;
346 const char *kind;
347 const char *received_kind;
348 const char *received_name;
349 int r, ifindex;
350
351 assert(netdev)do { if ((__builtin_expect(!!(!(netdev)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev"), "../src/network/netdev/netdev.c"
, 351, __PRETTY_FUNCTION__); } while (0)
;
352 assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("message"), "../src/network/netdev/netdev.c"
, 352, __PRETTY_FUNCTION__); } while (0)
;
353
354 r = sd_netlink_message_get_type(message, &type);
355 if (r < 0)
356 return log_netdev_error_errno(netdev, r, "Could not get rtnl message type: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 356, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not get rtnl message type: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 356, __func__, "Could not get rtnl message type: %m"
); })
;
357
358 if (type != RTM_NEWLINKRTM_NEWLINK) {
359 log_netdev_error(netdev, "Cannot set ifindex from unexpected rtnl message type.")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, 0
, "../src/network/netdev/netdev.c", 359, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Cannot set ifindex from unexpected rtnl message type."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), 0, "../src/network/netdev/netdev.c", 359, __func__, "Cannot set ifindex from unexpected rtnl message type."
); })
;
360 return -EINVAL22;
361 }
362
363 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
364 if (r < 0) {
365 log_netdev_error_errno(netdev, r, "Could not get ifindex: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 365, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not get ifindex: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 365, __func__, "Could not get ifindex: %m"
); })
;
366 netdev_enter_failed(netdev);
367 return r;
368 } else if (ifindex <= 0) {
369 log_netdev_error(netdev, "Got invalid ifindex: %d", ifindex)({ const NetDev *_n = (netdev); _n ? log_object_internal(3, 0
, "../src/network/netdev/netdev.c", 369, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Got invalid ifindex: %d"
, ifindex) : log_internal_realm(((LOG_REALM_SYSTEMD) <<
10 | ((3))), 0, "../src/network/netdev/netdev.c", 369, __func__
, "Got invalid ifindex: %d", ifindex); })
;
370 netdev_enter_failed(netdev);
371 return -EINVAL22;
372 }
373
374 if (netdev->ifindex > 0) {
375 if (netdev->ifindex != ifindex) {
376 log_netdev_error(netdev, "Could not set ifindex to %d, already set to %d",({ const NetDev *_n = (netdev); _n ? log_object_internal(3, 0
, "../src/network/netdev/netdev.c", 377, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not set ifindex to %d, already set to %d"
, ifindex, netdev->ifindex) : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((3))), 0, "../src/network/netdev/netdev.c", 377
, __func__, "Could not set ifindex to %d, already set to %d",
ifindex, netdev->ifindex); })
377 ifindex, netdev->ifindex)({ const NetDev *_n = (netdev); _n ? log_object_internal(3, 0
, "../src/network/netdev/netdev.c", 377, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not set ifindex to %d, already set to %d"
, ifindex, netdev->ifindex) : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((3))), 0, "../src/network/netdev/netdev.c", 377
, __func__, "Could not set ifindex to %d, already set to %d",
ifindex, netdev->ifindex); })
;
378 netdev_enter_failed(netdev);
379 return -EEXIST17;
380 } else
381 /* ifindex already set to the same for this netdev */
382 return 0;
383 }
384
385 r = sd_netlink_message_read_string(message, IFLA_IFNAME, &received_name);
386 if (r < 0)
387 return log_netdev_error_errno(netdev, r, "Could not get IFNAME: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 387, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not get IFNAME: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 387, __func__, "Could not get IFNAME: %m"
); })
;
388
389 if (!streq(netdev->ifname, received_name)(strcmp((netdev->ifname),(received_name)) == 0)) {
390 log_netdev_error(netdev, "Received newlink with wrong IFNAME %s", received_name)({ const NetDev *_n = (netdev); _n ? log_object_internal(3, 0
, "../src/network/netdev/netdev.c", 390, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Received newlink with wrong IFNAME %s"
, received_name) : log_internal_realm(((LOG_REALM_SYSTEMD) <<
10 | ((3))), 0, "../src/network/netdev/netdev.c", 390, __func__
, "Received newlink with wrong IFNAME %s", received_name); })
;
391 netdev_enter_failed(netdev);
392 return r;
393 }
394
395 r = sd_netlink_message_enter_container(message, IFLA_LINKINFOIFLA_LINKINFO);
396 if (r < 0)
397 return log_netdev_error_errno(netdev, r, "Could not get LINKINFO: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 397, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not get LINKINFO: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 397, __func__, "Could not get LINKINFO: %m"
); })
;
398
399 r = sd_netlink_message_read_string(message, IFLA_INFO_KIND, &received_kind);
400 if (r < 0)
401 return log_netdev_error_errno(netdev, r, "Could not get KIND: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 401, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not get KIND: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 401, __func__, "Could not get KIND: %m"
); })
;
402
403 r = sd_netlink_message_exit_container(message);
404 if (r < 0)
405 return log_netdev_error_errno(netdev, r, "Could not exit container: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 405, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not exit container: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 405, __func__, "Could not exit container: %m"
); })
;
406
407 if (netdev->kind == NETDEV_KIND_TAP)
408 /* the kernel does not distinguish between tun and tap */
409 kind = "tun";
410 else {
411 kind = netdev_kind_to_string(netdev->kind);
412 if (!kind) {
413 log_netdev_error(netdev, "Could not get kind")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, 0
, "../src/network/netdev/netdev.c", 413, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not get kind"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), 0, "../src/network/netdev/netdev.c", 413, __func__, "Could not get kind"
); })
;
414 netdev_enter_failed(netdev);
415 return -EINVAL22;
416 }
417 }
418
419 if (!streq(kind, received_kind)(strcmp((kind),(received_kind)) == 0)) {
420 log_netdev_error(netdev,({ const NetDev *_n = (netdev); _n ? log_object_internal(3, 0
, "../src/network/netdev/netdev.c", 422, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Received newlink with wrong KIND %s, "
"expected %s", received_kind, kind) : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((3))), 0, "../src/network/netdev/netdev.c", 422
, __func__, "Received newlink with wrong KIND %s, " "expected %s"
, received_kind, kind); })
421 "Received newlink with wrong KIND %s, "({ const NetDev *_n = (netdev); _n ? log_object_internal(3, 0
, "../src/network/netdev/netdev.c", 422, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Received newlink with wrong KIND %s, "
"expected %s", received_kind, kind) : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((3))), 0, "../src/network/netdev/netdev.c", 422
, __func__, "Received newlink with wrong KIND %s, " "expected %s"
, received_kind, kind); })
422 "expected %s", received_kind, kind)({ const NetDev *_n = (netdev); _n ? log_object_internal(3, 0
, "../src/network/netdev/netdev.c", 422, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Received newlink with wrong KIND %s, "
"expected %s", received_kind, kind) : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((3))), 0, "../src/network/netdev/netdev.c", 422
, __func__, "Received newlink with wrong KIND %s, " "expected %s"
, received_kind, kind); })
;
423 netdev_enter_failed(netdev);
424 return r;
425 }
426
427 netdev->ifindex = ifindex;
428
429 log_netdev_debug(netdev, "netdev has index %d", netdev->ifindex)({ const NetDev *_n = (netdev); _n ? log_object_internal(7, 0
, "../src/network/netdev/netdev.c", 429, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "netdev has index %d"
, netdev->ifindex) : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((7))), 0, "../src/network/netdev/netdev.c", 429
, __func__, "netdev has index %d", netdev->ifindex); })
;
430
431 netdev_enter_ready(netdev);
432
433 return 0;
434}
435
436#define HASH_KEY((const sd_id128_t) { .bytes = { 0x52, 0xe1, 0x45, 0xbd, 0x00
, 0x6f, 0x29, 0x96, 0x21, 0xc6, 0x30, 0x6d, 0x83, 0x71, 0x04,
0x48 }})
SD_ID128_MAKE(52,e1,45,bd,00,6f,29,96,21,c6,30,6d,83,71,04,48)((const sd_id128_t) { .bytes = { 0x52, 0xe1, 0x45, 0xbd, 0x00
, 0x6f, 0x29, 0x96, 0x21, 0xc6, 0x30, 0x6d, 0x83, 0x71, 0x04,
0x48 }})
437
438int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
439 _cleanup_free___attribute__((cleanup(freep))) struct ether_addr *mac = NULL((void*)0);
440 uint64_t result;
441 size_t l, sz;
442 uint8_t *v;
443 int r;
444
445 assert(ifname)do { if ((__builtin_expect(!!(!(ifname)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ifname"), "../src/network/netdev/netdev.c"
, 445, __PRETTY_FUNCTION__); } while (0)
;
446 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/network/netdev/netdev.c"
, 446, __PRETTY_FUNCTION__); } while (0)
;
447
448 mac = new0(struct ether_addr, 1)((struct ether_addr*) calloc((1), sizeof(struct ether_addr)));
449 if (!mac)
450 return -ENOMEM12;
451
452 l = strlen(ifname);
453 sz = sizeof(sd_id128_t) + l;
454 v = alloca(sz)__builtin_alloca (sz);
455
456 /* fetch some persistent data unique to the machine */
457 r = sd_id128_get_machine((sd_id128_t*) v);
458 if (r < 0)
459 return r;
460
461 /* combine with some data unique (on this machine) to this
462 * netdev */
463 memcpy(v + sizeof(sd_id128_t), ifname, l);
464
465 /* Let's hash the host machine ID plus the container name. We
466 * use a fixed, but originally randomly created hash key here. */
467 result = siphash24(v, sz, HASH_KEY((const sd_id128_t) { .bytes = { 0x52, 0xe1, 0x45, 0xbd, 0x00
, 0x6f, 0x29, 0x96, 0x21, 0xc6, 0x30, 0x6d, 0x83, 0x71, 0x04,
0x48 }})
.bytes);
468
469 assert_cc(ETH_ALEN <= sizeof(result))GCC diagnostic push ; GCC diagnostic ignored "-Wdeclaration-after-statement"
; struct _assert_struct_10 { char x[(6 <= sizeof(result))
? 0 : -1]; }; GCC diagnostic pop
;
470 memcpy(mac->ether_addr_octet, &result, ETH_ALEN6);
471
472 /* see eth_random_addr in the kernel */
473 mac->ether_addr_octet[0] &= 0xfe; /* clear multicast bit */
474 mac->ether_addr_octet[0] |= 0x02; /* set local assignment bit (IEEE802) */
475
476 *ret = TAKE_PTR(mac)({ typeof(mac) _ptr_ = (mac); (mac) = ((void*)0); _ptr_; });
477
478 return 0;
479}
480
481static int netdev_create(NetDev *netdev, Link *link,
482 sd_netlink_message_handler_t callback) {
483 int r;
484
485 assert(netdev)do { if ((__builtin_expect(!!(!(netdev)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev"), "../src/network/netdev/netdev.c"
, 485, __PRETTY_FUNCTION__); } while (0)
;
486 assert(!link || callback)do { if ((__builtin_expect(!!(!(!link || callback)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("!link || callback"), "../src/network/netdev/netdev.c"
, 486, __PRETTY_FUNCTION__); } while (0)
;
487
488 /* create netdev */
489 if (NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
->create) {
490 assert(!link)do { if ((__builtin_expect(!!(!(!link)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("!link"), "../src/network/netdev/netdev.c"
, 490, __PRETTY_FUNCTION__); } while (0)
;
491
492 r = NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
->create(netdev);
493 if (r < 0)
494 return r;
495
496 log_netdev_debug(netdev, "Created")({ const NetDev *_n = (netdev); _n ? log_object_internal(7, 0
, "../src/network/netdev/netdev.c", 496, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Created") : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/network/netdev/netdev.c"
, 496, __func__, "Created"); })
;
497 } else {
498 _cleanup_(sd_netlink_message_unrefp)__attribute__((cleanup(sd_netlink_message_unrefp))) sd_netlink_message *m = NULL((void*)0);
499
500 r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINKRTM_NEWLINK, 0);
501 if (r < 0)
502 return log_netdev_error_errno(netdev, r, "Could not allocate RTM_NEWLINK message: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 502, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not allocate RTM_NEWLINK message: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 502, __func__, "Could not allocate RTM_NEWLINK message: %m"
); })
;
503
504 r = sd_netlink_message_append_string(m, IFLA_IFNAME, netdev->ifname);
505 if (r < 0)
506 return log_netdev_error_errno(netdev, r, "Could not append IFLA_IFNAME, attribute: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 506, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not append IFLA_IFNAME, attribute: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 506, __func__, "Could not append IFLA_IFNAME, attribute: %m"
); })
;
507
508 if (netdev->mac) {
509 r = sd_netlink_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
510 if (r < 0)
511 return log_netdev_error_errno(netdev, r, "Could not append IFLA_ADDRESS attribute: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 511, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not append IFLA_ADDRESS attribute: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 511, __func__, "Could not append IFLA_ADDRESS attribute: %m"
); })
;
512 }
513
514 if (netdev->mtu) {
515 r = sd_netlink_message_append_u32(m, IFLA_MTU, netdev->mtu);
516 if (r < 0)
517 return log_netdev_error_errno(netdev, r, "Could not append IFLA_MTU attribute: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 517, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not append IFLA_MTU attribute: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 517, __func__, "Could not append IFLA_MTU attribute: %m"
); })
;
518 }
519
520 if (link) {
521 r = sd_netlink_message_append_u32(m, IFLA_LINK, link->ifindex);
522 if (r < 0)
523 return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINK attribute: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 523, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not append IFLA_LINK attribute: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 523, __func__, "Could not append IFLA_LINK attribute: %m"
); })
;
524 }
525
526 r = sd_netlink_message_open_container(m, IFLA_LINKINFOIFLA_LINKINFO);
527 if (r < 0)
528 return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 528, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not append IFLA_LINKINFO attribute: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 528, __func__, "Could not append IFLA_LINKINFO attribute: %m"
); })
;
529
530 r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind));
531 if (r < 0)
532 return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 532, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not append IFLA_INFO_DATA attribute: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 532, __func__, "Could not append IFLA_INFO_DATA attribute: %m"
); })
;
533
534 if (NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
->fill_message_create) {
535 r = NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
->fill_message_create(netdev, link, m);
536 if (r < 0)
537 return r;
538 }
539
540 r = sd_netlink_message_close_container(m);
541 if (r < 0)
542 return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 542, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not append IFLA_INFO_DATA attribute: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 542, __func__, "Could not append IFLA_INFO_DATA attribute: %m"
); })
;
543
544 r = sd_netlink_message_close_container(m);
545 if (r < 0)
546 return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 546, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not append IFLA_LINKINFO attribute: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 546, __func__, "Could not append IFLA_LINKINFO attribute: %m"
); })
;
547
548 if (link) {
549 r = sd_netlink_call_async(netdev->manager->rtnl, m, callback, link, 0, NULL((void*)0));
550 if (r < 0)
551 return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 551, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not send rtnetlink message: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 551, __func__, "Could not send rtnetlink message: %m"
); })
;
552
553 link_ref(link);
554 } else {
555 r = sd_netlink_call_async(netdev->manager->rtnl, m, netdev_create_handler, netdev, 0, NULL((void*)0));
556 if (r < 0)
557 return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m")({ const NetDev *_n = (netdev); _n ? log_object_internal(3, r
, "../src/network/netdev/netdev.c", 557, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Could not send rtnetlink message: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/network/netdev/netdev.c", 557, __func__, "Could not send rtnetlink message: %m"
); })
;
558
559 netdev_ref(netdev);
560 }
561
562 netdev->state = NETDEV_STATE_CREATING;
563
564 log_netdev_debug(netdev, "Creating")({ const NetDev *_n = (netdev); _n ? log_object_internal(7, 0
, "../src/network/netdev/netdev.c", 564, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "Creating") : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/network/netdev/netdev.c"
, 564, __func__, "Creating"); })
;
565 }
566
567 return 0;
568}
569
570/* the callback must be called, possibly after a timeout, as otherwise the Link will hang */
571int netdev_join(NetDev *netdev, Link *link, sd_netlink_message_handler_t callback) {
572 int r;
573
574 assert(netdev)do { if ((__builtin_expect(!!(!(netdev)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev"), "../src/network/netdev/netdev.c"
, 574, __PRETTY_FUNCTION__); } while (0)
;
575 assert(netdev->manager)do { if ((__builtin_expect(!!(!(netdev->manager)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("netdev->manager"), "../src/network/netdev/netdev.c"
, 575, __PRETTY_FUNCTION__); } while (0)
;
576 assert(netdev->manager->rtnl)do { if ((__builtin_expect(!!(!(netdev->manager->rtnl))
,0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("netdev->manager->rtnl"
), "../src/network/netdev/netdev.c", 576, __PRETTY_FUNCTION__
); } while (0)
;
577 assert(NETDEV_VTABLE(netdev))do { if ((__builtin_expect(!!(!(((netdev)->kind != _NETDEV_KIND_INVALID
? netdev_vtable[(netdev)->kind] : ((void*)0)))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("NETDEV_VTABLE(netdev)"), "../src/network/netdev/netdev.c"
, 577, __PRETTY_FUNCTION__); } while (0)
;
578
579 switch (NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
->create_type) {
580 case NETDEV_CREATE_MASTER:
581 r = netdev_enslave(netdev, link, callback);
582 if (r < 0)
583 return r;
584
585 break;
586 case NETDEV_CREATE_STACKED:
587 r = netdev_create(netdev, link, callback);
588 if (r < 0)
589 return r;
590
591 break;
592 default:
593 assert_not_reached("Can not join independent netdev")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Can not join independent netdev"), "../src/network/netdev/netdev.c"
, 593, __PRETTY_FUNCTION__); } while (0)
;
594 }
595
596 return 0;
597}
598
599static int netdev_load_one(Manager *manager, const char *filename) {
600 _cleanup_(netdev_unrefp)__attribute__((cleanup(netdev_unrefp))) NetDev *netdev_raw = NULL((void*)0), *netdev = NULL((void*)0);
601 _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *file = NULL((void*)0);
602 const char *dropin_dirname;
603 bool_Bool independent = false0;
604 int r;
605
606 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("manager"), "../src/network/netdev/netdev.c"
, 606, __PRETTY_FUNCTION__); } while (0)
;
607 assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("filename"), "../src/network/netdev/netdev.c"
, 607, __PRETTY_FUNCTION__); } while (0)
;
608
609 file = fopen(filename, "re");
610 if (!file) {
611 if (errno(*__errno_location ()) == ENOENT2)
612 return 0;
613
614 return -errno(*__errno_location ());
615 }
616
617 if (null_or_empty_fd(fileno(file))) {
618 log_debug("Skipping empty file: %s", filename)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/netdev/netdev.c", 618, __func__, "Skipping empty file: %s"
, filename) : -abs(_e); })
;
619 return 0;
620 }
621
622 netdev_raw = new0(NetDev, 1)((NetDev*) calloc((1), sizeof(NetDev)));
623 if (!netdev_raw)
624 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/netdev/netdev.c"
, 624, __func__)
;
625
626 netdev_raw->n_ref = 1;
627 netdev_raw->kind = _NETDEV_KIND_INVALID;
628 netdev_raw->state = _NETDEV_STATE_INVALID; /* an invalid state means done() of the implementation won't be called on destruction */
629
630 dropin_dirname = strjoina(basename(filename), ".d")({ const char *_appendees_[] = { basename(filename), ".d" }; char
*_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ <
__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
631 r = config_parse_many(filename, network_dirs, dropin_dirname,
632 "Match\0NetDev\0",
633 config_item_perf_lookup, network_netdev_gperf_lookup,
634 CONFIG_PARSE_WARN|CONFIG_PARSE_RELAXED, netdev_raw);
635 if (r < 0)
636 return r;
637
638 /* skip out early if configuration does not match the environment */
639 if (net_match_config(NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0),
640 netdev_raw->match_host, netdev_raw->match_virt,
641 netdev_raw->match_kernel_cmdline, netdev_raw->match_kernel_version,
642 netdev_raw->match_arch,
643 NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)) <= 0)
644 return 0;
645
646 if (netdev_raw->kind == _NETDEV_KIND_INVALID) {
647 log_warning("NetDev has no Kind configured in %s. Ignoring", filename)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/netdev/netdev.c", 647, __func__, "NetDev has no Kind configured in %s. Ignoring"
, filename) : -abs(_e); })
;
648 return 0;
649 }
650
651 if (!netdev_raw->ifname) {
652 log_warning("NetDev without Name configured in %s. Ignoring", filename)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/netdev/netdev.c", 652, __func__, "NetDev without Name configured in %s. Ignoring"
, filename) : -abs(_e); })
;
653 return 0;
654 }
655
656 r = fseek(file, 0, SEEK_SET0);
657 if (r < 0)
658 return -errno(*__errno_location ());
659
660 netdev = malloc0(NETDEV_VTABLE(netdev_raw)->object_size)(calloc(1, (((netdev_raw)->kind != _NETDEV_KIND_INVALID ? netdev_vtable
[(netdev_raw)->kind] : ((void*)0))->object_size)))
;
661 if (!netdev)
662 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/netdev/netdev.c"
, 662, __func__)
;
663
664 netdev->n_ref = 1;
665 netdev->manager = manager;
666 netdev->kind = netdev_raw->kind;
667 netdev->state = NETDEV_STATE_LOADING; /* we initialize the state here for the first time, so that done() will be called on destruction */
668
669 if (NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
->init)
670 NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
->init(netdev);
671
672 r = config_parse(NULL((void*)0), filename, file,
673 NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
->sections,
674 config_item_perf_lookup, network_netdev_gperf_lookup,
675 CONFIG_PARSE_WARN, netdev);
676 if (r < 0)
677 return r;
678
679 /* verify configuration */
680 if (NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
->config_verify) {
681 r = NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
->config_verify(netdev, filename);
682 if (r < 0)
683 return 0;
684 }
685
686 netdev->filename = strdup(filename);
687 if (!netdev->filename)
688 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/netdev/netdev.c"
, 688, __func__)
;
689
690 if (!netdev->mac && netdev->kind != NETDEV_KIND_VLAN) {
691 r = netdev_get_mac(netdev->ifname, &netdev->mac);
692 if (r < 0)
693 return log_error_errno(r, "Failed to generate predictable MAC address for %s: %m", netdev->ifname)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/netdev/netdev.c", 693, __func__, "Failed to generate predictable MAC address for %s: %m"
, netdev->ifname) : -abs(_e); })
;
694 }
695
696 r = hashmap_put(netdev->manager->netdevs, netdev->ifname, netdev);
697 if (r < 0)
698 return r;
699
700 LIST_HEAD_INIT(netdev->callbacks)do { (netdev->callbacks) = ((void*)0); } while (0);
701
702 log_netdev_debug(netdev, "loaded %s", netdev_kind_to_string(netdev->kind))({ const NetDev *_n = (netdev); _n ? log_object_internal(7, 0
, "../src/network/netdev/netdev.c", 702, __func__, "INTERFACE="
, _n->ifname, ((void*)0), ((void*)0), "loaded %s", netdev_kind_to_string
(netdev->kind)) : log_internal_realm(((LOG_REALM_SYSTEMD) <<
10 | ((7))), 0, "../src/network/netdev/netdev.c", 702, __func__
, "loaded %s", netdev_kind_to_string(netdev->kind)); })
;
703
704 switch (NETDEV_VTABLE(netdev)((netdev)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(netdev
)->kind] : ((void*)0))
->create_type) {
705 case NETDEV_CREATE_MASTER:
706 case NETDEV_CREATE_INDEPENDENT:
707 r = netdev_create(netdev, NULL((void*)0), NULL((void*)0));
708 if (r < 0)
709 return r;
710
711 break;
712 default:
713 break;
714 }
715
716 switch (netdev->kind) {
717 case NETDEV_KIND_IPIP:
718 independent = IPIP(netdev)->independent;
719 break;
720 case NETDEV_KIND_GRE:
721 independent = GRE(netdev)->independent;
722 break;
723 case NETDEV_KIND_GRETAP:
724 independent = GRETAP(netdev)->independent;
725 break;
726 case NETDEV_KIND_IP6GRE:
727 independent = IP6GRE(netdev)->independent;
728 break;
729 case NETDEV_KIND_IP6GRETAP:
730 independent = IP6GRETAP(netdev)->independent;
731 break;
732 case NETDEV_KIND_SIT:
733 independent = SIT(netdev)->independent;
734 break;
735 case NETDEV_KIND_VTI:
736 independent = VTI(netdev)->independent;
737 break;
738 case NETDEV_KIND_VTI6:
739 independent = VTI6(netdev)->independent;
740 break;
741 case NETDEV_KIND_IP6TNL:
742 independent = IP6TNL(netdev)->independent;
743 break;
744 default:
745 break;
746 }
747
748 if (independent) {
749 r = netdev_create(netdev, NULL((void*)0), NULL((void*)0));
750 if (r < 0)
751 return r;
752 }
753
754 netdev = NULL((void*)0);
755
756 return 0;
757}
758
759int netdev_load(Manager *manager) {
760 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **files = NULL((void*)0);
761 NetDev *netdev;
762 char **f;
763 int r;
764
765 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("manager"), "../src/network/netdev/netdev.c"
, 765, __PRETTY_FUNCTION__); } while (0)
;
1
Assuming 'manager' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
766
767 while ((netdev = hashmap_first(manager->netdevs)))
4
Loop condition is true. Entering loop body
768 netdev_unref(netdev);
5
Calling 'netdev_unref'
769
770 r = conf_files_list_strv(&files, ".netdev", NULL((void*)0), 0, network_dirs);
771 if (r < 0)
772 return log_error_errno(r, "Failed to enumerate netdev files: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/netdev/netdev.c", 772, __func__, "Failed to enumerate netdev files: %m"
) : -abs(_e); })
;
773
774 STRV_FOREACH_BACKWARDS(f, files)for (f = ({ char **_l = files; _l ? _l + strv_length(_l) - 1U
: ((void*)0); }); (files) && ((f) >= (files)); (f
)--)
{
775 r = netdev_load_one(manager, *f);
776 if (r < 0)
777 return r;
778 }
779
780 return 0;
781}