]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
0ef6f454 LP |
2 | #pragma once |
3 | ||
634f0f98 | 4 | #include "sd-netlink.h" |
3be1d7e0 | 5 | |
538f15cf | 6 | #include "conf-parser.h" |
634f0f98 | 7 | #include "list.h" |
60643448 | 8 | #include "log-link.h" |
737f1405 | 9 | #include "networkd-link.h" |
634f0f98 | 10 | #include "time-util.h" |
fc2f9534 | 11 | |
130b812f ZJS |
12 | #define NETDEV_COMMON_SECTIONS "Match\0NetDev\0" |
13 | /* This is the list of known sections. We need to ignore them in the initial parsing phase. */ | |
14 | #define NETDEV_OTHER_SECTIONS \ | |
e6980c72 | 15 | "-BareUDP\0" \ |
c0267a59 | 16 | "-BatmanAdvanced\0" \ |
130b812f ZJS |
17 | "-Bond\0" \ |
18 | "-Bridge\0" \ | |
19 | "-FooOverUDP\0" \ | |
20 | "-GENEVE\0" \ | |
21 | "-IPVLAN\0" \ | |
22 | "-IPVTAP\0" \ | |
23 | "-L2TP\0" \ | |
24 | "-L2TPSession\0" \ | |
25 | "-MACsec\0" \ | |
26 | "-MACsecReceiveChannel\0" \ | |
27 | "-MACsecTransmitAssociation\0" \ | |
28 | "-MACsecReceiveAssociation\0" \ | |
29 | "-MACVTAP\0" \ | |
30 | "-MACVLAN\0" \ | |
31 | "-Tunnel\0" \ | |
32 | "-Tun\0" \ | |
33 | "-Tap\0" \ | |
34 | "-Peer\0" \ | |
35 | "-VLAN\0" \ | |
36 | "-VRF\0" \ | |
37 | "-VXCAN\0" \ | |
38 | "-VXLAN\0" \ | |
39 | "-WireGuard\0" \ | |
40 | "-WireGuardPeer\0" \ | |
41 | "-Xfrm\0" | |
42 | ||
3be1d7e0 TG |
43 | typedef enum NetDevKind { |
44 | NETDEV_KIND_BRIDGE, | |
45 | NETDEV_KIND_BOND, | |
46 | NETDEV_KIND_VLAN, | |
47 | NETDEV_KIND_MACVLAN, | |
f33ff02b | 48 | NETDEV_KIND_MACVTAP, |
c4a5ddc9 | 49 | NETDEV_KIND_IPVLAN, |
69c317a0 | 50 | NETDEV_KIND_IPVTAP, |
3be1d7e0 TG |
51 | NETDEV_KIND_VXLAN, |
52 | NETDEV_KIND_IPIP, | |
53 | NETDEV_KIND_GRE, | |
1af2536a | 54 | NETDEV_KIND_GRETAP, |
b16492f8 SS |
55 | NETDEV_KIND_IP6GRE, |
56 | NETDEV_KIND_IP6GRETAP, | |
3be1d7e0 TG |
57 | NETDEV_KIND_SIT, |
58 | NETDEV_KIND_VETH, | |
59 | NETDEV_KIND_VTI, | |
9011ce77 | 60 | NETDEV_KIND_VTI6, |
855ee1a1 | 61 | NETDEV_KIND_IP6TNL, |
3be1d7e0 TG |
62 | NETDEV_KIND_DUMMY, |
63 | NETDEV_KIND_TUN, | |
64 | NETDEV_KIND_TAP, | |
20897a0d | 65 | NETDEV_KIND_VRF, |
92c918b0 | 66 | NETDEV_KIND_VCAN, |
6598e046 | 67 | NETDEV_KIND_GENEVE, |
d6df583c | 68 | NETDEV_KIND_VXCAN, |
e5719363 | 69 | NETDEV_KIND_WIREGUARD, |
56e7fb50 | 70 | NETDEV_KIND_NETDEVSIM, |
53cb501a | 71 | NETDEV_KIND_FOU, |
2266864b | 72 | NETDEV_KIND_ERSPAN, |
3a56e697 | 73 | NETDEV_KIND_L2TP, |
81962db7 | 74 | NETDEV_KIND_MACSEC, |
d61e4c5b | 75 | NETDEV_KIND_NLMON, |
98d20a17 | 76 | NETDEV_KIND_XFRM, |
3295a461 | 77 | NETDEV_KIND_IFB, |
e6980c72 | 78 | NETDEV_KIND_BAREUDP, |
c0267a59 | 79 | NETDEV_KIND_BATADV, |
3be1d7e0 | 80 | _NETDEV_KIND_MAX, |
cebe1257 | 81 | _NETDEV_KIND_TUNNEL, /* Used by config_parse_stacked_netdev() */ |
2d93c20e | 82 | _NETDEV_KIND_INVALID = -EINVAL, |
3be1d7e0 TG |
83 | } NetDevKind; |
84 | ||
85 | typedef enum NetDevState { | |
f3c33b23 | 86 | NETDEV_STATE_LOADING, |
3be1d7e0 TG |
87 | NETDEV_STATE_FAILED, |
88 | NETDEV_STATE_CREATING, | |
89 | NETDEV_STATE_READY, | |
90 | NETDEV_STATE_LINGER, | |
91 | _NETDEV_STATE_MAX, | |
2d93c20e | 92 | _NETDEV_STATE_INVALID = -EINVAL, |
3be1d7e0 TG |
93 | } NetDevState; |
94 | ||
aa9f1140 TG |
95 | typedef enum NetDevCreateType { |
96 | NETDEV_CREATE_INDEPENDENT, | |
97 | NETDEV_CREATE_MASTER, | |
98 | NETDEV_CREATE_STACKED, | |
7033af49 | 99 | NETDEV_CREATE_AFTER_CONFIGURED, |
aa9f1140 | 100 | _NETDEV_CREATE_MAX, |
2d93c20e | 101 | _NETDEV_CREATE_INVALID = -EINVAL, |
aa9f1140 TG |
102 | } NetDevCreateType; |
103 | ||
634f0f98 ZJS |
104 | typedef struct Manager Manager; |
105 | typedef struct Condition Condition; | |
71a754f7 | 106 | typedef struct Request Request; |
634f0f98 ZJS |
107 | |
108 | typedef struct NetDev { | |
3be1d7e0 TG |
109 | Manager *manager; |
110 | ||
cf4b2f99 | 111 | unsigned n_ref; |
3be1d7e0 TG |
112 | |
113 | char *filename; | |
114 | ||
1beabe08 | 115 | LIST_HEAD(Condition, conditions); |
3be1d7e0 | 116 | |
aa9f1140 TG |
117 | NetDevState state; |
118 | NetDevKind kind; | |
3be1d7e0 TG |
119 | char *description; |
120 | char *ifname; | |
3be1d7e0 | 121 | struct ether_addr *mac; |
4e964aa0 | 122 | uint32_t mtu; |
3be1d7e0 | 123 | int ifindex; |
634f0f98 | 124 | } NetDev; |
3be1d7e0 | 125 | |
634f0f98 | 126 | typedef struct NetDevVTable { |
aa9f1140 TG |
127 | /* How much memory does an object of this unit type need */ |
128 | size_t object_size; | |
129 | ||
130 | /* Config file sections this netdev kind understands, separated | |
131 | * by NUL chars */ | |
132 | const char *sections; | |
3be1d7e0 | 133 | |
aa9f1140 TG |
134 | /* This should reset all type-specific variables. This should |
135 | * not allocate memory, and is called with zero-initialized | |
136 | * data. It should hence only initialize variables that need | |
137 | * to be set != 0. */ | |
138 | void (*init)(NetDev *n); | |
3be1d7e0 | 139 | |
aa9f1140 TG |
140 | /* This should free all kind-specific variables. It should be |
141 | * idempotent. */ | |
142 | void (*done)(NetDev *n); | |
143 | ||
144 | /* fill in message to create netdev */ | |
1c4baffc | 145 | int (*fill_message_create)(NetDev *netdev, Link *link, sd_netlink_message *message); |
aa9f1140 TG |
146 | |
147 | /* specifies if netdev is independent, or a master device or a stacked device */ | |
148 | NetDevCreateType create_type; | |
3be1d7e0 TG |
149 | |
150 | /* create netdev, if not done via rtnl */ | |
151 | int (*create)(NetDev *netdev); | |
152 | ||
7033af49 YW |
153 | /* create netdev after link is fully configured */ |
154 | int (*create_after_configured)(NetDev *netdev, Link *link); | |
155 | ||
540eb5f0 SS |
156 | /* perform additional configuration after netdev has been createad */ |
157 | int (*post_create)(NetDev *netdev, Link *link, sd_netlink_message *message); | |
158 | ||
3be1d7e0 TG |
159 | /* verify that compulsory configuration options were specified */ |
160 | int (*config_verify)(NetDev *netdev, const char *filename); | |
daf0f8ca YW |
161 | |
162 | /* Generate MAC address or not When MACAddress= is not specified. */ | |
163 | bool generate_mac; | |
634f0f98 | 164 | } NetDevVTable; |
3be1d7e0 TG |
165 | |
166 | extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX]; | |
167 | ||
281bb5c1 | 168 | #define NETDEV_VTABLE(n) ((n)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(n)->kind] : NULL) |
3be1d7e0 | 169 | |
aa9f1140 | 170 | /* For casting a netdev into the various netdev kinds */ |
634f0f98 | 171 | #define DEFINE_NETDEV_CAST(UPPERCASE, MixedCase) \ |
aa9f1140 | 172 | static inline MixedCase* UPPERCASE(NetDev *n) { \ |
f3c33b23 LP |
173 | if (_unlikely_(!n || \ |
174 | n->kind != NETDEV_KIND_##UPPERCASE) || \ | |
175 | n->state == _NETDEV_STATE_INVALID) \ | |
aa9f1140 TG |
176 | return NULL; \ |
177 | \ | |
178 | return (MixedCase*) n; \ | |
179 | } | |
180 | ||
181 | /* For casting the various netdev kinds into a netdev */ | |
182 | #define NETDEV(n) (&(n)->meta) | |
183 | ||
e272b621 | 184 | int netdev_load(Manager *manager, bool reload); |
e27aac11 | 185 | int netdev_load_one(Manager *manager, const char *filename); |
3be1d7e0 TG |
186 | void netdev_drop(NetDev *netdev); |
187 | ||
188 | NetDev *netdev_unref(NetDev *netdev); | |
189 | NetDev *netdev_ref(NetDev *netdev); | |
302a796f | 190 | DEFINE_TRIVIAL_DESTRUCTOR(netdev_destroy_callback, NetDev, netdev_unref); |
3be1d7e0 | 191 | DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref); |
3be1d7e0 | 192 | |
9e2bbf99 | 193 | bool netdev_is_managed(NetDev *netdev); |
3be1d7e0 | 194 | int netdev_get(Manager *manager, const char *name, NetDev **ret); |
1c4baffc | 195 | int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink); |
3be1d7e0 | 196 | int netdev_get_mac(const char *ifname, struct ether_addr **ret); |
302a796f | 197 | int netdev_join(NetDev *netdev, Link *link, link_netlink_message_handler_t cb); |
3be1d7e0 | 198 | |
71a754f7 YW |
199 | int request_process_create_stacked_netdev(Request *req); |
200 | int link_request_to_crate_stacked_netdev(Link *link, NetDev *netdev); | |
201 | ||
3be1d7e0 TG |
202 | const char *netdev_kind_to_string(NetDevKind d) _const_; |
203 | NetDevKind netdev_kind_from_string(const char *d) _pure_; | |
204 | ||
859e9c04 YW |
205 | static inline NetDevCreateType netdev_get_create_type(NetDev *netdev) { |
206 | assert(netdev); | |
207 | assert(NETDEV_VTABLE(netdev)); | |
208 | ||
209 | return NETDEV_VTABLE(netdev)->create_type; | |
210 | } | |
211 | ||
538f15cf | 212 | CONFIG_PARSER_PROTOTYPE(config_parse_netdev_kind); |
3be1d7e0 TG |
213 | |
214 | /* gperf */ | |
c9f7b4d3 | 215 | const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, GPERF_LEN_TYPE length); |
3be1d7e0 TG |
216 | |
217 | /* Macros which append INTERFACE= to the message */ | |
218 | ||
60643448 | 219 | #define log_netdev_full_errno_zerook(netdev, level, error, ...) \ |
f2341e0a | 220 | ({ \ |
8dec4a9d | 221 | const NetDev *_n = (netdev); \ |
60643448 | 222 | log_interface_full_errno_zerook(_n ? _n->ifname : NULL, level, error, __VA_ARGS__); \ |
f2341e0a | 223 | }) |
6a7a4e4d | 224 | |
60643448 YW |
225 | #define log_netdev_full_errno(netdev, level, error, ...) \ |
226 | ({ \ | |
227 | int _error = (error); \ | |
228 | ASSERT_NON_ZERO(_error); \ | |
229 | log_netdev_full_errno_zerook(netdev, level, _error, __VA_ARGS__); \ | |
230 | }) | |
231 | ||
232 | #define log_netdev_full(netdev, level, ...) (void) log_netdev_full_errno_zerook(netdev, level, 0, __VA_ARGS__) | |
233 | ||
234 | #define log_netdev_debug(netdev, ...) log_netdev_full(netdev, LOG_DEBUG, __VA_ARGS__) | |
235 | #define log_netdev_info(netdev, ...) log_netdev_full(netdev, LOG_INFO, __VA_ARGS__) | |
236 | #define log_netdev_notice(netdev, ...) log_netdev_full(netdev, LOG_NOTICE, __VA_ARGS__) | |
237 | #define log_netdev_warning(netdev, ...) log_netdev_full(netdev, LOG_WARNING, __VA_ARGS__) | |
238 | #define log_netdev_error(netdev, ...) log_netdev_full(netdev, LOG_ERR, __VA_ARGS__) | |
239 | ||
240 | #define log_netdev_debug_errno(netdev, error, ...) log_netdev_full_errno(netdev, LOG_DEBUG, error, __VA_ARGS__) | |
241 | #define log_netdev_info_errno(netdev, error, ...) log_netdev_full_errno(netdev, LOG_INFO, error, __VA_ARGS__) | |
242 | #define log_netdev_notice_errno(netdev, error, ...) log_netdev_full_errno(netdev, LOG_NOTICE, error, __VA_ARGS__) | |
243 | #define log_netdev_warning_errno(netdev, error, ...) log_netdev_full_errno(netdev, LOG_WARNING, error, __VA_ARGS__) | |
244 | #define log_netdev_error_errno(netdev, error, ...) log_netdev_full_errno(netdev, LOG_ERR, error, __VA_ARGS__) | |
98b32556 | 245 | |
f2341e0a LP |
246 | #define LOG_NETDEV_MESSAGE(netdev, fmt, ...) "MESSAGE=%s: " fmt, (netdev)->ifname, ##__VA_ARGS__ |
247 | #define LOG_NETDEV_INTERFACE(netdev) "INTERFACE=%s", (netdev)->ifname |