2 This file is part of systemd.
4 Copyright 2014 Susant Sahani
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include "sd-netlink.h"
24 #include "conf-parser.h"
25 #include "alloc-util.h"
26 #include "parse-util.h"
28 #include "networkd-link.h"
29 #include "networkd-netdev-vxlan.h"
31 static int netdev_vxlan_fill_message_create(NetDev
*netdev
, Link
*link
, sd_netlink_message
*m
) {
43 if (v
->id
<= VXLAN_VID_MAX
) {
44 r
= sd_netlink_message_append_u32(m
, IFLA_VXLAN_ID
, v
->id
);
46 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_ID attribute: %m");
49 r
= sd_netlink_message_append_in_addr(m
, IFLA_VXLAN_GROUP
, &v
->group
.in
);
51 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_GROUP attribute: %m");
53 r
= sd_netlink_message_append_u32(m
, IFLA_VXLAN_LINK
, link
->ifindex
);
55 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_LINK attribute: %m");
58 r
= sd_netlink_message_append_u8(m
, IFLA_VXLAN_TTL
, v
->ttl
);
60 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_TTL attribute: %m");
64 r
= sd_netlink_message_append_u8(m
, IFLA_VXLAN_TOS
, v
->tos
);
66 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_TOS attribute: %m");
69 r
= sd_netlink_message_append_u8(m
, IFLA_VXLAN_LEARNING
, v
->learning
);
71 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_LEARNING attribute: %m");
73 r
= sd_netlink_message_append_u8(m
, IFLA_VXLAN_RSC
, v
->route_short_circuit
);
75 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_RSC attribute: %m");
77 r
= sd_netlink_message_append_u8(m
, IFLA_VXLAN_PROXY
, v
->arp_proxy
);
79 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_PROXY attribute: %m");
81 r
= sd_netlink_message_append_u8(m
, IFLA_VXLAN_L2MISS
, v
->l2miss
);
83 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_L2MISS attribute: %m");
85 r
= sd_netlink_message_append_u8(m
, IFLA_VXLAN_L3MISS
, v
->l3miss
);
87 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_L3MISS attribute: %m");
90 r
= sd_netlink_message_append_u32(m
, IFLA_VXLAN_AGEING
, v
->fdb_ageing
/ USEC_PER_SEC
);
92 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_AGEING attribute: %m");
96 r
= sd_netlink_message_append_u32(m
, IFLA_VXLAN_LIMIT
, v
->max_fdb
);
98 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_LIMIT attribute: %m");
101 r
= sd_netlink_message_append_u8(m
, IFLA_VXLAN_UDP_CSUM
, v
->udpcsum
);
103 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_UDP_CSUM attribute: %m");
105 r
= sd_netlink_message_append_u8(m
, IFLA_VXLAN_UDP_ZERO_CSUM6_TX
, v
->udp6zerocsumtx
);
107 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_UDP_ZERO_CSUM6_TX attribute: %m");
109 r
= sd_netlink_message_append_u8(m
, IFLA_VXLAN_UDP_ZERO_CSUM6_RX
, v
->udp6zerocsumrx
);
111 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_UDP_ZERO_CSUM6_RX attribute: %m");
113 r
= sd_netlink_message_append_u16(m
, IFLA_VXLAN_PORT
, htobe16(v
->dest_port
));
115 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_PORT attribute: %m");
117 if (v
->port_range
.low
|| v
->port_range
.high
) {
118 struct ifla_vxlan_port_range port_range
;
120 port_range
.low
= htobe16(v
->port_range
.low
);
121 port_range
.high
= htobe16(v
->port_range
.high
);
123 r
= sd_netlink_message_append_data(m
, IFLA_VXLAN_PORT_RANGE
, &port_range
, sizeof(port_range
));
125 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_PORT_RANGE attribute: %m");
128 if (v
->group_policy
) {
129 r
= sd_netlink_message_append_flag(m
, IFLA_VXLAN_GBP
);
131 return log_netdev_error_errno(netdev
, r
, "Could not append IFLA_VXLAN_GBP attribute: %m");
137 int config_parse_vxlan_group_address(const char *unit
,
138 const char *filename
,
141 unsigned section_line
,
148 union in_addr_union
*addr
= data
, buffer
;
156 r
= in_addr_from_string_auto(rvalue
, &f
, &buffer
);
158 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "vxlan multicast group address is invalid, ignoring assignment: %s", rvalue
);
162 if (v
->family
!= AF_UNSPEC
&& v
->family
!= f
) {
163 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "vxlan multicast group incompatible, ignoring assignment: %s", rvalue
);
173 int config_parse_port_range(const char *unit
,
174 const char *filename
,
177 unsigned section_line
,
183 _cleanup_free_
char *word
= NULL
;
193 r
= extract_first_word(&rvalue
, &word
, NULL
, 0);
195 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract VXLAN port range, ignoring: %s", rvalue
);
202 r
= parse_range(word
, &low
, &high
);
204 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse VXLAN port range '%s'", word
);
208 if (low
<= 0 || low
> 65535 || high
<= 0 || high
> 65535) {
209 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
210 "Failed to parse VXLAN port range '%s'. Port should be greater than 0 and less than 65535.", word
);
215 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
216 "Failed to parse VXLAN port range '%s'. Port range %u .. %u not valid", word
, low
, high
);
220 v
->port_range
.low
= low
;
221 v
->port_range
.high
= high
;
226 int config_parse_destination_port(const char *unit
,
227 const char *filename
,
230 unsigned section_line
,
245 r
= safe_atou16(rvalue
, &port
);
246 if (r
< 0 || port
<= 0) {
247 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse VXLAN destination port '%s'.", rvalue
);
256 static int netdev_vxlan_verify(NetDev
*netdev
, const char *filename
) {
257 VxLan
*v
= VXLAN(netdev
);
263 if (v
->id
> VXLAN_VID_MAX
) {
264 log_warning("VXLAN without valid Id configured in %s. Ignoring", filename
);
271 static void vxlan_init(NetDev
*netdev
) {
280 v
->id
= VXLAN_VID_MAX
+ 1;
283 v
->udp6zerocsumtx
= false;
284 v
->udp6zerocsumrx
= false;
287 const NetDevVTable vxlan_vtable
= {
288 .object_size
= sizeof(VxLan
),
290 .sections
= "Match\0NetDev\0VXLAN\0",
291 .fill_message_create
= netdev_vxlan_fill_message_create
,
292 .create_type
= NETDEV_CREATE_STACKED
,
293 .config_verify
= netdev_vxlan_verify
,