]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-netdev-vxlan.c
networkd: vxlan add support for GBP
[thirdparty/systemd.git] / src / network / networkd-netdev-vxlan.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2014 Susant Sahani
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <net/if.h>
23
24 #include "sd-netlink.h"
25 #include "networkd-netdev-vxlan.h"
26 #include "networkd-link.h"
27 #include "conf-parser.h"
28 #include "missing.h"
29
30 static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
31 VxLan *v = VXLAN(netdev);
32 int r;
33
34 assert(netdev);
35 assert(v);
36 assert(link);
37 assert(m);
38
39
40 if (v->id <= VXLAN_VID_MAX) {
41 r = sd_netlink_message_append_u32(m, IFLA_VXLAN_ID, v->id);
42 if (r < 0)
43 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_ID attribute: %m");
44 }
45
46 r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->group.in);
47 if (r < 0)
48 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_GROUP attribute: %m");
49
50 r = sd_netlink_message_append_u32(m, IFLA_VXLAN_LINK, link->ifindex);
51 if (r < 0)
52 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_LINK attribute: %m");
53
54 if(v->ttl) {
55 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_TTL, v->ttl);
56 if (r < 0)
57 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_TTL attribute: %m");
58 }
59
60 if(v->tos) {
61 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_TOS, v->tos);
62 if (r < 0)
63 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_TOS attribute: %m");
64 }
65
66 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_LEARNING, v->learning);
67 if (r < 0)
68 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_LEARNING attribute: %m");
69
70 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_RSC, v->route_short_circuit);
71 if (r < 0)
72 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_RSC attribute: %m");
73
74 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_PROXY, v->arp_proxy);
75 if (r < 0)
76 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_PROXY attribute: %m");
77
78 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_L2MISS, v->l2miss);
79 if (r < 0)
80 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_L2MISS attribute: %m");
81
82 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_L3MISS, v->l3miss);
83 if (r < 0)
84 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_L3MISS attribute: %m");
85
86 if(v->fdb_ageing) {
87 r = sd_netlink_message_append_u32(m, IFLA_VXLAN_AGEING, v->fdb_ageing / USEC_PER_SEC);
88 if (r < 0)
89 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_AGEING attribute: %m");
90 }
91
92 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_UDP_CSUM, v->udpcsum);
93 if (r < 0)
94 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_UDP_CSUM attribute: %m");
95
96 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, v->udp6zerocsumtx);
97 if (r < 0)
98 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_UDP_ZERO_CSUM6_TX attribute: %m");
99
100 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, v->udp6zerocsumrx);
101 if (r < 0)
102 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_UDP_ZERO_CSUM6_RX attribute: %m");
103
104 if (v->group_policy) {
105 r = sd_netlink_message_append_flag(m, IFLA_VXLAN_GBP);
106 if (r < 0)
107 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_GBP attribute: %m");
108 }
109
110 return r;
111 }
112
113 int config_parse_vxlan_group_address(const char *unit,
114 const char *filename,
115 unsigned line,
116 const char *section,
117 unsigned section_line,
118 const char *lvalue,
119 int ltype,
120 const char *rvalue,
121 void *data,
122 void *userdata) {
123 VxLan *v = userdata;
124 union in_addr_union *addr = data, buffer;
125 int r, f;
126
127 assert(filename);
128 assert(lvalue);
129 assert(rvalue);
130 assert(data);
131
132 r = in_addr_from_string_auto(rvalue, &f, &buffer);
133 if (r < 0) {
134 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
135 "vxlan multicast group address is invalid, ignoring assignment: %s", rvalue);
136 return 0;
137 }
138
139 if(v->family != AF_UNSPEC && v->family != f) {
140 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
141 "vxlan multicast group incompatible, ignoring assignment: %s", rvalue);
142 return 0;
143 }
144
145 v->family = f;
146 *addr = buffer;
147
148 return 0;
149 }
150
151 static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
152 VxLan *v = VXLAN(netdev);
153
154 assert(netdev);
155 assert(v);
156 assert(filename);
157
158 if (v->id > VXLAN_VID_MAX) {
159 log_warning("VXLAN without valid Id configured in %s. Ignoring", filename);
160 return -EINVAL;
161 }
162
163 return 0;
164 }
165
166 static void vxlan_init(NetDev *netdev) {
167 VxLan *v = VXLAN(netdev);
168
169 assert(netdev);
170 assert(v);
171
172 v->id = VXLAN_VID_MAX + 1;
173 v->learning = true;
174 v->udpcsum = false;
175 v->udp6zerocsumtx = false;
176 v->udp6zerocsumrx = false;
177 }
178
179 const NetDevVTable vxlan_vtable = {
180 .object_size = sizeof(VxLan),
181 .init = vxlan_init,
182 .sections = "Match\0NetDev\0VXLAN\0",
183 .fill_message_create = netdev_vxlan_fill_message_create,
184 .create_type = NETDEV_CREATE_STACKED,
185 .config_verify = netdev_vxlan_verify,
186 };