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)