<term><varname>Mode=</varname></term>
<listitem>
<para>The IPVLAN mode to use. The supported options are
- <literal>L2</literal> and <literal>L3</literal>.
+ <literal>L2</literal>,<literal>L3</literal> and <literal>L3S</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>Flags=</varname></term>
+ <listitem>
+ <para>The IPVLAN flags to use. The supported options are
+ <literal>bridge</literal>,<literal>private</literal> and <literal>vepa</literal>.
</para>
</listitem>
</varlistentry>
['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'],
['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'],
#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
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[] = {
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;
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;
}
assert(m);
m->mode = _NETDEV_IPVLAN_MODE_INVALID;
+ m->mode = _NETDEV_IPVLAN_FLAGS_INVALID;
}
const NetDevVTable ipvlan_vtable = {
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <linux/if_link.h>
+
#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);
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);
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)