Line data Source code
1 : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
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 : #pragma once
23 :
24 : #include "networkd.h"
25 : #include "list.h"
26 :
27 : typedef struct NetDevVTable NetDevVTable;
28 :
29 : typedef struct netdev_join_callback netdev_join_callback;
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_MAX,
60 : _NETDEV_KIND_INVALID = -1
61 : } NetDevKind;
62 :
63 : typedef enum NetDevState {
64 : NETDEV_STATE_FAILED,
65 : NETDEV_STATE_CREATING,
66 : NETDEV_STATE_READY,
67 : NETDEV_STATE_LINGER,
68 : _NETDEV_STATE_MAX,
69 : _NETDEV_STATE_INVALID = -1,
70 : } NetDevState;
71 :
72 : typedef enum NetDevCreateType {
73 : NETDEV_CREATE_INDEPENDENT,
74 : NETDEV_CREATE_MASTER,
75 : NETDEV_CREATE_STACKED,
76 : _NETDEV_CREATE_MAX,
77 : _NETDEV_CREATE_INVALID = -1,
78 : } NetDevCreateType;
79 :
80 : struct NetDev {
81 : Manager *manager;
82 :
83 : int n_ref;
84 :
85 : char *filename;
86 :
87 : Condition *match_host;
88 : Condition *match_virt;
89 : Condition *match_kernel;
90 : Condition *match_arch;
91 :
92 : NetDevState state;
93 : NetDevKind kind;
94 : char *description;
95 : char *ifname;
96 : struct ether_addr *mac;
97 : size_t mtu;
98 : int ifindex;
99 :
100 : LIST_HEAD(netdev_join_callback, callbacks);
101 : };
102 :
103 : #include "networkd-netdev-bridge.h"
104 : #include "networkd-netdev-bond.h"
105 : #include "networkd-netdev-vlan.h"
106 : #include "networkd-netdev-macvlan.h"
107 : #include "networkd-netdev-ipvlan.h"
108 : #include "networkd-netdev-vxlan.h"
109 : #include "networkd-netdev-veth.h"
110 : #include "networkd-netdev-tunnel.h"
111 : #include "networkd-netdev-dummy.h"
112 : #include "networkd-netdev-tuntap.h"
113 :
114 : struct NetDevVTable {
115 : /* How much memory does an object of this unit type need */
116 : size_t object_size;
117 :
118 : /* Config file sections this netdev kind understands, separated
119 : * by NUL chars */
120 : const char *sections;
121 :
122 : /* This should reset all type-specific variables. This should
123 : * not allocate memory, and is called with zero-initialized
124 : * data. It should hence only initialize variables that need
125 : * to be set != 0. */
126 : void (*init)(NetDev *n);
127 :
128 : /* This should free all kind-specific variables. It should be
129 : * idempotent. */
130 : void (*done)(NetDev *n);
131 :
132 : /* fill in message to create netdev */
133 : int (*fill_message_create)(NetDev *netdev, Link *link, sd_netlink_message *message);
134 :
135 : /* specifies if netdev is independent, or a master device or a stacked device */
136 : NetDevCreateType create_type;
137 :
138 : /* create netdev, if not done via rtnl */
139 : int (*create)(NetDev *netdev);
140 :
141 : /* verify that compulsory configuration options were specified */
142 : int (*config_verify)(NetDev *netdev, const char *filename);
143 : };
144 :
145 : extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
146 :
147 : #define NETDEV_VTABLE(n) netdev_vtable[(n)->kind]
148 :
149 : /* For casting a netdev into the various netdev kinds */
150 : #define DEFINE_CAST(UPPERCASE, MixedCase) \
151 : static inline MixedCase* UPPERCASE(NetDev *n) { \
152 : if (_unlikely_(!n || n->kind != NETDEV_KIND_##UPPERCASE)) \
153 : return NULL; \
154 : \
155 : return (MixedCase*) n; \
156 : }
157 :
158 : /* For casting the various netdev kinds into a netdev */
159 : #define NETDEV(n) (&(n)->meta)
160 :
161 : DEFINE_CAST(BRIDGE, Bridge);
162 0 : DEFINE_CAST(BOND, Bond);
163 0 : DEFINE_CAST(VLAN, VLan);
164 0 : DEFINE_CAST(MACVLAN, MacVlan);
165 0 : DEFINE_CAST(MACVTAP, MacVlan);
166 0 : DEFINE_CAST(IPVLAN, IPVlan);
167 0 : DEFINE_CAST(VXLAN, VxLan);
168 0 : DEFINE_CAST(IPIP, Tunnel);
169 0 : DEFINE_CAST(GRE, Tunnel);
170 0 : DEFINE_CAST(GRETAP, Tunnel);
171 0 : DEFINE_CAST(IP6GRE, Tunnel);
172 0 : DEFINE_CAST(IP6GRETAP, Tunnel);
173 0 : DEFINE_CAST(SIT, Tunnel);
174 0 : DEFINE_CAST(VTI, Tunnel);
175 0 : DEFINE_CAST(VTI6, Tunnel);
176 0 : DEFINE_CAST(IP6TNL, Tunnel);
177 0 : DEFINE_CAST(VETH, Veth);
178 : DEFINE_CAST(DUMMY, Dummy);
179 0 : DEFINE_CAST(TUN, TunTap);
180 0 : DEFINE_CAST(TAP, TunTap);
181 :
182 : int netdev_load(Manager *manager);
183 : void netdev_drop(NetDev *netdev);
184 :
185 : NetDev *netdev_unref(NetDev *netdev);
186 : NetDev *netdev_ref(NetDev *netdev);
187 :
188 0 : DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref);
189 : #define _cleanup_netdev_unref_ _cleanup_(netdev_unrefp)
190 :
191 : int netdev_get(Manager *manager, const char *name, NetDev **ret);
192 : int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink);
193 : int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler_t callback);
194 : int netdev_get_mac(const char *ifname, struct ether_addr **ret);
195 : int netdev_join(NetDev *netdev, Link *link, sd_netlink_message_handler_t cb);
196 :
197 : const char *netdev_kind_to_string(NetDevKind d) _const_;
198 : NetDevKind netdev_kind_from_string(const char *d) _pure_;
199 :
200 : 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);
201 :
202 : /* gperf */
203 : const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsigned length);
204 :
205 : /* Macros which append INTERFACE= to the message */
206 :
207 : #define log_netdev_full(netdev, level, error, ...) \
208 : ({ \
209 : NetDev *_n = (netdev); \
210 : _n ? log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", _n->ifname, ##__VA_ARGS__) : \
211 : log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
212 : })
213 :
214 : #define log_netdev_debug(netdev, ...) log_netdev_full(netdev, LOG_DEBUG, 0, ##__VA_ARGS__)
215 : #define log_netdev_info(netdev, ...) log_netdev_full(netdev, LOG_INFO, 0, ##__VA_ARGS__)
216 : #define log_netdev_notice(netdev, ...) log_netdev_full(netdev, LOG_NOTICE, 0, ##__VA_ARGS__)
217 : #define log_netdev_warning(netdev, ...) log_netdev_full(netdev, LOG_WARNING, 0, ## __VA_ARGS__)
218 : #define log_netdev_error(netdev, ...) log_netdev_full(netdev, LOG_ERR, 0, ##__VA_ARGS__)
219 :
220 : #define log_netdev_debug_errno(netdev, error, ...) log_netdev_full(netdev, LOG_DEBUG, error, ##__VA_ARGS__)
221 : #define log_netdev_info_errno(netdev, error, ...) log_netdev_full(netdev, LOG_INFO, error, ##__VA_ARGS__)
222 : #define log_netdev_notice_errno(netdev, error, ...) log_netdev_full(netdev, LOG_NOTICE, error, ##__VA_ARGS__)
223 : #define log_netdev_warning_errno(netdev, error, ...) log_netdev_full(netdev, LOG_WARNING, error, ##__VA_ARGS__)
224 : #define log_netdev_error_errno(netdev, error, ...) log_netdev_full(netdev, LOG_ERR, error, ##__VA_ARGS__)
225 :
226 : #define LOG_NETDEV_MESSAGE(netdev, fmt, ...) "MESSAGE=%s: " fmt, (netdev)->ifname, ##__VA_ARGS__
227 : #define LOG_NETDEV_INTERFACE(netdev) "INTERFACE=%s", (netdev)->ifname
|