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