]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-netdev-vxlan.c
networkd: vxlan add support for GBP
[thirdparty/systemd.git] / src / network / networkd-netdev-vxlan.c
CommitLineData
326cb406
SS
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
ea84fd5c 6 Copyright 2014 Susant Sahani
326cb406
SS
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
326cb406
SS
22#include <net/if.h>
23
1c4baffc 24#include "sd-netlink.h"
3be1d7e0 25#include "networkd-netdev-vxlan.h"
0b1831c2 26#include "networkd-link.h"
85a8eeee 27#include "conf-parser.h"
81577dc2 28#include "missing.h"
326cb406 29
1c4baffc 30static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
aa9f1140 31 VxLan *v = VXLAN(netdev);
326cb406
SS
32 int r;
33
3be1d7e0 34 assert(netdev);
aa9f1140 35 assert(v);
326cb406 36 assert(link);
326cb406
SS
37 assert(m);
38
326cb406 39
aa9f1140 40 if (v->id <= VXLAN_VID_MAX) {
1c4baffc 41 r = sd_netlink_message_append_u32(m, IFLA_VXLAN_ID, v->id);
f545680e
SS
42 if (r < 0)
43 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_ID attribute: %m");
326cb406
SS
44 }
45
1c4baffc 46 r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->group.in);
f545680e
SS
47 if (r < 0)
48 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_GROUP attribute: %m");
326cb406 49
1c4baffc 50 r = sd_netlink_message_append_u32(m, IFLA_VXLAN_LINK, link->ifindex);
f545680e
SS
51 if (r < 0)
52 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_LINK attribute: %m");
326cb406 53
aa9f1140 54 if(v->ttl) {
1c4baffc 55 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_TTL, v->ttl);
f545680e
SS
56 if (r < 0)
57 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_TTL attribute: %m");
326cb406
SS
58 }
59
aa9f1140 60 if(v->tos) {
1c4baffc 61 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_TOS, v->tos);
f545680e
SS
62 if (r < 0)
63 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_TOS attribute: %m");
326cb406
SS
64 }
65
1c4baffc 66 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_LEARNING, v->learning);
f545680e
SS
67 if (r < 0)
68 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_LEARNING attribute: %m");
326cb406 69
1c4baffc 70 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_RSC, v->route_short_circuit);
f545680e
SS
71 if (r < 0)
72 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_RSC attribute: %m");
85a8eeee 73
1c4baffc 74 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_PROXY, v->arp_proxy);
f545680e
SS
75 if (r < 0)
76 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_PROXY attribute: %m");
85a8eeee 77
1c4baffc 78 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_L2MISS, v->l2miss);
f545680e
SS
79 if (r < 0)
80 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_L2MISS attribute: %m");
85a8eeee 81
1c4baffc 82 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_L3MISS, v->l3miss);
f545680e
SS
83 if (r < 0)
84 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_L3MISS attribute: %m");
85a8eeee
SS
85
86 if(v->fdb_ageing) {
1c4baffc 87 r = sd_netlink_message_append_u32(m, IFLA_VXLAN_AGEING, v->fdb_ageing / USEC_PER_SEC);
f545680e
SS
88 if (r < 0)
89 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_AGEING attribute: %m");
85a8eeee
SS
90 }
91
1c4baffc 92 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_UDP_CSUM, v->udpcsum);
f545680e
SS
93 if (r < 0)
94 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_UDP_CSUM attribute: %m");
cffacc74 95
1c4baffc 96 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, v->udp6zerocsumtx);
f545680e
SS
97 if (r < 0)
98 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_UDP_ZERO_CSUM6_TX attribute: %m");
cffacc74 99
1c4baffc 100 r = sd_netlink_message_append_u8(m, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, v->udp6zerocsumrx);
f545680e
SS
101 if (r < 0)
102 return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_UDP_ZERO_CSUM6_RX attribute: %m");
cffacc74 103
ea84fd5c
SS
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
326cb406
SS
110 return r;
111}
112
85a8eeee
SS
113int 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
3be1d7e0 151static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
aa9f1140
TG
152 VxLan *v = VXLAN(netdev);
153
326cb406 154 assert(netdev);
aa9f1140 155 assert(v);
3be1d7e0 156 assert(filename);
326cb406 157
aa9f1140 158 if (v->id > VXLAN_VID_MAX) {
3be1d7e0
TG
159 log_warning("VXLAN without valid Id configured in %s. Ignoring", filename);
160 return -EINVAL;
326cb406
SS
161 }
162
326cb406
SS
163 return 0;
164}
3be1d7e0 165
aa9f1140
TG
166static 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;
cffacc74
SS
174 v->udpcsum = false;
175 v->udp6zerocsumtx = false;
176 v->udp6zerocsumrx = false;
aa9f1140
TG
177}
178
3be1d7e0 179const NetDevVTable vxlan_vtable = {
aa9f1140
TG
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,
3be1d7e0
TG
185 .config_verify = netdev_vxlan_verify,
186};