Merge pull request #1975 from ssahani/vxlan2

networkd: Add support to configure VXLAN Port
This commit is contained in:
Tom Gundersen 2016-01-27 01:17:52 +01:00
commit 1cdc944823
6 changed files with 160 additions and 0 deletions

View file

@ -493,6 +493,25 @@
VXLAN Group Policy </ulink> document. Defaults to false.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>DestinationPort=</varname></term>
<listitem>
<para>Configures the default destination UDP port on a per-device basis.
If destination port is not specified then Linux kernel default will be used.
Set destination port 4789 to get the IANA assigned value,
and destination port 0 to get default values.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>PortRange=</varname></term>
<listitem>
<para>Configures VXLAN port range. VXLAN bases source
UDP port based on flow to help the receiver to be able
to load balance based on outer header flow. It
restricts the port range to the normal UDP local
ports, and allows overriding via configuration.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>

View file

@ -342,6 +342,19 @@ int sd_netlink_message_append_u32(sd_netlink_message *m, unsigned short type, ui
return 0;
}
int sd_netlink_message_append_data(sd_netlink_message *m, unsigned short type, const void *data, size_t len) {
int r;
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
r = add_rtattr(m, type, &data, len);
if (r < 0)
return r;
return 0;
}
int sd_netlink_message_append_in_addr(sd_netlink_message *m, unsigned short type, const struct in_addr *data) {
int r;

View file

@ -57,6 +57,8 @@ VXLAN.UDP6ZeroCheckSumTx, config_parse_bool, 0,
VXLAN.FDBAgeingSec, config_parse_sec, 0, offsetof(VxLan, fdb_ageing)
VXLAN.GroupPolicyExtension, config_parse_bool, 0, offsetof(VxLan, group_policy)
VXLAN.MaximumFDBEntries, config_parse_unsigned, 0, offsetof(VxLan, max_fdb)
VXLAN.PortRange, config_parse_port_range, 0, 0
VXLAN.DestinationPort, config_parse_destination_port, 0, offsetof(VxLan, dest_port)
Tun.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue)
Tun.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
Tun.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)

View file

@ -24,6 +24,8 @@
#include "sd-netlink.h"
#include "conf-parser.h"
#include "alloc-util.h"
#include "parse-util.h"
#include "missing.h"
#include "networkd-link.h"
#include "networkd-netdev-vxlan.h"
@ -110,6 +112,21 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_UDP_ZERO_CSUM6_RX attribute: %m");
r = sd_netlink_message_append_u16(m, IFLA_VXLAN_PORT, htobe16(v->dest_port));
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_PORT attribute: %m");
if (v->port_range.low || v->port_range.high) {
struct ifla_vxlan_port_range port_range;
port_range.low = htobe16(v->port_range.low);
port_range.high = htobe16(v->port_range.high);
r = sd_netlink_message_append_data(m, IFLA_VXLAN_PORT_RANGE, &port_range, sizeof(port_range));
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_PORT_RANGE attribute: %m");
}
if (v->group_policy) {
r = sd_netlink_message_append_flag(m, IFLA_VXLAN_GBP);
if (r < 0)
@ -155,6 +172,89 @@ int config_parse_vxlan_group_address(const char *unit,
return 0;
}
int config_parse_port_range(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_free_ char *word = NULL;
VxLan *v = userdata;
unsigned low, high;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = extract_first_word(&rvalue, &word, NULL, 0);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract VXLAN port range, ignoring: %s", rvalue);
return 0;
}
if (r == 0)
return 0;
r = parse_range(word, &low, &high);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse VXLAN port range '%s'", word);
return 0;
}
if (low <= 0 || low > 65535 || high <= 0 || high > 65535) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse VXLAN port range '%s'. Port should be greater than 0 and less than 65535.", word);
return 0;
}
if (high < low) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse VXLAN port range '%s'. Port range %u .. %u not valid", word, low, high);
return 0;
}
v->port_range.low = low;
v->port_range.high = high;
return 0;
}
int config_parse_destination_port(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
VxLan *v = userdata;
uint16_t port;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = safe_atou16(rvalue, &port);
if (r < 0 || port <= 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse VXLAN destination port '%s'.", rvalue);
return 0;
}
v->dest_port = port;
return 0;
}
static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
VxLan *v = VXLAN(netdev);

View file

@ -40,6 +40,8 @@ struct VxLan {
unsigned ttl;
unsigned max_fdb;
uint16_t dest_port;
usec_t fdb_ageing;
bool learning;
@ -51,6 +53,8 @@ struct VxLan {
bool udp6zerocsumtx;
bool udp6zerocsumrx;
bool group_policy;
struct ifla_vxlan_port_range port_range;
};
extern const NetDevVTable vxlan_vtable;
@ -65,3 +69,24 @@ int config_parse_vxlan_group_address(const char *unit,
const char *rvalue,
void *data,
void *userdata);
int config_parse_port_range(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata);
int config_parse_destination_port(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata);

View file

@ -74,6 +74,7 @@ int sd_netlink_message_append_flag(sd_netlink_message *m, unsigned short type);
int sd_netlink_message_append_u8(sd_netlink_message *m, unsigned short type, uint8_t data);
int sd_netlink_message_append_u16(sd_netlink_message *m, unsigned short type, uint16_t data);
int sd_netlink_message_append_u32(sd_netlink_message *m, unsigned short type, uint32_t data);
int sd_netlink_message_append_data(sd_netlink_message *m, unsigned short type, const void *data, size_t len);
int sd_netlink_message_append_in_addr(sd_netlink_message *m, unsigned short type, const struct in_addr *data);
int sd_netlink_message_append_in6_addr(sd_netlink_message *m, unsigned short type, const struct in6_addr *data);
int sd_netlink_message_append_ether_addr(sd_netlink_message *m, unsigned short type, const struct ether_addr *data);