From: Nickolai Zeldovich Date: Fri, 5 Oct 2001 21:44:35 +0000 (+0000) Subject: solaris-mtu-cleanup-20011005 X-Git-Tag: openafs-devel-1_3_0~260 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=5bcf626ddaf92e199c4b46c11ad276013a47db52;p=packages%2Fo%2Fopenafs.git solaris-mtu-cleanup-20011005 This patch provides better MTU selection on Solaris, by actually going through the list of interfaces and picking the correct MTU, rather than assuming 1500. It also fixes a small bug in the server preference code, which wasn't checking for IPv6 interfaces, and if there were any IPv6 interface, it would believe all servers were on the local subnet. --- diff --git a/src/afs/afs_server.c b/src/afs/afs_server.c index c148ee4b6..f60691c49 100644 --- a/src/afs/afs_server.c +++ b/src/afs/afs_server.c @@ -1084,6 +1084,10 @@ static afs_SetServerPrefs(sa) if (sa) sa->sa_iprank= 0; for (ill = (struct ill_s *)*addr /*ill_g_headp*/; ill; ill = ill->ill_next ) { +#ifdef AFS_SUN58_ENV + /* Make sure this is an IPv4 ILL */ + if (ill->ill_isv6) continue; +#endif for (ipif = ill->ill_ipif; ipif; ipif = ipif->ipif_next ) { subnet = ipif->ipif_local_addr & ipif->ipif_net_mask; subnetmask = ipif->ipif_net_mask; diff --git a/src/rx/SOLARIS/rx_knet.c b/src/rx/SOLARIS/rx_knet.c index 9598b9179..d884bfc52 100644 --- a/src/rx/SOLARIS/rx_knet.c +++ b/src/rx/SOLARIS/rx_knet.c @@ -27,8 +27,13 @@ RCSID("$Header$"); #include "../sys/fcntl.h" #ifdef AFS_SUN58_ENV #include "../netinet/ip6.h" +#define ipif_local_addr ipif_lcl_addr +#ifndef V4_PART_OF_V6 +#define V4_PART_OF_V6(v6) v6.s6_addr32[3] +#endif #endif #include "../inet/ip.h" +#include "../inet/ip_if.h" #include "../netinet/udp.h" /* @@ -47,9 +52,137 @@ int (*sockfs_sosendmsg) int (*sockfs_sosetsockopt) (struct sonode *, int, int, void *, int) = NULL; -int rxi_GetIFInfo() +static afs_uint32 myNetAddrs[ADDRSPERSITE]; +static int myNetMTUs[ADDRSPERSITE]; +static int numMyNetAddrs = 0; + +int +rxi_GetIFInfo() { - return 0; + int i = 0; + int different = 0; + + ill_t *ill; + ipif_t *ipif; + int rxmtu, maxmtu; + + int mtus[ADDRSPERSITE]; + afs_uint32 addrs[ADDRSPERSITE]; + afs_uint32 ifinaddr; + + memset(mtus, 0, sizeof(mtus)); + memset(addrs, 0, sizeof(addrs)); + + for (ill = ill_g_head; ill; ill = ill->ill_next) { +#ifdef AFS_SUN58_ENV + /* Make sure this is an IPv4 ILL */ + if (ill->ill_isv6) continue; +#endif + + /* Iterate over all the addresses on this ILL */ + for (ipif = ill->ill_ipif; ipif; ipif = ipif->ipif_next) { + if (i >= ADDRSPERSITE) break; + + /* Ignore addresses which are down.. */ + if (!(ipif->ipif_flags & IFF_UP)) continue; + + /* Compute the Rx interface MTU */ + rxmtu = (ipif->ipif_mtu - RX_IPUDP_SIZE); + + ifinaddr = ntohl(ipif->ipif_local_addr); + if (myNetAddrs[i] != ifinaddr) + different++; + + /* Copy interface MTU and address; adjust maxmtu */ + mtus[i] = rxmtu; + rxmtu = rxi_AdjustIfMTU(rxmtu); + maxmtu = rxmtu * rxi_nRecvFrags + ((rxi_nRecvFrags-1) * + UDP_HDR_SIZE); + maxmtu = rxi_AdjustMaxMTU(rxmtu, maxmtu); + addrs[i] = ifinaddr; + i++; + + if (ifinaddr != 0x7f000001 && maxmtu > rx_maxReceiveSize) { + rx_maxReceiveSize = MIN( RX_MAX_PACKET_SIZE, maxmtu); + rx_maxReceiveSize = MIN( rx_maxReceiveSize, + rx_maxReceiveSizeUser); + } + } + } + + rx_maxJumboRecvSize = RX_HEADER_SIZE + + rxi_nDgramPackets * RX_JUMBOBUFFERSIZE + + (rxi_nDgramPackets-1) * RX_JUMBOHEADERSIZE; + rx_maxJumboRecvSize = MAX(rx_maxJumboRecvSize, rx_maxReceiveSize); + + if (different) { + int j; + + for (j = 0; j < i; j++) { + myNetMTUs[j] = mtus[j]; + myNetAddrs[j] = addrs[j]; + } + } + + return different; +} + +int +rxi_FindIfMTU(addr) + afs_uint32 addr; +{ + ill_t *ill; + ipif_t *ipif; + afs_uint32 myAddr, netMask; + int match_value = 0; + int mtu = -1; + + if (numMyNetAddrs == 0) + rxi_GetIFInfo(); + myAddr = ntohl(addr); + + if (IN_CLASSA(myAddr)) netMask = IN_CLASSA_NET; + else if (IN_CLASSB(myAddr)) netMask = IN_CLASSB_NET; + else if (IN_CLASSC(myAddr)) netMask = IN_CLASSC_NET; + else netMask = 0; + + for (ill = ill_g_head; ill; ill = ill->ill_next) { +#ifdef AFS_SUN58_ENV + /* Make sure this is an IPv4 ILL */ + if (ill->ill_isv6) continue; +#endif + + /* Iterate over all the addresses on this ILL */ + for (ipif = ill->ill_ipif; ipif; ipif = ipif->ipif_next) { + afs_uint32 thisAddr, subnetMask; + int thisMtu; + + thisAddr = ipif->ipif_local_addr; + subnetMask = ipif->ipif_net_mask; + thisMtu = ipif->ipif_mtu; + + if ((myAddr & netMask) == (thisAddr & netMask)) { + if ((myAddr & subnetMask) == (thisAddr & subnetMask)) { + if (myAddr == thisAddr) { + match_value = 4; + mtu = thisMtu; + } + + if (match_value < 3) { + match_value = 3; + mtu = thisMtu; + } + } + + if (match_value < 2) { + match_value = 2; + mtu = thisMtu; + } + } + } + } + + return mtu; } /* rxi_NewSocket, rxi_FreeSocket and osi_NetSend are from the now defunct diff --git a/src/rx/rx_kcommon.c b/src/rx/rx_kcommon.c index 53a57c573..8755fb31f 100644 --- a/src/rx/rx_kcommon.c +++ b/src/rx/rx_kcommon.c @@ -343,6 +343,7 @@ register struct rx_peer *pp; u_short rxmtu; afs_int32 i, mtu; +#ifndef AFS_SUN5_ENV #ifdef AFS_USERSPACE_IP_ADDR i = rxi_Findcbi(pp->host); if (i == -1) { @@ -402,6 +403,30 @@ register struct rx_peer *pp; pp->ifMTU = RX_REMOTE_PACKET_SIZE; } #endif/* else AFS_USERSPACE_IP_ADDR */ +#else /* AFS_SUN5_ENV */ + mtu = rxi_FindIfMTU(pp->host); + + if (mtu <= 0) { + pp->timeout.sec = 3; + /* pp->timeout.usec = 0; */ + pp->ifMTU = RX_REMOTE_PACKET_SIZE; + } else { + pp->timeout.sec = 2; + /* pp->timeout.usec = 0; */ + pp->ifMTU = MIN(RX_MAX_PACKET_SIZE, rx_MyMaxSendSize); + } + + if (mtu > 0) { + /* Diminish the packet size to one based on the MTU given by + * the interface. */ + if (mtu > (RX_IPUDP_SIZE + RX_HEADER_SIZE)) { + rxmtu = mtu - RX_IPUDP_SIZE; + if (rxmtu < pp->ifMTU) pp->ifMTU = rxmtu; + } + } else { /* couldn't find the interface, so assume the worst */ + pp->ifMTU = RX_REMOTE_PACKET_SIZE; + } +#endif /* AFS_SUN5_ENV */ #else /* ADAPT_MTU */ pp->rateFlag = 2; /* start timing after two full packets */ pp->timeout.sec = 2; diff --git a/src/rx/rx_kcommon.h b/src/rx/rx_kcommon.h index a11c14537..92b2bc332 100644 --- a/src/rx/rx_kcommon.h +++ b/src/rx/rx_kcommon.h @@ -111,6 +111,7 @@ extern rxk_portRocks_t rxk_portRocks; extern struct osi_socket *rxk_NewSocket(short aport); extern struct ifnet *rxi_FindIfnet(); +extern int rxi_FindIfMTU(); extern int rxk_initDone; diff --git a/src/rx/rx_misc.h b/src/rx/rx_misc.h index 743a44a22..1f66c25c8 100644 --- a/src/rx/rx_misc.h +++ b/src/rx/rx_misc.h @@ -14,14 +14,10 @@ #ifndef _RX_MISC_H_ #define _RX_MISC_H_ -#ifndef AFS_SUN5_ENV #define MISCMTU #define ADAPT_MTU -#endif -#if defined(AFS_SUN5_ENV) && !defined(KERNEL) -#define MISCMTU -#define ADAPT_MTU +#if defined(AFS_SUN5_ENV) #include #include #endif