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