From: Yu Watanabe Date: Mon, 8 Nov 2021 00:41:51 +0000 (+0900) Subject: network: add support to configure IPoIB interfaces X-Git-Tag: v250-rc1~83^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=72e65e6ffd9d8f2ea52c8c6f76fbf6e5cc5da3ab;p=thirdparty%2Fsystemd.git network: add support to configure IPoIB interfaces --- diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 1de7bb05387..e8e01f9094c 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -3227,6 +3227,15 @@ Token=prefixstable:2002:da8:1:: + + [IPoIB] Section Options + The [IPoIB] section manages the IP over Infiniband and accepts the following keys: + + + + + + [QDisc] Section Options The [QDisc] section manages the traffic control queueing discipline (qdisc). diff --git a/src/network/netdev/ipoib.c b/src/network/netdev/ipoib.c index b341001bc4f..c3f583fc467 100644 --- a/src/network/netdev/ipoib.c +++ b/src/network/netdev/ipoib.c @@ -4,6 +4,7 @@ #include #include "ipoib.h" +#include "networkd-network.h" #include "parse-util.h" #include "string-table.h" @@ -56,6 +57,48 @@ static int netdev_ipoib_fill_message_create(NetDev *netdev, Link *link, sd_netli return 0; } +int ipoib_set_netlink_message(Link *link, sd_netlink_message *m) { + int r; + + assert(link); + assert(link->network); + assert(m); + + r = sd_netlink_message_set_flags(m, NLM_F_REQUEST | NLM_F_ACK); + if (r < 0) + return log_link_debug_errno(link, r, "Could not set netlink flags: %m"); + + r = sd_netlink_message_open_container(m, IFLA_LINKINFO); + if (r < 0) + return log_link_debug_errno(link, r, "Failed to open IFLA_LINKINFO container: %m"); + + r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, link->kind); + if (r < 0) + return log_link_debug_errno(link, r, "Could not open IFLA_INFO_DATA container: %m"); + + if (link->network->ipoib_mode >= 0) { + r = sd_netlink_message_append_u16(m, IFLA_IPOIB_MODE, link->network->ipoib_mode); + if (r < 0) + return log_link_debug_errno(link, r, "Could not append IFLA_IPOIB_MODE attribute: %m"); + } + + if (link->network->ipoib_umcast >= 0) { + r = sd_netlink_message_append_u16(m, IFLA_IPOIB_UMCAST, link->network->ipoib_umcast); + if (r < 0) + return log_link_debug_errno(link, r, "Could not append IFLA_IPOIB_UMCAST attribute: %m"); + } + + r = sd_netlink_message_close_container(m); + if (r < 0) + return log_link_debug_errno(link, r, "Failed to close IFLA_INFO_DATA container: %m"); + + r = sd_netlink_message_close_container(m); + if (r < 0) + return log_link_debug_errno(link, r, "Failed to close IFLA_LINKINFO container: %m"); + + return 0; +} + static const char * const ipoib_mode_table[_IP_OVER_INFINIBAND_MODE_MAX] = { [IP_OVER_INFINIBAND_MODE_DATAGRAM] = "datagram", [IP_OVER_INFINIBAND_MODE_CONNECTED] = "connected", diff --git a/src/network/netdev/ipoib.h b/src/network/netdev/ipoib.h index d2f5d9350f0..415d3b107c8 100644 --- a/src/network/netdev/ipoib.h +++ b/src/network/netdev/ipoib.h @@ -24,5 +24,7 @@ typedef struct IPoIB { DEFINE_NETDEV_CAST(IPOIB, IPoIB); extern const NetDevVTable ipoib_vtable; +int ipoib_set_netlink_message(Link *link, sd_netlink_message *m); + CONFIG_PARSER_PROTOTYPE(config_parse_ipoib_pkey); CONFIG_PARSER_PROTOTYPE(config_parse_ipoib_mode); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 4df3e19220d..266334e78ce 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1101,6 +1101,10 @@ static int link_configure(Link *link) { if (r < 0) return r; + r = link_request_to_set_ipoib(link); + if (r < 0) + return r; + r = link_request_to_set_flags(link); if (r < 0) return r; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 4ac58a26ad0..3b8d45c1bb5 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -382,6 +382,8 @@ CAN.PresumeACK, config_parse_can_control_mode, CAN.FDNonISO, config_parse_can_control_mode, CAN_CTRLMODE_FD_NON_ISO, 0 CAN.ClassicDataLengthCode, config_parse_can_control_mode, CAN_CTRLMODE_CC_LEN8_DLC, 0 CAN.Termination, config_parse_can_termination, 0, 0 +IPoIB.Mode, config_parse_ipoib_mode, 0, offsetof(Network, ipoib_mode) +IPoIB.IgnoreUserspaceMulticastGroups, config_parse_tristate, 0, offsetof(Network, ipoib_umcast) QDisc.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0 QDisc.Handle, config_parse_qdisc_handle, _QDISC_KIND_INVALID, 0 BFIFO.Parent, config_parse_qdisc_parent, QDISC_KIND_BFIFO, 0 diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 7640429f461..6651c6c04cc 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -476,6 +476,9 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi .ipv6_accept_ra_start_dhcp6_client = IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES, .can_termination = -1, + + .ipoib_mode = _IP_OVER_INFINIBAND_MODE_INVALID, + .ipoib_umcast = -1, }; r = config_parse_many( diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 2fdd4994c4c..9304ceaafbf 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -11,6 +11,7 @@ #include "condition.h" #include "conf-parser.h" #include "hashmap.h" +#include "ipoib.h" #include "net-condition.h" #include "netdev.h" #include "networkd-bridge-vlan.h" @@ -286,6 +287,10 @@ struct Network { uint16_t can_termination; bool can_termination_set; + /* IPoIB support */ + IPoIBMode ipoib_mode; + int ipoib_umcast; + /* sysctl settings */ AddressFamily ip_forward; int ipv4_accept_local; diff --git a/src/network/networkd-setlink.c b/src/network/networkd-setlink.c index e7b39778da6..d32dc81794c 100644 --- a/src/network/networkd-setlink.c +++ b/src/network/networkd-setlink.c @@ -24,6 +24,7 @@ static const char *const set_link_operation_table[_SET_LINK_OPERATION_MAX] = { [SET_LINK_CAN] = "CAN interface configurations", [SET_LINK_FLAGS] = "link flags", [SET_LINK_GROUP] = "interface group", + [SET_LINK_IPOIB] = "IPoIB configurations", [SET_LINK_MAC] = "MAC address", [SET_LINK_MASTER] = "master interface", [SET_LINK_MTU] = "MTU", @@ -153,6 +154,10 @@ static int link_set_group_handler(sd_netlink *rtnl, sd_netlink_message *m, Link return set_link_handler_internal(rtnl, m, link, SET_LINK_GROUP, /* ignore = */ false, NULL); } +static int link_set_ipoib_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { + return set_link_handler_internal(rtnl, m, link, SET_LINK_IPOIB, /* ignore = */ true, NULL); +} + static int link_set_mac_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { return set_link_handler_internal(rtnl, m, link, SET_LINK_MAC, /* ignore = */ true, get_link_default_handler); } @@ -236,7 +241,7 @@ static int link_configure( r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->master_ifindex); if (r < 0) return log_link_debug_errno(link, r, "Could not allocate RTM_NEWLINK message: %m"); - } else if (op == SET_LINK_CAN) { + } else if (IN_SET(op, SET_LINK_CAN, SET_LINK_IPOIB)) { r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->ifindex); if (r < 0) return log_link_debug_errno(link, r, "Could not allocate RTM_NEWLINK message: %m"); @@ -468,6 +473,11 @@ static int link_configure( if (r < 0) return log_link_debug_errno(link, r, "Could not append IFLA_ADDRESS attribute: %m"); break; + case SET_LINK_IPOIB: + r = ipoib_set_netlink_message(link, req); + if (r < 0) + return r; + break; case SET_LINK_MASTER: r = sd_netlink_message_append_u32(req, IFLA_MASTER, PTR_TO_UINT32(userdata)); if (r < 0) @@ -800,6 +810,20 @@ int link_request_to_set_mac(Link *link, bool allow_retry) { NULL); } +int link_request_to_set_ipoib(Link *link) { + assert(link); + assert(link->network); + + if (link->iftype != ARPHRD_INFINIBAND) + return 0; + + if (link->network->ipoib_mode < 0 && + link->network->ipoib_umcast < 0) + return 0; + + return link_request_set_link(link, SET_LINK_IPOIB, link_set_ipoib_handler, NULL); +} + int link_request_to_set_master(Link *link) { assert(link); assert(link->network); diff --git a/src/network/networkd-setlink.h b/src/network/networkd-setlink.h index d3e9f2b9d7b..39a85a6871d 100644 --- a/src/network/networkd-setlink.h +++ b/src/network/networkd-setlink.h @@ -14,6 +14,7 @@ typedef enum SetLinkOperation { SET_LINK_CAN, /* Setting CAN interface configs. */ SET_LINK_FLAGS, /* Setting IFF_NOARP or friends. */ SET_LINK_GROUP, /* Setting interface group. */ + SET_LINK_IPOIB, /* Setting IPoIB configs. */ SET_LINK_MAC, /* Setting MAC address. */ SET_LINK_MASTER, /* Setting IFLA_MASTER. */ SET_LINK_MTU, /* Setting MTU. */ @@ -33,6 +34,7 @@ int link_request_to_set_can(Link *link); int link_request_to_set_flags(Link *link); int link_request_to_set_group(Link *link); int link_request_to_set_mac(Link *link, bool allow_retry); +int link_request_to_set_ipoib(Link *link); int link_request_to_set_master(Link *link); int link_request_to_set_mtu(Link *link, uint32_t mtu); diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 68cf1ba6919..c1c00262341 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -287,6 +287,9 @@ Loopback= OneShot= PresumeACK= ClassicDataLengthCode= +[IPoIB] +Mode= +IgnoreUserspaceMulticastGroups= [Address] DuplicateAddressDetection= AutoJoin=