Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : : #pragma once
3 : :
4 : : #include "sd-netlink.h"
5 : :
6 : : #include "conf-parser.h"
7 : : #include "list.h"
8 : : #include "../networkd-link.h"
9 : : #include "time-util.h"
10 : :
11 : : typedef struct netdev_join_callback netdev_join_callback;
12 : :
13 : : struct netdev_join_callback {
14 : : link_netlink_message_handler_t callback;
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,
25 : : NETDEV_KIND_MACVTAP,
26 : : NETDEV_KIND_IPVLAN,
27 : : NETDEV_KIND_IPVTAP,
28 : : NETDEV_KIND_VXLAN,
29 : : NETDEV_KIND_IPIP,
30 : : NETDEV_KIND_GRE,
31 : : NETDEV_KIND_GRETAP,
32 : : NETDEV_KIND_IP6GRE,
33 : : NETDEV_KIND_IP6GRETAP,
34 : : NETDEV_KIND_SIT,
35 : : NETDEV_KIND_VETH,
36 : : NETDEV_KIND_VTI,
37 : : NETDEV_KIND_VTI6,
38 : : NETDEV_KIND_IP6TNL,
39 : : NETDEV_KIND_DUMMY,
40 : : NETDEV_KIND_TUN,
41 : : NETDEV_KIND_TAP,
42 : : NETDEV_KIND_VRF,
43 : : NETDEV_KIND_VCAN,
44 : : NETDEV_KIND_GENEVE,
45 : : NETDEV_KIND_VXCAN,
46 : : NETDEV_KIND_WIREGUARD,
47 : : NETDEV_KIND_NETDEVSIM,
48 : : NETDEV_KIND_FOU,
49 : : NETDEV_KIND_ERSPAN,
50 : : NETDEV_KIND_L2TP,
51 : : NETDEV_KIND_MACSEC,
52 : : NETDEV_KIND_NLMON,
53 : : NETDEV_KIND_XFRM,
54 : : _NETDEV_KIND_MAX,
55 : : _NETDEV_KIND_TUNNEL, /* Used by config_parse_stacked_netdev() */
56 : : _NETDEV_KIND_INVALID = -1
57 : : } NetDevKind;
58 : :
59 : : typedef enum NetDevState {
60 : : NETDEV_STATE_LOADING,
61 : : NETDEV_STATE_FAILED,
62 : : NETDEV_STATE_CREATING,
63 : : NETDEV_STATE_READY,
64 : : NETDEV_STATE_LINGER,
65 : : _NETDEV_STATE_MAX,
66 : : _NETDEV_STATE_INVALID = -1,
67 : : } NetDevState;
68 : :
69 : : typedef enum NetDevCreateType {
70 : : NETDEV_CREATE_INDEPENDENT,
71 : : NETDEV_CREATE_MASTER,
72 : : NETDEV_CREATE_STACKED,
73 : : NETDEV_CREATE_AFTER_CONFIGURED,
74 : : _NETDEV_CREATE_MAX,
75 : : _NETDEV_CREATE_INVALID = -1,
76 : : } NetDevCreateType;
77 : :
78 : : typedef struct Manager Manager;
79 : : typedef struct Condition Condition;
80 : :
81 : : typedef struct NetDev {
82 : : Manager *manager;
83 : :
84 : : unsigned n_ref;
85 : :
86 : : char *filename;
87 : :
88 : : LIST_HEAD(Condition, conditions);
89 : :
90 : : NetDevState state;
91 : : NetDevKind kind;
92 : : char *description;
93 : : char *ifname;
94 : : struct ether_addr *mac;
95 : : uint32_t mtu;
96 : : int ifindex;
97 : :
98 : : LIST_HEAD(netdev_join_callback, callbacks);
99 : : } NetDev;
100 : :
101 : : typedef struct NetDevVTable {
102 : : /* How much memory does an object of this unit type need */
103 : : size_t object_size;
104 : :
105 : : /* Config file sections this netdev kind understands, separated
106 : : * by NUL chars */
107 : : const char *sections;
108 : :
109 : : /* This should reset all type-specific variables. This should
110 : : * not allocate memory, and is called with zero-initialized
111 : : * data. It should hence only initialize variables that need
112 : : * to be set != 0. */
113 : : void (*init)(NetDev *n);
114 : :
115 : : /* This should free all kind-specific variables. It should be
116 : : * idempotent. */
117 : : void (*done)(NetDev *n);
118 : :
119 : : /* fill in message to create netdev */
120 : : int (*fill_message_create)(NetDev *netdev, Link *link, sd_netlink_message *message);
121 : :
122 : : /* specifies if netdev is independent, or a master device or a stacked device */
123 : : NetDevCreateType create_type;
124 : :
125 : : /* create netdev, if not done via rtnl */
126 : : int (*create)(NetDev *netdev);
127 : :
128 : : /* create netdev after link is fully configured */
129 : : int (*create_after_configured)(NetDev *netdev, Link *link);
130 : :
131 : : /* perform additional configuration after netdev has been createad */
132 : : int (*post_create)(NetDev *netdev, Link *link, sd_netlink_message *message);
133 : :
134 : : /* verify that compulsory configuration options were specified */
135 : : int (*config_verify)(NetDev *netdev, const char *filename);
136 : :
137 : : /* Generate MAC address or not When MACAddress= is not specified. */
138 : : bool generate_mac;
139 : : } NetDevVTable;
140 : :
141 : : extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
142 : :
143 : : #define NETDEV_VTABLE(n) ((n)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(n)->kind] : NULL)
144 : :
145 : : /* For casting a netdev into the various netdev kinds */
146 : : #define DEFINE_NETDEV_CAST(UPPERCASE, MixedCase) \
147 : : static inline MixedCase* UPPERCASE(NetDev *n) { \
148 : : if (_unlikely_(!n || \
149 : : n->kind != NETDEV_KIND_##UPPERCASE) || \
150 : : n->state == _NETDEV_STATE_INVALID) \
151 : : return NULL; \
152 : : \
153 : : return (MixedCase*) n; \
154 : : }
155 : :
156 : : /* For casting the various netdev kinds into a netdev */
157 : : #define NETDEV(n) (&(n)->meta)
158 : :
159 : : int netdev_load(Manager *manager);
160 : : int netdev_load_one(Manager *manager, const char *filename);
161 : : void netdev_drop(NetDev *netdev);
162 : :
163 : : NetDev *netdev_unref(NetDev *netdev);
164 : : NetDev *netdev_ref(NetDev *netdev);
165 : 0 : DEFINE_TRIVIAL_DESTRUCTOR(netdev_destroy_callback, NetDev, netdev_unref);
166 [ # # ]: 0 : DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref);
167 : :
168 : : bool netdev_is_managed(NetDev *netdev);
169 : : int netdev_get(Manager *manager, const char *name, NetDev **ret);
170 : : int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink);
171 : : int netdev_get_mac(const char *ifname, struct ether_addr **ret);
172 : : int netdev_join(NetDev *netdev, Link *link, link_netlink_message_handler_t cb);
173 : : int netdev_join_after_configured(NetDev *netdev, Link *link, link_netlink_message_handler_t callback);
174 : :
175 : : const char *netdev_kind_to_string(NetDevKind d) _const_;
176 : : NetDevKind netdev_kind_from_string(const char *d) _pure_;
177 : :
178 : 0 : static inline NetDevCreateType netdev_get_create_type(NetDev *netdev) {
179 [ # # ]: 0 : assert(netdev);
180 [ # # # # ]: 0 : assert(NETDEV_VTABLE(netdev));
181 : :
182 [ # # ]: 0 : return NETDEV_VTABLE(netdev)->create_type;
183 : : }
184 : :
185 : : CONFIG_PARSER_PROTOTYPE(config_parse_netdev_kind);
186 : :
187 : : /* gperf */
188 : : const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
189 : :
190 : : /* Macros which append INTERFACE= to the message */
191 : :
192 : : #define log_netdev_full(netdev, level, error, ...) \
193 : : ({ \
194 : : const NetDev *_n = (netdev); \
195 : : _n ? log_object_internal(level, error, PROJECT_FILE, __LINE__, __func__, "INTERFACE=", _n->ifname, NULL, NULL, ##__VA_ARGS__) : \
196 : : log_internal(level, error, PROJECT_FILE, __LINE__, __func__, ##__VA_ARGS__); \
197 : : })
198 : :
199 : : #define log_netdev_debug(netdev, ...) log_netdev_full(netdev, LOG_DEBUG, 0, ##__VA_ARGS__)
200 : : #define log_netdev_info(netdev, ...) log_netdev_full(netdev, LOG_INFO, 0, ##__VA_ARGS__)
201 : : #define log_netdev_notice(netdev, ...) log_netdev_full(netdev, LOG_NOTICE, 0, ##__VA_ARGS__)
202 : : #define log_netdev_warning(netdev, ...) log_netdev_full(netdev, LOG_WARNING, 0, ## __VA_ARGS__)
203 : : #define log_netdev_error(netdev, ...) log_netdev_full(netdev, LOG_ERR, 0, ##__VA_ARGS__)
204 : :
205 : : #define log_netdev_debug_errno(netdev, error, ...) log_netdev_full(netdev, LOG_DEBUG, error, ##__VA_ARGS__)
206 : : #define log_netdev_info_errno(netdev, error, ...) log_netdev_full(netdev, LOG_INFO, error, ##__VA_ARGS__)
207 : : #define log_netdev_notice_errno(netdev, error, ...) log_netdev_full(netdev, LOG_NOTICE, error, ##__VA_ARGS__)
208 : : #define log_netdev_warning_errno(netdev, error, ...) log_netdev_full(netdev, LOG_WARNING, error, ##__VA_ARGS__)
209 : : #define log_netdev_error_errno(netdev, error, ...) log_netdev_full(netdev, LOG_ERR, error, ##__VA_ARGS__)
210 : :
211 : : #define LOG_NETDEV_MESSAGE(netdev, fmt, ...) "MESSAGE=%s: " fmt, (netdev)->ifname, ##__VA_ARGS__
212 : : #define LOG_NETDEV_INTERFACE(netdev) "INTERFACE=%s", (netdev)->ifname
|