diff --git a/Makefile.am b/Makefile.am index 37ea845ed43..5b789d00275 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5481,6 +5481,7 @@ libsystemd_networkd_core_la_SOURCES = \ src/network/networkd-netdev-vxlan.h \ src/network/networkd-netdev-vlan.h \ src/network/networkd-netdev-macvlan.h \ + src/network/networkd-netdev-ipvlan.h \ src/network/networkd-netdev-dummy.h \ src/network/networkd-netdev-tuntap.h \ src/network/networkd-netdev-bond.h \ @@ -5491,6 +5492,7 @@ libsystemd_networkd_core_la_SOURCES = \ src/network/networkd-netdev-vxlan.c \ src/network/networkd-netdev-vlan.c \ src/network/networkd-netdev-macvlan.c \ + src/network/networkd-netdev-ipvlan.c \ src/network/networkd-netdev-dummy.c \ src/network/networkd-netdev-tuntap.c \ src/network/networkd-netdev-bond.c \ diff --git a/configure.ac b/configure.ac index 6d510df332b..d82cfe890a8 100644 --- a/configure.ac +++ b/configure.ac @@ -322,6 +322,7 @@ AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at, setns, getrandom, renamea ]]) AC_CHECK_DECLS([IFLA_MACVLAN_FLAGS, + IFLA_IPVLAN_MODE, IFLA_VTI_REMOTE, IFLA_PHYS_PORT_ID, IFLA_BOND_AD_INFO, diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index 9e9d3e848fa..03b0940716d 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -163,7 +163,8 @@ The netdev kind. Currently, bridge, bond, vlan, - macvlan, vxlan, + macvlan, + ipvlan, vxlan, ipip, gre, sit, vti, veth, tun, @@ -233,6 +234,26 @@ + + + [IPVLAN] Section Options + + The [IPVLAN] section only applies for netdevs of kind + ipvlan, and accepts the following key: + + + + Mode= + + The IPVLAN mode to use. The supported options are + L2 and L3. + + + + + + + [VXLAN] Section Options The [VXLAN] section only applies for netdevs of kind diff --git a/src/libsystemd/sd-rtnl/rtnl-types.c b/src/libsystemd/sd-rtnl/rtnl-types.c index 735ad75390b..b0bd661b843 100644 --- a/src/libsystemd/sd-rtnl/rtnl-types.c +++ b/src/libsystemd/sd-rtnl/rtnl-types.c @@ -31,6 +31,7 @@ #include #include +#include #include #include "macro.h" @@ -45,6 +46,9 @@ static const NLType rtnl_link_info_data_veth_types[VETH_INFO_MAX + 1] = { [VETH_INFO_PEER] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, }; +static const NLType rtnl_link_info_data_ipvlan_types[IFLA_IPVLAN_MAX + 1] = { + [IFLA_IPVLAN_MODE] = { .type = NLA_U16 }, +}; static const NLType rtnl_link_info_data_macvlan_types[IFLA_MACVLAN_MAX + 1] = { [IFLA_MACVLAN_MODE] = { .type = NLA_U32 }, @@ -157,6 +161,7 @@ static const char* const nl_union_link_info_data_table[_NL_UNION_LINK_INFO_DATA_ [NL_UNION_LINK_INFO_DATA_VETH] = "veth", [NL_UNION_LINK_INFO_DATA_DUMMY] = "dummy", [NL_UNION_LINK_INFO_DATA_MACVLAN] = "macvlan", + [NL_UNION_LINK_INFO_DATA_IPVLAN] = "ipvlan", [NL_UNION_LINK_INFO_DATA_VXLAN] = "vxlan", [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = "ipip", [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = "gre", @@ -177,6 +182,8 @@ static const NLTypeSystem rtnl_link_info_data_type_systems[_NL_UNION_LINK_INFO_D .types = rtnl_link_info_data_veth_types }, [NL_UNION_LINK_INFO_DATA_MACVLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_macvlan_types) - 1, .types = rtnl_link_info_data_macvlan_types }, + [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvlan_types) - 1, + .types = rtnl_link_info_data_ipvlan_types }, [NL_UNION_LINK_INFO_DATA_VXLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_vxlan_types) - 1, .types = rtnl_link_info_data_vxlan_types }, [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1, diff --git a/src/libsystemd/sd-rtnl/rtnl-types.h b/src/libsystemd/sd-rtnl/rtnl-types.h index 86217460159..1bb17a4cda9 100644 --- a/src/libsystemd/sd-rtnl/rtnl-types.h +++ b/src/libsystemd/sd-rtnl/rtnl-types.h @@ -71,6 +71,7 @@ typedef enum NLUnionLinkInfoData { NL_UNION_LINK_INFO_DATA_VETH, NL_UNION_LINK_INFO_DATA_DUMMY, NL_UNION_LINK_INFO_DATA_MACVLAN, + NL_UNION_LINK_INFO_DATA_IPVLAN, NL_UNION_LINK_INFO_DATA_VXLAN, NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL, NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL, diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf index b311ebe4fb2..cb741b470d5 100644 --- a/src/network/networkd-netdev-gperf.gperf +++ b/src/network/networkd-netdev-gperf.gperf @@ -29,6 +29,7 @@ NetDev.MTUBytes, config_parse_iec_size, 0, NetDev.MACAddress, config_parse_hwaddr, 0, offsetof(NetDev, mac) VLAN.Id, config_parse_uint64, 0, offsetof(VLan, id) MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode) +IPVLAN.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode) Tunnel.Local, config_parse_tunnel_address, 0, offsetof(Tunnel, local) Tunnel.Remote, config_parse_tunnel_address, 0, offsetof(Tunnel, remote) Tunnel.TOS, config_parse_unsigned, 0, offsetof(Tunnel, tos) diff --git a/src/network/networkd-netdev-ipvlan.c b/src/network/networkd-netdev-ipvlan.c new file mode 100644 index 00000000000..9a7c280c6b4 --- /dev/null +++ b/src/network/networkd-netdev-ipvlan.c @@ -0,0 +1,75 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013-2015 Tom Gundersen + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "networkd-netdev-ipvlan.h" +#include "network-internal.h" +#include "conf-parser.h" +#include "list.h" + +static const char* const ipvlan_mode_table[_NETDEV_IPVLAN_MODE_MAX] = { + [NETDEV_IPVLAN_MODE_L2] = "L2", + [NETDEV_IPVLAN_MODE_L3] = "L3", +}; + +DEFINE_STRING_TABLE_LOOKUP(ipvlan_mode, IPVlanMode); +DEFINE_CONFIG_PARSE_ENUM(config_parse_ipvlan_mode, ipvlan_mode, IPVlanMode, "Failed to parse ipvlan mode"); + +static int netdev_ipvlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *req) { + IPVlan *m = IPVLAN(netdev); + int r; + + assert(netdev); + assert(m); + assert(link); + assert(netdev->ifname); + + if (m->mode != _NETDEV_IPVLAN_MODE_INVALID) { + r = sd_rtnl_message_append_u16(req, IFLA_IPVLAN_MODE, m->mode); + if (r < 0) { + log_netdev_error(netdev, + "Could not append IFLA_IPVLAN_MODE attribute: %s", + strerror(-r)); + return r; + } + } + + return 0; +} + +static void ipvlan_init(NetDev *n) { + IPVlan *m = IPVLAN(n); + + assert(n); + assert(m); + + m->mode = _NETDEV_IPVLAN_MODE_INVALID; +} + +const NetDevVTable ipvlan_vtable = { + .object_size = sizeof(IPVlan), + .init = ipvlan_init, + .sections = "Match\0NetDev\0IPVLAN\0", + .fill_message_create = netdev_ipvlan_fill_message_create, + .create_type = NETDEV_CREATE_STACKED, +}; diff --git a/src/network/networkd-netdev-ipvlan.h b/src/network/networkd-netdev-ipvlan.h new file mode 100644 index 00000000000..408386f3787 --- /dev/null +++ b/src/network/networkd-netdev-ipvlan.h @@ -0,0 +1,47 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014-2015 Tom Gundersen + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#pragma once + +typedef struct IPVlan IPVlan; + +#include "missing.h" +#include "networkd-netdev.h" + +typedef enum IPVlanMode { + NETDEV_IPVLAN_MODE_L2 = IPVLAN_MODE_L2, + NETDEV_IPVLAN_MODE_L3 = IPVLAN_MODE_L3, + _NETDEV_IPVLAN_MODE_MAX, + _NETDEV_IPVLAN_MODE_INVALID = -1 +} IPVlanMode; + +struct IPVlan { + NetDev meta; + + IPVlanMode mode; +}; + +extern const NetDevVTable ipvlan_vtable; + +const char *ipvlan_mode_to_string(IPVlanMode d) _const_; +IPVlanMode ipvlan_mode_from_string(const char *d) _pure_; + +int config_parse_ipvlan_mode(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); diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index 974547dcdac..89efc8814b9 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -35,6 +35,7 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = { [NETDEV_KIND_BOND] = &bond_vtable, [NETDEV_KIND_VLAN] = &vlan_vtable, [NETDEV_KIND_MACVLAN] = &macvlan_vtable, + [NETDEV_KIND_IPVLAN] = &ipvlan_vtable, [NETDEV_KIND_VXLAN] = &vxlan_vtable, [NETDEV_KIND_IPIP] = &ipip_vtable, [NETDEV_KIND_GRE] = &gre_vtable, @@ -51,6 +52,7 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { [NETDEV_KIND_BOND] = "bond", [NETDEV_KIND_VLAN] = "vlan", [NETDEV_KIND_MACVLAN] = "macvlan", + [NETDEV_KIND_IPVLAN] = "ipvlan", [NETDEV_KIND_VXLAN] = "vxlan", [NETDEV_KIND_IPIP] = "ipip", [NETDEV_KIND_GRE] = "gre", diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h index c1e05c21fbe..1b311c67852 100644 --- a/src/network/networkd-netdev.h +++ b/src/network/networkd-netdev.h @@ -43,6 +43,7 @@ typedef enum NetDevKind { NETDEV_KIND_BOND, NETDEV_KIND_VLAN, NETDEV_KIND_MACVLAN, + NETDEV_KIND_IPVLAN, NETDEV_KIND_VXLAN, NETDEV_KIND_IPIP, NETDEV_KIND_GRE, @@ -100,6 +101,7 @@ struct NetDev { #include "networkd-netdev-bond.h" #include "networkd-netdev-vlan.h" #include "networkd-netdev-macvlan.h" +#include "networkd-netdev-ipvlan.h" #include "networkd-netdev-vxlan.h" #include "networkd-netdev-veth.h" #include "networkd-netdev-tunnel.h" @@ -157,6 +159,7 @@ DEFINE_CAST(BRIDGE, Bridge); DEFINE_CAST(BOND, Bond); DEFINE_CAST(VLAN, VLan); DEFINE_CAST(MACVLAN, MacVlan); +DEFINE_CAST(IPVLAN, IPVlan); DEFINE_CAST(VXLAN, VxLan); DEFINE_CAST(IPIP, Tunnel); DEFINE_CAST(GRE, Tunnel); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 5f2f7419667..26fce97b6ae 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -31,6 +31,7 @@ Network.Bridge, config_parse_netdev, 0, Network.Bond, config_parse_netdev, 0, offsetof(Network, bond) Network.VLAN, config_parse_netdev, 0, 0 Network.MACVLAN, config_parse_netdev, 0, 0 +Network.IPVLAN, config_parse_netdev, 0, 0 Network.VXLAN, config_parse_netdev, 0, 0 Network.Tunnel, config_parse_tunnel, 0, 0 Network.DHCP, config_parse_dhcp, 0, offsetof(Network, dhcp) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 34a06d3f34e..b82452640ac 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -362,6 +362,7 @@ int config_parse_netdev(const char *unit, break; case NETDEV_KIND_VLAN: case NETDEV_KIND_MACVLAN: + case NETDEV_KIND_IPVLAN: case NETDEV_KIND_VXLAN: r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev); if (r < 0) { diff --git a/src/network/test-network-tables.c b/src/network/test-network-tables.c index d1e475a4c02..6709ab0957b 100644 --- a/src/network/test-network-tables.c +++ b/src/network/test-network-tables.c @@ -21,6 +21,7 @@ int main(int argc, char **argv) { test_table(nl_union_link_info_data, NL_UNION_LINK_INFO_DATA); test_table_sparse(macvlan_mode, NETDEV_MACVLAN_MODE); + test_table_sparse(ipvlan_mode, NETDEV_IPVLAN_MODE); test_table_sparse(dhcp6_message_type, DHCP6_MESSAGE); return EXIT_SUCCESS; diff --git a/src/shared/missing.h b/src/shared/missing.h index d074405bec9..5b95b0006f5 100644 --- a/src/shared/missing.h +++ b/src/shared/missing.h @@ -441,6 +441,18 @@ static inline int setns(int fd, int nstype) { #define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1) #endif +#if !HAVE_DECL_IFLA_IPVLAN_MODE +#define IFLA_IPVLAN_UNSPEC 0 +#define IFLA_IPVLAN_MODE 1 +#define __IFLA_IPVLAN_MAX 2 + +#define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1) + +#define IPVLAN_MODE_L2 0 +#define IPVLAN_MODE_L3 1 +#define IPVLAN_MAX 2 +#endif + #if !HAVE_DECL_IFLA_VTI_REMOTE #define IFLA_VTI_UNSPEC 0 #define IFLA_VTI_LINK 1