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