From: Yu Watanabe Date: Mon, 22 Jun 2020 10:48:33 +0000 (+0900) Subject: network: add MACAddress= setting in [SR-IOV] section X-Git-Tag: v246-rc1~54^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c3a5025dc61b6902f39bc8a374beda9345e8fa40;p=thirdparty%2Fsystemd.git network: add MACAddress= setting in [SR-IOV] section --- diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 7c31f345ab8..ea470be5b1e 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -315,6 +315,12 @@ + + MACAddress= + + Specifies the MAC address for the virtual function. + + diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index f1937ac251f..9bdd6398312 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -62,6 +62,7 @@ SR-IOV.MACSpoofCheck, config_parse_sr_iov_boolean, SR-IOV.QueryReceiveSideScaling, config_parse_sr_iov_boolean, 0, 0 SR-IOV.Trust, config_parse_sr_iov_boolean, 0, 0 SR-IOV.LinkState, config_parse_sr_iov_link_state, 0, 0 +SR-IOV.MACAddress, config_parse_sr_iov_mac, 0, 0 Network.Description, config_parse_string, 0, offsetof(Network, description) Network.Bridge, config_parse_ifname, 0, offsetof(Network, bridge_name) Network.Bond, config_parse_ifname, 0, offsetof(Network, bond_name) diff --git a/src/network/networkd-sriov.c b/src/network/networkd-sriov.c index 62a6fc9c225..5ae751ed46f 100644 --- a/src/network/networkd-sriov.c +++ b/src/network/networkd-sriov.c @@ -131,6 +131,17 @@ int sr_iov_configure(Link *link, SRIOV *sr_iov) { if (r < 0) return log_link_error_errno(link, r, "Could not open IFLA_VF_INFO container: %m"); + if (!ether_addr_is_null(&sr_iov->mac)) { + struct ifla_vf_mac ivm = { + .vf = sr_iov->vf, + }; + + memcpy(ivm.mac, &sr_iov->mac, ETH_ALEN); + r = sd_netlink_message_append_data(req, IFLA_VF_MAC, &ivm, sizeof(struct ifla_vf_mac)); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_VF_MAC: %m"); + } + if (sr_iov->vf_spoof_check_setting >= 0) { struct ifla_vf_spoofchk ivs = { .vf = sr_iov->vf, @@ -446,3 +457,45 @@ int config_parse_sr_iov_boolean( TAKE_PTR(sr_iov); return 0; } + +int config_parse_sr_iov_mac( + 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) { + + _cleanup_(sr_iov_free_or_set_invalidp) SRIOV *sr_iov = NULL; + Network *network = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + r = sr_iov_new_static(network, filename, section_line, &sr_iov); + if (r < 0) + return r; + + if (isempty(rvalue)) { + sr_iov->mac = ETHER_ADDR_NULL; + TAKE_PTR(sr_iov); + return 0; + } + + r = ether_addr_from_string(rvalue, &sr_iov->mac); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, 0, + "Failed to parse SR-IOV '%s=', ignoring assignment: %s", lvalue, rvalue); + return 0; + } + + TAKE_PTR(sr_iov); + return 0; +} diff --git a/src/network/networkd-sriov.h b/src/network/networkd-sriov.h index 65ad3266b3d..a545d1292ae 100644 --- a/src/network/networkd-sriov.h +++ b/src/network/networkd-sriov.h @@ -29,6 +29,7 @@ typedef struct SRIOV { int query_rss; int trust; SRIOVLinkState link_state; + struct ether_addr mac; } SRIOV; SRIOV *sr_iov_free(SRIOV *sr_iov); @@ -42,3 +43,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_uint32); CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_boolean); CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_link_state); CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_vlan_proto); +CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_mac); diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index c5bab2abf83..da4a9647ab3 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -47,6 +47,7 @@ QualityOfService= QueryReceiveSideScaling= Trust= LinkState= +MACAddress= [BridgeFDB] VLANId= MACAddress=