From 403f72ec7620c8c5d39d860edd7d8e775e2776e6 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Wed, 1 Aug 2012 15:19:02 -0400 Subject: [PATCH] rx: Create AFS_ADAPT_PMTU and AFS_RXERRQ_ENV Currently we have the ADAPT_PMTU define, which turns on functionality in Linux to detect PMTU-related ICMP errors for Rx. However, this is really turning on two separate pieces of functionality: the PMTU processing, and the processing for ICMP errors in general. So split this out into two defines: AFS_ADAPT_PMTU, and AFS_RXERRQ_ENV. The former is for processing PMTU discovery, and the latter is for processing ICMP errors. Both of these are left disabled due to issues in the error processing. Although PMTU discovery is the only functionality which makes use of ICMP errors, this will change in the future. Change-Id: Ia334c68ce5eb3fa01c01a8a1c52a0e0a2e41b2c0 Reviewed-on: http://gerrit.openafs.org/7925 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- acinclude.m4 | 8 ++------ src/config/param.linux26.h | 9 +++++++++ src/rx/LINUX/rx_knet.c | 31 +++++++++++++++++++++---------- src/rx/rx.c | 4 ++-- src/rx/rx_lwp.c | 4 ++-- src/rx/rx_pthread.c | 2 +- src/rx/rx_user.c | 27 +++++++++++++++------------ 7 files changed, 52 insertions(+), 33 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index e67d2207c..7f69dadb3 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1141,8 +1141,8 @@ setsockopt(0, SOL_IP, IP_RECVERR, &on, sizeof(on));], [ac_cv_setsockopt_iprecverr=no])]) AS_IF([test "$ac_cv_setsockopt_iprecverr" = "yes"], - [AC_DEFINE(ADAPT_PMTU_RECVERR, 1, - [define if asynchronous socket errors can be received])]) + [AC_DEFINE([HAVE_SETSOCKOPT_IP_RECVERR], [1], + [define if we can receive socket errors via IP_RECVERR])]) PTHREAD_LIBS=error if test "x$MKAFS_OSTYPE" = OBSD; then @@ -1213,10 +1213,6 @@ else fi AC_SUBST(USE_UNIX_SOCKETS) -dnl if test "$ac_cv_setsockopt_iprecverr" = "yes"; then -dnl AC_DEFINE(ADAPT_PMTU, 1, [define if you want to decode icmp unreachable packets to discover path mtu]) -dnl fi - if test "$enable_namei_fileserver" = "yes"; then AC_DEFINE(AFS_NAMEI_ENV, 1, [define if you want to want namei fileserver]) VFSCK="" diff --git a/src/config/param.linux26.h b/src/config/param.linux26.h index 4e192b8bc..4a7b942ec 100644 --- a/src/config/param.linux26.h +++ b/src/config/param.linux26.h @@ -99,6 +99,15 @@ #include #endif +#ifdef notyet +#if defined(HAVE_LINUX_ERRQUEUE_H) && defined(HAVE_SETSOCKOPT_IP_RECVERR) +# define AFS_RXERRQ_ENV +#endif +#ifdef AFS_RXERRQ_ENV +# define AFS_ADAPT_PMTU +#endif +#endif + #ifdef __GLIBC__ #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 3) #define USE_UCONTEXT diff --git a/src/rx/LINUX/rx_knet.c b/src/rx/LINUX/rx_knet.c index 942a0724b..fccdbc42b 100644 --- a/src/rx/LINUX/rx_knet.c +++ b/src/rx/LINUX/rx_knet.c @@ -18,8 +18,15 @@ #include #include "rx/rx_kcommon.h" +#include "rx.h" +#include "rx_atomic.h" +#include "rx_globals.h" +#include "rx_stats.h" +#include "rx_peer.h" +#include "rx_packet.h" +#include "rx_internal.h" #include -#ifdef ADAPT_PMTU +#ifdef AFS_RXERRQ_ENV #include #include #endif @@ -35,9 +42,8 @@ rxk_NewSocketHost(afs_uint32 ahost, short aport) struct socket *sockp; struct sockaddr_in myaddr; int code; -#ifdef ADAPT_PMTU +#ifdef AFS_ADAPT_PMTU int pmtu = IP_PMTUDISC_WANT; - int do_recverr = 1; #else int pmtu = IP_PMTUDISC_DONT; #endif @@ -67,9 +73,12 @@ rxk_NewSocketHost(afs_uint32 ahost, short aport) kernel_setsockopt(sockp, SOL_IP, IP_MTU_DISCOVER, (char *)&pmtu, sizeof(pmtu)); -#ifdef ADAPT_PMTU - kernel_setsockopt(sockp, SOL_IP, IP_RECVERR, (char *)&do_recverr, - sizeof(do_recverr)); +#ifdef AFS_RXERRQ_ENV + { + int recverr = 1; + kernel_setsockopt(sockp, SOL_IP, IP_RECVERR, (char *)&recverr, + sizeof(recverr)); + } #endif return (osi_socket *)sockp; } @@ -88,7 +97,7 @@ rxk_FreeSocket(struct socket *asocket) return 0; } -#ifdef ADAPT_PMTU +#ifdef AFS_RXERRQ_ENV void handle_socket_error(osi_socket so) { @@ -130,12 +139,14 @@ handle_socket_error(osi_socket so) memcpy(&addr, offender, sizeof(addr)); +# ifdef AFS_ADAPT_PMTU if (err->ee_origin == SO_EE_ORIGIN_ICMP && err->ee_type == ICMP_DEST_UNREACH && err->ee_code == ICMP_FRAG_NEEDED) { rxi_SetPeerMtu(NULL, ntohl(addr.sin_addr.s_addr), ntohs(addr.sin_port), err->ee_info); } +# endif /* other DEST_UNREACH's and TIME_EXCEEDED should be dealt with too */ out: @@ -156,7 +167,7 @@ osi_NetSend(osi_socket sop, struct sockaddr_in *to, struct iovec *iovec, { struct msghdr msg; int code; -#ifdef ADAPT_PMTU +#ifdef AFS_RXERRQ_ENV int sockerr; int esize; @@ -208,7 +219,7 @@ osi_NetReceive(osi_socket so, struct sockaddr_in *from, struct iovec *iov, { struct msghdr msg; int code; -#ifdef ADAPT_PMTU +#ifdef AFS_RXERRQ_ENV int sockerr; int esize; #endif @@ -218,7 +229,7 @@ osi_NetReceive(osi_socket so, struct sockaddr_in *from, struct iovec *iov, if (iovcnt > RX_MAXWVECS + 2) { osi_Panic("Too many (%d) iovecs passed to osi_NetReceive\n", iovcnt); } -#ifdef ADAPT_PMTU +#ifdef AFS_RXERRQ_ENV while (1) { sockerr=0; esize = sizeof(sockerr); diff --git a/src/rx/rx.c b/src/rx/rx.c index 53db0a3f5..17ab869e3 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -6221,7 +6221,7 @@ rxi_CheckCall(struct rx_call *call) * number of seconds. */ if (now > (call->lastReceiveTime + deadTime)) { if (call->state == RX_STATE_ACTIVE) { -#ifdef ADAPT_PMTU +#ifdef AFS_ADAPT_PMTU # if defined(KERNEL) && defined(AFS_SUN5_ENV) ire_t *ire; # if defined(AFS_SUN510_ENV) && defined(GLOBAL_NETSTACKID) @@ -6247,7 +6247,7 @@ rxi_CheckCall(struct rx_call *call) netstack_rele(ns); # endif # endif -#endif /* ADAPT_PMTU */ +#endif /* AFS_ADAPT_PMTU */ cerror = RX_CALL_DEAD; goto mtuout; } else { diff --git a/src/rx/rx_lwp.c b/src/rx/rx_lwp.c index 229b1ec98..0923642e4 100644 --- a/src/rx/rx_lwp.c +++ b/src/rx/rx_lwp.c @@ -410,7 +410,7 @@ rxi_Listen(osi_socket sock) int rxi_Recvmsg(osi_socket socket, struct msghdr *msg_p, int flags) { -#if defined(HAVE_LINUX_ERRQUEUE_H) && defined(ADAPT_PMTU) +#ifdef AFS_RXERRQ_ENV while((rxi_HandleSocketError(socket)) > 0) ; #endif @@ -438,7 +438,7 @@ rxi_Sendmsg(osi_socket socket, struct msghdr *msg_p, int flags) } FD_SET(socket, sfds); } -#if defined(HAVE_LINUX_ERRQUEUE_H) && defined(ADAPT_PMTU) +#ifdef AFS_RXERRQ_ENV while((rxi_HandleSocketError(socket)) > 0) ; #endif diff --git a/src/rx/rx_pthread.c b/src/rx/rx_pthread.c index a8a8ef0b9..d76ed6d29 100644 --- a/src/rx/rx_pthread.c +++ b/src/rx/rx_pthread.c @@ -391,7 +391,7 @@ int rxi_Recvmsg(osi_socket socket, struct msghdr *msg_p, int flags) { int ret; -#if defined(HAVE_LINUX_ERRQUEUE_H) && defined(ADAPT_PMTU) +#ifdef AFS_RXERRQ_ENV while((rxi_HandleSocketError(socket)) > 0) ; #endif diff --git a/src/rx/rx_user.c b/src/rx/rx_user.c index c55949e2b..a0427e457 100644 --- a/src/rx/rx_user.c +++ b/src/rx/rx_user.c @@ -36,10 +36,10 @@ #define IPPORT_USERRESERVED 5000 # endif -#if defined(HAVE_LINUX_ERRQUEUE_H) && defined(ADAPT_PMTU) +#if defined(AFS_LINUX22_ENV) && defined(AFS_RXERRQ_ENV) # include # include -# ifndef IP_MTU +# if defined(AFS_ADAPT_PMTU) && !defined(IP_MTU) # define IP_MTU 14 # endif #endif @@ -50,6 +50,7 @@ #include "rx_stats.h" #include "rx_peer.h" #include "rx_packet.h" +#include "rx_internal.h" #ifdef AFS_PTHREAD_ENV @@ -94,9 +95,8 @@ rxi_GetHostUDPSocket(u_int ahost, u_short port) struct sockaddr_in taddr; char *name = "rxi_GetUDPSocket: "; #ifdef AFS_LINUX22_ENV -# if defined(ADAPT_PMTU) +# if defined(AFS_ADAPT_PMTU) int pmtu = IP_PMTUDISC_WANT; - int recverr = 1; # else int pmtu = IP_PMTUDISC_DONT; # endif @@ -198,9 +198,12 @@ rxi_GetHostUDPSocket(u_int ahost, u_short port) #ifdef AFS_LINUX22_ENV setsockopt(socketFd, SOL_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu)); -#if defined(ADAPT_PMTU) - setsockopt(socketFd, SOL_IP, IP_RECVERR, &recverr, sizeof(recverr)); #endif +#ifdef AFS_RXERRQ_ENV + { + int recverr = 1; + setsockopt(socketFd, SOL_IP, IP_RECVERR, &recverr, sizeof(recverr)); + } #endif if (rxi_Listen(socketFd) < 0) { goto error; @@ -668,7 +671,7 @@ rxi_InitPeerParams(struct rx_peer *pp) afs_uint32 ppaddr; u_short rxmtu; int ix; -#if defined(ADAPT_PMTU) && defined(IP_MTU) +#ifdef AFS_ADAPT_PMTU int sock; struct sockaddr_in addr; #endif @@ -715,7 +718,7 @@ rxi_InitPeerParams(struct rx_peer *pp) rx_rto_setPeerTimeoutSecs(pp, 3); pp->ifMTU = MIN(rx_MyMaxSendSize, RX_REMOTE_PACKET_SIZE); } -#if defined(ADAPT_PMTU) && defined(IP_MTU) +#ifdef AFS_ADAPT_PMTU sock=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock != OSI_NULLSOCKET) { addr.sin_family = AF_INET; @@ -773,12 +776,11 @@ rx_SetMaxMTU(int mtu) return 0; } -#if defined(ADAPT_PMTU) +#ifdef AFS_RXERRQ_ENV int rxi_HandleSocketError(int socket) { - int ret=0; -#if defined(HAVE_LINUX_ERRQUEUE_H) + int ret = 0; struct msghdr msg; struct cmsghdr *cmsg; struct sock_extended_err *err; @@ -813,14 +815,15 @@ rxi_HandleSocketError(int socket) ret = 1; err = (struct sock_extended_err *) CMSG_DATA(cmsg); +# ifdef AFS_ADAPT_PMTU if (err->ee_errno == EMSGSIZE && err->ee_info >= 68) { rxi_SetPeerMtu(NULL, addr.sin_addr.s_addr, addr.sin_port, err->ee_info - RX_IPUDP_SIZE); } +# endif /* other DEST_UNREACH's and TIME_EXCEEDED should be dealt with too */ out: -#endif return ret; } #endif -- 2.39.5