diff options
author | Alvin Šipraga <alsi@bang-olufsen.dk> | 2020-07-08 15:52:23 +0200 |
---|---|---|
committer | Alvin Šipraga <alsi@bang-olufsen.dk> | 2020-07-08 18:01:52 +0200 |
commit | 0d0de133f04d3870273970cfa4d61aac1ae06098 (patch) | |
tree | 911c536fc8cebdb40cb85b787641057c54e568f4 /src/network/netdev | |
parent | Merge pull request #16385 from JackFangXN/master (diff) | |
download | systemd-0d0de133f04d3870273970cfa4d61aac1ae06098.tar.xz systemd-0d0de133f04d3870273970cfa4d61aac1ae06098.zip |
network: add support for MACVLAN source mode
Add support for creating a MACVLAN interface in "source" mode by
specifying Mode=source in the [MACVLAN] section of a .netdev file.
A list of allowed MAC addresses for the corresponding MACVLAN can also
be specified with the SourceMACAddress= option of the [MACVLAN] section.
An example .netdev file:
[NetDev]
Name=macvlan0
Kind=macvlan
MACAddress=02:DE:AD:BE:EF:00
[MACVLAN]
Mode=source
SourceMACAddress=02:AB:AB:AB:AB:01 02:CD:CD:CD:CD:01
SourceMACAddress=02:EF:EF:EF:EF:01
The same keys can also be specified in [MACVTAP] for MACVTAP kinds of
interfaces, with the same semantics.
Diffstat (limited to 'src/network/netdev')
-rw-r--r-- | src/network/netdev/macvlan.c | 40 | ||||
-rw-r--r-- | src/network/netdev/macvlan.h | 2 | ||||
-rw-r--r-- | src/network/netdev/netdev-gperf.gperf | 2 |
3 files changed, 44 insertions, 0 deletions
diff --git a/src/network/netdev/macvlan.c b/src/network/netdev/macvlan.c index e41ed9e6ed..41391788b0 100644 --- a/src/network/netdev/macvlan.c +++ b/src/network/netdev/macvlan.c @@ -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, diff --git a/src/network/netdev/macvlan.h b/src/network/netdev/macvlan.h index 7e4d685bdb..7bc6eef12d 100644 --- a/src/network/netdev/macvlan.h +++ b/src/network/netdev/macvlan.h @@ -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); diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf index b14835c313..0e2a9ce045 100644 --- a/src/network/netdev/netdev-gperf.gperf +++ b/src/network/netdev/netdev-gperf.gperf @@ -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) |