1 /*
2 * Copyright (c) 2013-2018 Intel Corporation. All rights reserved.
3 * Copyright (c) 2016 Cisco Systems, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33
34 #ifndef _OFI_NET_H_
35 #define _OFI_NET_H_
36
37 #include "config.h"
38
39 #include <assert.h>
40 #include <pthread.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <sys/param.h>
44 #include <netinet/in.h>
45 #include <ifaddrs.h>
46
47 #include <ofi_osd.h>
48 #include <ofi_list.h>
49
50 #include <rdma/fabric.h>
51 #include <rdma/providers/fi_prov.h>
52 #include <rdma/providers/fi_log.h>
53
54
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58
59
60 extern struct fi_provider core_prov;
61
62
63 /*
64 * OS X doesn't have __BYTE_ORDER, Linux usually has BYTE_ORDER but not under
65 * all features.h flags
66 */
67 #if !defined(BYTE_ORDER)
68 # if defined(__BYTE_ORDER) && \
69 defined(__LITTLE_ENDIAN) && \
70 defined(__BIG_ENDIAN)
71 # define BYTE_ORDER __BYTE_ORDER
72 # define LITTLE_ENDIAN __LITTLE_ENDIAN
73 # define BIG_ENDIAN __BIG_ENDIAN
74 # else
75 # error "cannot determine endianness!"
76 # endif
77 #endif
78
79 #if BYTE_ORDER == LITTLE_ENDIAN
80 #ifndef htonll
htonll(uint64_t x)81 static inline uint64_t htonll(uint64_t x) { return bswap_64(x); }
82 #endif
83 #ifndef ntohll
ntohll(uint64_t x)84 static inline uint64_t ntohll(uint64_t x) { return bswap_64(x); }
85 #endif
86 #else
87 #ifndef htonll
htonll(uint64_t x)88 static inline uint64_t htonll(uint64_t x) { return x; }
89 #endif
90 #ifndef ntohll
ntohll(uint64_t x)91 static inline uint64_t ntohll(uint64_t x) { return x; }
92 #endif
93 #endif
94
95
ofi_recvall_socket(SOCKET sock,void * buf,size_t len)96 static inline int ofi_recvall_socket(SOCKET sock, void *buf, size_t len)
97 {
98 ssize_t ret;
99
100 ret = ofi_recv_socket(sock, buf, len, MSG_WAITALL);
101 return (size_t) ret != len;
102 }
103
ofi_sendall_socket(SOCKET sock,const void * buf,size_t len)104 static inline int ofi_sendall_socket(SOCKET sock, const void *buf, size_t len)
105 {
106 size_t sent;
107 ssize_t ret;
108
109 for (sent = 0, ret = 0; (sent < len) && (ret >= 0); ) {
110 ret = ofi_send_socket(sock, ((char *) buf) + sent, len - sent, 0);
111 if (ret > 0)
112 sent += ret;
113 }
114
115 return (size_t) sent != len;
116 }
117
118 int ofi_discard_socket(SOCKET sock, size_t len);
119
120 /*
121 * Address utility functions
122 */
123
124 #ifndef AF_IB
125 #define AF_IB 27
126 #endif
127
128 #define OFI_ADDRSTRLEN (INET6_ADDRSTRLEN + 50)
129
130 union ofi_sock_ip {
131 struct sockaddr sa;
132 struct sockaddr_in sin;
133 struct sockaddr_in6 sin6;
134 uint8_t align[32];
135 };
136
137 struct ofi_addr_list_entry {
138 struct slist_entry entry;
139 char ipstr[INET6_ADDRSTRLEN];
140 union ofi_sock_ip ipaddr;
141 size_t speed;
142 char net_name[OFI_ADDRSTRLEN];
143 char ifa_name[OFI_ADDRSTRLEN];
144 };
145
146 int ofi_addr_cmp(const struct fi_provider *prov, const struct sockaddr *sa1,
147 const struct sockaddr *sa2);
148 int ofi_getifaddrs(struct ifaddrs **ifap);
149
150 void ofi_set_netmask_str(char *netstr, size_t len, struct ifaddrs *ifa);
151
152 void ofi_get_list_of_addr(const struct fi_provider *prov, const char *env_name,
153 struct slist *addr_list);
154 void ofi_free_list_of_addr(struct slist *addr_list);
155
156 #define ofi_sa_family(addr) ((struct sockaddr *)(addr))->sa_family
157 #define ofi_sin_addr(addr) (((struct sockaddr_in *)(addr))->sin_addr)
158 #define ofi_sin_port(addr) (((struct sockaddr_in *)(addr))->sin_port)
159
160 #define ofi_sin6_addr(addr) (((struct sockaddr_in6 *)(addr))->sin6_addr)
161 #define ofi_sin6_port(addr) (((struct sockaddr_in6 *)(addr))->sin6_port)
162
163
ofi_sizeofaddr(const struct sockaddr * addr)164 static inline size_t ofi_sizeofaddr(const struct sockaddr *addr)
165 {
166 switch (addr->sa_family) {
167 case AF_INET:
168 return sizeof(struct sockaddr_in);
169 case AF_INET6:
170 return sizeof(struct sockaddr_in6);
171 default:
172 FI_WARN(&core_prov, FI_LOG_CORE, "Unknown address format\n");
173 return 0;
174 }
175 }
176
ofi_sizeofip(const struct sockaddr * addr)177 static inline size_t ofi_sizeofip(const struct sockaddr *addr)
178 {
179 switch (addr->sa_family) {
180 case AF_INET:
181 return sizeof(struct in_addr);
182 case AF_INET6:
183 return sizeof(struct in6_addr);
184 default:
185 FI_WARN(&core_prov, FI_LOG_CORE, "Unknown address format\n");
186 return 0;
187 }
188 }
189
ofi_translate_addr_format(int family)190 static inline int ofi_translate_addr_format(int family)
191 {
192 switch (family) {
193 case AF_INET:
194 return FI_SOCKADDR_IN;
195 case AF_INET6:
196 return FI_SOCKADDR_IN6;
197 case AF_IB:
198 return FI_SOCKADDR_IB;
199 default:
200 return FI_FORMAT_UNSPEC;
201 }
202 }
203
204 uint16_t ofi_get_sa_family(const struct fi_info *info);
205
ofi_ipv4_is_any_addr(struct sockaddr * sa)206 static inline int ofi_ipv4_is_any_addr(struct sockaddr *sa)
207 {
208 struct in_addr ia_any = {
209 .s_addr = INADDR_ANY,
210 };
211
212 if (!sa)
213 return 0;
214
215 return !memcmp(&ofi_sin_addr(sa).s_addr, &ia_any, sizeof(ia_any));
216
217 }
218
ofi_ipv6_is_any_addr(struct sockaddr * sa)219 static inline int ofi_ipv6_is_any_addr(struct sockaddr *sa)
220 {
221 struct in6_addr ia6_any = IN6ADDR_ANY_INIT;
222
223 if (!sa)
224 return 0;
225
226 return !memcmp(&ofi_sin6_addr(sa), &ia6_any, sizeof(ia6_any));
227 }
228
ofi_is_any_addr(struct sockaddr * sa)229 static inline int ofi_is_any_addr(struct sockaddr *sa)
230 {
231 if (!sa)
232 return 0;
233
234 switch(sa->sa_family) {
235 case AF_INET:
236 return ofi_ipv4_is_any_addr(sa);
237 case AF_INET6:
238 return ofi_ipv6_is_any_addr(sa);
239 default:
240 FI_WARN(&core_prov, FI_LOG_CORE, "Unknown address format!\n");
241 return 0;
242 }
243 }
244
ofi_addr_get_port(const struct sockaddr * addr)245 static inline uint16_t ofi_addr_get_port(const struct sockaddr *addr)
246 {
247 if (!addr)
248 return 0;
249
250 switch (ofi_sa_family(addr)) {
251 case AF_INET:
252 return ntohs(ofi_sin_port((const struct sockaddr_in *) addr));
253 case AF_INET6:
254 return ntohs(ofi_sin6_port((const struct sockaddr_in6 *) addr));
255 default:
256 FI_WARN(&core_prov, FI_LOG_FABRIC, "Unknown address format\n");
257 assert(0);
258 return 0;
259 }
260 }
261
ofi_addr_set_port(struct sockaddr * addr,uint16_t port)262 static inline void ofi_addr_set_port(struct sockaddr *addr, uint16_t port)
263 {
264 switch (ofi_sa_family(addr)) {
265 case AF_INET:
266 ofi_sin_port(addr) = htons(port);
267 break;
268 case AF_INET6:
269 ofi_sin6_port(addr) = htons(port);
270 break;
271 default:
272 FI_WARN(&core_prov, FI_LOG_FABRIC, "Unknown address format\n");
273 assert(0);
274 }
275 }
276
ofi_get_ipaddr(const struct sockaddr * addr)277 static inline void * ofi_get_ipaddr(const struct sockaddr *addr)
278 {
279 switch (addr->sa_family) {
280 case AF_INET:
281 return &ofi_sin_addr((const struct sockaddr_in *) addr);
282 case AF_INET6:
283 return &ofi_sin6_addr((const struct sockaddr_in6 *) addr);
284 default:
285 return NULL;
286 }
287 }
288
ofi_equals_ipaddr(const struct sockaddr * addr1,const struct sockaddr * addr2)289 static inline int ofi_equals_ipaddr(const struct sockaddr *addr1,
290 const struct sockaddr *addr2)
291 {
292 if (addr1->sa_family != addr2->sa_family)
293 return 0;
294
295 switch (addr1->sa_family) {
296 case AF_INET:
297 return !memcmp(&ofi_sin_addr(addr1), &ofi_sin_addr(addr2),
298 sizeof(ofi_sin_addr(addr1)));
299 case AF_INET6:
300 return !memcmp(&ofi_sin6_addr(addr1), &ofi_sin6_addr(addr2),
301 sizeof(ofi_sin6_addr(addr1)));
302 default:
303 return 0;
304 }
305 }
306
ofi_equals_sockaddr(const struct sockaddr * addr1,const struct sockaddr * addr2)307 static inline int ofi_equals_sockaddr(const struct sockaddr *addr1,
308 const struct sockaddr *addr2)
309 {
310 return (ofi_addr_get_port(addr1) == ofi_addr_get_port(addr2)) &&
311 ofi_equals_ipaddr(addr1, addr2);
312 }
313
314 int ofi_is_wildcard_listen_addr(const char *node, const char *service,
315 uint64_t flags, const struct fi_info *hints);
316
317 size_t ofi_mask_addr(struct sockaddr *maskaddr, const struct sockaddr *srcaddr,
318 const struct sockaddr *netmask);
319
320
321 /*
322 * Address logging
323 */
324 const char *ofi_straddr(char *buf, size_t *len,
325 uint32_t addr_format, const void *addr);
326
327 /* Returns allocated address to caller. Caller must free. */
328 int ofi_str_toaddr(const char *str, uint32_t *addr_format,
329 void **addr, size_t *len);
330
331 void ofi_straddr_log_internal(const char *func, int line,
332 const struct fi_provider *prov,
333 enum fi_log_level level,
334 enum fi_log_subsys subsys, char *log_str,
335 const void *addr);
336
337 #define ofi_straddr_log(...) \
338 ofi_straddr_log_internal(__func__, __LINE__, __VA_ARGS__)
339
340 #if ENABLE_DEBUG
341 #define ofi_straddr_dbg(prov, subsystem, ...) \
342 ofi_straddr_log(prov, FI_LOG_DEBUG, subsystem, __VA_ARGS__)
343 #else
344 #define ofi_straddr_dbg(prov, subsystem, ...) do {} while(0)
345 #endif
346
347
348 #ifdef __cplusplus
349 }
350 #endif
351
352 #endif /* _OFI_NET_H_ */
353