1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
37 #if !defined(__KERNEL__) || !defined(REDSTORM)
39 #include <libcfs/libcfs.h>
41 #include <sys/socket.h>
42 #ifdef HAVE_NETINET_IN_H
43 #include <netinet/in.h>
45 #include <netinet/tcp.h>
46 #include <sys/ioctl.h>
52 #include <arpa/inet.h>
55 #if defined(__sun__) || defined(__sun)
56 #include <sys/sockio.h>
59 #include <sys/syscall.h>
63 * Functions to get network interfaces info
67 libcfs_sock_ioctl(int cmd, unsigned long arg)
71 fd = socket(AF_INET, SOCK_STREAM, 0);
75 CERROR("socket() failed: errno==%d\n", errno);
79 rc = ioctl(fd, cmd, arg);
86 libcfs_ipif_query (char *name, int *up, __u32 *ip)
94 if (nob >= IFNAMSIZ) {
95 CERROR("Interface name %s too long\n", name);
99 CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);
101 strcpy(ifr.ifr_name, name);
102 rc = libcfs_sock_ioctl(SIOCGIFFLAGS, (unsigned long)&ifr);
105 CERROR("Can't get flags for interface %s\n", name);
109 if ((ifr.ifr_flags & IFF_UP) == 0) {
110 CDEBUG(D_NET, "Interface %s down\n", name);
118 strcpy(ifr.ifr_name, name);
119 ifr.ifr_addr.sa_family = AF_INET;
120 rc = libcfs_sock_ioctl(SIOCGIFADDR, (unsigned long)&ifr);
123 CERROR("Can't get IP address for interface %s\n", name);
127 val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
134 libcfs_ipif_free_enumeration (char **names, int n)
140 for (i = 0; i < n && names[i] != NULL; i++)
141 LIBCFS_FREE(names[i], IFNAMSIZ);
143 LIBCFS_FREE(names, n * sizeof(*names));
147 libcfs_ipif_enumerate (char ***namesp)
149 /* Allocate and fill in 'names', returning # interfaces/error */
160 nalloc = 16; /* first guess at max interfaces */
162 LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
164 CERROR ("ENOMEM enumerating up to %d interfaces\n",
170 ifc.ifc_buf = (char *)ifr;
171 ifc.ifc_len = nalloc * sizeof(*ifr);
173 rc = libcfs_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc);
176 CERROR ("Error %d enumerating interfaces\n", rc);
182 nfound = ifc.ifc_len/sizeof(*ifr);
183 LASSERT (nfound <= nalloc);
188 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
195 LIBCFS_ALLOC(names, nfound * sizeof(*names));
200 /* NULL out all names[i] */
201 memset (names, 0, nfound * sizeof(*names));
203 for (i = 0; i < nfound; i++) {
205 nob = strlen (ifr[i].ifr_name);
206 if (nob >= IFNAMSIZ) {
207 /* no space for terminating NULL */
208 CERROR("interface name %.*s too long (%d max)\n",
209 nob, ifr[i].ifr_name, IFNAMSIZ);
214 LIBCFS_ALLOC(names[i], IFNAMSIZ);
215 if (names[i] == NULL) {
220 memcpy(names[i], ifr[i].ifr_name, nob);
229 libcfs_ipif_free_enumeration(names, nfound);
231 LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
237 * Network functions used by user-land lnet acceptor
241 libcfs_sock_listen (cfs_socket_t **sockp,
242 __u32 local_ip, int local_port, int backlog)
247 rc = libcfs_sock_create(sockp, &fatal, local_ip, local_port);
251 if ( listen((*sockp)->s_fd, backlog) ) {
253 CERROR("listen() with backlog==%d failed: errno==%d\n",
261 libcfs_sock_release(*sockp);
266 libcfs_sock_release (cfs_socket_t *sock)
269 LIBCFS_FREE(sock, sizeof(cfs_socket_t));
273 libcfs_sock_accept (cfs_socket_t **newsockp, cfs_socket_t *sock)
275 struct sockaddr_in accaddr;
276 socklen_t accaddr_len = sizeof(struct sockaddr_in);
278 LIBCFS_ALLOC(*newsockp, sizeof(cfs_socket_t));
279 if (*newsockp == NULL) {
280 CERROR ("Can't alloc memory for cfs_socket_t\n");
284 (*newsockp)->s_fd = accept(sock->s_fd,
285 (struct sockaddr *)&accaddr, &accaddr_len);
287 if ( (*newsockp)->s_fd < 0 ) {
289 CERROR("accept() failed: errno==%d\n", -rc);
290 LIBCFS_FREE(*newsockp, sizeof(cfs_socket_t));
298 libcfs_sock_read (cfs_socket_t *sock, void *buffer, int nob, int timeout)
302 cfs_time_t start_time = cfs_time_current();
308 /* poll(2) measures timeout in msec */
311 while (nob != 0 && timeout > 0) {
312 cfs_time_t current_time;
314 rc = poll(&pfd, 1, timeout);
319 if ((pfd.revents & POLLIN) == 0)
322 rc = read(sock->s_fd, buffer, nob);
328 buffer = ((char *)buffer) + rc;
331 current_time = cfs_time_current();
333 cfs_duration_sec(cfs_time_sub(current_time,
335 start_time = current_time;
345 libcfs_sock_write (cfs_socket_t *sock, void *buffer, int nob, int timeout)
349 cfs_time_t start_time = cfs_time_current();
352 pfd.events = POLLOUT;
355 /* poll(2) measures timeout in msec */
358 while (nob != 0 && timeout > 0) {
359 cfs_time_t current_time;
361 rc = poll(&pfd, 1, timeout);
366 if ((pfd.revents & POLLOUT) == 0)
369 rc = write(sock->s_fd, buffer, nob);
375 buffer = ((char *)buffer) + rc;
378 current_time = cfs_time_current();
380 cfs_duration_sec(cfs_time_sub(current_time,
382 start_time = current_time;
391 /* Just try to connect to localhost to wake up entity that are
392 * sleeping in accept() */
394 libcfs_sock_abort_accept(cfs_socket_t *sock)
397 struct sockaddr_in remaddr;
398 struct sockaddr_in locaddr;
399 socklen_t alen = sizeof(struct sockaddr_in);
401 rc = getsockname(sock->s_fd, (struct sockaddr *)&remaddr, &alen);
403 CERROR("getsockname() failed: errno==%d\n", errno);
407 memset(&locaddr, 0, sizeof(locaddr));
408 locaddr.sin_family = AF_INET;
409 locaddr.sin_port = remaddr.sin_port;
410 locaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
412 fd = socket(AF_INET, SOCK_STREAM, 0);
414 CERROR("socket() failed: errno==%d\n", errno);
418 rc = connect(fd, (struct sockaddr *)&locaddr, sizeof(locaddr));
420 if ( errno != ECONNREFUSED )
421 CERROR("connect() failed: errno==%d\n", errno);
423 CDEBUG(D_NET, "Nobody to wake up at %d\n",
424 ntohs(remaddr.sin_port));
431 libcfs_sock_getaddr(cfs_socket_t *sock, int remote, __u32 *ip, int *port)
434 struct sockaddr_in peer_addr;
435 socklen_t peer_addr_len = sizeof(peer_addr);
437 LASSERT(remote == 1);
439 rc = getpeername(sock->s_fd,
440 (struct sockaddr *)&peer_addr, &peer_addr_len);
445 *ip = ntohl(peer_addr.sin_addr.s_addr);
447 *port = ntohs(peer_addr.sin_port);
453 * Network functions of common use
457 libcfs_socketpair(cfs_socket_t **sockp)
461 LIBCFS_ALLOC(sockp[0], sizeof(cfs_socket_t));
462 if (sockp[0] == NULL) {
463 CERROR ("Can't alloc memory for cfs_socket_t (1)\n");
467 LIBCFS_ALLOC(sockp[1], sizeof(cfs_socket_t));
468 if (sockp[1] == NULL) {
469 CERROR ("Can't alloc memory for cfs_socket_t (2)\n");
470 LIBCFS_FREE(sockp[0], sizeof(cfs_socket_t));
474 rc = socketpair(AF_UNIX, SOCK_STREAM, 0, fdp);
477 CERROR ("Cannot create socket pair\n");
478 LIBCFS_FREE(sockp[0], sizeof(cfs_socket_t));
479 LIBCFS_FREE(sockp[1], sizeof(cfs_socket_t));
483 sockp[0]->s_fd = fdp[0];
484 sockp[1]->s_fd = fdp[1];
486 for (i = 0; i < 2; i++) {
487 rc = libcfs_fcntl_nonblock(sockp[i]);
489 libcfs_sock_release(sockp[0]);
490 libcfs_sock_release(sockp[1]);
499 libcfs_fcntl_nonblock(cfs_socket_t *sock)
503 flags = fcntl(sock->s_fd, F_GETFL, 0);
506 CERROR ("Cannot get socket flags\n");
510 rc = fcntl(sock->s_fd, F_SETFL, flags | O_NONBLOCK);
513 CERROR ("Cannot set socket flags\n");
521 libcfs_sock_set_nagle(cfs_socket_t *sock, int nagle)
524 int option = nagle ? 0 : 1;
526 #if defined(__sun__) || defined(__sun)
527 rc = setsockopt(sock->s_fd,
528 IPPROTO_TCP, TCP_NODELAY, &option, sizeof(option));
530 rc = setsockopt(sock->s_fd,
531 SOL_TCP, TCP_NODELAY, &option, sizeof(option));
536 CERROR ("Cannot set NODELAY socket option\n");
544 libcfs_sock_set_bufsiz(cfs_socket_t *sock, int bufsiz)
548 LASSERT (bufsiz != 0);
551 rc = setsockopt(sock->s_fd,
552 SOL_SOCKET, SO_SNDBUF, &option, sizeof(option));
555 CERROR ("Cannot set SNDBUF socket option\n");
560 rc = setsockopt(sock->s_fd,
561 SOL_SOCKET, SO_RCVBUF, &option, sizeof(option));
564 CERROR ("Cannot set RCVBUF socket option\n");
572 libcfs_sock_bind(cfs_socket_t *sock, __u32 ip, __u16 port)
575 struct sockaddr_in locaddr;
577 if (ip == 0 && port == 0)
580 memset(&locaddr, 0, sizeof(locaddr));
581 locaddr.sin_family = AF_INET;
582 locaddr.sin_addr.s_addr = (ip == 0) ? INADDR_ANY : htonl(ip);
583 locaddr.sin_port = htons(port);
585 rc = bind(sock->s_fd, (struct sockaddr *)&locaddr, sizeof(locaddr));
588 CERROR("Cannot bind to %d.%d.%d.%d %d: %d\n",
589 HIPQUAD(ip), port, rc);
597 libcfs_sock_create(cfs_socket_t **sockp, int *fatal,
598 __u32 local_ip, int local_port)
604 LIBCFS_ALLOC(*sockp, sizeof(cfs_socket_t));
605 if (*sockp == NULL) {
606 CERROR("Can't alloc memory for cfs_socket_t\n");
610 fd = socket(AF_INET, SOCK_STREAM, 0);
613 CERROR("Cannot create socket: %d\n", rc);
614 LIBCFS_FREE(*sockp, sizeof(cfs_socket_t));
621 rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
622 &option, sizeof(option));
625 CERROR("Cannot set SO_REUSEADDR for socket: %d\n", rc);
626 libcfs_sock_release(*sockp);
630 rc = libcfs_sock_bind(*sockp, local_ip, local_port);
633 libcfs_sock_release(*sockp);
640 libcfs_sock_connect(cfs_socket_t *sock, __u32 ip, __u16 port)
643 struct sockaddr_in addr;
645 memset(&addr, 0, sizeof(addr));
646 addr.sin_family = AF_INET;
647 addr.sin_addr.s_addr = htonl(ip);
648 addr.sin_port = htons(port);
650 rc = connect(sock->s_fd, (struct sockaddr *)&addr,
651 sizeof(struct sockaddr_in));
653 if(rc != 0 && errno != EINPROGRESS) {
655 if (rc != -EADDRINUSE && rc != -EADDRNOTAVAIL)
656 CERROR ("Cannot connect to %u.%u.%u.%u:%d (err=%d)\n",
657 HIPQUAD(ip), port, errno);
664 /* NB: EPIPE and ECONNRESET are considered as non-fatal
666 * 1) it still makes sense to continue reading &&
667 * 2) anyway, poll() will set up POLLHUP|POLLERR flags */
669 libcfs_sock_writev(cfs_socket_t *sock, const struct iovec *vector, int count)
673 rc = syscall(SYS_writev, sock->s_fd, vector, count);
675 if (rc == 0) /* write nothing */
679 if (errno == EAGAIN || /* write nothing */
680 errno == EPIPE || /* non-fatal error */
681 errno == ECONNRESET) /* non-fatal error */
691 libcfs_sock_readv(cfs_socket_t *sock, const struct iovec *vector, int count)
695 rc = syscall(SYS_readv, sock->s_fd, vector, count);
697 if (rc == 0) /* EOF */
701 if (errno == EAGAIN) /* read nothing */
710 #endif /* !__KERNEL__ || !defined(REDSTORM) */