Merge pull request #636 from ssahani/tunnel

networkd: ip6 tunnel add support for flowlabel
This commit is contained in:
Tom Gundersen 2015-07-21 11:19:00 +02:00
commit bd37a199c9
4 changed files with 88 additions and 0 deletions

View file

@ -490,6 +490,19 @@
the tunnel.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>IPv6FlowLabel=</varname></term>
<listitem>
<para>Configures The 20-bit Flow Label (see <ulink url="https://tools.ietf.org/html/rfc6437">
RFC 6437</ulink>) field in the IPv6 header (see <ulink url="https://tools.ietf.org/html/rfc2460">
RFC 2460</ulink>), is used by a node to label packets of a flow.
It's only used for IPv6 Tunnels.
A Flow Label of zero is used to indicate packets that have
not been labeled. Takes following values.
When <literal>inherit</literal> it uses the original flowlabel,
or can be configured to any value betwen 0 to 0xFFFFF.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Mode=</varname></term>
<listitem>

View file

@ -36,6 +36,7 @@ Tunnel.TOS, config_parse_unsigned, 0,
Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl)
Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(Tunnel, pmtudisc)
Tunnel.Mode, config_parse_ip6tnl_mode, 0, offsetof(Tunnel, ip6tnl_mode)
Tunnel.IPv6FlowLabel, config_parse_ipv6_flowlabel, 0, offsetof(Tunnel, ipv6_flowlabel)
Peer.Name, config_parse_ifname, 0, offsetof(Veth, ifname_peer)
Peer.MACAddress, config_parse_hwaddr, 0, offsetof(Veth, mac_peer)
VXLAN.Id, config_parse_uint64, 0, offsetof(VxLan, id)

View file

@ -33,6 +33,7 @@
#include "conf-parser.h"
#define DEFAULT_TNL_HOP_LIMIT 64
#define IP6_FLOWINFO_FLOWLABEL htonl(0x000FFFFF)
static const char* const ip6tnl_mode_table[_NETDEV_IP6_TNL_MODE_MAX] = {
[NETDEV_IP6_TNL_MODE_IP6IP6] = "ip6ip6",
@ -264,6 +265,16 @@ static int netdev_ip6tnl_fill_message_create(NetDev *netdev, Link *link, sd_netl
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_TTL attribute: %m");
if (t->ipv6_flowlabel != _NETDEV_IPV6_FLOWLABEL_INVALID) {
r = sd_netlink_message_append_u32(m, IFLA_IPTUN_FLOWINFO, t->ipv6_flowlabel);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_FLOWINFO attribute: %m");
}
r = sd_netlink_message_append_u32(m, IFLA_IPTUN_FLAGS, t->flags);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_FLAGS attribute: %m");
switch (t->ip6tnl_mode) {
case NETDEV_IP6_TNL_MODE_IP6IP6:
proto = IPPROTO_IPV6;
@ -380,6 +391,52 @@ int config_parse_tunnel_address(const char *unit,
return 0;
}
static const char* const ipv6_flowlabel_table[_NETDEV_IPV6_FLOWLABEL_MAX] = {
[NETDEV_IPV6_FLOWLABEL_INHERIT] = "inherit",
};
DEFINE_STRING_TABLE_LOOKUP(ipv6_flowlabel, IPv6FlowLabel);
int config_parse_ipv6_flowlabel(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) {
IPv6FlowLabel *ipv6_flowlabel = data;
Tunnel *t = userdata;
IPv6FlowLabel s;
int k = 0;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(ipv6_flowlabel);
s = ipv6_flowlabel_from_string(rvalue);
if (s != _NETDEV_IPV6_FLOWLABEL_INVALID) {
*ipv6_flowlabel = IP6_FLOWINFO_FLOWLABEL;
t->flags |= IP6_TNL_F_USE_ORIG_FLOWLABEL;
} else {
r = config_parse_unsigned(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &k, userdata);
if (r >= 0) {
if (k > 0xFFFFF)
log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse IPv6 flowlabel option, ignoring: %s", rvalue);
else {
*ipv6_flowlabel = htonl(k) & IP6_FLOWINFO_FLOWLABEL;
t->flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL;
}
}
}
return 0;
}
static void ipip_init(NetDev *n) {
Tunnel *t = IPIP(n);
@ -452,6 +509,7 @@ static void ip6tnl_init(NetDev *n) {
t->ttl = DEFAULT_TNL_HOP_LIMIT;
t->encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT;
t->ip6tnl_mode = _NETDEV_IP6_TNL_MODE_INVALID;
t->ipv6_flowlabel = _NETDEV_IPV6_FLOWLABEL_INVALID;
}
const NetDevVTable ipip_vtable = {

View file

@ -33,6 +33,12 @@ typedef enum Ip6TnlMode {
_NETDEV_IP6_TNL_MODE_INVALID = -1,
} Ip6TnlMode;
typedef enum IPv6FlowLabel {
NETDEV_IPV6_FLOWLABEL_INHERIT = 0xFFFFF + 1,
_NETDEV_IPV6_FLOWLABEL_MAX,
_NETDEV_IPV6_FLOWLABEL_INVALID = -1,
} IPv6FlowLabel;
struct Tunnel {
NetDev meta;
@ -48,6 +54,7 @@ struct Tunnel {
union in_addr_union remote;
Ip6TnlMode ip6tnl_mode;
IPv6FlowLabel ipv6_flowlabel;
bool pmtudisc;
};
@ -81,3 +88,12 @@ int config_parse_tunnel_address(const char *unit,
const char *rvalue,
void *data,
void *userdata);
const char *ipv6_flowlabel_to_string(IPv6FlowLabel d) _const_;
IPv6FlowLabel ipv6_flowlabel_from_string(const char *d) _pure_;
int config_parse_ipv6_flowlabel(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);