4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
31 * This file is part of Lustre, http://www.lustre.org/
32 * Lustre is a trademark of Sun Microsystems, Inc.
35 #if !defined(__KERNEL__) || !defined(REDSTORM)
37 #include <libcfs/libcfs.h>
39 #include <sys/socket.h>
40 #ifdef HAVE_NETINET_IN_H
41 #include <netinet/in.h>
43 #include <netinet/tcp.h>
44 #include <sys/ioctl.h>
50 #include <arpa/inet.h>
53 #if defined(__sun__) || defined(__sun)
54 #include <sys/sockio.h>
57 #include <sys/syscall.h>
61 * Functions to get network interfaces info
65 libcfs_sock_ioctl(int cmd, unsigned long arg)
69 fd = socket(AF_INET, SOCK_STREAM, 0);
73 CERROR("socket() failed: errno==%d\n", errno);
77 rc = ioctl(fd, cmd, arg);
84 libcfs_ipif_query (char *name, int *up, __u32 *ip)
92 if (nob >= IFNAMSIZ) {
93 CERROR("Interface name %s too long\n", name);
97 CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
99 strcpy(ifr.ifr_name, name);
100 rc = libcfs_sock_ioctl(SIOCGIFFLAGS, (unsigned long)&ifr);
103 CERROR("Can't get flags for interface %s\n", name);
107 if ((ifr.ifr_flags & IFF_UP) == 0) {
108 CDEBUG(D_NET, "Interface %s down\n", name);
116 strcpy(ifr.ifr_name, name);
117 ifr.ifr_addr.sa_family = AF_INET;
118 rc = libcfs_sock_ioctl(SIOCGIFADDR, (unsigned long)&ifr);
121 CERROR("Can't get IP address for interface %s\n", name);
125 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
132 libcfs_ipif_free_enumeration (char **names, int n)
138 for (i = 0; i < n && names[i] != NULL; i++)
139 LIBCFS_FREE(names[i], IFNAMSIZ);
141 LIBCFS_FREE(names, n * sizeof(*names));
145 libcfs_ipif_enumerate (char ***namesp)
147 /* Allocate and fill in 'names', returning # interfaces/error */
158 nalloc = 16; /* first guess at max interfaces */
160 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
162 CERROR ("ENOMEM enumerating up to %d interfaces\n",
168 ifc.ifc_buf = (char *)ifr;
169 ifc.ifc_len = nalloc * sizeof(*ifr);
171 rc = libcfs_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc);
174 CERROR ("Error %d enumerating interfaces\n", rc);
180 nfound = ifc.ifc_len/sizeof(*ifr);
181 LASSERT (nfound <= nalloc);
186 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
193 LIBCFS_ALLOC(names, nfound * sizeof(*names));
198 /* NULL out all names[i] */
199 memset (names, 0, nfound * sizeof(*names));
201 for (i = 0; i < nfound; i++) {
203 nob = strlen (ifr[i].ifr_name);
204 if (nob >= IFNAMSIZ) {
205 /* no space for terminating NULL */
206 CERROR("interface name %.*s too long (%d max)\n",
207 nob, ifr[i].ifr_name, IFNAMSIZ);
212 LIBCFS_ALLOC(names[i], IFNAMSIZ);
213 if (names[i] == NULL) {
218 memcpy(names[i], ifr[i].ifr_name, nob);
227 libcfs_ipif_free_enumeration(names, nfound);
229 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
235 * Network functions used by user-land lnet acceptor
239 libcfs_sock_listen (cfs_socket_t **sockp,
240 __u32 local_ip, int local_port, int backlog)
245 rc = libcfs_sock_create(sockp, &fatal, local_ip, local_port);
249 if ( listen((*sockp)->s_fd, backlog) ) {
251 CERROR("listen() with backlog==%d failed: errno==%d\n",
259 libcfs_sock_release(*sockp);
264 libcfs_sock_release (cfs_socket_t *sock)
267 LIBCFS_FREE(sock, sizeof(cfs_socket_t));
271 libcfs_sock_accept (cfs_socket_t **newsockp, cfs_socket_t *sock)
273 struct sockaddr_in accaddr;
274 socklen_t accaddr_len = sizeof(struct sockaddr_in);
276 LIBCFS_ALLOC(*newsockp, sizeof(cfs_socket_t));
277 if (*newsockp == NULL) {
278 CERROR ("Can't alloc memory for cfs_socket_t\n");
282 (*newsockp)->s_fd = accept(sock->s_fd,
283 (struct sockaddr *)&accaddr, &accaddr_len);
285 if ( (*newsockp)->s_fd < 0 ) {
287 CERROR("accept() failed: errno==%d\n", -rc);
288 LIBCFS_FREE(*newsockp, sizeof(cfs_socket_t));
296 libcfs_sock_read (cfs_socket_t *sock, void *buffer, int nob, int timeout)
300 cfs_time_t start_time = cfs_time_current();
306 /* poll(2) measures timeout in msec */
309 while (nob != 0 && timeout > 0) {
310 cfs_time_t current_time;
312 rc = poll(&pfd, 1, timeout);
317 if ((pfd.revents & POLLIN) == 0)
320 rc = read(sock->s_fd, buffer, nob);
326 buffer = ((char *)buffer) + rc;
329 current_time = cfs_time_current();
331 cfs_duration_sec(cfs_time_sub(current_time,
333 start_time = current_time;
343 libcfs_sock_write (cfs_socket_t *sock, void *buffer, int nob, int timeout)
347 cfs_time_t start_time = cfs_time_current();
350 pfd.events = POLLOUT;
353 /* poll(2) measures timeout in msec */
356 while (nob != 0 && timeout > 0) {
357 cfs_time_t current_time;
359 rc = poll(&pfd, 1, timeout);
364 if ((pfd.revents & POLLOUT) == 0)
367 rc = write(sock->s_fd, buffer, nob);
373 buffer = ((char *)buffer) + rc;
376 current_time = cfs_time_current();
378 cfs_duration_sec(cfs_time_sub(current_time,
380 start_time = current_time;
389 /* Just try to connect to localhost to wake up entity that are
390 * sleeping in accept() */
392 libcfs_sock_abort_accept(cfs_socket_t *sock)
395 struct sockaddr_in remaddr;
396 struct sockaddr_in locaddr;
397 socklen_t alen = sizeof(struct sockaddr_in);
399 rc = getsockname(sock->s_fd, (struct sockaddr *)&remaddr, &alen);
401 CERROR("getsockname() failed: errno==%d\n", errno);
405 memset(&locaddr, 0, sizeof(locaddr));
406 locaddr.sin_family = AF_INET;
407 locaddr.sin_port = remaddr.sin_port;
408 locaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
410 fd = socket(AF_INET, SOCK_STREAM, 0);
412 CERROR("socket() failed: errno==%d\n", errno);
416 rc = connect(fd, (struct sockaddr *)&locaddr, sizeof(locaddr));
418 if ( errno != ECONNREFUSED )
419 CERROR("connect() failed: errno==%d\n", errno);
421 CDEBUG(D_NET, "Nobody to wake up at %d\n",
422 ntohs(remaddr.sin_port));
429 libcfs_sock_getaddr(cfs_socket_t *sock, int remote, __u32 *ip, int *port)
432 struct sockaddr_in peer_addr;
433 socklen_t peer_addr_len = sizeof(peer_addr);
435 LASSERT(remote == 1);
437 rc = getpeername(sock->s_fd,
438 (struct sockaddr *)&peer_addr, &peer_addr_len);
443 *ip = ntohl(peer_addr.sin_addr.s_addr);
445 *port = ntohs(peer_addr.sin_port);
451 * Network functions of common use
455 libcfs_socketpair(cfs_socket_t **sockp)
459 LIBCFS_ALLOC(sockp[0], sizeof(cfs_socket_t));
460 if (sockp[0] == NULL) {
461 CERROR ("Can't alloc memory for cfs_socket_t (1)\n");
465 LIBCFS_ALLOC(sockp[1], sizeof(cfs_socket_t));
466 if (sockp[1] == NULL) {
467 CERROR ("Can't alloc memory for cfs_socket_t (2)\n");
468 LIBCFS_FREE(sockp[0], sizeof(cfs_socket_t));
472 rc = socketpair(AF_UNIX, SOCK_STREAM, 0, fdp);
475 CERROR ("Cannot create socket pair\n");
476 LIBCFS_FREE(sockp[0], sizeof(cfs_socket_t));
477 LIBCFS_FREE(sockp[1], sizeof(cfs_socket_t));
481 sockp[0]->s_fd = fdp[0];
482 sockp[1]->s_fd = fdp[1];
484 for (i = 0; i < 2; i++) {
485 rc = libcfs_fcntl_nonblock(sockp[i]);
487 libcfs_sock_release(sockp[0]);
488 libcfs_sock_release(sockp[1]);
497 libcfs_fcntl_nonblock(cfs_socket_t *sock)
501 flags = fcntl(sock->s_fd, F_GETFL, 0);
504 CERROR ("Cannot get socket flags\n");
508 rc = fcntl(sock->s_fd, F_SETFL, flags | O_NONBLOCK);
511 CERROR ("Cannot set socket flags\n");
519 libcfs_sock_set_nagle(cfs_socket_t *sock, int nagle)
522 int option = nagle ? 0 : 1;
524 #if defined(__sun__) || defined(__sun)
525 rc = setsockopt(sock->s_fd,
526 IPPROTO_TCP, TCP_NODELAY, &option, sizeof(option));
528 rc = setsockopt(sock->s_fd,
529 SOL_TCP, TCP_NODELAY, &option, sizeof(option));
534 CERROR ("Cannot set NODELAY socket option\n");
542 libcfs_sock_set_bufsiz(cfs_socket_t *sock, int bufsiz)
546 LASSERT (bufsiz != 0);
549 rc = setsockopt(sock->s_fd,
550 SOL_SOCKET, SO_SNDBUF, &option, sizeof(option));
553 CERROR ("Cannot set SNDBUF socket option\n");
558 rc = setsockopt(sock->s_fd,
559 SOL_SOCKET, SO_RCVBUF, &option, sizeof(option));
562 CERROR ("Cannot set RCVBUF socket option\n");
570 libcfs_sock_bind(cfs_socket_t *sock, __u32 ip, __u16 port)
573 struct sockaddr_in locaddr;
575 if (ip == 0 && port == 0)
578 memset(&locaddr, 0, sizeof(locaddr));
579 locaddr.sin_family = AF_INET;
580 locaddr.sin_addr.s_addr = (ip == 0) ? INADDR_ANY : htonl(ip);
581 locaddr.sin_port = htons(port);
583 rc = bind(sock->s_fd, (struct sockaddr *)&locaddr, sizeof(locaddr));
586 CERROR("Cannot bind to %d.%d.%d.%d %d: %d\n",
587 HIPQUAD(ip), port, rc);
595 libcfs_sock_create(cfs_socket_t **sockp, int *fatal,
596 __u32 local_ip, int local_port)
602 LIBCFS_ALLOC(*sockp, sizeof(cfs_socket_t));
603 if (*sockp == NULL) {
604 CERROR("Can't alloc memory for cfs_socket_t\n");
608 fd = socket(AF_INET, SOCK_STREAM, 0);
611 CERROR("Cannot create socket: %d\n", rc);
612 LIBCFS_FREE(*sockp, sizeof(cfs_socket_t));
619 rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
620 &option, sizeof(option));
623 CERROR("Cannot set SO_REUSEADDR for socket: %d\n", rc);
624 libcfs_sock_release(*sockp);
628 rc = libcfs_sock_bind(*sockp, local_ip, local_port);
631 libcfs_sock_release(*sockp);
638 libcfs_sock_connect(cfs_socket_t *sock, __u32 ip, __u16 port)
641 struct sockaddr_in addr;
643 memset(&addr, 0, sizeof(addr));
644 addr.sin_family = AF_INET;
645 addr.sin_addr.s_addr = htonl(ip);
646 addr.sin_port = htons(port);
648 rc = connect(sock->s_fd, (struct sockaddr *)&addr,
649 sizeof(struct sockaddr_in));
651 if(rc != 0 && errno != EINPROGRESS) {
653 if (rc != -EADDRINUSE && rc != -EADDRNOTAVAIL)
654 CERROR ("Cannot connect to %u.%u.%u.%u:%d (err=%d)\n",
655 HIPQUAD(ip), port, errno);
662 /* NB: EPIPE and ECONNRESET are considered as non-fatal
664 * 1) it still makes sense to continue reading &&
665 * 2) anyway, poll() will set up POLLHUP|POLLERR flags */
667 libcfs_sock_writev(cfs_socket_t *sock, const struct iovec *vector, int count)
671 rc = syscall(SYS_writev, sock->s_fd, vector, count);
673 if (rc == 0) /* write nothing */
677 if (errno == EAGAIN || /* write nothing */
678 errno == EPIPE || /* non-fatal error */
679 errno == ECONNRESET) /* non-fatal error */
689 libcfs_sock_readv(cfs_socket_t *sock, const struct iovec *vector, int count)
693 rc = syscall(SYS_readv, sock->s_fd, vector, count);
695 if (rc == 0) /* EOF */
699 if (errno == EAGAIN) /* read nothing */
708 #endif /* !__KERNEL__ || !defined(REDSTORM) */