libnl  3.6.0
vxlan.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * Copyright (c) 2013 Yasunobu Chiba <yasu@dsl.gr.jp>
4  */
5 
6 /**
7  * @ingroup link
8  * @defgroup vxlan VXLAN
9  * Virtual eXtensible Local Area Network link module
10  *
11  * @details
12  * \b Link Type Name: "vxlan"
13  *
14  * @route_doc{link_vxlan, VXLAN Documentation}
15  *
16  * @{
17  */
18 
19 #include <netlink-private/netlink.h>
20 #include <netlink/netlink.h>
21 #include <netlink/attr.h>
22 #include <netlink/utils.h>
23 #include <netlink/object.h>
24 #include <netlink/route/rtnl.h>
25 #include <netlink-private/route/link/api.h>
26 #include <netlink/route/link/vxlan.h>
27 
28 #include <linux/if_link.h>
29 
30 /** @cond SKIP */
31 #define VXLAN_ATTR_ID (1<<0)
32 #define VXLAN_ATTR_GROUP (1<<1)
33 #define VXLAN_ATTR_LINK (1<<2)
34 #define VXLAN_ATTR_LOCAL (1<<3)
35 #define VXLAN_ATTR_TTL (1<<4)
36 #define VXLAN_ATTR_TOS (1<<5)
37 #define VXLAN_ATTR_LEARNING (1<<6)
38 #define VXLAN_ATTR_AGEING (1<<7)
39 #define VXLAN_ATTR_LIMIT (1<<8)
40 #define VXLAN_ATTR_PORT_RANGE (1<<9)
41 #define VXLAN_ATTR_PROXY (1<<10)
42 #define VXLAN_ATTR_RSC (1<<11)
43 #define VXLAN_ATTR_L2MISS (1<<12)
44 #define VXLAN_ATTR_L3MISS (1<<13)
45 #define VXLAN_ATTR_GROUP6 (1<<14)
46 #define VXLAN_ATTR_LOCAL6 (1<<15)
47 #define VXLAN_ATTR_PORT (1<<16)
48 #define VXLAN_ATTR_UDP_CSUM (1<<17)
49 #define VXLAN_ATTR_UDP_ZERO_CSUM6_TX (1<<18)
50 #define VXLAN_ATTR_UDP_ZERO_CSUM6_RX (1<<19)
51 #define VXLAN_ATTR_REMCSUM_TX (1<<20)
52 #define VXLAN_ATTR_REMCSUM_RX (1<<21)
53 #define VXLAN_ATTR_COLLECT_METADATA (1<<22)
54 #define VXLAN_ATTR_LABEL (1<<23)
55 #define VXLAN_ATTR_FLAGS (1<<24)
56 
57 struct vxlan_info
58 {
59  uint32_t vxi_id;
60  uint32_t vxi_group;
61  struct in6_addr vxi_group6;
62  uint32_t vxi_link;
63  uint32_t vxi_local;
64  struct in6_addr vxi_local6;
65  uint8_t vxi_ttl;
66  uint8_t vxi_tos;
67  uint8_t vxi_learning;
68  uint8_t vxi_flags;
69  uint32_t vxi_ageing;
70  uint32_t vxi_limit;
71  struct ifla_vxlan_port_range vxi_port_range;
72  uint8_t vxi_proxy;
73  uint8_t vxi_rsc;
74  uint8_t vxi_l2miss;
75  uint8_t vxi_l3miss;
76  uint16_t vxi_port;
77  uint8_t vxi_udp_csum;
78  uint8_t vxi_udp_zero_csum6_tx;
79  uint8_t vxi_udp_zero_csum6_rx;
80  uint8_t vxi_remcsum_tx;
81  uint8_t vxi_remcsum_rx;
82  uint8_t vxi_collect_metadata;
83  uint32_t vxi_label;
84  uint32_t ce_mask;
85 };
86 
87 /** @endcond */
88 
89 static struct nla_policy vxlan_policy[IFLA_VXLAN_MAX+1] = {
90  [IFLA_VXLAN_ID] = { .type = NLA_U32 },
91  [IFLA_VXLAN_GROUP] = { .minlen = sizeof(uint32_t) },
92  [IFLA_VXLAN_GROUP6] = { .minlen = sizeof(struct in6_addr) },
93  [IFLA_VXLAN_LINK] = { .type = NLA_U32 },
94  [IFLA_VXLAN_LOCAL] = { .minlen = sizeof(uint32_t) },
95  [IFLA_VXLAN_LOCAL6] = { .minlen = sizeof(struct in6_addr) },
96  [IFLA_VXLAN_TTL] = { .type = NLA_U8 },
97  [IFLA_VXLAN_TOS] = { .type = NLA_U8 },
98  [IFLA_VXLAN_LABEL] = { .type = NLA_U32 },
99  [IFLA_VXLAN_LEARNING] = { .type = NLA_U8 },
100  [IFLA_VXLAN_AGEING] = { .type = NLA_U32 },
101  [IFLA_VXLAN_LIMIT] = { .type = NLA_U32 },
102  [IFLA_VXLAN_PORT_RANGE] = { .minlen = sizeof(struct ifla_vxlan_port_range) },
103  [IFLA_VXLAN_PROXY] = { .type = NLA_U8 },
104  [IFLA_VXLAN_RSC] = { .type = NLA_U8 },
105  [IFLA_VXLAN_L2MISS] = { .type = NLA_U8 },
106  [IFLA_VXLAN_L3MISS] = { .type = NLA_U8 },
107  [IFLA_VXLAN_COLLECT_METADATA] = { .type = NLA_U8 },
108  [IFLA_VXLAN_PORT] = { .type = NLA_U16 },
109  [IFLA_VXLAN_UDP_CSUM] = { .type = NLA_U8 },
110  [IFLA_VXLAN_UDP_ZERO_CSUM6_TX] = { .type = NLA_U8 },
111  [IFLA_VXLAN_UDP_ZERO_CSUM6_RX] = { .type = NLA_U8 },
112  [IFLA_VXLAN_REMCSUM_TX] = { .type = NLA_U8 },
113  [IFLA_VXLAN_REMCSUM_RX] = { .type = NLA_U8 },
114  [IFLA_VXLAN_GBP] = { .type = NLA_FLAG, },
115  [IFLA_VXLAN_GPE] = { .type = NLA_FLAG, },
116  [IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG },
117 };
118 
119 static int vxlan_alloc(struct rtnl_link *link)
120 {
121  struct vxlan_info *vxi;
122 
123  if (link->l_info)
124  memset(link->l_info, 0, sizeof(*vxi));
125  else {
126  if ((vxi = calloc(1, sizeof(*vxi))) == NULL)
127  return -NLE_NOMEM;
128 
129  link->l_info = vxi;
130  }
131 
132  return 0;
133 }
134 
135 static int vxlan_parse(struct rtnl_link *link, struct nlattr *data,
136  struct nlattr *xstats)
137 {
138  struct nlattr *tb[IFLA_VXLAN_MAX+1];
139  struct vxlan_info *vxi;
140  int err;
141 
142  NL_DBG(3, "Parsing VXLAN link info\n");
143 
144  if ((err = nla_parse_nested(tb, IFLA_VXLAN_MAX, data, vxlan_policy)) < 0)
145  goto errout;
146 
147  if ((err = vxlan_alloc(link)) < 0)
148  goto errout;
149 
150  vxi = link->l_info;
151 
152  if (tb[IFLA_VXLAN_ID]) {
153  vxi->vxi_id = nla_get_u32(tb[IFLA_VXLAN_ID]);
154  vxi->ce_mask |= VXLAN_ATTR_ID;
155  }
156 
157  if (tb[IFLA_VXLAN_GROUP6]) {
158  nla_memcpy(&vxi->vxi_group6, tb[IFLA_VXLAN_GROUP6],
159  sizeof(vxi->vxi_group6));
160  vxi->ce_mask |= VXLAN_ATTR_GROUP6;
161  }
162 
163  if (tb[IFLA_VXLAN_GROUP]) {
164  nla_memcpy(&vxi->vxi_group, tb[IFLA_VXLAN_GROUP],
165  sizeof(vxi->vxi_group));
166  vxi->ce_mask |= VXLAN_ATTR_GROUP;
167  vxi->ce_mask &= ~VXLAN_ATTR_GROUP6;
168  }
169 
170  if (tb[IFLA_VXLAN_LINK]) {
171  vxi->vxi_link = nla_get_u32(tb[IFLA_VXLAN_LINK]);
172  vxi->ce_mask |= VXLAN_ATTR_LINK;
173  }
174 
175  if (tb[IFLA_VXLAN_LOCAL6]) {
176  nla_memcpy(&vxi->vxi_local6, tb[IFLA_VXLAN_LOCAL6],
177  sizeof(vxi->vxi_local6));
178  vxi->ce_mask |= VXLAN_ATTR_LOCAL6;
179  }
180 
181  if (tb[IFLA_VXLAN_LOCAL]) {
182  nla_memcpy(&vxi->vxi_local, tb[IFLA_VXLAN_LOCAL],
183  sizeof(vxi->vxi_local));
184  vxi->ce_mask |= VXLAN_ATTR_LOCAL;
185  vxi->ce_mask &= ~VXLAN_ATTR_LOCAL6;
186  }
187 
188  if (tb[IFLA_VXLAN_TTL]) {
189  vxi->vxi_ttl = nla_get_u8(tb[IFLA_VXLAN_TTL]);
190  vxi->ce_mask |= VXLAN_ATTR_TTL;
191  }
192 
193  if (tb[IFLA_VXLAN_TOS]) {
194  vxi->vxi_tos = nla_get_u8(tb[IFLA_VXLAN_TOS]);
195  vxi->ce_mask |= VXLAN_ATTR_TOS;
196  }
197 
198  if (tb[IFLA_VXLAN_LEARNING]) {
199  vxi->vxi_learning = nla_get_u8(tb[IFLA_VXLAN_LEARNING]);
200  vxi->ce_mask |= VXLAN_ATTR_LEARNING;
201  }
202 
203  if (tb[IFLA_VXLAN_AGEING]) {
204  vxi->vxi_ageing = nla_get_u32(tb[IFLA_VXLAN_AGEING]);
205  vxi->ce_mask |= VXLAN_ATTR_AGEING;
206  }
207 
208  if (tb[IFLA_VXLAN_LIMIT]) {
209  vxi->vxi_limit = nla_get_u32(tb[IFLA_VXLAN_LIMIT]);
210  vxi->ce_mask |= VXLAN_ATTR_LIMIT;
211  }
212 
213  if (tb[IFLA_VXLAN_PORT_RANGE]) {
214  nla_memcpy(&vxi->vxi_port_range, tb[IFLA_VXLAN_PORT_RANGE],
215  sizeof(vxi->vxi_port_range));
216  vxi->ce_mask |= VXLAN_ATTR_PORT_RANGE;
217  }
218 
219  if (tb[IFLA_VXLAN_PROXY]) {
220  vxi->vxi_proxy = nla_get_u8(tb[IFLA_VXLAN_PROXY]);
221  vxi->ce_mask |= VXLAN_ATTR_PROXY;
222  }
223 
224  if (tb[IFLA_VXLAN_RSC]) {
225  vxi->vxi_rsc = nla_get_u8(tb[IFLA_VXLAN_RSC]);
226  vxi->ce_mask |= VXLAN_ATTR_RSC;
227  }
228 
229  if (tb[IFLA_VXLAN_L2MISS]) {
230  vxi->vxi_l2miss = nla_get_u8(tb[IFLA_VXLAN_L2MISS]);
231  vxi->ce_mask |= VXLAN_ATTR_L2MISS;
232  }
233 
234  if (tb[IFLA_VXLAN_L3MISS]) {
235  vxi->vxi_l3miss = nla_get_u8(tb[IFLA_VXLAN_L3MISS]);
236  vxi->ce_mask |= VXLAN_ATTR_L3MISS;
237  }
238 
239  if (tb[IFLA_VXLAN_PORT]) {
240  vxi->vxi_port = nla_get_u16(tb[IFLA_VXLAN_PORT]);
241  vxi->ce_mask |= VXLAN_ATTR_PORT;
242  }
243 
244  if (tb[IFLA_VXLAN_UDP_CSUM]) {
245  vxi->vxi_udp_csum = nla_get_u8(tb[IFLA_VXLAN_UDP_CSUM]);
246  vxi->ce_mask |= VXLAN_ATTR_UDP_CSUM;
247  }
248 
249  if (tb[IFLA_VXLAN_UDP_ZERO_CSUM6_TX]) {
250  vxi->vxi_udp_zero_csum6_tx = nla_get_u8(tb[IFLA_VXLAN_UDP_ZERO_CSUM6_TX]);
251  vxi->ce_mask |= VXLAN_ATTR_UDP_ZERO_CSUM6_TX;
252  }
253 
254  if (tb[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]) {
255  vxi->vxi_udp_zero_csum6_rx = nla_get_u8(tb[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]);
256  vxi->ce_mask |= VXLAN_ATTR_UDP_ZERO_CSUM6_RX;
257  }
258 
259  if (tb[IFLA_VXLAN_REMCSUM_TX]) {
260  vxi->vxi_remcsum_tx = nla_get_u8(tb[IFLA_VXLAN_REMCSUM_TX]);
261  vxi->ce_mask |= VXLAN_ATTR_REMCSUM_TX;
262  }
263 
264  if (tb[IFLA_VXLAN_REMCSUM_RX]) {
265  vxi->vxi_remcsum_rx = nla_get_u8(tb[IFLA_VXLAN_REMCSUM_RX]);
266  vxi->ce_mask |= VXLAN_ATTR_REMCSUM_RX;
267  }
268 
269  if (tb[IFLA_VXLAN_GBP])
270  vxi->vxi_flags |= RTNL_LINK_VXLAN_F_GBP;
271 
272  if (tb[IFLA_VXLAN_REMCSUM_NOPARTIAL])
273  vxi->vxi_flags |= RTNL_LINK_VXLAN_F_REMCSUM_NOPARTIAL;
274 
275  if (tb[IFLA_VXLAN_COLLECT_METADATA]) {
276  vxi->vxi_collect_metadata = nla_get_u8(tb[IFLA_VXLAN_COLLECT_METADATA]);
277  vxi->ce_mask |= VXLAN_ATTR_COLLECT_METADATA;
278  }
279 
280  if (tb[IFLA_VXLAN_LABEL]) {
281  vxi->vxi_label = nla_get_u32(tb[IFLA_VXLAN_LABEL]);
282  vxi->ce_mask |= VXLAN_ATTR_LABEL;
283  }
284 
285  if (tb[IFLA_VXLAN_GPE])
286  vxi->vxi_flags |= RTNL_LINK_VXLAN_F_GPE;
287 
288  err = 0;
289 
290 errout:
291  return err;
292 }
293 
294 static void vxlan_free(struct rtnl_link *link)
295 {
296  struct vxlan_info *vxi = link->l_info;
297 
298  free(vxi);
299  link->l_info = NULL;
300 }
301 
302 static void vxlan_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
303 {
304  struct vxlan_info *vxi = link->l_info;
305 
306  nl_dump(p, "vxlan-id %u", vxi->vxi_id);
307 }
308 
309 static void vxlan_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
310 {
311  struct vxlan_info *vxi = link->l_info;
312  char *name, addr[INET6_ADDRSTRLEN];
313  struct rtnl_link *parent;
314 
315  nl_dump_line(p, " vxlan-id %u\n", vxi->vxi_id);
316 
317  if (vxi->ce_mask & VXLAN_ATTR_GROUP) {
318  nl_dump(p, " group ");
319  if (inet_ntop(AF_INET, &vxi->vxi_group, addr, sizeof(addr)))
320  nl_dump_line(p, "%s\n", addr);
321  else
322  nl_dump_line(p, "%#x\n", ntohs(vxi->vxi_group));
323  } else if (vxi->ce_mask & VXLAN_ATTR_GROUP6) {
324  nl_dump(p, " group ");
325  if (inet_ntop(AF_INET6, &vxi->vxi_group6, addr, sizeof(addr)))
326  nl_dump_line(p, "%s\n", addr);
327  else
328  nl_dump_line(p, "%#x\n", vxi->vxi_group6);
329  }
330 
331  if (vxi->ce_mask & VXLAN_ATTR_LINK) {
332  nl_dump(p, " link ");
333 
334  name = NULL;
335  parent = link_lookup(link->ce_cache, vxi->vxi_link);
336  if (parent)
337  name = rtnl_link_get_name(parent);
338 
339  if (name)
340  nl_dump_line(p, "%s\n", name);
341  else
342  nl_dump_line(p, "%u\n", vxi->vxi_link);
343  }
344 
345  if (vxi->ce_mask & VXLAN_ATTR_LOCAL) {
346  nl_dump(p, " local ");
347  if (inet_ntop(AF_INET, &vxi->vxi_local, addr, sizeof(addr)))
348  nl_dump_line(p, "%s\n", addr);
349  else
350  nl_dump_line(p, "%#x\n", ntohs(vxi->vxi_local));
351  } else if (vxi->ce_mask & VXLAN_ATTR_LOCAL6) {
352  nl_dump(p, " local ");
353  if (inet_ntop(AF_INET6, &vxi->vxi_local6, addr, sizeof(addr)))
354  nl_dump_line(p, "%s\n", addr);
355  else
356  nl_dump_line(p, "%#x\n", vxi->vxi_local6);
357  }
358 
359 
360  if (vxi->ce_mask & VXLAN_ATTR_TTL) {
361  nl_dump(p, " ttl ");
362  if(vxi->vxi_ttl)
363  nl_dump_line(p, "%u\n", vxi->vxi_ttl);
364  else
365  nl_dump_line(p, "inherit\n");
366  }
367 
368  if (vxi->ce_mask & VXLAN_ATTR_TOS) {
369  nl_dump(p, " tos ");
370  if (vxi->vxi_tos == 1)
371  nl_dump_line(p, "inherit\n", vxi->vxi_tos);
372  else
373  nl_dump_line(p, "%#x\n", vxi->vxi_tos);
374  }
375 
376  if (vxi->ce_mask & VXLAN_ATTR_LEARNING) {
377  nl_dump(p, " learning ");
378  if (vxi->vxi_learning)
379  nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_learning);
380  else
381  nl_dump_line(p, "disabled\n");
382  }
383 
384  if (vxi->ce_mask & VXLAN_ATTR_AGEING) {
385  nl_dump(p, " ageing ");
386  if (vxi->vxi_ageing)
387  nl_dump_line(p, "%u seconds\n", vxi->vxi_ageing);
388  else
389  nl_dump_line(p, "disabled\n");
390  }
391 
392  if (vxi->ce_mask & VXLAN_ATTR_LIMIT) {
393  nl_dump(p, " limit ");
394  if (vxi->vxi_limit)
395  nl_dump_line(p, "%u\n", vxi->vxi_limit);
396  else
397  nl_dump_line(p, "unlimited\n");
398  }
399 
400  if (vxi->ce_mask & VXLAN_ATTR_PORT_RANGE)
401  nl_dump_line(p, " port range %u - %u\n",
402  ntohs(vxi->vxi_port_range.low),
403  ntohs(vxi->vxi_port_range.high));
404 
405  if (vxi->ce_mask & VXLAN_ATTR_PROXY) {
406  nl_dump(p, " proxy ");
407  if (vxi->vxi_proxy)
408  nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_proxy);
409  else
410  nl_dump_line(p, "disabled\n");
411  }
412 
413  if (vxi->ce_mask & VXLAN_ATTR_RSC) {
414  nl_dump(p, " rsc ");
415  if (vxi->vxi_rsc)
416  nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_rsc);
417  else
418  nl_dump_line(p, "disabled\n");
419  }
420 
421  if (vxi->ce_mask & VXLAN_ATTR_L2MISS) {
422  nl_dump(p, " l2miss ");
423  if (vxi->vxi_l2miss)
424  nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_l2miss);
425  else
426  nl_dump_line(p, "disabled\n");
427  }
428 
429  if (vxi->ce_mask & VXLAN_ATTR_L3MISS) {
430  nl_dump(p, " l3miss ");
431  if (vxi->vxi_l3miss)
432  nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_l3miss);
433  else
434  nl_dump_line(p, "disabled\n");
435  }
436 
437  if (vxi->ce_mask & VXLAN_ATTR_PORT) {
438  nl_dump(p, " port ");
439  nl_dump_line(p, "%u\n", ntohs(vxi->vxi_port));
440  }
441 
442  if (vxi->ce_mask & VXLAN_ATTR_UDP_CSUM) {
443  nl_dump(p, " UDP checksums ");
444  if (vxi->vxi_udp_csum)
445  nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_udp_csum);
446  else
447  nl_dump_line(p, "disabled\n");
448  }
449 
450  if (vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_TX) {
451  nl_dump(p, " udp-zero-csum6-tx ");
452  if (vxi->vxi_udp_zero_csum6_tx)
453  nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_udp_zero_csum6_tx);
454  else
455  nl_dump_line(p, "disabled\n");
456  }
457 
458  if (vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_RX) {
459  nl_dump(p, " udp-zero-csum6-rx ");
460  if (vxi->vxi_udp_zero_csum6_rx)
461  nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_udp_zero_csum6_rx);
462  else
463  nl_dump_line(p, "disabled\n");
464  }
465 
466  if (vxi->ce_mask & VXLAN_ATTR_REMCSUM_TX) {
467  nl_dump(p, " remcsum-tx ");
468  if (vxi->vxi_remcsum_tx)
469  nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_remcsum_tx);
470  else
471  nl_dump_line(p, "disabled\n");
472  }
473 
474  if (vxi->ce_mask & VXLAN_ATTR_REMCSUM_RX) {
475  nl_dump(p, " remcsum-rx ");
476  if (vxi->vxi_remcsum_rx)
477  nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_remcsum_rx);
478  else
479  nl_dump_line(p, "disabled\n");
480  }
481 
482  if (vxi->vxi_flags & RTNL_LINK_VXLAN_F_GBP)
483  nl_dump(p, " gbp\n");
484 
485  if (vxi->vxi_flags & RTNL_LINK_VXLAN_F_REMCSUM_NOPARTIAL)
486  nl_dump(p, " rncsum-nopartial\n");
487 
488  if (vxi->ce_mask & VXLAN_ATTR_COLLECT_METADATA) {
489  nl_dump(p, " remcsum-rx ");
490  if (vxi->vxi_collect_metadata)
491  nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_collect_metadata);
492  else
493  nl_dump_line(p, "disabled\n");
494  }
495 
496  if (vxi->ce_mask & VXLAN_ATTR_LABEL) {
497  nl_dump(p, " label ");
498  nl_dump_line(p, "%u\n", ntohl(vxi->vxi_label));
499  }
500 
501  if (vxi->vxi_flags & RTNL_LINK_VXLAN_F_GPE)
502  nl_dump(p, " gpe\n");
503 }
504 
505 static int vxlan_clone(struct rtnl_link *dst, struct rtnl_link *src)
506 {
507  struct vxlan_info *vdst, *vsrc = src->l_info;
508  int err;
509 
510  dst->l_info = NULL;
511  if ((err = rtnl_link_set_type(dst, "vxlan")) < 0)
512  return err;
513  vdst = dst->l_info;
514 
515  if (!vdst || !vsrc)
516  return -NLE_NOMEM;
517 
518  memcpy(vdst, vsrc, sizeof(struct vxlan_info));
519 
520  return 0;
521 }
522 
523 static int vxlan_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
524 {
525  struct vxlan_info *vxi = link->l_info;
526  struct nlattr *data;
527 
528  if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
529  return -NLE_MSGSIZE;
530 
531  if (vxi->ce_mask & VXLAN_ATTR_ID)
532  NLA_PUT_U32(msg, IFLA_VXLAN_ID, vxi->vxi_id);
533 
534  if (vxi->ce_mask & VXLAN_ATTR_GROUP)
535  NLA_PUT(msg, IFLA_VXLAN_GROUP, sizeof(vxi->vxi_group), &vxi->vxi_group);
536 
537  if (vxi->ce_mask & VXLAN_ATTR_GROUP6)
538  NLA_PUT(msg, IFLA_VXLAN_GROUP6, sizeof(vxi->vxi_group6), &vxi->vxi_group6);
539 
540  if (vxi->ce_mask & VXLAN_ATTR_LINK)
541  NLA_PUT_U32(msg, IFLA_VXLAN_LINK, vxi->vxi_link);
542 
543  if (vxi->ce_mask & VXLAN_ATTR_LOCAL)
544  NLA_PUT(msg, IFLA_VXLAN_LOCAL, sizeof(vxi->vxi_local), &vxi->vxi_local);
545 
546  if (vxi->ce_mask & VXLAN_ATTR_LOCAL6)
547  NLA_PUT(msg, IFLA_VXLAN_LOCAL6, sizeof(vxi->vxi_local6), &vxi->vxi_local6);
548 
549  if (vxi->ce_mask & VXLAN_ATTR_TTL)
550  NLA_PUT_U8(msg, IFLA_VXLAN_TTL, vxi->vxi_ttl);
551 
552  if (vxi->ce_mask & VXLAN_ATTR_TOS)
553  NLA_PUT_U8(msg, IFLA_VXLAN_TOS, vxi->vxi_tos);
554 
555  if (vxi->ce_mask & VXLAN_ATTR_LEARNING)
556  NLA_PUT_U8(msg, IFLA_VXLAN_LEARNING, vxi->vxi_learning);
557 
558  if (vxi->ce_mask & VXLAN_ATTR_AGEING)
559  NLA_PUT_U32(msg, IFLA_VXLAN_AGEING, vxi->vxi_ageing);
560 
561  if (vxi->ce_mask & VXLAN_ATTR_LIMIT)
562  NLA_PUT_U32(msg, IFLA_VXLAN_LIMIT, vxi->vxi_limit);
563 
564  if (vxi->ce_mask & VXLAN_ATTR_PORT_RANGE)
565  NLA_PUT(msg, IFLA_VXLAN_PORT_RANGE, sizeof(vxi->vxi_port_range),
566  &vxi->vxi_port_range);
567 
568  if (vxi->ce_mask & VXLAN_ATTR_PROXY)
569  NLA_PUT_U8(msg, IFLA_VXLAN_PROXY, vxi->vxi_proxy);
570 
571  if (vxi->ce_mask & VXLAN_ATTR_RSC)
572  NLA_PUT_U8(msg, IFLA_VXLAN_RSC, vxi->vxi_rsc);
573 
574  if (vxi->ce_mask & VXLAN_ATTR_L2MISS)
575  NLA_PUT_U8(msg, IFLA_VXLAN_L2MISS, vxi->vxi_l2miss);
576 
577  if (vxi->ce_mask & VXLAN_ATTR_L3MISS)
578  NLA_PUT_U8(msg, IFLA_VXLAN_L3MISS, vxi->vxi_l3miss);
579 
580  if (vxi->ce_mask & VXLAN_ATTR_PORT)
581  NLA_PUT_U32(msg, IFLA_VXLAN_PORT, vxi->vxi_port);
582 
583  if (vxi->ce_mask & VXLAN_ATTR_UDP_CSUM)
584  NLA_PUT_U8(msg, IFLA_VXLAN_UDP_CSUM, vxi->vxi_udp_csum);
585 
586  if (vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_TX)
587  NLA_PUT_U8(msg, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, vxi->vxi_udp_zero_csum6_tx);
588 
589  if (vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_RX)
590  NLA_PUT_U8(msg, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, vxi->vxi_udp_zero_csum6_rx);
591 
592  if (vxi->ce_mask & VXLAN_ATTR_REMCSUM_TX)
593  NLA_PUT_U8(msg, IFLA_VXLAN_REMCSUM_TX, vxi->vxi_remcsum_tx);
594 
595  if (vxi->ce_mask & VXLAN_ATTR_REMCSUM_RX)
596  NLA_PUT_U8(msg, IFLA_VXLAN_REMCSUM_RX, vxi->vxi_remcsum_rx);
597 
598  if (vxi->vxi_flags & RTNL_LINK_VXLAN_F_GBP)
599  NLA_PUT_FLAG(msg, IFLA_VXLAN_GBP);
600 
601  if (vxi->vxi_flags & RTNL_LINK_VXLAN_F_REMCSUM_NOPARTIAL)
602  NLA_PUT_FLAG(msg, IFLA_VXLAN_REMCSUM_NOPARTIAL);
603 
604  if (vxi->ce_mask & VXLAN_ATTR_COLLECT_METADATA)
605  NLA_PUT_U8(msg, IFLA_VXLAN_COLLECT_METADATA, vxi->vxi_collect_metadata);
606 
607  if (vxi->ce_mask & VXLAN_ATTR_LABEL)
608  NLA_PUT_U32(msg, IFLA_VXLAN_LABEL, vxi->vxi_label);
609 
610  if (vxi->vxi_flags & RTNL_LINK_VXLAN_F_GPE)
611  NLA_PUT_FLAG(msg, IFLA_VXLAN_GPE);
612 
613  nla_nest_end(msg, data);
614 
615 nla_put_failure:
616 
617  return 0;
618 }
619 
620 static int vxlan_compare(struct rtnl_link *link_a, struct rtnl_link *link_b,
621  int flags)
622 {
623  struct vxlan_info *a = link_a->l_info;
624  struct vxlan_info *b = link_b->l_info;
625  int diff = 0;
626  uint32_t attrs = flags & LOOSE_COMPARISON ? b->ce_mask : ~0;
627 
628 #define VXLAN_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, VXLAN_ATTR_##ATTR, a, b, EXPR)
629 
630  diff |= VXLAN_DIFF(ID, a->vxi_id != b->vxi_id);
631  diff |= VXLAN_DIFF(GROUP, a->vxi_group != b->vxi_group);
632  diff |= VXLAN_DIFF(LINK, a->vxi_link != b->vxi_link);
633  diff |= VXLAN_DIFF(LOCAL, a->vxi_local != b->vxi_local);
634  diff |= VXLAN_DIFF(TOS, a->vxi_tos != b->vxi_tos);
635  diff |= VXLAN_DIFF(TTL, a->vxi_ttl != b->vxi_ttl);
636  diff |= VXLAN_DIFF(LEARNING, a->vxi_learning != b->vxi_learning);
637  diff |= VXLAN_DIFF(AGEING, a->vxi_ageing != b->vxi_ageing);
638  diff |= VXLAN_DIFF(LIMIT, a->vxi_limit != b->vxi_limit);
639  diff |= VXLAN_DIFF(PORT_RANGE,
640  a->vxi_port_range.low != b->vxi_port_range.low);
641  diff |= VXLAN_DIFF(PORT_RANGE,
642  a->vxi_port_range.high != b->vxi_port_range.high);
643  diff |= VXLAN_DIFF(PROXY, a->vxi_proxy != b->vxi_proxy);
644  diff |= VXLAN_DIFF(RSC, a->vxi_proxy != b->vxi_proxy);
645  diff |= VXLAN_DIFF(L2MISS, a->vxi_proxy != b->vxi_proxy);
646  diff |= VXLAN_DIFF(L3MISS, a->vxi_proxy != b->vxi_proxy);
647  diff |= VXLAN_DIFF(PORT, a->vxi_port != b->vxi_port);
648  diff |= VXLAN_DIFF(GROUP6, memcmp(&a->vxi_group6, &b->vxi_group6, sizeof(a->vxi_group6)) != 0);
649  diff |= VXLAN_DIFF(LOCAL6, memcmp(&a->vxi_local6, &b->vxi_local6, sizeof(a->vxi_local6)) != 0);
650  diff |= VXLAN_DIFF(UDP_CSUM, a->vxi_proxy != b->vxi_proxy);
651  diff |= VXLAN_DIFF(UDP_ZERO_CSUM6_TX, a->vxi_proxy != b->vxi_proxy);
652  diff |= VXLAN_DIFF(UDP_ZERO_CSUM6_RX, a->vxi_proxy != b->vxi_proxy);
653  diff |= VXLAN_DIFF(REMCSUM_TX, a->vxi_proxy != b->vxi_proxy);
654  diff |= VXLAN_DIFF(REMCSUM_RX, a->vxi_proxy != b->vxi_proxy);
655  diff |= VXLAN_DIFF(COLLECT_METADATA, a->vxi_collect_metadata != b->vxi_collect_metadata);
656  diff |= VXLAN_DIFF(LABEL, a->vxi_label != b->vxi_label);
657  diff |= VXLAN_DIFF(FLAGS, a->vxi_flags != b->vxi_flags);
658 #undef VXLAN_DIFF
659 
660  return diff;
661 }
662 
663 static struct rtnl_link_info_ops vxlan_info_ops = {
664  .io_name = "vxlan",
665  .io_alloc = vxlan_alloc,
666  .io_parse = vxlan_parse,
667  .io_dump = {
668  [NL_DUMP_LINE] = vxlan_dump_line,
669  [NL_DUMP_DETAILS] = vxlan_dump_details,
670  },
671  .io_clone = vxlan_clone,
672  .io_put_attrs = vxlan_put_attrs,
673  .io_free = vxlan_free,
674  .io_compare = vxlan_compare,
675 };
676 
677 /** @cond SKIP */
678 #define IS_VXLAN_LINK_ASSERT(link) \
679  if ((link)->l_info_ops != &vxlan_info_ops) { \
680  APPBUG("Link is not a vxlan link. set type \"vxlan\" first."); \
681  return -NLE_OPNOTSUPP; \
682  }
683 /** @endcond */
684 
685 /**
686  * @name VXLAN Object
687  * @{
688  */
689 
690 /**
691  * Allocate link object of type VXLAN
692  *
693  * @return Allocated link object or NULL.
694  */
696 {
697  struct rtnl_link *link;
698  int err;
699 
700  if (!(link = rtnl_link_alloc()))
701  return NULL;
702 
703  if ((err = rtnl_link_set_type(link, "vxlan")) < 0) {
704  rtnl_link_put(link);
705  return NULL;
706  }
707 
708  return link;
709 }
710 
711 /**
712  * Check if link is a VXLAN link
713  * @arg link Link object
714  *
715  * @return True if link is a VXLAN link, otherwise false is returned.
716  */
717 int rtnl_link_is_vxlan(struct rtnl_link *link)
718 {
719  return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "vxlan");
720 }
721 
722 /**
723  * Set VXLAN Network Identifier
724  * @arg link Link object
725  * @arg id VXLAN network identifier (or VXLAN segment identifier)
726  *
727  * @return 0 on success or a negative error code
728  */
729 int rtnl_link_vxlan_set_id(struct rtnl_link *link, uint32_t id)
730 {
731  struct vxlan_info *vxi = link->l_info;
732 
733  IS_VXLAN_LINK_ASSERT(link);
734 
735  if (id > VXLAN_ID_MAX)
736  return -NLE_INVAL;
737 
738  vxi->vxi_id = id;
739  vxi->ce_mask |= VXLAN_ATTR_ID;
740 
741  return 0;
742 }
743 
744 /**
745  * Get VXLAN Network Identifier
746  * @arg link Link object
747  * @arg id Pointer to store network identifier
748  *
749  * @return 0 on success or a negative error code
750  */
751 int rtnl_link_vxlan_get_id(struct rtnl_link *link, uint32_t *id)
752 {
753  struct vxlan_info *vxi = link->l_info;
754 
755  IS_VXLAN_LINK_ASSERT(link);
756 
757  if(!id)
758  return -NLE_INVAL;
759 
760  if (vxi->ce_mask & VXLAN_ATTR_ID)
761  *id = vxi->vxi_id;
762  else
763  return -NLE_AGAIN;
764 
765  return 0;
766 }
767 
768 /**
769  * Set VXLAN multicast IP address
770  * @arg link Link object
771  * @arg addr Multicast IP address to join
772  *
773  * @return 0 on success or a negative error code
774  */
775 int rtnl_link_vxlan_set_group(struct rtnl_link *link, struct nl_addr *addr)
776 {
777  struct vxlan_info *vxi = link->l_info;
778 
779  IS_VXLAN_LINK_ASSERT(link);
780 
781  if ((nl_addr_get_family(addr) == AF_INET) &&
782  (nl_addr_get_len(addr) == sizeof(vxi->vxi_group))) {
783  memcpy(&vxi->vxi_group, nl_addr_get_binary_addr(addr),
784  sizeof(vxi->vxi_group));
785  vxi->ce_mask |= VXLAN_ATTR_GROUP;
786  vxi->ce_mask &= ~VXLAN_ATTR_GROUP6;
787  } else if ((nl_addr_get_family(addr) == AF_INET6) &&
788  (nl_addr_get_len(addr) == sizeof(vxi->vxi_group6))) {
789  memcpy(&vxi->vxi_group6, nl_addr_get_binary_addr(addr),
790  sizeof(vxi->vxi_group6));
791  vxi->ce_mask |= VXLAN_ATTR_GROUP6;
792  vxi->ce_mask &= ~VXLAN_ATTR_GROUP;
793  } else
794  return -NLE_INVAL;
795 
796  return 0;
797 }
798 
799 /**
800  * Get VXLAN multicast IP address
801  * @arg link Link object
802  * @arg addr Pointer to store multicast IP address
803  *
804  * @return 0 on success or a negative error code
805  */
806 int rtnl_link_vxlan_get_group(struct rtnl_link *link, struct nl_addr **addr)
807 {
808  struct vxlan_info *vxi = link->l_info;
809 
810  IS_VXLAN_LINK_ASSERT(link);
811 
812  if (!addr)
813  return -NLE_INVAL;
814 
815  if (vxi->ce_mask & VXLAN_ATTR_GROUP)
816  *addr = nl_addr_build(AF_INET, &vxi->vxi_group, sizeof(vxi->vxi_group));
817  else if (vxi->ce_mask & VXLAN_ATTR_GROUP6)
818  *addr = nl_addr_build(AF_INET6, &vxi->vxi_group6, sizeof(vxi->vxi_group6));
819  else
820  return -NLE_AGAIN;
821 
822  return 0;
823 }
824 
825 /**
826  * Set physical device to use for VXLAN
827  * @arg link Link object
828  * @arg index Interface index
829  *
830  * @return 0 on success or a negative error code
831  */
832 int rtnl_link_vxlan_set_link(struct rtnl_link *link, uint32_t index)
833 {
834  struct vxlan_info *vxi = link->l_info;
835 
836  IS_VXLAN_LINK_ASSERT(link);
837 
838  vxi->vxi_link = index;
839  vxi->ce_mask |= VXLAN_ATTR_LINK;
840 
841  return 0;
842 }
843 
844 /**
845  * Get physical device to use for VXLAN
846  * @arg link Link object
847  * @arg index Pointer to store interface index
848  *
849  * @return 0 on success or a negative error code
850  */
851 int rtnl_link_vxlan_get_link(struct rtnl_link *link, uint32_t *index)
852 {
853  struct vxlan_info *vxi = link->l_info;
854 
855  IS_VXLAN_LINK_ASSERT(link);
856 
857  if (!index)
858  return -NLE_INVAL;
859 
860  if (!(vxi->ce_mask & VXLAN_ATTR_LINK))
861  return -NLE_AGAIN;
862 
863  *index = vxi->vxi_link;
864 
865  return 0;
866 }
867 
868 /**
869  * Set source address to use for VXLAN
870  * @arg link Link object
871  * @arg addr Local address
872  *
873  * @return 0 on success or a negative error code
874  */
875 int rtnl_link_vxlan_set_local(struct rtnl_link *link, struct nl_addr *addr)
876 {
877  struct vxlan_info *vxi = link->l_info;
878 
879  IS_VXLAN_LINK_ASSERT(link);
880 
881  if ((nl_addr_get_family(addr) == AF_INET) &&
882  (nl_addr_get_len(addr) == sizeof(vxi->vxi_local))) {
883  memcpy(&vxi->vxi_local, nl_addr_get_binary_addr(addr),
884  sizeof(vxi->vxi_local));
885  vxi->ce_mask |= VXLAN_ATTR_LOCAL;
886  vxi->ce_mask &= ~VXLAN_ATTR_LOCAL6;
887  } else if ((nl_addr_get_family(addr) == AF_INET6) &&
888  (nl_addr_get_len(addr) == sizeof(vxi->vxi_local6))) {
889  memcpy(&vxi->vxi_local6, nl_addr_get_binary_addr(addr),
890  sizeof(vxi->vxi_local6));
891  vxi->ce_mask |= VXLAN_ATTR_LOCAL6;
892  vxi->ce_mask &= ~VXLAN_ATTR_LOCAL;
893  } else
894  return -NLE_INVAL;
895 
896  return 0;
897 }
898 
899 /**
900  * Get source address to use for VXLAN
901  * @arg link Link object
902  * @arg addr Pointer to store local address
903  *
904  * @return 0 on success or a negative error code
905  */
906 int rtnl_link_vxlan_get_local(struct rtnl_link *link, struct nl_addr **addr)
907 {
908  struct vxlan_info *vxi = link->l_info;
909 
910  IS_VXLAN_LINK_ASSERT(link);
911 
912  if (!addr)
913  return -NLE_INVAL;
914 
915  if (vxi->ce_mask & VXLAN_ATTR_LOCAL)
916  *addr = nl_addr_build(AF_INET, &vxi->vxi_local, sizeof(vxi->vxi_local));
917  else if (vxi->ce_mask & VXLAN_ATTR_LOCAL6)
918  *addr = nl_addr_build(AF_INET6, &vxi->vxi_local6, sizeof(vxi->vxi_local6));
919  else
920  return -NLE_AGAIN;
921 
922  return 0;
923 }
924 
925 /**
926  * Set IP TTL value to use for VXLAN
927  * @arg link Link object
928  * @arg ttl TTL value
929  *
930  * @return 0 on success or a negative error code
931  */
932 int rtnl_link_vxlan_set_ttl(struct rtnl_link *link, uint8_t ttl)
933 {
934  struct vxlan_info *vxi = link->l_info;
935 
936  IS_VXLAN_LINK_ASSERT(link);
937 
938  vxi->vxi_ttl = ttl;
939  vxi->ce_mask |= VXLAN_ATTR_TTL;
940 
941  return 0;
942 }
943 
944 /**
945  * Get IP TTL value to use for VXLAN
946  * @arg link Link object
947  *
948  * @return TTL value on success or a negative error code
949  */
951 {
952  struct vxlan_info *vxi = link->l_info;
953 
954  IS_VXLAN_LINK_ASSERT(link);
955 
956  if (!(vxi->ce_mask & VXLAN_ATTR_TTL))
957  return -NLE_AGAIN;
958 
959  return vxi->vxi_ttl;
960 }
961 
962 /**
963  * Set IP ToS value to use for VXLAN
964  * @arg link Link object
965  * @arg tos ToS value
966  *
967  * @return 0 on success or a negative error code
968  */
969 int rtnl_link_vxlan_set_tos(struct rtnl_link *link, uint8_t tos)
970 {
971  struct vxlan_info *vxi = link->l_info;
972 
973  IS_VXLAN_LINK_ASSERT(link);
974 
975  vxi->vxi_tos = tos;
976  vxi->ce_mask |= VXLAN_ATTR_TOS;
977 
978  return 0;
979 }
980 
981 /**
982  * Get IP ToS value to use for VXLAN
983  * @arg link Link object
984  *
985  * @return ToS value on success or a negative error code
986  */
988 {
989  struct vxlan_info *vxi = link->l_info;
990 
991  IS_VXLAN_LINK_ASSERT(link);
992 
993  if (!(vxi->ce_mask & VXLAN_ATTR_TOS))
994  return -NLE_AGAIN;
995 
996  return vxi->vxi_tos;
997 }
998 
999 /**
1000  * Set VXLAN learning status
1001  * @arg link Link object
1002  * @arg learning Learning status value
1003  *
1004  * @return 0 on success or a negative error code
1005  */
1006 int rtnl_link_vxlan_set_learning(struct rtnl_link *link, uint8_t learning)
1007 {
1008  struct vxlan_info *vxi = link->l_info;
1009 
1010  IS_VXLAN_LINK_ASSERT(link);
1011 
1012  vxi->vxi_learning = learning;
1013  vxi->ce_mask |= VXLAN_ATTR_LEARNING;
1014 
1015  return 0;
1016 }
1017 
1018 /**
1019  * Get VXLAN learning status
1020  * @arg link Link object
1021  *
1022  * @return Learning status value on success or a negative error code
1023  */
1025 {
1026  struct vxlan_info *vxi = link->l_info;
1027 
1028  IS_VXLAN_LINK_ASSERT(link);
1029 
1030  if (!(vxi->ce_mask & VXLAN_ATTR_LEARNING))
1031  return -NLE_AGAIN;
1032 
1033  return vxi->vxi_learning;
1034 }
1035 
1036 /**
1037  * Enable VXLAN address learning
1038  * @arg link Link object
1039  *
1040  * @return 0 on success or a negative error code
1041  */
1043 {
1044  return rtnl_link_vxlan_set_learning(link, 1);
1045 }
1046 
1047 /**
1048  * Disable VXLAN address learning
1049  * @arg link Link object
1050  *
1051  * @return 0 on success or a negative error code
1052  */
1054 {
1055  return rtnl_link_vxlan_set_learning(link, 0);
1056 }
1057 
1058 /**
1059  * Set expiration timer value to use for VXLAN
1060  * @arg link Link object
1061  * @arg expiry Expiration timer value
1062  *
1063  * @return 0 on success or a negative error code
1064  */
1065 int rtnl_link_vxlan_set_ageing(struct rtnl_link *link, uint32_t expiry)
1066 {
1067  struct vxlan_info *vxi = link->l_info;
1068 
1069  IS_VXLAN_LINK_ASSERT(link);
1070 
1071  vxi->vxi_ageing = expiry;
1072  vxi->ce_mask |= VXLAN_ATTR_AGEING;
1073 
1074  return 0;
1075 }
1076 
1077 /**
1078  * Get expiration timer value to use for VXLAN
1079  * @arg link Link object
1080  * @arg expiry Pointer to store expiration timer value
1081  *
1082  * @return 0 on success or a negative error code
1083  */
1084 int rtnl_link_vxlan_get_ageing(struct rtnl_link *link, uint32_t *expiry)
1085 {
1086  struct vxlan_info *vxi = link->l_info;
1087 
1088  IS_VXLAN_LINK_ASSERT(link);
1089 
1090  if (!expiry)
1091  return -NLE_INVAL;
1092 
1093  if (vxi->ce_mask & VXLAN_ATTR_AGEING)
1094  *expiry = vxi->vxi_ageing;
1095  else
1096  return -NLE_AGAIN;
1097 
1098  return 0;
1099 }
1100 
1101 /**
1102  * Set maximum number of forwarding database entries to use for VXLAN
1103  * @arg link Link object
1104  * @arg limit Maximum number
1105  *
1106  * @return 0 on success or a negative error code
1107  */
1108 int rtnl_link_vxlan_set_limit(struct rtnl_link *link, uint32_t limit)
1109 {
1110  struct vxlan_info *vxi = link->l_info;
1111 
1112  IS_VXLAN_LINK_ASSERT(link);
1113 
1114  vxi->vxi_limit = limit;
1115  vxi->ce_mask |= VXLAN_ATTR_LIMIT;
1116 
1117  return 0;
1118 }
1119 
1120 /**
1121  * Get maximum number of forwarding database entries to use for VXLAN
1122  * @arg link Link object
1123  * @arg limit Pointer to store maximum number
1124  *
1125  * @return 0 on success or a negative error code
1126  */
1127 int rtnl_link_vxlan_get_limit(struct rtnl_link *link, uint32_t *limit)
1128 {
1129  struct vxlan_info *vxi = link->l_info;
1130 
1131  IS_VXLAN_LINK_ASSERT(link);
1132 
1133  if (!limit)
1134  return -NLE_INVAL;
1135 
1136  if (vxi->ce_mask & VXLAN_ATTR_LIMIT)
1137  *limit = vxi->vxi_limit;
1138  else
1139  return -NLE_AGAIN;
1140 
1141  return 0;
1142 }
1143 
1144 /**
1145  * Set range of UDP port numbers to use for VXLAN
1146  * @arg link Link object
1147  * @arg range Port number range
1148  *
1149  * @return 0 on success or a negative error code
1150  */
1152  struct ifla_vxlan_port_range *range)
1153 {
1154  struct vxlan_info *vxi = link->l_info;
1155 
1156  IS_VXLAN_LINK_ASSERT(link);
1157 
1158  if (!range)
1159  return -NLE_INVAL;
1160 
1161  memcpy(&vxi->vxi_port_range, range, sizeof(vxi->vxi_port_range));
1162  vxi->ce_mask |= VXLAN_ATTR_PORT_RANGE;
1163 
1164  return 0;
1165 }
1166 
1167 /**
1168  * Get range of UDP port numbers to use for VXLAN
1169  * @arg link Link object
1170  * @arg range Pointer to store port range
1171  *
1172  * @return 0 on success or a negative error code
1173  */
1175  struct ifla_vxlan_port_range *range)
1176 {
1177  struct vxlan_info *vxi = link->l_info;
1178 
1179  IS_VXLAN_LINK_ASSERT(link);
1180 
1181  if (!range)
1182  return -NLE_INVAL;
1183 
1184  if (vxi->ce_mask & VXLAN_ATTR_PORT_RANGE)
1185  memcpy(range, &vxi->vxi_port_range, sizeof(*range));
1186  else
1187  return -NLE_AGAIN;
1188 
1189  return 0;
1190 }
1191 
1192 /**
1193  * Set ARP proxy status to use for VXLAN
1194  * @arg link Link object
1195  * @arg proxy Status value
1196  *
1197  * @return 0 on success or a negative error code
1198  */
1199 int rtnl_link_vxlan_set_proxy(struct rtnl_link *link, uint8_t proxy)
1200 {
1201  struct vxlan_info *vxi = link->l_info;
1202 
1203  IS_VXLAN_LINK_ASSERT(link);
1204 
1205  vxi->vxi_proxy = proxy;
1206  vxi->ce_mask |= VXLAN_ATTR_PROXY;
1207 
1208  return 0;
1209 }
1210 
1211 /**
1212  * Get ARP proxy status to use for VXLAN
1213  * @arg link Link object
1214  *
1215  * @return Status value on success or a negative error code
1216  */
1218 {
1219  struct vxlan_info *vxi = link->l_info;
1220 
1221  IS_VXLAN_LINK_ASSERT(link);
1222 
1223  if (!(vxi->ce_mask & VXLAN_ATTR_PROXY))
1224  return -NLE_AGAIN;
1225 
1226  return vxi->vxi_proxy;
1227 }
1228 
1229 /**
1230  * Enable ARP proxy
1231  * @arg link Link object
1232  *
1233  * @return 0 on success or a negative error code
1234  */
1236 {
1237  return rtnl_link_vxlan_set_proxy(link, 1);
1238 }
1239 
1240 /**
1241  * Disable ARP proxy
1242  * @arg link Link object
1243  *
1244  * @return 0 on success or a negative error code
1245  */
1247 {
1248  return rtnl_link_vxlan_set_proxy(link, 0);
1249 }
1250 
1251 /**
1252  * Set Route Short Circuit status to use for VXLAN
1253  * @arg link Link object
1254  * @arg rsc Status value
1255  *
1256  * @return 0 on success or a negative error code
1257  */
1258 int rtnl_link_vxlan_set_rsc(struct rtnl_link *link, uint8_t rsc)
1259 {
1260  struct vxlan_info *vxi = link->l_info;
1261 
1262  IS_VXLAN_LINK_ASSERT(link);
1263 
1264  vxi->vxi_rsc = rsc;
1265  vxi->ce_mask |= VXLAN_ATTR_RSC;
1266 
1267  return 0;
1268 }
1269 
1270 /**
1271  * Get Route Short Circuit status to use for VXLAN
1272  * @arg link Link object
1273  *
1274  * @return Status value on success or a negative error code
1275  */
1277 {
1278  struct vxlan_info *vxi = link->l_info;
1279 
1280  IS_VXLAN_LINK_ASSERT(link);
1281 
1282  if (!(vxi->ce_mask & VXLAN_ATTR_RSC))
1283  return -NLE_AGAIN;
1284 
1285  return vxi->vxi_rsc;
1286 }
1287 
1288 /**
1289  * Enable Route Short Circuit
1290  * @arg link Link object
1291  *
1292  * @return 0 on success or a negative error code
1293  */
1295 {
1296  return rtnl_link_vxlan_set_rsc(link, 1);
1297 }
1298 
1299 /**
1300  * Disable Route Short Circuit
1301  * @arg link Link object
1302  *
1303  * @return 0 on success or a negative error code
1304  */
1306 {
1307  return rtnl_link_vxlan_set_rsc(link, 0);
1308 }
1309 
1310 /**
1311  * Set netlink LLADDR miss notification status to use for VXLAN
1312  * @arg link Link object
1313  * @arg miss Status value
1314  *
1315  * @return 0 on success or a negative error code
1316  */
1317 int rtnl_link_vxlan_set_l2miss(struct rtnl_link *link, uint8_t miss)
1318 {
1319  struct vxlan_info *vxi = link->l_info;
1320 
1321  IS_VXLAN_LINK_ASSERT(link);
1322 
1323  vxi->vxi_l2miss = miss;
1324  vxi->ce_mask |= VXLAN_ATTR_L2MISS;
1325 
1326  return 0;
1327 }
1328 
1329 /**
1330  * Get netlink LLADDR miss notification status to use for VXLAN
1331  * @arg link Link object
1332  *
1333  * @return Status value on success or a negative error code
1334  */
1336 {
1337  struct vxlan_info *vxi = link->l_info;
1338 
1339  IS_VXLAN_LINK_ASSERT(link);
1340 
1341  if (!(vxi->ce_mask & VXLAN_ATTR_L2MISS))
1342  return -NLE_AGAIN;
1343 
1344  return vxi->vxi_l2miss;
1345 }
1346 
1347 /**
1348  * Enable netlink LLADDR miss notifications
1349  * @arg link Link object
1350  *
1351  * @return 0 on success or a negative error code
1352  */
1354 {
1355  return rtnl_link_vxlan_set_l2miss(link, 1);
1356 }
1357 
1358 /**
1359  * Disable netlink LLADDR miss notifications
1360  * @arg link Link object
1361  *
1362  * @return 0 on success or a negative error code
1363  */
1365 {
1366  return rtnl_link_vxlan_set_l2miss(link, 0);
1367 }
1368 
1369 /**
1370  * Set netlink IP ADDR miss notification status to use for VXLAN
1371  * @arg link Link object
1372  * @arg miss Status value
1373  *
1374  * @return 0 on success or a negative error code
1375  */
1376 int rtnl_link_vxlan_set_l3miss(struct rtnl_link *link, uint8_t miss)
1377 {
1378  struct vxlan_info *vxi = link->l_info;
1379 
1380  IS_VXLAN_LINK_ASSERT(link);
1381 
1382  vxi->vxi_l3miss = miss;
1383  vxi->ce_mask |= VXLAN_ATTR_L3MISS;
1384 
1385  return 0;
1386 }
1387 
1388 /**
1389  * Get netlink IP ADDR miss notification status to use for VXLAN
1390  * @arg link Link object
1391  *
1392  * @return Status value on success or a negative error code
1393  */
1395 {
1396  struct vxlan_info *vxi = link->l_info;
1397 
1398  IS_VXLAN_LINK_ASSERT(link);
1399 
1400  if (!(vxi->ce_mask & VXLAN_ATTR_L3MISS))
1401  return -NLE_AGAIN;
1402 
1403  return vxi->vxi_l3miss;
1404 }
1405 
1406 /**
1407  * Enable netlink IP ADDR miss notifications
1408  * @arg link Link object
1409  *
1410  * @return 0 on success or a negative error code
1411  */
1413 {
1414  return rtnl_link_vxlan_set_l3miss(link, 1);
1415 }
1416 
1417 /**
1418  * Disable netlink IP ADDR miss notifications
1419  * @arg link Link object
1420  *
1421  * @return 0 on success or a negative error code
1422  */
1424 {
1425  return rtnl_link_vxlan_set_l3miss(link, 0);
1426 }
1427 
1428 /**
1429  * Set UDP destination port to use for VXLAN
1430  * @arg link Link object
1431  * @arg port Destination port
1432  *
1433  * @return 0 on success or a negative error code
1434  */
1435 int rtnl_link_vxlan_set_port(struct rtnl_link *link, uint32_t port)
1436 {
1437  struct vxlan_info *vxi = link->l_info;
1438 
1439  IS_VXLAN_LINK_ASSERT(link);
1440 
1441  vxi->vxi_port = htons(port);
1442  vxi->ce_mask |= VXLAN_ATTR_PORT;
1443 
1444  return 0;
1445 }
1446 
1447 /**
1448  * Get UDP destination port to use for VXLAN
1449  * @arg link Link object
1450  * @arg port Pointer to store destination port
1451  *
1452  * @return 0 on success or a negative error code
1453  */
1454 int rtnl_link_vxlan_get_port(struct rtnl_link *link, uint32_t *port)
1455 {
1456  struct vxlan_info *vxi = link->l_info;
1457 
1458  IS_VXLAN_LINK_ASSERT(link);
1459 
1460  if (!port)
1461  return -NLE_INVAL;
1462 
1463  if (!(vxi->ce_mask & VXLAN_ATTR_PORT))
1464  return -NLE_NOATTR;
1465 
1466  *port = ntohs(vxi->vxi_port);
1467 
1468  return 0;
1469 }
1470 
1471 /**
1472  * Set UDP checksum status to use for VXLAN
1473  * @arg link Link object
1474  * @arg csum Status value
1475  *
1476  * @return 0 on success or a negative error code
1477  */
1478 int rtnl_link_vxlan_set_udp_csum(struct rtnl_link *link, uint8_t csum)
1479 {
1480  struct vxlan_info *vxi = link->l_info;
1481 
1482  IS_VXLAN_LINK_ASSERT(link);
1483 
1484  vxi->vxi_udp_csum = csum;
1485  vxi->ce_mask |= VXLAN_ATTR_UDP_CSUM;
1486 
1487  return 0;
1488 }
1489 
1490 /**
1491  * Get UDP checksum status to use for VXLAN
1492  * @arg link Link object
1493  *
1494  * @return Status value on success or a negative error code
1495  */
1497 {
1498  struct vxlan_info *vxi = link->l_info;
1499 
1500  IS_VXLAN_LINK_ASSERT(link);
1501 
1502  if (!(vxi->ce_mask & VXLAN_ATTR_UDP_CSUM))
1503  return -NLE_NOATTR;
1504 
1505  return vxi->vxi_udp_csum;
1506 }
1507 
1508 /**
1509  * Set skip UDP checksum transmitted over IPv6 status to use for VXLAN
1510  * @arg link Link object
1511  * @arg csum Status value
1512  *
1513  * @return 0 on success or a negative error code
1514  */
1515 int rtnl_link_vxlan_set_udp_zero_csum6_tx(struct rtnl_link *link, uint8_t csum)
1516 {
1517  struct vxlan_info *vxi = link->l_info;
1518 
1519  IS_VXLAN_LINK_ASSERT(link);
1520 
1521  vxi->vxi_udp_zero_csum6_tx = csum;
1522  vxi->ce_mask |= VXLAN_ATTR_UDP_ZERO_CSUM6_TX;
1523 
1524  return 0;
1525 }
1526 
1527 /**
1528  * Get skip UDP checksum transmitted over IPv6 status to use for VXLAN
1529  * @arg link Link object
1530  *
1531  * @return Status value on success or a negative error code
1532  */
1534 {
1535  struct vxlan_info *vxi = link->l_info;
1536 
1537  IS_VXLAN_LINK_ASSERT(link);
1538 
1539  if (!(vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_TX))
1540  return -NLE_NOATTR;
1541 
1542  return vxi->vxi_udp_zero_csum6_tx;
1543 }
1544 
1545 /**
1546  * Set skip UDP checksum received over IPv6 status to use for VXLAN
1547  * @arg link Link object
1548  * @arg csum Status value
1549  *
1550  * @return 0 on success or a negative error code
1551  */
1552 int rtnl_link_vxlan_set_udp_zero_csum6_rx(struct rtnl_link *link, uint8_t csum)
1553 {
1554  struct vxlan_info *vxi = link->l_info;
1555 
1556  IS_VXLAN_LINK_ASSERT(link);
1557 
1558  vxi->vxi_udp_zero_csum6_rx = csum;
1559  vxi->ce_mask |= VXLAN_ATTR_UDP_ZERO_CSUM6_RX;
1560 
1561  return 0;
1562 }
1563 
1564 /**
1565  * Get skip UDP checksum received over IPv6 status to use for VXLAN
1566  * @arg link Link object
1567  *
1568  * @return Status value on success or a negative error code
1569  */
1571 {
1572  struct vxlan_info *vxi = link->l_info;
1573 
1574  IS_VXLAN_LINK_ASSERT(link);
1575 
1576  if (!(vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_RX))
1577  return -NLE_NOATTR;
1578 
1579  return vxi->vxi_udp_zero_csum6_rx;
1580 }
1581 
1582 /**
1583  * Set remote offload transmit checksum status to use for VXLAN
1584  * @arg link Link object
1585  * @arg csum Status value
1586  *
1587  * @return 0 on success or a negative error code
1588  */
1589 int rtnl_link_vxlan_set_remcsum_tx(struct rtnl_link *link, uint8_t csum)
1590 {
1591  struct vxlan_info *vxi = link->l_info;
1592 
1593  IS_VXLAN_LINK_ASSERT(link);
1594 
1595  vxi->vxi_remcsum_tx = csum;
1596  vxi->ce_mask |= VXLAN_ATTR_REMCSUM_TX;
1597 
1598  return 0;
1599 }
1600 
1601 /**
1602  * Get remote offload transmit checksum status to use for VXLAN
1603  * @arg link Link object
1604  *
1605  * @return Status value on success or a negative error code
1606  */
1608 {
1609  struct vxlan_info *vxi = link->l_info;
1610 
1611  IS_VXLAN_LINK_ASSERT(link);
1612 
1613  if (!(vxi->ce_mask & VXLAN_ATTR_REMCSUM_TX))
1614  return -NLE_NOATTR;
1615 
1616  return vxi->vxi_remcsum_tx;
1617 }
1618 
1619 /**
1620  * Set remote offload receive checksum status to use for VXLAN
1621  * @arg link Link object
1622  * @arg csum Status value
1623  *
1624  * @return 0 on success or a negative error code
1625  */
1626 int rtnl_link_vxlan_set_remcsum_rx(struct rtnl_link *link, uint8_t csum)
1627 {
1628  struct vxlan_info *vxi = link->l_info;
1629 
1630  IS_VXLAN_LINK_ASSERT(link);
1631 
1632  vxi->vxi_remcsum_rx = csum;
1633  vxi->ce_mask |= VXLAN_ATTR_REMCSUM_RX;
1634 
1635  return 0;
1636 }
1637 
1638 /**
1639  * Get remote offload receive checksum status to use for VXLAN
1640  * @arg link Link object
1641  *
1642  * @return Status value on success or a negative error code
1643  */
1645 {
1646  struct vxlan_info *vxi = link->l_info;
1647 
1648  IS_VXLAN_LINK_ASSERT(link);
1649 
1650  if (!(vxi->ce_mask & VXLAN_ATTR_REMCSUM_RX))
1651  return -NLE_NOATTR;
1652 
1653  return vxi->vxi_remcsum_rx;
1654 }
1655 
1656 /**
1657  * Set collect metadata status to use for VXLAN
1658  * @arg link Link object
1659  * @arg collect Status value
1660  *
1661  * @return 0 on success or a negative error code
1662  */
1663 int rtnl_link_vxlan_set_collect_metadata(struct rtnl_link *link, uint8_t collect)
1664 {
1665  struct vxlan_info *vxi = link->l_info;
1666 
1667  IS_VXLAN_LINK_ASSERT(link);
1668 
1669  vxi->vxi_collect_metadata = collect;
1670  vxi->ce_mask |= VXLAN_ATTR_COLLECT_METADATA;
1671 
1672  return 0;
1673 }
1674 
1675 /**
1676  * Get collect metadata status to use for VXLAN
1677  * @arg link Link object
1678  *
1679  * @return Status value on success or a negative error code
1680  */
1682 {
1683  struct vxlan_info *vxi = link->l_info;
1684 
1685  IS_VXLAN_LINK_ASSERT(link);
1686 
1687  if (!(vxi->ce_mask & VXLAN_ATTR_COLLECT_METADATA))
1688  return -NLE_NOATTR;
1689 
1690  return vxi->vxi_collect_metadata;
1691 }
1692 
1693 /**
1694  * Set flow label to use for VXLAN
1695  * @arg link Link object
1696  * @arg label Destination label
1697  *
1698  * @return 0 on success or a negative error code
1699  */
1700 int rtnl_link_vxlan_set_label(struct rtnl_link *link, uint32_t label)
1701 {
1702  struct vxlan_info *vxi = link->l_info;
1703 
1704  IS_VXLAN_LINK_ASSERT(link);
1705 
1706  vxi->vxi_label = htonl(label);
1707  vxi->ce_mask |= VXLAN_ATTR_LABEL;
1708 
1709  return 0;
1710 }
1711 
1712 /**
1713  * Get flow label to use for VXLAN
1714  * @arg link Link object
1715  * @arg label Pointer to store destination label
1716  *
1717  * @return 0 on success or a negative error code
1718  */
1719 int rtnl_link_vxlan_get_label(struct rtnl_link *link, uint32_t *label)
1720 {
1721  struct vxlan_info *vxi = link->l_info;
1722 
1723  IS_VXLAN_LINK_ASSERT(link);
1724 
1725  if (!label)
1726  return -NLE_INVAL;
1727 
1728  if (!(vxi->ce_mask & VXLAN_ATTR_LABEL))
1729  return -NLE_NOATTR;
1730 
1731  *label = ntohl(vxi->vxi_label);
1732 
1733  return 0;
1734 }
1735 
1736 /**
1737  * Set VXLAN flags RTNL_LINK_VXLAN_F_*
1738  * @arg link Link object
1739  * @flags Which flags to set
1740  * @arg enable Boolean enabling or disabling flag
1741  *
1742  * @return 0 on success or a negative error code
1743  */
1744 int rtnl_link_vxlan_set_flags(struct rtnl_link *link, uint32_t flags, int enable)
1745 {
1746  struct vxlan_info *vxi = link->l_info;
1747 
1748  IS_VXLAN_LINK_ASSERT(link);
1749 
1750  if (flags & ~(RTNL_LINK_VXLAN_F_GBP | RTNL_LINK_VXLAN_F_GPE | RTNL_LINK_VXLAN_F_REMCSUM_NOPARTIAL))
1751  return -NLE_INVAL;
1752 
1753  if (enable)
1754  vxi->vxi_flags |= flags;
1755  else
1756  vxi->vxi_flags &= ~flags;
1757 
1758  return 0;
1759 }
1760 
1761 /**
1762  * Get VXLAN flags RTNL_LINK_VXLAN_F_*
1763  * @arg link Link object
1764  * @arg out_flags Output value for flags. Must be present.
1765  *
1766  * @return Zero on success or a negative error code
1767  */
1768 int rtnl_link_vxlan_get_flags(struct rtnl_link *link, uint32_t *out_flags)
1769 {
1770  struct vxlan_info *vxi = link->l_info;
1771 
1772  IS_VXLAN_LINK_ASSERT(link);
1773 
1774  *out_flags = vxi->vxi_flags;
1775  return 0;
1776 }
1777 
1778 /** @} */
1779 
1780 static void __init vxlan_init(void)
1781 {
1782  rtnl_link_register_info(&vxlan_info_ops);
1783 }
1784 
1785 static void __exit vxlan_exit(void)
1786 {
1787  rtnl_link_unregister_info(&vxlan_info_ops);
1788 }
1789 
1790 /** @} */
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
Definition: addr.c:935
struct nl_addr * nl_addr_build(int family, const void *buf, size_t size)
Allocate abstract address based on a binary address.
Definition: addr.c:211
int nl_addr_get_family(const struct nl_addr *addr)
Return address family.
Definition: addr.c:887
unsigned int nl_addr_get_len(const struct nl_addr *addr)
Get length of binary address of abstract address object.
Definition: addr.c:947
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:699
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
Definition: attr.c:649
#define NLA_PUT_FLAG(msg, attrtype)
Add flag attribute to netlink message.
Definition: attr.h:265
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
Definition: attr.h:194
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
Definition: attr.h:159
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
Definition: attr.h:230
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
Definition: attr.c:599
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
Definition: attr.c:346
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
Definition: attr.c:895
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, const struct nla_policy *policy)
Create attribute index based on nested attribute.
Definition: attr.c:1013
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
Definition: attr.c:958
@ NLA_U8
8 bit integer
Definition: attr.h:35
@ NLA_FLAG
Flag.
Definition: attr.h:40
@ NLA_U16
16 bit integer
Definition: attr.h:36
@ NLA_U32
32 bit integer
Definition: attr.h:37
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:955
@ NL_DUMP_LINE
Dump object briefly on one line.
Definition: types.h:16
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Definition: types.h:17
int rtnl_link_vxlan_get_tos(struct rtnl_link *link)
Get IP ToS value to use for VXLAN.
Definition: vxlan.c:987
int rtnl_link_vxlan_get_rsc(struct rtnl_link *link)
Get Route Short Circuit status to use for VXLAN.
Definition: vxlan.c:1276
int rtnl_link_vxlan_disable_learning(struct rtnl_link *link)
Disable VXLAN address learning.
Definition: vxlan.c:1053
int rtnl_link_vxlan_get_port_range(struct rtnl_link *link, struct ifla_vxlan_port_range *range)
Get range of UDP port numbers to use for VXLAN.
Definition: vxlan.c:1174
int rtnl_link_vxlan_set_udp_zero_csum6_rx(struct rtnl_link *link, uint8_t csum)
Set skip UDP checksum received over IPv6 status to use for VXLAN.
Definition: vxlan.c:1552
int rtnl_link_vxlan_get_ttl(struct rtnl_link *link)
Get IP TTL value to use for VXLAN.
Definition: vxlan.c:950
int rtnl_link_vxlan_get_learning(struct rtnl_link *link)
Get VXLAN learning status.
Definition: vxlan.c:1024
int rtnl_link_vxlan_set_learning(struct rtnl_link *link, uint8_t learning)
Set VXLAN learning status.
Definition: vxlan.c:1006
int rtnl_link_vxlan_get_label(struct rtnl_link *link, uint32_t *label)
Get flow label to use for VXLAN.
Definition: vxlan.c:1719
int rtnl_link_vxlan_set_tos(struct rtnl_link *link, uint8_t tos)
Set IP ToS value to use for VXLAN.
Definition: vxlan.c:969
int rtnl_link_vxlan_set_port(struct rtnl_link *link, uint32_t port)
Set UDP destination port to use for VXLAN.
Definition: vxlan.c:1435
int rtnl_link_vxlan_get_proxy(struct rtnl_link *link)
Get ARP proxy status to use for VXLAN.
Definition: vxlan.c:1217
int rtnl_link_vxlan_enable_rsc(struct rtnl_link *link)
Enable Route Short Circuit.
Definition: vxlan.c:1294
int rtnl_link_vxlan_set_group(struct rtnl_link *link, struct nl_addr *addr)
Set VXLAN multicast IP address.
Definition: vxlan.c:775
int rtnl_link_vxlan_enable_proxy(struct rtnl_link *link)
Enable ARP proxy.
Definition: vxlan.c:1235
int rtnl_link_vxlan_disable_l3miss(struct rtnl_link *link)
Disable netlink IP ADDR miss notifications.
Definition: vxlan.c:1423
int rtnl_link_vxlan_set_local(struct rtnl_link *link, struct nl_addr *addr)
Set source address to use for VXLAN.
Definition: vxlan.c:875
int rtnl_link_vxlan_set_remcsum_rx(struct rtnl_link *link, uint8_t csum)
Set remote offload receive checksum status to use for VXLAN.
Definition: vxlan.c:1626
int rtnl_link_vxlan_set_flags(struct rtnl_link *link, uint32_t flags, int enable)
Set VXLAN flags RTNL_LINK_VXLAN_F_*.
Definition: vxlan.c:1744
int rtnl_link_vxlan_set_udp_csum(struct rtnl_link *link, uint8_t csum)
Set UDP checksum status to use for VXLAN.
Definition: vxlan.c:1478
int rtnl_link_vxlan_get_udp_zero_csum6_rx(struct rtnl_link *link)
Get skip UDP checksum received over IPv6 status to use for VXLAN.
Definition: vxlan.c:1570
int rtnl_link_vxlan_set_link(struct rtnl_link *link, uint32_t index)
Set physical device to use for VXLAN.
Definition: vxlan.c:832
int rtnl_link_vxlan_enable_l2miss(struct rtnl_link *link)
Enable netlink LLADDR miss notifications.
Definition: vxlan.c:1353
int rtnl_link_vxlan_get_flags(struct rtnl_link *link, uint32_t *out_flags)
Get VXLAN flags RTNL_LINK_VXLAN_F_*.
Definition: vxlan.c:1768
int rtnl_link_vxlan_get_remcsum_rx(struct rtnl_link *link)
Get remote offload receive checksum status to use for VXLAN.
Definition: vxlan.c:1644
int rtnl_link_vxlan_get_group(struct rtnl_link *link, struct nl_addr **addr)
Get VXLAN multicast IP address.
Definition: vxlan.c:806
int rtnl_link_vxlan_set_port_range(struct rtnl_link *link, struct ifla_vxlan_port_range *range)
Set range of UDP port numbers to use for VXLAN.
Definition: vxlan.c:1151
int rtnl_link_vxlan_set_collect_metadata(struct rtnl_link *link, uint8_t collect)
Set collect metadata status to use for VXLAN.
Definition: vxlan.c:1663
int rtnl_link_vxlan_get_l2miss(struct rtnl_link *link)
Get netlink LLADDR miss notification status to use for VXLAN.
Definition: vxlan.c:1335
int rtnl_link_vxlan_set_id(struct rtnl_link *link, uint32_t id)
Set VXLAN Network Identifier.
Definition: vxlan.c:729
struct rtnl_link * rtnl_link_vxlan_alloc(void)
Allocate link object of type VXLAN.
Definition: vxlan.c:695
int rtnl_link_vxlan_get_collect_metadata(struct rtnl_link *link)
Get collect metadata status to use for VXLAN.
Definition: vxlan.c:1681
int rtnl_link_vxlan_disable_l2miss(struct rtnl_link *link)
Disable netlink LLADDR miss notifications.
Definition: vxlan.c:1364
int rtnl_link_vxlan_set_limit(struct rtnl_link *link, uint32_t limit)
Set maximum number of forwarding database entries to use for VXLAN.
Definition: vxlan.c:1108
int rtnl_link_vxlan_set_label(struct rtnl_link *link, uint32_t label)
Set flow label to use for VXLAN.
Definition: vxlan.c:1700
int rtnl_link_is_vxlan(struct rtnl_link *link)
Check if link is a VXLAN link.
Definition: vxlan.c:717
int rtnl_link_vxlan_set_remcsum_tx(struct rtnl_link *link, uint8_t csum)
Set remote offload transmit checksum status to use for VXLAN.
Definition: vxlan.c:1589
int rtnl_link_vxlan_get_local(struct rtnl_link *link, struct nl_addr **addr)
Get source address to use for VXLAN.
Definition: vxlan.c:906
int rtnl_link_vxlan_get_link(struct rtnl_link *link, uint32_t *index)
Get physical device to use for VXLAN.
Definition: vxlan.c:851
int rtnl_link_vxlan_set_proxy(struct rtnl_link *link, uint8_t proxy)
Set ARP proxy status to use for VXLAN.
Definition: vxlan.c:1199
int rtnl_link_vxlan_enable_learning(struct rtnl_link *link)
Enable VXLAN address learning.
Definition: vxlan.c:1042
int rtnl_link_vxlan_set_ttl(struct rtnl_link *link, uint8_t ttl)
Set IP TTL value to use for VXLAN.
Definition: vxlan.c:932
int rtnl_link_vxlan_get_udp_zero_csum6_tx(struct rtnl_link *link)
Get skip UDP checksum transmitted over IPv6 status to use for VXLAN.
Definition: vxlan.c:1533
int rtnl_link_vxlan_get_l3miss(struct rtnl_link *link)
Get netlink IP ADDR miss notification status to use for VXLAN.
Definition: vxlan.c:1394
int rtnl_link_vxlan_get_remcsum_tx(struct rtnl_link *link)
Get remote offload transmit checksum status to use for VXLAN.
Definition: vxlan.c:1607
int rtnl_link_vxlan_get_port(struct rtnl_link *link, uint32_t *port)
Get UDP destination port to use for VXLAN.
Definition: vxlan.c:1454
int rtnl_link_vxlan_disable_proxy(struct rtnl_link *link)
Disable ARP proxy.
Definition: vxlan.c:1246
int rtnl_link_vxlan_set_l2miss(struct rtnl_link *link, uint8_t miss)
Set netlink LLADDR miss notification status to use for VXLAN.
Definition: vxlan.c:1317
int rtnl_link_vxlan_set_ageing(struct rtnl_link *link, uint32_t expiry)
Set expiration timer value to use for VXLAN.
Definition: vxlan.c:1065
int rtnl_link_vxlan_get_id(struct rtnl_link *link, uint32_t *id)
Get VXLAN Network Identifier.
Definition: vxlan.c:751
int rtnl_link_vxlan_disable_rsc(struct rtnl_link *link)
Disable Route Short Circuit.
Definition: vxlan.c:1305
int rtnl_link_vxlan_set_rsc(struct rtnl_link *link, uint8_t rsc)
Set Route Short Circuit status to use for VXLAN.
Definition: vxlan.c:1258
int rtnl_link_vxlan_set_l3miss(struct rtnl_link *link, uint8_t miss)
Set netlink IP ADDR miss notification status to use for VXLAN.
Definition: vxlan.c:1376
int rtnl_link_vxlan_set_udp_zero_csum6_tx(struct rtnl_link *link, uint8_t csum)
Set skip UDP checksum transmitted over IPv6 status to use for VXLAN.
Definition: vxlan.c:1515
int rtnl_link_vxlan_get_udp_csum(struct rtnl_link *link)
Get UDP checksum status to use for VXLAN.
Definition: vxlan.c:1496
int rtnl_link_vxlan_enable_l3miss(struct rtnl_link *link)
Enable netlink IP ADDR miss notifications.
Definition: vxlan.c:1412
int rtnl_link_vxlan_get_limit(struct rtnl_link *link, uint32_t *limit)
Get maximum number of forwarding database entries to use for VXLAN.
Definition: vxlan.c:1127
int rtnl_link_vxlan_get_ageing(struct rtnl_link *link, uint32_t *expiry)
Get expiration timer value to use for VXLAN.
Definition: vxlan.c:1084
Dumping parameters.
Definition: types.h:28
Attribute validation policy.
Definition: attr.h:63
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:65