]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/netdev/netdev.h
51b3ea7a8f6c1dabc7a504a8c4acb4804dd8085f
[thirdparty/systemd.git] / src / network / netdev / netdev.h
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 #pragma once
3
4 /***
5 This file is part of systemd.
6
7 Copyright 2013 Tom Gundersen <teg@jklm.no>
8
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 ***/
22
23 #include "sd-netlink.h"
24
25 #include "list.h"
26 #include "time-util.h"
27
28 typedef struct netdev_join_callback netdev_join_callback;
29 typedef struct Link Link;
30
31 struct netdev_join_callback {
32 sd_netlink_message_handler_t callback;
33 Link *link;
34
35 LIST_FIELDS(netdev_join_callback, callbacks);
36 };
37
38 typedef enum NetDevKind {
39 NETDEV_KIND_BRIDGE,
40 NETDEV_KIND_BOND,
41 NETDEV_KIND_VLAN,
42 NETDEV_KIND_MACVLAN,
43 NETDEV_KIND_MACVTAP,
44 NETDEV_KIND_IPVLAN,
45 NETDEV_KIND_VXLAN,
46 NETDEV_KIND_IPIP,
47 NETDEV_KIND_GRE,
48 NETDEV_KIND_GRETAP,
49 NETDEV_KIND_IP6GRE,
50 NETDEV_KIND_IP6GRETAP,
51 NETDEV_KIND_SIT,
52 NETDEV_KIND_VETH,
53 NETDEV_KIND_VTI,
54 NETDEV_KIND_VTI6,
55 NETDEV_KIND_IP6TNL,
56 NETDEV_KIND_DUMMY,
57 NETDEV_KIND_TUN,
58 NETDEV_KIND_TAP,
59 NETDEV_KIND_VRF,
60 NETDEV_KIND_VCAN,
61 NETDEV_KIND_GENEVE,
62 NETDEV_KIND_VXCAN,
63 NETDEV_KIND_WIREGUARD,
64 _NETDEV_KIND_MAX,
65 _NETDEV_KIND_INVALID = -1
66 } NetDevKind;
67
68 typedef enum NetDevState {
69 NETDEV_STATE_LOADING,
70 NETDEV_STATE_FAILED,
71 NETDEV_STATE_CREATING,
72 NETDEV_STATE_READY,
73 NETDEV_STATE_LINGER,
74 _NETDEV_STATE_MAX,
75 _NETDEV_STATE_INVALID = -1,
76 } NetDevState;
77
78 typedef enum NetDevCreateType {
79 NETDEV_CREATE_INDEPENDENT,
80 NETDEV_CREATE_MASTER,
81 NETDEV_CREATE_STACKED,
82 _NETDEV_CREATE_MAX,
83 _NETDEV_CREATE_INVALID = -1,
84 } NetDevCreateType;
85
86 typedef struct Manager Manager;
87 typedef struct Condition Condition;
88
89 typedef struct NetDev {
90 Manager *manager;
91
92 int n_ref;
93
94 char *filename;
95
96 Condition *match_host;
97 Condition *match_virt;
98 Condition *match_kernel_cmdline;
99 Condition *match_kernel_version;
100 Condition *match_arch;
101
102 NetDevState state;
103 NetDevKind kind;
104 char *description;
105 char *ifname;
106 struct ether_addr *mac;
107 size_t mtu;
108 int ifindex;
109
110 LIST_HEAD(netdev_join_callback, callbacks);
111 } NetDev;
112
113 typedef struct NetDevVTable {
114 /* How much memory does an object of this unit type need */
115 size_t object_size;
116
117 /* Config file sections this netdev kind understands, separated
118 * by NUL chars */
119 const char *sections;
120
121 /* This should reset all type-specific variables. This should
122 * not allocate memory, and is called with zero-initialized
123 * data. It should hence only initialize variables that need
124 * to be set != 0. */
125 void (*init)(NetDev *n);
126
127 /* This should free all kind-specific variables. It should be
128 * idempotent. */
129 void (*done)(NetDev *n);
130
131 /* fill in message to create netdev */
132 int (*fill_message_create)(NetDev *netdev, Link *link, sd_netlink_message *message);
133
134 /* specifies if netdev is independent, or a master device or a stacked device */
135 NetDevCreateType create_type;
136
137 /* create netdev, if not done via rtnl */
138 int (*create)(NetDev *netdev);
139
140 /* perform additional configuration after netdev has been createad */
141 int (*post_create)(NetDev *netdev, Link *link, sd_netlink_message *message);
142
143 /* verify that compulsory configuration options were specified */
144 int (*config_verify)(NetDev *netdev, const char *filename);
145 } NetDevVTable;
146
147 extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
148
149 #define NETDEV_VTABLE(n) ((n)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(n)->kind] : NULL)
150
151 /* For casting a netdev into the various netdev kinds */
152 #define DEFINE_NETDEV_CAST(UPPERCASE, MixedCase) \
153 static inline MixedCase* UPPERCASE(NetDev *n) { \
154 if (_unlikely_(!n || \
155 n->kind != NETDEV_KIND_##UPPERCASE) || \
156 n->state == _NETDEV_STATE_INVALID) \
157 return NULL; \
158 \
159 return (MixedCase*) n; \
160 }
161
162 /* For casting the various netdev kinds into a netdev */
163 #define NETDEV(n) (&(n)->meta)
164
165 int netdev_load(Manager *manager);
166 void netdev_drop(NetDev *netdev);
167
168 NetDev *netdev_unref(NetDev *netdev);
169 NetDev *netdev_ref(NetDev *netdev);
170
171 DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref);
172 #define _cleanup_netdev_unref_ _cleanup_(netdev_unrefp)
173
174 int netdev_get(Manager *manager, const char *name, NetDev **ret);
175 int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink);
176 int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler_t callback);
177 int netdev_get_mac(const char *ifname, struct ether_addr **ret);
178 int netdev_join(NetDev *netdev, Link *link, sd_netlink_message_handler_t cb);
179
180 const char *netdev_kind_to_string(NetDevKind d) _const_;
181 NetDevKind netdev_kind_from_string(const char *d) _pure_;
182
183 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);
184
185 /* gperf */
186 const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
187
188 /* Macros which append INTERFACE= to the message */
189
190 #define log_netdev_full(netdev, level, error, ...) \
191 ({ \
192 const NetDev *_n = (netdev); \
193 _n ? log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", _n->ifname, NULL, NULL, ##__VA_ARGS__) : \
194 log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
195 })
196
197 #define log_netdev_debug(netdev, ...) log_netdev_full(netdev, LOG_DEBUG, 0, ##__VA_ARGS__)
198 #define log_netdev_info(netdev, ...) log_netdev_full(netdev, LOG_INFO, 0, ##__VA_ARGS__)
199 #define log_netdev_notice(netdev, ...) log_netdev_full(netdev, LOG_NOTICE, 0, ##__VA_ARGS__)
200 #define log_netdev_warning(netdev, ...) log_netdev_full(netdev, LOG_WARNING, 0, ## __VA_ARGS__)
201 #define log_netdev_error(netdev, ...) log_netdev_full(netdev, LOG_ERR, 0, ##__VA_ARGS__)
202
203 #define log_netdev_debug_errno(netdev, error, ...) log_netdev_full(netdev, LOG_DEBUG, error, ##__VA_ARGS__)
204 #define log_netdev_info_errno(netdev, error, ...) log_netdev_full(netdev, LOG_INFO, error, ##__VA_ARGS__)
205 #define log_netdev_notice_errno(netdev, error, ...) log_netdev_full(netdev, LOG_NOTICE, error, ##__VA_ARGS__)
206 #define log_netdev_warning_errno(netdev, error, ...) log_netdev_full(netdev, LOG_WARNING, error, ##__VA_ARGS__)
207 #define log_netdev_error_errno(netdev, error, ...) log_netdev_full(netdev, LOG_ERR, error, ##__VA_ARGS__)
208
209 #define LOG_NETDEV_MESSAGE(netdev, fmt, ...) "MESSAGE=%s: " fmt, (netdev)->ifname, ##__VA_ARGS__
210 #define LOG_NETDEV_INTERFACE(netdev) "INTERFACE=%s", (netdev)->ifname