]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-netlink/netlink-types.c
Merge pull request #346 from poettering/install-bad-memory
[thirdparty/systemd.git] / src / libsystemd / sd-netlink / netlink-types.c
CommitLineData
d8e538ec
TG
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2014 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
d8e538ec
TG
22#include <stdint.h>
23#include <sys/socket.h>
24#include <linux/netlink.h>
25#include <linux/rtnetlink.h>
e410b07d 26#include <linux/in6.h>
d8e538ec
TG
27#include <linux/veth.h>
28#include <linux/if_bridge.h>
29#include <linux/if_addr.h>
30#include <linux/if.h>
31
0a827d10 32#include <linux/ip.h>
c4a5ddc9 33#include <linux/if_link.h>
0a827d10
SS
34#include <linux/if_tunnel.h>
35
d8e538ec
TG
36#include "macro.h"
37#include "util.h"
38
1c4baffc 39#include "netlink-types.h"
0830ba61 40#include "missing.h"
d8e538ec
TG
41
42static const NLTypeSystem rtnl_link_type_system;
43
44static const NLType rtnl_link_info_data_veth_types[VETH_INFO_MAX + 1] = {
45 [VETH_INFO_PEER] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
46};
47
c4a5ddc9
TG
48static const NLType rtnl_link_info_data_ipvlan_types[IFLA_IPVLAN_MAX + 1] = {
49 [IFLA_IPVLAN_MODE] = { .type = NLA_U16 },
50};
d8e538ec
TG
51
52static const NLType rtnl_link_info_data_macvlan_types[IFLA_MACVLAN_MAX + 1] = {
53 [IFLA_MACVLAN_MODE] = { .type = NLA_U32 },
54 [IFLA_MACVLAN_FLAGS] = { .type = NLA_U16 },
55};
56
57static const NLType rtnl_link_info_data_bridge_types[IFLA_BRIDGE_MAX + 1] = {
58 [IFLA_BRIDGE_FLAGS] = { .type = NLA_U16 },
59 [IFLA_BRIDGE_MODE] = { .type = NLA_U16 },
60/*
61 [IFLA_BRIDGE_VLAN_INFO] = { .type = NLA_BINARY,
62 .len = sizeof(struct bridge_vlan_info), },
63*/
64};
65
66static const NLType rtnl_link_info_data_vlan_types[IFLA_VLAN_MAX + 1] = {
67 [IFLA_VLAN_ID] = { .type = NLA_U16 },
68/*
69 [IFLA_VLAN_FLAGS] = { .len = sizeof(struct ifla_vlan_flags) },
70 [IFLA_VLAN_EGRESS_QOS] = { .type = NLA_NESTED },
71 [IFLA_VLAN_INGRESS_QOS] = { .type = NLA_NESTED },
72*/
73 [IFLA_VLAN_PROTOCOL] = { .type = NLA_U16 },
74};
75
6ef81477
SS
76static const NLType rtnl_link_info_data_vxlan_types[IFLA_VXLAN_MAX+1] = {
77 [IFLA_VXLAN_ID] = { .type = NLA_U32 },
78 [IFLA_VXLAN_GROUP] = {.type = NLA_IN_ADDR },
79 [IFLA_VXLAN_LINK] = { .type = NLA_U32 },
80 [IFLA_VXLAN_LOCAL] = { .type = NLA_U32},
81 [IFLA_VXLAN_TTL] = { .type = NLA_U8 },
82 [IFLA_VXLAN_TOS] = { .type = NLA_U8 },
83 [IFLA_VXLAN_LEARNING] = { .type = NLA_U8 },
84 [IFLA_VXLAN_AGEING] = { .type = NLA_U32 },
85 [IFLA_VXLAN_LIMIT] = { .type = NLA_U32 },
86 [IFLA_VXLAN_PORT_RANGE] = { .type = NLA_U32},
87 [IFLA_VXLAN_PROXY] = { .type = NLA_U8 },
88 [IFLA_VXLAN_RSC] = { .type = NLA_U8 },
89 [IFLA_VXLAN_L2MISS] = { .type = NLA_U8 },
90 [IFLA_VXLAN_L3MISS] = { .type = NLA_U8 },
91};
92
81bd37a8
SS
93static const NLType rtnl_bond_arp_target_types[BOND_ARP_TARGETS_MAX + 1] = {
94 [BOND_ARP_TARGETS_0] = { .type = NLA_U32 },
95 [BOND_ARP_TARGETS_1] = { .type = NLA_U32 },
96 [BOND_ARP_TARGETS_2] = { .type = NLA_U32 },
97 [BOND_ARP_TARGETS_3] = { .type = NLA_U32 },
98 [BOND_ARP_TARGETS_4] = { .type = NLA_U32 },
99 [BOND_ARP_TARGETS_5] = { .type = NLA_U32 },
100 [BOND_ARP_TARGETS_6] = { .type = NLA_U32 },
101 [BOND_ARP_TARGETS_7] = { .type = NLA_U32 },
102 [BOND_ARP_TARGETS_8] = { .type = NLA_U32 },
103 [BOND_ARP_TARGETS_9] = { .type = NLA_U32 },
104 [BOND_ARP_TARGETS_10] = { .type = NLA_U32 },
105 [BOND_ARP_TARGETS_11] = { .type = NLA_U32 },
106 [BOND_ARP_TARGETS_12] = { .type = NLA_U32 },
107 [BOND_ARP_TARGETS_13] = { .type = NLA_U32 },
108 [BOND_ARP_TARGETS_14] = { .type = NLA_U32 },
109 [BOND_ARP_TARGETS_MAX] = { .type = NLA_U32 },
110};
111
112static const NLTypeSystem rtnl_bond_arp_type_system = {
113 .max = ELEMENTSOF(rtnl_bond_arp_target_types) - 1,
114 .types = rtnl_bond_arp_target_types,
115};
116
d8e538ec
TG
117static const NLType rtnl_link_info_data_bond_types[IFLA_BOND_MAX + 1] = {
118 [IFLA_BOND_MODE] = { .type = NLA_U8 },
119 [IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 },
d8e538ec
TG
120 [IFLA_BOND_MIIMON] = { .type = NLA_U32 },
121 [IFLA_BOND_UPDELAY] = { .type = NLA_U32 },
122 [IFLA_BOND_DOWNDELAY] = { .type = NLA_U32 },
123 [IFLA_BOND_USE_CARRIER] = { .type = NLA_U8 },
124 [IFLA_BOND_ARP_INTERVAL] = { .type = NLA_U32 },
81bd37a8 125 [IFLA_BOND_ARP_IP_TARGET] = { .type = NLA_NESTED, .type_system = &rtnl_bond_arp_type_system },
d8e538ec
TG
126 [IFLA_BOND_ARP_VALIDATE] = { .type = NLA_U32 },
127 [IFLA_BOND_ARP_ALL_TARGETS] = { .type = NLA_U32 },
128 [IFLA_BOND_PRIMARY] = { .type = NLA_U32 },
129 [IFLA_BOND_PRIMARY_RESELECT] = { .type = NLA_U8 },
130 [IFLA_BOND_FAIL_OVER_MAC] = { .type = NLA_U8 },
131 [IFLA_BOND_XMIT_HASH_POLICY] = { .type = NLA_U8 },
132 [IFLA_BOND_RESEND_IGMP] = { .type = NLA_U32 },
133 [IFLA_BOND_NUM_PEER_NOTIF] = { .type = NLA_U8 },
134 [IFLA_BOND_ALL_SLAVES_ACTIVE] = { .type = NLA_U8 },
135 [IFLA_BOND_MIN_LINKS] = { .type = NLA_U32 },
136 [IFLA_BOND_LP_INTERVAL] = { .type = NLA_U32 },
137 [IFLA_BOND_PACKETS_PER_SLAVE] = { .type = NLA_U32 },
138 [IFLA_BOND_AD_LACP_RATE] = { .type = NLA_U8 },
139 [IFLA_BOND_AD_SELECT] = { .type = NLA_U8 },
d8e538ec 140 [IFLA_BOND_AD_INFO] = { .type = NLA_NESTED },
d8e538ec
TG
141};
142
0a827d10
SS
143static const NLType rtnl_link_info_data_iptun_types[IFLA_IPTUN_MAX + 1] = {
144 [IFLA_IPTUN_LINK] = { .type = NLA_U32 },
7951dea2
SS
145 [IFLA_IPTUN_LOCAL] = { .type = NLA_IN_ADDR },
146 [IFLA_IPTUN_REMOTE] = { .type = NLA_IN_ADDR },
0a827d10
SS
147 [IFLA_IPTUN_TTL] = { .type = NLA_U8 },
148 [IFLA_IPTUN_TOS] = { .type = NLA_U8 },
149 [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 },
150 [IFLA_IPTUN_FLAGS] = { .type = NLA_U16 },
151 [IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
152 [IFLA_IPTUN_6RD_PREFIX] = { .type = NLA_IN_ADDR },
153 [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NLA_U32 },
154 [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NLA_U16 },
155 [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NLA_U16 },
156};
157
8bb088c5
SS
158static const NLType rtnl_link_info_data_ipgre_types[IFLA_GRE_MAX + 1] = {
159 [IFLA_GRE_LINK] = { .type = NLA_U32 },
160 [IFLA_GRE_IFLAGS] = { .type = NLA_U16 },
161 [IFLA_GRE_OFLAGS] = { .type = NLA_U16 },
162 [IFLA_GRE_IKEY] = { .type = NLA_U32 },
163 [IFLA_GRE_OKEY] = { .type = NLA_U32 },
164 [IFLA_GRE_LOCAL] = { .type = NLA_IN_ADDR },
165 [IFLA_GRE_REMOTE] = { .type = NLA_IN_ADDR },
166 [IFLA_GRE_TTL] = { .type = NLA_U8 },
167 [IFLA_GRE_TOS] = { .type = NLA_U8 },
168 [IFLA_GRE_PMTUDISC] = { .type = NLA_U8 },
169};
170
a613382b
SS
171static const NLType rtnl_link_info_data_ipvti_types[IFLA_VTI_MAX + 1] = {
172 [IFLA_VTI_LINK] = { .type = NLA_U32 },
173 [IFLA_VTI_IKEY] = { .type = NLA_U32 },
174 [IFLA_VTI_OKEY] = { .type = NLA_U32 },
175 [IFLA_VTI_LOCAL] = { .type = NLA_IN_ADDR },
176 [IFLA_VTI_REMOTE] = { .type = NLA_IN_ADDR },
177};
178
855ee1a1
SS
179static const NLType rtnl_link_info_data_ip6tnl_types[IFLA_IPTUN_MAX + 1] = {
180 [IFLA_IPTUN_LINK] = { .type = NLA_U32 },
181 [IFLA_IPTUN_LOCAL] = { .type = NLA_IN_ADDR },
182 [IFLA_IPTUN_REMOTE] = { .type = NLA_IN_ADDR },
183 [IFLA_IPTUN_TTL] = { .type = NLA_U8 },
184 [IFLA_IPTUN_FLAGS] = { .type = NLA_U32 },
185 [IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
186 [IFLA_IPTUN_ENCAP_LIMIT] = { .type = NLA_U8 },
187 [IFLA_IPTUN_FLOWINFO] = { .type = NLA_U32},
188};
189
0a827d10 190/* these strings must match the .kind entries in the kernel */
d8e538ec
TG
191static const char* const nl_union_link_info_data_table[_NL_UNION_LINK_INFO_DATA_MAX] = {
192 [NL_UNION_LINK_INFO_DATA_BOND] = "bond",
193 [NL_UNION_LINK_INFO_DATA_BRIDGE] = "bridge",
194 [NL_UNION_LINK_INFO_DATA_VLAN] = "vlan",
195 [NL_UNION_LINK_INFO_DATA_VETH] = "veth",
9e358851 196 [NL_UNION_LINK_INFO_DATA_DUMMY] = "dummy",
d8e538ec 197 [NL_UNION_LINK_INFO_DATA_MACVLAN] = "macvlan",
c4a5ddc9 198 [NL_UNION_LINK_INFO_DATA_IPVLAN] = "ipvlan",
6ef81477 199 [NL_UNION_LINK_INFO_DATA_VXLAN] = "vxlan",
0a827d10 200 [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = "ipip",
8bb088c5 201 [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = "gre",
1af2536a 202 [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = "gretap",
b16492f8
SS
203 [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = "ip6gre",
204 [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = "ip6gretap",
0a827d10 205 [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = "sit",
a613382b 206 [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = "vti",
9011ce77 207 [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = "vti6",
855ee1a1 208 [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = "ip6tnl",
d8e538ec
TG
209};
210
211DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
212
213static const NLTypeSystem rtnl_link_info_data_type_systems[_NL_UNION_LINK_INFO_DATA_MAX] = {
0a827d10
SS
214 [NL_UNION_LINK_INFO_DATA_BOND] = { .max = ELEMENTSOF(rtnl_link_info_data_bond_types) - 1,
215 .types = rtnl_link_info_data_bond_types },
216 [NL_UNION_LINK_INFO_DATA_BRIDGE] = { .max = ELEMENTSOF(rtnl_link_info_data_bridge_types) - 1,
217 .types = rtnl_link_info_data_bridge_types },
218 [NL_UNION_LINK_INFO_DATA_VLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_vlan_types) - 1,
219 .types = rtnl_link_info_data_vlan_types },
220 [NL_UNION_LINK_INFO_DATA_VETH] = { .max = ELEMENTSOF(rtnl_link_info_data_veth_types) - 1,
221 .types = rtnl_link_info_data_veth_types },
222 [NL_UNION_LINK_INFO_DATA_MACVLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_macvlan_types) - 1,
223 .types = rtnl_link_info_data_macvlan_types },
c4a5ddc9
TG
224 [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvlan_types) - 1,
225 .types = rtnl_link_info_data_ipvlan_types },
6ef81477
SS
226 [NL_UNION_LINK_INFO_DATA_VXLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_vxlan_types) - 1,
227 .types = rtnl_link_info_data_vxlan_types },
0a827d10
SS
228 [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1,
229 .types = rtnl_link_info_data_iptun_types },
8bb088c5
SS
230 [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
231 .types = rtnl_link_info_data_ipgre_types },
1af2536a
SS
232 [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
233 .types = rtnl_link_info_data_ipgre_types },
b16492f8
SS
234 [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
235 .types = rtnl_link_info_data_ipgre_types },
236 [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
237 .types = rtnl_link_info_data_ipgre_types },
0a827d10
SS
238 [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1,
239 .types = rtnl_link_info_data_iptun_types },
a613382b
SS
240 [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvti_types) - 1,
241 .types = rtnl_link_info_data_ipvti_types },
9011ce77
SS
242 [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvti_types) - 1,
243 .types = rtnl_link_info_data_ipvti_types },
855ee1a1
SS
244 [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types) - 1,
245 .types = rtnl_link_info_data_ip6tnl_types },
246
d8e538ec
TG
247};
248
249static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
250 .num = _NL_UNION_LINK_INFO_DATA_MAX,
251 .lookup = nl_union_link_info_data_from_string,
252 .type_systems = rtnl_link_info_data_type_systems,
4af7b60d 253 .match_type = NL_MATCH_SIBLING,
d8e538ec
TG
254 .match = IFLA_INFO_KIND,
255};
256
257static const NLType rtnl_link_info_types[IFLA_INFO_MAX + 1] = {
258 [IFLA_INFO_KIND] = { .type = NLA_STRING },
259 [IFLA_INFO_DATA] = { .type = NLA_UNION, .type_system_union = &rtnl_link_info_data_type_system_union},
260/*
261 [IFLA_INFO_XSTATS],
262 [IFLA_INFO_SLAVE_KIND] = { .type = NLA_STRING },
263 [IFLA_INFO_SLAVE_DATA] = { .type = NLA_NESTED },
264*/
265};
266
267static const NLTypeSystem rtnl_link_info_type_system = {
268 .max = ELEMENTSOF(rtnl_link_info_types) - 1,
269 .types = rtnl_link_info_types,
270};
271
4af7b60d 272static const struct NLType rtnl_prot_info_bridge_port_types[IFLA_BRPORT_MAX + 1] = {
d0159fdc
SS
273 [IFLA_BRPORT_STATE] = { .type = NLA_U8 },
274 [IFLA_BRPORT_COST] = { .type = NLA_U32 },
275 [IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 },
276 [IFLA_BRPORT_MODE] = { .type = NLA_U8 },
277 [IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
278 [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
279 [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 },
280 [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 },
281};
282
4af7b60d
TG
283static const NLTypeSystem rtnl_prot_info_type_systems[AF_MAX] = {
284 [AF_BRIDGE] = { .max = ELEMENTSOF(rtnl_prot_info_bridge_port_types) - 1,
285 .types = rtnl_prot_info_bridge_port_types },
286};
287
288static const NLTypeSystemUnion rtnl_prot_info_type_system_union = {
289 .num = AF_MAX,
290 .type_systems = rtnl_prot_info_type_systems,
291 .match_type = NL_MATCH_PROTOCOL,
d0159fdc
SS
292};
293
c149ae08
TG
294static const struct NLType rtnl_af_spec_inet6_types[IFLA_INET6_MAX + 1] = {
295 [IFLA_INET6_FLAGS] = { .type = NLA_U32 },
296/*
297 IFLA_INET6_CONF,
298 IFLA_INET6_STATS,
299 IFLA_INET6_MCAST,
300 IFLA_INET6_CACHEINFO,
301 IFLA_INET6_ICMP6STATS,
302*/
303 [IFLA_INET6_TOKEN] = { .type = NLA_IN_ADDR },
304 [IFLA_INET6_ADDR_GEN_MODE] = { .type = NLA_U8 },
305};
306
73cb1c14
TG
307static const NLTypeSystem rtnl_af_spec_inet6_type_system = {
308 .max = ELEMENTSOF(rtnl_af_spec_inet6_types) - 1,
309 .types = rtnl_af_spec_inet6_types,
c149ae08
TG
310};
311
73cb1c14
TG
312static const NLType rtnl_af_spec_types[AF_MAX + 1] = {
313 [AF_INET6] = { .type = NLA_NESTED, .type_system = &rtnl_af_spec_inet6_type_system },
314};
315
316static const NLTypeSystem rtnl_af_spec_type_system = {
317 .max = ELEMENTSOF(rtnl_af_spec_types) - 1,
318 .types = rtnl_af_spec_types,
c149ae08
TG
319};
320
d0159fdc 321static const NLType rtnl_link_types[IFLA_MAX + 1 ] = {
d8e538ec
TG
322 [IFLA_ADDRESS] = { .type = NLA_ETHER_ADDR, },
323 [IFLA_BROADCAST] = { .type = NLA_ETHER_ADDR, },
324 [IFLA_IFNAME] = { .type = NLA_STRING, .size = IFNAMSIZ - 1, },
325 [IFLA_MTU] = { .type = NLA_U32 },
326 [IFLA_LINK] = { .type = NLA_U32 },
327/*
328 [IFLA_QDISC],
329 [IFLA_STATS],
330 [IFLA_COST],
331 [IFLA_PRIORITY],
332*/
333 [IFLA_MASTER] = { .type = NLA_U32 },
334/*
335 [IFLA_WIRELESS],
d8e538ec 336*/
4af7b60d 337 [IFLA_PROTINFO] = { .type = NLA_UNION, .type_system_union = &rtnl_prot_info_type_system_union },
d8e538ec
TG
338 [IFLA_TXQLEN] = { .type = NLA_U32 },
339/*
340 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
341*/
342 [IFLA_WEIGHT] = { .type = NLA_U32 },
343 [IFLA_OPERSTATE] = { .type = NLA_U8 },
344 [IFLA_LINKMODE] = { .type = NLA_U8 },
345 [IFLA_LINKINFO] = { .type = NLA_NESTED, .type_system = &rtnl_link_info_type_system },
346 [IFLA_NET_NS_PID] = { .type = NLA_U32 },
347 [IFLA_IFALIAS] = { .type = NLA_STRING, .size = IFALIASZ - 1 },
348/*
349 [IFLA_NUM_VF],
350 [IFLA_VFINFO_LIST] = {. type = NLA_NESTED, },
351 [IFLA_STATS64],
352 [IFLA_VF_PORTS] = { .type = NLA_NESTED },
353 [IFLA_PORT_SELF] = { .type = NLA_NESTED },
c149ae08 354*/
73cb1c14 355 [IFLA_AF_SPEC] = { .type = NLA_NESTED, .type_system = &rtnl_af_spec_type_system },
c149ae08 356/*
d8e538ec
TG
357 [IFLA_VF_PORTS],
358 [IFLA_PORT_SELF],
359 [IFLA_AF_SPEC],
360*/
361 [IFLA_GROUP] = { .type = NLA_U32 },
362 [IFLA_NET_NS_FD] = { .type = NLA_U32 },
363 [IFLA_EXT_MASK] = { .type = NLA_U32 },
364 [IFLA_PROMISCUITY] = { .type = NLA_U32 },
365 [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 },
366 [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
367 [IFLA_CARRIER] = { .type = NLA_U8 },
368/*
369 [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
370*/
371};
372
373static const NLTypeSystem rtnl_link_type_system = {
374 .max = ELEMENTSOF(rtnl_link_types) - 1,
375 .types = rtnl_link_types,
376};
377
de79f906
LP
378/* IFA_FLAGS was defined in kernel 3.14, but we still support older
379 * kernels where IFA_MAX is lower. */
380static const NLType rtnl_address_types[CONST_MAX(IFA_MAX, IFA_FLAGS) + 1] = {
d8e538ec
TG
381 [IFA_ADDRESS] = { .type = NLA_IN_ADDR },
382 [IFA_LOCAL] = { .type = NLA_IN_ADDR },
383 [IFA_LABEL] = { .type = NLA_STRING, .size = IFNAMSIZ - 1 },
384 [IFA_BROADCAST] = { .type = NLA_IN_ADDR }, /* 6? */
aba496a5 385 [IFA_CACHEINFO] = { .type = NLA_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) },
d8e538ec
TG
386/*
387 [IFA_ANYCAST],
d8e538ec
TG
388 [IFA_MULTICAST],
389*/
d8e538ec 390 [IFA_FLAGS] = { .type = NLA_U32 },
d8e538ec
TG
391};
392
393static const NLTypeSystem rtnl_address_type_system = {
394 .max = ELEMENTSOF(rtnl_address_types) - 1,
395 .types = rtnl_address_types,
396};
397
398static const NLType rtnl_route_types[RTA_MAX + 1] = {
399 [RTA_DST] = { .type = NLA_IN_ADDR }, /* 6? */
400 [RTA_SRC] = { .type = NLA_IN_ADDR }, /* 6? */
401 [RTA_IIF] = { .type = NLA_U32 },
402 [RTA_OIF] = { .type = NLA_U32 },
403 [RTA_GATEWAY] = { .type = NLA_IN_ADDR },
404 [RTA_PRIORITY] = { .type = NLA_U32 },
405 [RTA_PREFSRC] = { .type = NLA_IN_ADDR }, /* 6? */
406/*
407 [RTA_METRICS] = { .type = NLA_NESTED },
408 [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) },
409*/
410 [RTA_FLOW] = { .type = NLA_U32 }, /* 6? */
411/*
412 RTA_CACHEINFO,
413 RTA_TABLE,
414 RTA_MARK,
415 RTA_MFC_STATS,
416*/
417};
418
419static const NLTypeSystem rtnl_route_type_system = {
420 .max = ELEMENTSOF(rtnl_route_types) - 1,
421 .types = rtnl_route_types,
422};
423
e559b384
TG
424static const NLType rtnl_neigh_types[NDA_MAX + 1] = {
425 [NDA_DST] = { .type = NLA_IN_ADDR },
426 [NDA_LLADDR] = { .type = NLA_ETHER_ADDR },
b98b483b
AR
427 [NDA_CACHEINFO] = { .type = NLA_CACHE_INFO, .size = sizeof(struct nda_cacheinfo) },
428 [NDA_PROBES] = { .type = NLA_U32 },
429 [NDA_VLAN] = { .type = NLA_U16 },
430 [NDA_PORT] = { .type = NLA_U16 },
431 [NDA_VNI] = { .type = NLA_U32 },
432 [NDA_IFINDEX] = { .type = NLA_U32 },
e559b384
TG
433};
434
435static const NLTypeSystem rtnl_neigh_type_system = {
436 .max = ELEMENTSOF(rtnl_neigh_types) - 1,
437 .types = rtnl_neigh_types,
438};
439
d8e538ec 440static const NLType rtnl_types[RTM_MAX + 1] = {
ea342a99 441 [NLMSG_DONE] = { .type = NLA_META, .size = 0 },
d8e538ec
TG
442 [NLMSG_ERROR] = { .type = NLA_META, .size = sizeof(struct nlmsgerr) },
443 [RTM_NEWLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
444 [RTM_DELLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
445 [RTM_GETLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
446 [RTM_SETLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
447 [RTM_NEWADDR] = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
448 [RTM_DELADDR] = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
449 [RTM_GETADDR] = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
450 [RTM_NEWROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
451 [RTM_DELROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
452 [RTM_GETROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
e559b384
TG
453 [RTM_NEWNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
454 [RTM_DELNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
455 [RTM_GETNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
d8e538ec
TG
456};
457
458const NLTypeSystem rtnl_type_system = {
459 .max = ELEMENTSOF(rtnl_types) - 1,
460 .types = rtnl_types,
461};
462
463int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) {
464 const NLType *nl_type;
465
466 assert(ret);
467
468 if (!type_system)
469 type_system = &rtnl_type_system;
470
471 assert(type_system->types);
472
473 if (type > type_system->max)
15411c0c 474 return -EOPNOTSUPP;
d8e538ec
TG
475
476 nl_type = &type_system->types[type];
477
478 if (nl_type->type == NLA_UNSPEC)
15411c0c 479 return -EOPNOTSUPP;
d8e538ec
TG
480
481 *ret = nl_type;
482
483 return 0;
484}
485
486int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type) {
487 const NLType *nl_type;
488 int r;
489
490 assert(ret);
491
492 r = type_system_get_type(type_system, &nl_type, type);
493 if (r < 0)
494 return r;
495
f8a6ca1b 496 assert(nl_type->type == NLA_NESTED);
d8e538ec
TG
497 assert(nl_type->type_system);
498
499 *ret = nl_type->type_system;
500
501 return 0;
502}
503
504int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type) {
505 const NLType *nl_type;
506 int r;
507
508 assert(ret);
509
510 r = type_system_get_type(type_system, &nl_type, type);
511 if (r < 0)
512 return r;
513
f8a6ca1b 514 assert(nl_type->type == NLA_UNION);
d8e538ec
TG
515 assert(nl_type->type_system_union);
516
517 *ret = nl_type->type_system_union;
518
519 return 0;
520}
521
522int type_system_union_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key) {
523 int type;
524
525 assert(type_system_union);
f8a6ca1b 526 assert(type_system_union->match_type == NL_MATCH_SIBLING);
d8e538ec
TG
527 assert(type_system_union->lookup);
528 assert(type_system_union->type_systems);
529 assert(ret);
530 assert(key);
531
532 type = type_system_union->lookup(key);
533 if (type < 0)
15411c0c 534 return -EOPNOTSUPP;
d8e538ec
TG
535
536 assert(type < type_system_union->num);
537
538 *ret = &type_system_union->type_systems[type];
539
540 return 0;
541}
4af7b60d
TG
542
543int type_system_union_protocol_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, uint16_t protocol) {
544 const NLTypeSystem *type_system;
545
546 assert(type_system_union);
547 assert(type_system_union->type_systems);
f8a6ca1b 548 assert(type_system_union->match_type == NL_MATCH_PROTOCOL);
4af7b60d 549 assert(ret);
4af7b60d
TG
550
551 if (protocol >= type_system_union->num)
15411c0c 552 return -EOPNOTSUPP;
4af7b60d
TG
553
554 type_system = &type_system_union->type_systems[protocol];
09c41fee 555 if (type_system->max == 0)
15411c0c 556 return -EOPNOTSUPP;
4af7b60d
TG
557
558 *ret = type_system;
559
560 return 0;
561}