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
|