summaryrefslogtreecommitdiffstats
path: root/src/network/netdev
diff options
context:
space:
mode:
authorAlvin Šipraga <alsi@bang-olufsen.dk>2020-07-08 15:52:23 +0200
committerAlvin Šipraga <alsi@bang-olufsen.dk>2020-07-08 18:01:52 +0200
commit0d0de133f04d3870273970cfa4d61aac1ae06098 (patch)
tree911c536fc8cebdb40cb85b787641057c54e568f4 /src/network/netdev
parentMerge pull request #16385 from JackFangXN/master (diff)
downloadsystemd-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.c40
-rw-r--r--src/network/netdev/macvlan.h2
-rw-r--r--src/network/netdev/netdev-gperf.gperf2
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)