diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index c92792341b..4e5d47f585 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -499,7 +499,15 @@ Mode= The IPVLAN mode to use. The supported options are - L2 and L3. + L2,L3 and L3S. + + + + + Flags= + + The IPVLAN flags to use. The supported options are + bridge,private and vepa. diff --git a/meson.build b/meson.build index 9c0b5dafc8..be8e610452 100644 --- a/meson.build +++ b/meson.build @@ -422,7 +422,7 @@ foreach decl : [['IFLA_INET6_ADDR_GEN_MODE', 'linux/if_link.h'], ['IN6_ADDR_GEN_MODE_STABLE_PRIVACY', 'linux/if_link.h'], ['IFLA_VRF_TABLE', 'linux/if_link.h'], ['IFLA_MACVLAN_FLAGS', 'linux/if_link.h'], - ['IFLA_IPVLAN_MODE', 'linux/if_link.h'], + ['IFLA_IPVLAN_FLAGS', 'linux/if_link.h'], ['IFLA_PHYS_PORT_ID', 'linux/if_link.h'], ['IFLA_BOND_AD_INFO', 'linux/if_link.h'], ['IFLA_VLAN_PROTOCOL', 'linux/if_link.h'], @@ -437,6 +437,7 @@ foreach decl : [['IFLA_INET6_ADDR_GEN_MODE', 'linux/if_link.h'], ['IFLA_BRPORT_PROXYARP', 'linux/if_link.h'], ['IFLA_BRPORT_LEARNING_SYNC', 'linux/if_link.h'], ['IFLA_BR_VLAN_DEFAULT_PVID', 'linux/if_link.h'], + ['IPVLAN_F_PRIVATE', 'linux/if_link.h'], ['NDA_IFINDEX', 'linux/neighbour.h'], ['IFA_FLAGS', 'linux/if_addr.h'], ['FRA_UID_RANGE', 'linux/fib_rules.h'], diff --git a/src/basic/missing.h b/src/basic/missing.h index 66f0caf294..a6b10b16bb 100644 --- a/src/basic/missing.h +++ b/src/basic/missing.h @@ -711,18 +711,28 @@ struct input_mask { #define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1) #endif -#if !HAVE_IFLA_IPVLAN_MODE +#if !HAVE_IFLA_IPVLAN_FLAGS #define IFLA_IPVLAN_UNSPEC 0 #define IFLA_IPVLAN_MODE 1 -#define __IFLA_IPVLAN_MAX 2 +#define IFLA_IPVLAN_FLAGS 2 +#define __IFLA_IPVLAN_MAX 3 #define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1) #define IPVLAN_MODE_L2 0 #define IPVLAN_MODE_L3 1 +#define IPVLAN_MODE_L3S 2 #define IPVLAN_MAX 2 #endif +#if !HAVE_IPVLAN_F_PRIVATE +#define IPVLAN_F_PRIVATE 0x01 +#define IPVLAN_F_VEPA 0x02 +#define __IPVLAN_F_PRIVATE_MAX 3 + +#define HAVE_IPVLAN_F_PRIVATE_MAX (__HAVE_IPVLAN_F_PRIVATE_MAX - 1) +#endif + #if !HAVE_IFLA_VTI_REMOTE #define IFLA_VTI_UNSPEC 0 #define IFLA_VTI_LINK 1 diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index f8be296d37..49a2f2a1e4 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -102,6 +102,7 @@ static const NLType rtnl_link_info_data_vxcan_types[] = { static const NLType rtnl_link_info_data_ipvlan_types[] = { [IFLA_IPVLAN_MODE] = { .type = NETLINK_TYPE_U16 }, + [IFLA_IPVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 }, }; static const NLType rtnl_link_info_data_macvlan_types[] = { diff --git a/src/network/netdev/ipvlan.c b/src/network/netdev/ipvlan.c index df9487418b..418729c7ef 100644 --- a/src/network/netdev/ipvlan.c +++ b/src/network/netdev/ipvlan.c @@ -27,11 +27,21 @@ static const char* const ipvlan_mode_table[_NETDEV_IPVLAN_MODE_MAX] = { [NETDEV_IPVLAN_MODE_L2] = "L2", [NETDEV_IPVLAN_MODE_L3] = "L3", + [NETDEV_IPVLAN_MODE_L3S] = "L3S", }; DEFINE_STRING_TABLE_LOOKUP(ipvlan_mode, IPVlanMode); DEFINE_CONFIG_PARSE_ENUM(config_parse_ipvlan_mode, ipvlan_mode, IPVlanMode, "Failed to parse ipvlan mode"); +static const char* const ipvlan_flags_table[_NETDEV_IPVLAN_FLAGS_MAX] = { + [NETDEV_IPVLAN_FLAGS_BRIGDE] = "bridge", + [NETDEV_IPVLAN_FLAGS_PRIVATE] = "private", + [NETDEV_IPVLAN_FLAGS_VEPA] = "vepa", +}; + +DEFINE_STRING_TABLE_LOOKUP(ipvlan_flags, IPVlanFlags); +DEFINE_CONFIG_PARSE_ENUM(config_parse_ipvlan_flags, ipvlan_flags, IPVlanFlags, "Failed to parse ipvlan flags"); + static int netdev_ipvlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) { IPVlan *m; int r; @@ -50,6 +60,12 @@ static int netdev_ipvlan_fill_message_create(NetDev *netdev, Link *link, sd_netl return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPVLAN_MODE attribute: %m"); } + if (m->flags != _NETDEV_IPVLAN_FLAGS_INVALID) { + r = sd_netlink_message_append_u16(req, IFLA_IPVLAN_FLAGS, m->flags); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPVLAN_FLAGS attribute: %m"); + } + return 0; } @@ -63,6 +79,7 @@ static void ipvlan_init(NetDev *n) { assert(m); m->mode = _NETDEV_IPVLAN_MODE_INVALID; + m->mode = _NETDEV_IPVLAN_FLAGS_INVALID; } const NetDevVTable ipvlan_vtable = { diff --git a/src/network/netdev/ipvlan.h b/src/network/netdev/ipvlan.h index cb43db4348..b6bc1ac739 100644 --- a/src/network/netdev/ipvlan.h +++ b/src/network/netdev/ipvlan.h @@ -20,20 +20,33 @@ along with systemd; If not, see . ***/ +#include + #include "missing.h" #include "netdev/netdev.h" + typedef enum IPVlanMode { NETDEV_IPVLAN_MODE_L2 = IPVLAN_MODE_L2, NETDEV_IPVLAN_MODE_L3 = IPVLAN_MODE_L3, + NETDEV_IPVLAN_MODE_L3S = IPVLAN_MODE_L3S, _NETDEV_IPVLAN_MODE_MAX, _NETDEV_IPVLAN_MODE_INVALID = -1 } IPVlanMode; +typedef enum IPVlanFlags { + NETDEV_IPVLAN_FLAGS_BRIGDE, + NETDEV_IPVLAN_FLAGS_PRIVATE = IPVLAN_F_PRIVATE, + NETDEV_IPVLAN_FLAGS_VEPA = IPVLAN_F_VEPA, + _NETDEV_IPVLAN_FLAGS_MAX, + _NETDEV_IPVLAN_FLAGS_INVALID = -1 +} IPVlanFlags; + typedef struct IPVlan { NetDev meta; IPVlanMode mode; + IPVlanFlags flags; } IPVlan; DEFINE_NETDEV_CAST(IPVLAN, IPVlan); @@ -42,4 +55,8 @@ extern const NetDevVTable ipvlan_vtable; const char *ipvlan_mode_to_string(IPVlanMode d) _const_; IPVlanMode ipvlan_mode_from_string(const char *d) _pure_; +const char *ipvlan_flags_to_string(IPVlanFlags d) _const_; +IPVlanFlags ipvlan_flags_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); +int config_parse_ipvlan_flags(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/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf index 628e6648b7..3aeba06ee0 100644 --- a/src/network/netdev/netdev-gperf.gperf +++ b/src/network/netdev/netdev-gperf.gperf @@ -48,6 +48,7 @@ VLAN.ReorderHeader, config_parse_tristate, 0, MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(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) 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)