]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
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" |
302a796f | 8 | #include "../networkd-link.h" |
634f0f98 | 9 | #include "time-util.h" |
fc2f9534 | 10 | |
3be1d7e0 TG |
11 | typedef struct netdev_join_callback netdev_join_callback; |
12 | ||
13 | struct netdev_join_callback { | |
302a796f | 14 | link_netlink_message_handler_t callback; |
3be1d7e0 TG |
15 | Link *link; |
16 | ||
17 | LIST_FIELDS(netdev_join_callback, callbacks); | |
18 | }; | |
19 | ||
20 | typedef enum NetDevKind { | |
21 | NETDEV_KIND_BRIDGE, | |
22 | NETDEV_KIND_BOND, | |
23 | NETDEV_KIND_VLAN, | |
24 | NETDEV_KIND_MACVLAN, | |
f33ff02b | 25 | NETDEV_KIND_MACVTAP, |
c4a5ddc9 | 26 | NETDEV_KIND_IPVLAN, |
3be1d7e0 TG |
27 | NETDEV_KIND_VXLAN, |
28 | NETDEV_KIND_IPIP, | |
29 | NETDEV_KIND_GRE, | |
1af2536a | 30 | NETDEV_KIND_GRETAP, |
b16492f8 SS |
31 | NETDEV_KIND_IP6GRE, |
32 | NETDEV_KIND_IP6GRETAP, | |
3be1d7e0 TG |
33 | NETDEV_KIND_SIT, |
34 | NETDEV_KIND_VETH, | |
35 | NETDEV_KIND_VTI, | |
9011ce77 | 36 | NETDEV_KIND_VTI6, |
855ee1a1 | 37 | NETDEV_KIND_IP6TNL, |
3be1d7e0 TG |
38 | NETDEV_KIND_DUMMY, |
39 | NETDEV_KIND_TUN, | |
40 | NETDEV_KIND_TAP, | |
20897a0d | 41 | NETDEV_KIND_VRF, |
92c918b0 | 42 | NETDEV_KIND_VCAN, |
6598e046 | 43 | NETDEV_KIND_GENEVE, |
d6df583c | 44 | NETDEV_KIND_VXCAN, |
e5719363 | 45 | NETDEV_KIND_WIREGUARD, |
56e7fb50 | 46 | NETDEV_KIND_NETDEVSIM, |
53cb501a | 47 | NETDEV_KIND_FOU, |
2266864b | 48 | NETDEV_KIND_ERSPAN, |
3be1d7e0 TG |
49 | _NETDEV_KIND_MAX, |
50 | _NETDEV_KIND_INVALID = -1 | |
51 | } NetDevKind; | |
52 | ||
53 | typedef enum NetDevState { | |
f3c33b23 | 54 | NETDEV_STATE_LOADING, |
3be1d7e0 TG |
55 | NETDEV_STATE_FAILED, |
56 | NETDEV_STATE_CREATING, | |
57 | NETDEV_STATE_READY, | |
58 | NETDEV_STATE_LINGER, | |
59 | _NETDEV_STATE_MAX, | |
60 | _NETDEV_STATE_INVALID = -1, | |
61 | } NetDevState; | |
62 | ||
aa9f1140 TG |
63 | typedef enum NetDevCreateType { |
64 | NETDEV_CREATE_INDEPENDENT, | |
65 | NETDEV_CREATE_MASTER, | |
66 | NETDEV_CREATE_STACKED, | |
67 | _NETDEV_CREATE_MAX, | |
68 | _NETDEV_CREATE_INVALID = -1, | |
69 | } NetDevCreateType; | |
70 | ||
634f0f98 ZJS |
71 | typedef struct Manager Manager; |
72 | typedef struct Condition Condition; | |
73 | ||
74 | typedef struct NetDev { | |
3be1d7e0 TG |
75 | Manager *manager; |
76 | ||
cf4b2f99 | 77 | unsigned n_ref; |
3be1d7e0 TG |
78 | |
79 | char *filename; | |
80 | ||
81 | Condition *match_host; | |
82 | Condition *match_virt; | |
5022f08a LP |
83 | Condition *match_kernel_cmdline; |
84 | Condition *match_kernel_version; | |
3be1d7e0 TG |
85 | Condition *match_arch; |
86 | ||
aa9f1140 TG |
87 | NetDevState state; |
88 | NetDevKind kind; | |
3be1d7e0 TG |
89 | char *description; |
90 | char *ifname; | |
3be1d7e0 | 91 | struct ether_addr *mac; |
4e964aa0 | 92 | uint32_t mtu; |
3be1d7e0 | 93 | int ifindex; |
3be1d7e0 TG |
94 | |
95 | LIST_HEAD(netdev_join_callback, callbacks); | |
634f0f98 | 96 | } NetDev; |
3be1d7e0 | 97 | |
634f0f98 | 98 | typedef struct NetDevVTable { |
aa9f1140 TG |
99 | /* How much memory does an object of this unit type need */ |
100 | size_t object_size; | |
101 | ||
102 | /* Config file sections this netdev kind understands, separated | |
103 | * by NUL chars */ | |
104 | const char *sections; | |
3be1d7e0 | 105 | |
aa9f1140 TG |
106 | /* This should reset all type-specific variables. This should |
107 | * not allocate memory, and is called with zero-initialized | |
108 | * data. It should hence only initialize variables that need | |
109 | * to be set != 0. */ | |
110 | void (*init)(NetDev *n); | |
3be1d7e0 | 111 | |
aa9f1140 TG |
112 | /* This should free all kind-specific variables. It should be |
113 | * idempotent. */ | |
114 | void (*done)(NetDev *n); | |
115 | ||
116 | /* fill in message to create netdev */ | |
1c4baffc | 117 | int (*fill_message_create)(NetDev *netdev, Link *link, sd_netlink_message *message); |
aa9f1140 TG |
118 | |
119 | /* specifies if netdev is independent, or a master device or a stacked device */ | |
120 | NetDevCreateType create_type; | |
3be1d7e0 TG |
121 | |
122 | /* create netdev, if not done via rtnl */ | |
123 | int (*create)(NetDev *netdev); | |
124 | ||
540eb5f0 SS |
125 | /* perform additional configuration after netdev has been createad */ |
126 | int (*post_create)(NetDev *netdev, Link *link, sd_netlink_message *message); | |
127 | ||
3be1d7e0 TG |
128 | /* verify that compulsory configuration options were specified */ |
129 | int (*config_verify)(NetDev *netdev, const char *filename); | |
634f0f98 | 130 | } NetDevVTable; |
3be1d7e0 TG |
131 | |
132 | extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX]; | |
133 | ||
281bb5c1 | 134 | #define NETDEV_VTABLE(n) ((n)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(n)->kind] : NULL) |
3be1d7e0 | 135 | |
aa9f1140 | 136 | /* For casting a netdev into the various netdev kinds */ |
634f0f98 | 137 | #define DEFINE_NETDEV_CAST(UPPERCASE, MixedCase) \ |
aa9f1140 | 138 | static inline MixedCase* UPPERCASE(NetDev *n) { \ |
f3c33b23 LP |
139 | if (_unlikely_(!n || \ |
140 | n->kind != NETDEV_KIND_##UPPERCASE) || \ | |
141 | n->state == _NETDEV_STATE_INVALID) \ | |
aa9f1140 TG |
142 | return NULL; \ |
143 | \ | |
144 | return (MixedCase*) n; \ | |
145 | } | |
146 | ||
147 | /* For casting the various netdev kinds into a netdev */ | |
148 | #define NETDEV(n) (&(n)->meta) | |
149 | ||
3be1d7e0 | 150 | int netdev_load(Manager *manager); |
e27aac11 | 151 | int netdev_load_one(Manager *manager, const char *filename); |
3be1d7e0 TG |
152 | void netdev_drop(NetDev *netdev); |
153 | ||
154 | NetDev *netdev_unref(NetDev *netdev); | |
155 | NetDev *netdev_ref(NetDev *netdev); | |
302a796f | 156 | DEFINE_TRIVIAL_DESTRUCTOR(netdev_destroy_callback, NetDev, netdev_unref); |
3be1d7e0 | 157 | DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref); |
3be1d7e0 | 158 | |
9e2bbf99 | 159 | bool netdev_is_managed(NetDev *netdev); |
3be1d7e0 | 160 | int netdev_get(Manager *manager, const char *name, NetDev **ret); |
1c4baffc | 161 | int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink); |
3be1d7e0 | 162 | int netdev_get_mac(const char *ifname, struct ether_addr **ret); |
302a796f | 163 | int netdev_join(NetDev *netdev, Link *link, link_netlink_message_handler_t cb); |
3be1d7e0 TG |
164 | |
165 | const char *netdev_kind_to_string(NetDevKind d) _const_; | |
166 | NetDevKind netdev_kind_from_string(const char *d) _pure_; | |
167 | ||
538f15cf | 168 | CONFIG_PARSER_PROTOTYPE(config_parse_netdev_kind); |
3be1d7e0 TG |
169 | |
170 | /* gperf */ | |
c9f7b4d3 | 171 | const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, GPERF_LEN_TYPE length); |
3be1d7e0 TG |
172 | |
173 | /* Macros which append INTERFACE= to the message */ | |
174 | ||
f2341e0a LP |
175 | #define log_netdev_full(netdev, level, error, ...) \ |
176 | ({ \ | |
8dec4a9d | 177 | const NetDev *_n = (netdev); \ |
4b58153d | 178 | _n ? log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", _n->ifname, NULL, NULL, ##__VA_ARGS__) : \ |
f2341e0a LP |
179 | log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ |
180 | }) | |
6a7a4e4d LP |
181 | |
182 | #define log_netdev_debug(netdev, ...) log_netdev_full(netdev, LOG_DEBUG, 0, ##__VA_ARGS__) | |
183 | #define log_netdev_info(netdev, ...) log_netdev_full(netdev, LOG_INFO, 0, ##__VA_ARGS__) | |
184 | #define log_netdev_notice(netdev, ...) log_netdev_full(netdev, LOG_NOTICE, 0, ##__VA_ARGS__) | |
185 | #define log_netdev_warning(netdev, ...) log_netdev_full(netdev, LOG_WARNING, 0, ## __VA_ARGS__) | |
186 | #define log_netdev_error(netdev, ...) log_netdev_full(netdev, LOG_ERR, 0, ##__VA_ARGS__) | |
187 | ||
188 | #define log_netdev_debug_errno(netdev, error, ...) log_netdev_full(netdev, LOG_DEBUG, error, ##__VA_ARGS__) | |
189 | #define log_netdev_info_errno(netdev, error, ...) log_netdev_full(netdev, LOG_INFO, error, ##__VA_ARGS__) | |
190 | #define log_netdev_notice_errno(netdev, error, ...) log_netdev_full(netdev, LOG_NOTICE, error, ##__VA_ARGS__) | |
191 | #define log_netdev_warning_errno(netdev, error, ...) log_netdev_full(netdev, LOG_WARNING, error, ##__VA_ARGS__) | |
192 | #define log_netdev_error_errno(netdev, error, ...) log_netdev_full(netdev, LOG_ERR, error, ##__VA_ARGS__) | |
98b32556 | 193 | |
f2341e0a LP |
194 | #define LOG_NETDEV_MESSAGE(netdev, fmt, ...) "MESSAGE=%s: " fmt, (netdev)->ifname, ##__VA_ARGS__ |
195 | #define LOG_NETDEV_INTERFACE(netdev) "INTERFACE=%s", (netdev)->ifname |