networkd-netdev-vxlan.c revision f545680e3d4fd84931704406a352f14d66716572
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering/***
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering This file is part of systemd.
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering Copyright 2014 Susant Sahani <susant@redhat.com>
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering systemd is free software; you can redistribute it and/or modify it
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering under the terms of the GNU Lesser General Public License as published by
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering (at your option) any later version.
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering systemd is distributed in the hope that it will be useful, but
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering Lesser General Public License for more details.
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering You should have received a copy of the GNU Lesser General Public License
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering***/
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering#include <net/if.h>
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "sd-rtnl.h"
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering#include "networkd-netdev-vxlan.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "networkd-link.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "conf-parser.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "missing.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering VxLan *v = VXLAN(netdev);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering int r;
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering assert(netdev);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering assert(v);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering assert(link);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering assert(m);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (v->id <= VXLAN_VID_MAX) {
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_ID, v->id);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (r < 0)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_ID attribute: %m");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering }
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering r = sd_rtnl_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->group.in);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (r < 0)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_GROUP attribute: %m");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_LINK, link->ifindex);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (r < 0)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_LINK attribute: %m");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if(v->ttl) {
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TTL, v->ttl);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (r < 0)
aa3be0dd36bae7f32daa35bc269d87f0d809d52fAlban Crequy return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_TTL attribute: %m");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering }
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if(v->tos) {
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TOS, v->tos);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (r < 0)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_TOS attribute: %m");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering }
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_LEARNING, v->learning);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (r < 0)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_LEARNING attribute: %m");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_RSC, v->route_short_circuit);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (r < 0)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_RSC attribute: %m");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_PROXY, v->arp_proxy);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (r < 0)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_PROXY attribute: %m");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_L2MISS, v->l2miss);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (r < 0)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_L2MISS attribute: %m");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_L3MISS, v->l3miss);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (r < 0)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_L3MISS attribute: %m");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if(v->fdb_ageing) {
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_AGEING, v->fdb_ageing / USEC_PER_SEC);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (r < 0)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_AGEING attribute: %m");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering }
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_UDP_CSUM, v->udpcsum);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (r < 0)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_UDP_CSUM attribute: %m");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, v->udp6zerocsumtx);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (r < 0)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_UDP_ZERO_CSUM6_TX attribute: %m");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, v->udp6zerocsumrx);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (r < 0)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_UDP_ZERO_CSUM6_RX attribute: %m");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return r;
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering}
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poetteringint config_parse_vxlan_group_address(const char *unit,
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering const char *filename,
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering unsigned line,
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering const char *section,
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering unsigned section_line,
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering const char *lvalue,
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering int ltype,
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering const char *rvalue,
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering void *data,
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering void *userdata) {
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering VxLan *v = userdata;
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering union in_addr_union *addr = data, buffer;
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering int r, f;
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering assert(filename);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering assert(lvalue);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering assert(rvalue);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering assert(data);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering r = in_addr_from_string_auto(rvalue, &f, &buffer);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (r < 0) {
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering log_syntax(unit, LOG_ERR, filename, line, EINVAL,
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering "vxlan multicast group address is invalid, ignoring assignment: %s", rvalue);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return 0;
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering }
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if(v->family != AF_UNSPEC && v->family != f) {
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering log_syntax(unit, LOG_ERR, filename, line, EINVAL,
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering "vxlan multicast group incompatible, ignoring assignment: %s", rvalue);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return 0;
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering }
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering v->family = f;
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering *addr = buffer;
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return 0;
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering}
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poetteringstatic int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering VxLan *v = VXLAN(netdev);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering assert(netdev);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering assert(v);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering assert(filename);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (v->id > VXLAN_VID_MAX) {
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering log_warning("VXLAN without valid Id configured in %s. Ignoring", filename);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return -EINVAL;
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering }
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering return 0;
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering}
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poetteringstatic void vxlan_init(NetDev *netdev) {
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering VxLan *v = VXLAN(netdev);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering assert(netdev);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering assert(v);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering
v->id = VXLAN_VID_MAX + 1;
v->learning = true;
v->udpcsum = false;
v->udp6zerocsumtx = false;
v->udp6zerocsumrx = false;
}
const NetDevVTable vxlan_vtable = {
.object_size = sizeof(VxLan),
.init = vxlan_init,
.sections = "Match\0NetDev\0VXLAN\0",
.fill_message_create = netdev_vxlan_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_vxlan_verify,
};