]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/netdev/ipoib.c
tree-wide: use ASSERT_PTR more
[thirdparty/systemd.git] / src / network / netdev / ipoib.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <linux/if_arp.h>
4 #include <linux/if_link.h>
5
6 #include "ipoib.h"
7 #include "networkd-network.h"
8 #include "parse-util.h"
9 #include "string-table.h"
10
11 assert_cc((int) IP_OVER_INFINIBAND_MODE_DATAGRAM == (int) IPOIB_MODE_DATAGRAM);
12 assert_cc((int) IP_OVER_INFINIBAND_MODE_CONNECTED == (int) IPOIB_MODE_CONNECTED);
13
14 static void netdev_ipoib_init(NetDev *netdev) {
15 IPoIB *ipoib;
16
17 assert(netdev);
18
19 ipoib = IPOIB(netdev);
20
21 assert(ipoib);
22
23 ipoib->mode = _IP_OVER_INFINIBAND_MODE_INVALID;
24 ipoib->umcast = -1;
25 }
26
27 static int netdev_ipoib_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
28 IPoIB *ipoib;
29 int r;
30
31 assert(netdev);
32 assert(link);
33 assert(m);
34
35 ipoib = IPOIB(netdev);
36
37 assert(ipoib);
38
39 if (ipoib->pkey > 0) {
40 r = sd_netlink_message_append_u16(m, IFLA_IPOIB_PKEY, ipoib->pkey);
41 if (r < 0)
42 return r;
43 }
44
45 if (ipoib->mode >= 0) {
46 r = sd_netlink_message_append_u16(m, IFLA_IPOIB_MODE, ipoib->mode);
47 if (r < 0)
48 return r;
49 }
50
51 if (ipoib->umcast >= 0) {
52 r = sd_netlink_message_append_u16(m, IFLA_IPOIB_UMCAST, ipoib->umcast);
53 if (r < 0)
54 return r;
55 }
56
57 return 0;
58 }
59
60 int ipoib_set_netlink_message(Link *link, sd_netlink_message *m) {
61 int r;
62
63 assert(link);
64 assert(link->network);
65 assert(m);
66
67 r = sd_netlink_message_set_flags(m, NLM_F_REQUEST | NLM_F_ACK);
68 if (r < 0)
69 return r;
70
71 r = sd_netlink_message_open_container(m, IFLA_LINKINFO);
72 if (r < 0)
73 return r;
74
75 r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, link->kind);
76 if (r < 0)
77 return r;
78
79 if (link->network->ipoib_mode >= 0) {
80 r = sd_netlink_message_append_u16(m, IFLA_IPOIB_MODE, link->network->ipoib_mode);
81 if (r < 0)
82 return r;
83 }
84
85 if (link->network->ipoib_umcast >= 0) {
86 r = sd_netlink_message_append_u16(m, IFLA_IPOIB_UMCAST, link->network->ipoib_umcast);
87 if (r < 0)
88 return r;
89 }
90
91 r = sd_netlink_message_close_container(m);
92 if (r < 0)
93 return r;
94
95 r = sd_netlink_message_close_container(m);
96 if (r < 0)
97 return r;
98
99 return 0;
100 }
101
102 static const char * const ipoib_mode_table[_IP_OVER_INFINIBAND_MODE_MAX] = {
103 [IP_OVER_INFINIBAND_MODE_DATAGRAM] = "datagram",
104 [IP_OVER_INFINIBAND_MODE_CONNECTED] = "connected",
105 };
106
107 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(ipoib_mode, IPoIBMode);
108 DEFINE_CONFIG_PARSE_ENUM(config_parse_ipoib_mode, ipoib_mode, IPoIBMode, "Failed to parse IPoIB mode");
109
110 int config_parse_ipoib_pkey(
111 const char *unit,
112 const char *filename,
113 unsigned line,
114 const char *section,
115 unsigned section_line,
116 const char *lvalue,
117 int ltype,
118 const char *rvalue,
119 void *data,
120 void *userdata) {
121
122 uint16_t u, *pkey = ASSERT_PTR(data);
123 int r;
124
125 assert(filename);
126 assert(lvalue);
127 assert(rvalue);
128
129 if (isempty(rvalue)) {
130 *pkey = 0; /* 0 means unset. */
131 return 0;
132 }
133
134 r = safe_atou16(rvalue, &u);
135 if (r < 0) {
136 log_syntax(unit, LOG_WARNING, filename, line, r,
137 "Failed to parse IPoIB pkey '%s', ignoring assignment: %m",
138 rvalue);
139 return 0;
140 }
141 if (IN_SET(u, 0, 0x8000)) {
142 log_syntax(unit, LOG_WARNING, filename, line, 0,
143 "IPoIB pkey cannot be 0 nor 0x8000, ignoring assignment: %s",
144 rvalue);
145 return 0;
146 }
147
148 *pkey = u;
149 return 0;
150 }
151
152
153 const NetDevVTable ipoib_vtable = {
154 .object_size = sizeof(IPoIB),
155 .sections = NETDEV_COMMON_SECTIONS "IPoIB\0",
156 .init = netdev_ipoib_init,
157 .fill_message_create = netdev_ipoib_fill_message_create,
158 .create_type = NETDEV_CREATE_STACKED,
159 .iftype = ARPHRD_INFINIBAND,
160 .generate_mac = true,
161 };