From a613382bbf4357ce13f17c988713b80172e091fb Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Fri, 23 May 2014 12:07:46 +0530 Subject: [PATCH] networkd: introduce vti tunnel This patch enables vti tunnel support. example conf: file : vti.netdev [NetDev] Name=vti-tun Kind=vti MTUBytes=1480 [Tunnel] Local=X.X.X.X Remote=X.X.X.X file: vti.network [Match] Name=em1 [Network] Tunnel=vti-tun TODO: Add more attributes for vti tunnel IFLA_VTI_IKEY IFLA_VTI_OKEY --- src/libsystemd/sd-rtnl/rtnl-types.c | 12 ++++ src/network/networkd-netdev.c | 7 ++- src/network/networkd-network.c | 3 +- src/network/networkd-tunnel.c | 95 +++++++++++++++++++++++++++++ src/network/networkd.h | 1 + 5 files changed, 115 insertions(+), 3 deletions(-) diff --git a/src/libsystemd/sd-rtnl/rtnl-types.c b/src/libsystemd/sd-rtnl/rtnl-types.c index d32855d94..2218afdbb 100644 --- a/src/libsystemd/sd-rtnl/rtnl-types.c +++ b/src/libsystemd/sd-rtnl/rtnl-types.c @@ -130,6 +130,14 @@ static const NLType rtnl_link_info_data_ipgre_types[IFLA_GRE_MAX + 1] = { [IFLA_GRE_PMTUDISC] = { .type = NLA_U8 }, }; +static const NLType rtnl_link_info_data_ipvti_types[IFLA_VTI_MAX + 1] = { + [IFLA_VTI_LINK] = { .type = NLA_U32 }, + [IFLA_VTI_IKEY] = { .type = NLA_U32 }, + [IFLA_VTI_OKEY] = { .type = NLA_U32 }, + [IFLA_VTI_LOCAL] = { .type = NLA_IN_ADDR }, + [IFLA_VTI_REMOTE] = { .type = NLA_IN_ADDR }, +}; + typedef enum NLUnionLinkInfoData { NL_UNION_LINK_INFO_DATA_BOND, NL_UNION_LINK_INFO_DATA_BRIDGE, @@ -139,6 +147,7 @@ typedef enum NLUnionLinkInfoData { NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL, NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL, NL_UNION_LINK_INFO_DATA_SIT_TUNNEL, + NL_UNION_LINK_INFO_DATA_VTI_TUNNEL, _NL_UNION_LINK_INFO_DATA_MAX, _NL_UNION_LINK_INFO_DATA_INVALID = -1 } NLUnionLinkInfoData; @@ -156,6 +165,7 @@ static const char* const nl_union_link_info_data_table[_NL_UNION_LINK_INFO_DATA_ [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = "ipip", [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = "gre", [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = "sit", + [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = "vti", }; DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData); @@ -177,6 +187,8 @@ static const NLTypeSystem rtnl_link_info_data_type_systems[_NL_UNION_LINK_INFO_D .types = rtnl_link_info_data_ipgre_types }, [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1, .types = rtnl_link_info_data_iptun_types }, + [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvti_types) - 1, + .types = rtnl_link_info_data_ipvti_types }, }; static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = { diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index 4439374a6..1519419c1 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -39,6 +39,7 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { [NETDEV_KIND_GRE] = "gre", [NETDEV_KIND_SIT] = "sit", [NETDEV_KIND_VETH] = "veth", + [NETDEV_KIND_VTI] = "vti" }; DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind); @@ -393,7 +394,8 @@ int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callbac if(netdev->kind == NETDEV_KIND_IPIP || netdev->kind == NETDEV_KIND_GRE || - netdev->kind == NETDEV_KIND_SIT) + netdev->kind == NETDEV_KIND_SIT || + netdev->kind == NETDEV_KIND_VTI) return netdev_create_tunnel(link, netdev_create_handler); if (netdev->state == NETDEV_STATE_READY) { @@ -606,7 +608,8 @@ static int netdev_load_one(Manager *manager, const char *filename) { netdev->kind != NETDEV_KIND_MACVLAN && netdev->kind != NETDEV_KIND_IPIP && netdev->kind != NETDEV_KIND_GRE && - netdev->kind != NETDEV_KIND_SIT) { + netdev->kind != NETDEV_KIND_SIT && + netdev->kind != NETDEV_KIND_VTI) { r = netdev_create(netdev, NULL, NULL); if (r < 0) return r; diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index a6cbee239..f42fc171b 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -363,7 +363,8 @@ int config_parse_tunnel(const char *unit, if (netdev->kind != NETDEV_KIND_IPIP && netdev->kind != NETDEV_KIND_SIT && - netdev->kind != NETDEV_KIND_GRE) { + netdev->kind != NETDEV_KIND_GRE && + netdev->kind != NETDEV_KIND_VTI) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, "NetDev is not a tunnel, ignoring assignment: %s", rvalue); return 0; diff --git a/src/network/networkd-tunnel.c b/src/network/networkd-tunnel.c index 1a06a17c7..e3ceb8b52 100644 --- a/src/network/networkd-tunnel.c +++ b/src/network/networkd-tunnel.c @@ -339,6 +339,94 @@ static int netdev_fill_ipgre_rtnl_message(Link *link, sd_rtnl_message *m) { return r; } +static int netdev_fill_vti_rtnl_message(Link *link, sd_rtnl_message *m) { + NetDev *netdev; + int r; + + assert(link); + assert(link->network); + assert(link->network->tunnel); + assert(m); + + netdev = link->network->tunnel; + + r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IFNAME, attribute: %s", + strerror(-r)); + return r; + } + + if(netdev->mtu) { + r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_MTU attribute: %s", + strerror(-r)); + return r; + } + } + + r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, + netdev_kind_to_string(netdev->kind)); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IPTUN_LINK attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &netdev->tunnel_local); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IPTUN_LOCAL attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &netdev->tunnel_remote); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IPTUN_REMOTE attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + return r; +} int netdev_create_tunnel(Link *link, sd_rtnl_message_handler_t callback) { _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL; @@ -371,6 +459,8 @@ int netdev_create_tunnel(Link *link, sd_rtnl_message_handler_t callback) { return r; } break; + case NETDEV_KIND_VTI: + break; default: return -ENOTSUP; } @@ -394,6 +484,11 @@ int netdev_create_tunnel(Link *link, sd_rtnl_message_handler_t callback) { if(r < 0) return r; break; + case NETDEV_KIND_VTI: + netdev_fill_vti_rtnl_message(link, m); + if(r < 0) + return r; + break; case NETDEV_KIND_GRE: r = netdev_fill_ipgre_rtnl_message(link, m); if(r < 0) diff --git a/src/network/networkd.h b/src/network/networkd.h index 6f69c9a48..82d8d706b 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -72,6 +72,7 @@ typedef enum NetDevKind { NETDEV_KIND_GRE, NETDEV_KIND_SIT, NETDEV_KIND_VETH, + NETDEV_KIND_VTI, _NETDEV_KIND_MAX, _NETDEV_KIND_INVALID = -1 } NetDevKind; -- 2.30.2