Merge pull request #16405 from sipraga/master

This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-07-08 22:31:42 +02:00
commit 48c190822b
8 changed files with 72 additions and 2 deletions

View File

@ -499,11 +499,22 @@
<para>The MACVLAN mode to use. The supported options are
<literal>private</literal>,
<literal>vepa</literal>,
<literal>bridge</literal>, and
<literal>passthru</literal>.
<literal>bridge</literal>,
<literal>passthru</literal>, and
<literal>source</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>SourceMACAddress=</varname></term>
<listitem>
<para>A whitespace-separated list of remote hardware addresses allowed on the MACVLAN. This
option only has an effect in source mode. Use full colon-, hyphen- or dot-delimited
hexadecimal. This option may appear more than once, in which case the lists are merged. If
the empty string is assigned to this option, the list of hardware addresses defined prior
to this is reset. Defaults to unset.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -93,9 +93,20 @@ static const NLType rtnl_link_info_data_ipvlan_types[] = {
[IFLA_IPVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 },
};
static const NLType rtnl_macvlan_macaddr_types[] = {
[IFLA_MACVLAN_MACADDR] = { .type = NETLINK_TYPE_ETHER_ADDR },
};
static const NLTypeSystem rtnl_macvlan_macaddr_type_system = {
.count = ELEMENTSOF(rtnl_macvlan_macaddr_types),
.types = rtnl_macvlan_macaddr_types,
};
static const NLType rtnl_link_info_data_macvlan_types[] = {
[IFLA_MACVLAN_MODE] = { .type = NETLINK_TYPE_U32 },
[IFLA_MACVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 },
[IFLA_MACVLAN_MACADDR_MODE] = { .type = NETLINK_TYPE_U32 },
[IFLA_MACVLAN_MACADDR_DATA] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_macvlan_macaddr_type_system },
};
static const NLType rtnl_link_info_data_bridge_types[] = {

View File

@ -23,6 +23,29 @@ static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_net
assert(m);
if (m->mode == NETDEV_MACVLAN_MODE_SOURCE && !set_isempty(m->match_source_mac)) {
Iterator i;
const struct ether_addr *mac_addr;
r = sd_netlink_message_append_u32(req, IFLA_MACVLAN_MACADDR_MODE, MACVLAN_MACADDR_SET);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_MACVLAN_MACADDR_MODE attribute: %m");
r = sd_netlink_message_open_container(req, IFLA_MACVLAN_MACADDR_DATA);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not open IFLA_MACVLAN_MACADDR_DATA container: %m");
SET_FOREACH(mac_addr, m->match_source_mac, i) {
r = sd_netlink_message_append_ether_addr(req, IFLA_MACVLAN_MACADDR, mac_addr);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_MACVLAN_MACADDR attribute: %m");
}
r = sd_netlink_message_close_container(req);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not close IFLA_MACVLAN_MACADDR_DATA container: %m");
}
if (m->mode != _NETDEV_MACVLAN_MODE_INVALID) {
r = sd_netlink_message_append_u32(req, IFLA_MACVLAN_MODE, m->mode);
if (r < 0)
@ -32,6 +55,21 @@ static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_net
return 0;
}
static void macvlan_done(NetDev *n) {
MacVlan *m;
assert(n);
if (n->kind == NETDEV_KIND_MACVLAN)
m = MACVLAN(n);
else
m = MACVTAP(n);
assert(m);
set_free_free(m->match_source_mac);
}
static void macvlan_init(NetDev *n) {
MacVlan *m;
@ -50,6 +88,7 @@ static void macvlan_init(NetDev *n) {
const NetDevVTable macvtap_vtable = {
.object_size = sizeof(MacVlan),
.init = macvlan_init,
.done = macvlan_done,
.sections = NETDEV_COMMON_SECTIONS "MACVTAP\0",
.fill_message_create = netdev_macvlan_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
@ -59,6 +98,7 @@ const NetDevVTable macvtap_vtable = {
const NetDevVTable macvlan_vtable = {
.object_size = sizeof(MacVlan),
.init = macvlan_init,
.done = macvlan_done,
.sections = NETDEV_COMMON_SECTIONS "MACVLAN\0",
.fill_message_create = netdev_macvlan_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,

View File

@ -5,11 +5,13 @@ typedef struct MacVlan MacVlan;
#include "macvlan-util.h"
#include "netdev.h"
#include "set.h"
struct MacVlan {
NetDev meta;
MacVlanMode mode;
Set *match_source_mac;
};
DEFINE_NETDEV_CAST(MACVLAN, MacVlan);

View File

@ -52,7 +52,9 @@ VLAN.MVRP, config_parse_tristate,
VLAN.LooseBinding, config_parse_tristate, 0, offsetof(VLan, loose_binding)
VLAN.ReorderHeader, config_parse_tristate, 0, offsetof(VLan, reorder_hdr)
MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
MACVLAN.SourceMACAddress, config_parse_hwaddrs, 0, offsetof(MacVlan, match_source_mac)
MACVTAP.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
MACVTAP.SourceMACAddress, config_parse_hwaddrs, 0, offsetof(MacVlan, match_source_mac)
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)

View File

@ -9,6 +9,7 @@ static const char* const macvlan_mode_table[_NETDEV_MACVLAN_MODE_MAX] = {
[NETDEV_MACVLAN_MODE_VEPA] = "vepa",
[NETDEV_MACVLAN_MODE_BRIDGE] = "bridge",
[NETDEV_MACVLAN_MODE_PASSTHRU] = "passthru",
[NETDEV_MACVLAN_MODE_SOURCE] = "source",
};
DEFINE_STRING_TABLE_LOOKUP(macvlan_mode, MacVlanMode);

View File

@ -8,6 +8,7 @@ typedef enum MacVlanMode {
NETDEV_MACVLAN_MODE_VEPA = MACVLAN_MODE_VEPA,
NETDEV_MACVLAN_MODE_BRIDGE = MACVLAN_MODE_BRIDGE,
NETDEV_MACVLAN_MODE_PASSTHRU = MACVLAN_MODE_PASSTHRU,
NETDEV_MACVLAN_MODE_SOURCE = MACVLAN_MODE_SOURCE,
_NETDEV_MACVLAN_MODE_MAX,
_NETDEV_MACVLAN_MODE_INVALID = -1
} MacVlanMode;

View File

@ -6,6 +6,7 @@ Id=
GVRP=
[MACVLAN]
Mode=
SourceMACAddress=
[WireGuard]
ListenPort=
PrivateKey=
@ -14,6 +15,7 @@ FwMark=
FirewallMark=
[MACVTAP]
Mode=
SourceMACAddress=
[Match]
Architecture=
Host=