From 69c317a07f86166a3b23a928dd4b042a43c18290 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 15 May 2019 15:42:30 +0530 Subject: [PATCH] networkd: introduce netdev ipvtap This patch adds netdev ipvtap that is based on the IP-VLAN network interface, called ipvtap. An ipvtap device can be created in the same way as an ipvlan device, using 'kind ipvtap', and then accessed using the tap user space interface. --- man/systemd.netdev.xml | 12 ++++++++++++ src/libsystemd/sd-netlink/netlink-types.c | 3 +++ src/libsystemd/sd-netlink/netlink-types.h | 1 + src/network/netdev/ipvlan.c | 18 ++++++++++++++++-- src/network/netdev/ipvlan.h | 2 ++ src/network/netdev/netdev-gperf.gperf | 2 ++ src/network/netdev/netdev.c | 2 ++ src/network/netdev/netdev.h | 1 + src/network/networkd-network-gperf.gperf | 1 + src/network/networkd-network.c | 4 ++-- test/fuzz/fuzz-netdev-parser/directives.netdev | 3 +++ .../fuzz-network-parser/directives.network | 1 + 12 files changed, 46 insertions(+), 4 deletions(-) diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index 42632a6540e..f11c3e142a6 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -115,6 +115,9 @@ ipvlan An ipvlan device is a stacked device which receives packets from its underlying device based on IP address filtering. + ipvtap + An ipvtap device is a stacked device which receives packets from its underlying device based on IP address filtering and can be accessed using the tap user space interface. + macvlan A macvlan device is a stacked device which receives packets from its underlying device based on MAC address filtering. @@ -519,6 +522,15 @@ + + [IPVTAP] Section Options + + The [IPVTAP] section only applies for + netdevs of kind ipvtap and accepts the + same key as [IPVLAN]. + + + [VXLAN] Section Options The [VXLAN] section only applies for diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index f207d2e5aae..cda9709ea00 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -337,6 +337,7 @@ static const char* const nl_union_link_info_data_table[] = { [NL_UNION_LINK_INFO_DATA_MACVLAN] = "macvlan", [NL_UNION_LINK_INFO_DATA_MACVTAP] = "macvtap", [NL_UNION_LINK_INFO_DATA_IPVLAN] = "ipvlan", + [NL_UNION_LINK_INFO_DATA_IPVTAP] = "ipvtap", [NL_UNION_LINK_INFO_DATA_VXLAN] = "vxlan", [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = "ipip", [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = "gre", @@ -375,6 +376,8 @@ static const NLTypeSystem rtnl_link_info_data_type_systems[] = { .types = rtnl_link_info_data_macvlan_types }, [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), .types = rtnl_link_info_data_ipvlan_types }, + [NL_UNION_LINK_INFO_DATA_IPVTAP] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), + .types = rtnl_link_info_data_ipvlan_types }, [NL_UNION_LINK_INFO_DATA_VXLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types), .types = rtnl_link_info_data_vxlan_types }, [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index a2b3087d159..8585280463a 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -62,6 +62,7 @@ typedef enum NLUnionLinkInfoData { NL_UNION_LINK_INFO_DATA_MACVLAN, NL_UNION_LINK_INFO_DATA_MACVTAP, NL_UNION_LINK_INFO_DATA_IPVLAN, + NL_UNION_LINK_INFO_DATA_IPVTAP, 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/netdev/ipvlan.c b/src/network/netdev/ipvlan.c index 5bb6a5bb35b..7b251767672 100644 --- a/src/network/netdev/ipvlan.c +++ b/src/network/netdev/ipvlan.c @@ -32,7 +32,10 @@ static int netdev_ipvlan_fill_message_create(NetDev *netdev, Link *link, sd_netl assert(link); assert(netdev->ifname); - m = IPVLAN(netdev); + if (netdev->kind == NETDEV_KIND_IPVLAN) + m = IPVLAN(netdev); + else + m = IPVTAP(netdev); assert(m); @@ -56,7 +59,10 @@ static void ipvlan_init(NetDev *n) { assert(n); - m = IPVLAN(n); + if (n->kind == NETDEV_KIND_IPVLAN) + m = IPVLAN(n); + else + m = IPVTAP(n); assert(m); @@ -71,3 +77,11 @@ const NetDevVTable ipvlan_vtable = { .fill_message_create = netdev_ipvlan_fill_message_create, .create_type = NETDEV_CREATE_STACKED, }; + +const NetDevVTable ipvtap_vtable = { + .object_size = sizeof(IPVlan), + .init = ipvlan_init, + .sections = "Match\0NetDev\0IPVTAP\0", + .fill_message_create = netdev_ipvlan_fill_message_create, + .create_type = NETDEV_CREATE_STACKED, +}; diff --git a/src/network/netdev/ipvlan.h b/src/network/netdev/ipvlan.h index eb67b5c1959..140cacf4fcb 100644 --- a/src/network/netdev/ipvlan.h +++ b/src/network/netdev/ipvlan.h @@ -30,7 +30,9 @@ typedef struct IPVlan { } IPVlan; DEFINE_NETDEV_CAST(IPVLAN, IPVlan); +DEFINE_NETDEV_CAST(IPVTAP, IPVlan); extern const NetDevVTable ipvlan_vtable; +extern const NetDevVTable ipvtap_vtable; const char *ipvlan_mode_to_string(IPVlanMode d) _const_; IPVlanMode ipvlan_mode_from_string(const char *d) _pure_; diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf index e18d746befc..dd2184249e1 100644 --- a/src/network/netdev/netdev-gperf.gperf +++ b/src/network/netdev/netdev-gperf.gperf @@ -54,6 +54,8 @@ MACVLAN.Mode, config_parse_macvlan_mode, MACVTAP.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode) IPVLAN.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode) IPVLAN.Flags, config_parse_ipvlan_flags, 0, offsetof(IPVlan, flags) +IPVTAP.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode) +IPVTAP.Flags, config_parse_ipvlan_flags, 0, offsetof(IPVlan, flags) 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/netdev/netdev.c b/src/network/netdev/netdev.c index 3f9d1e5f122..3968ab54956 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -45,6 +45,7 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = { [NETDEV_KIND_MACVLAN] = &macvlan_vtable, [NETDEV_KIND_MACVTAP] = &macvtap_vtable, [NETDEV_KIND_IPVLAN] = &ipvlan_vtable, + [NETDEV_KIND_IPVTAP] = &ipvtap_vtable, [NETDEV_KIND_VXLAN] = &vxlan_vtable, [NETDEV_KIND_IPIP] = &ipip_vtable, [NETDEV_KIND_GRE] = &gre_vtable, @@ -78,6 +79,7 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { [NETDEV_KIND_MACVLAN] = "macvlan", [NETDEV_KIND_MACVTAP] = "macvtap", [NETDEV_KIND_IPVLAN] = "ipvlan", + [NETDEV_KIND_IPVTAP] = "ipvtap", [NETDEV_KIND_VXLAN] = "vxlan", [NETDEV_KIND_IPIP] = "ipip", [NETDEV_KIND_GRE] = "gre", diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index 29ecead029b..dcf072ce944 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -24,6 +24,7 @@ typedef enum NetDevKind { NETDEV_KIND_MACVLAN, NETDEV_KIND_MACVTAP, NETDEV_KIND_IPVLAN, + NETDEV_KIND_IPVTAP, NETDEV_KIND_VXLAN, NETDEV_KIND_IPIP, NETDEV_KIND_GRE, diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 3c6b5ac1004..825fbf603a0 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -44,6 +44,7 @@ Network.VLAN, config_parse_stacked_netdev, Network.MACVLAN, config_parse_stacked_netdev, NETDEV_KIND_MACVLAN, offsetof(Network, stacked_netdev_names) Network.MACVTAP, config_parse_stacked_netdev, NETDEV_KIND_MACVTAP, offsetof(Network, stacked_netdev_names) Network.IPVLAN, config_parse_stacked_netdev, NETDEV_KIND_IPVLAN, offsetof(Network, stacked_netdev_names) +Network.IPVTAP, config_parse_stacked_netdev, NETDEV_KIND_IPVTAP, offsetof(Network, stacked_netdev_names) Network.VXLAN, config_parse_stacked_netdev, NETDEV_KIND_VXLAN, offsetof(Network, stacked_netdev_names) Network.L2TP, config_parse_stacked_netdev, NETDEV_KIND_L2TP, offsetof(Network, stacked_netdev_names) Network.MACsec, config_parse_stacked_netdev, NETDEV_KIND_MACSEC, offsetof(Network, stacked_netdev_names) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 755cd604dca..324026e975e 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -708,8 +708,8 @@ int config_parse_stacked_netdev(const char *unit, assert(data); assert(IN_SET(kind, NETDEV_KIND_VLAN, NETDEV_KIND_MACVLAN, NETDEV_KIND_MACVTAP, - NETDEV_KIND_IPVLAN, NETDEV_KIND_VXLAN, NETDEV_KIND_L2TP, - NETDEV_KIND_MACSEC, _NETDEV_KIND_TUNNEL)); + NETDEV_KIND_IPVLAN, NETDEV_KIND_IPVTAP, NETDEV_KIND_VXLAN, + NETDEV_KIND_L2TP, NETDEV_KIND_MACSEC, _NETDEV_KIND_TUNNEL)); if (!ifname_valid(rvalue)) { log_syntax(unit, LOG_ERR, filename, line, 0, diff --git a/test/fuzz/fuzz-netdev-parser/directives.netdev b/test/fuzz/fuzz-netdev-parser/directives.netdev index 0b332a6e7a2..a49acacc3f5 100644 --- a/test/fuzz/fuzz-netdev-parser/directives.netdev +++ b/test/fuzz/fuzz-netdev-parser/directives.netdev @@ -151,6 +151,9 @@ VNetHeader= [IPVLAN] Mode= Flags= +[IPVTAP] +Mode= +Flags= [Tun] OneQueue= MultiQueue= diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index ef29c7951f3..5861c41e757 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -104,6 +104,7 @@ Tunnel= Gateway= IPv4LL= IPVLAN= +IPVTAP= EmitLLDP= IPv6MTUBytes= IPv4ProxyARP=