* directory or online at http://www.openafs.org/dl/license10.html
*/
-#include "../afs/param.h"
+#include <afsconfig.h>
+#include "afs/param.h"
+
+RCSID("$Header$");
+
#ifdef AFS_SUN5_ENV
-#include "../rx/rx_kcommon.h"
+#include "rx/rx_kcommon.h"
#ifdef AFS_SUN56_ENV
-#include "../inet/common.h"
-#include "../sys/tiuser.h"
-#include "../sys/t_kuser.h"
-#include "../sys/stropts.h"
-#include "../sys/stream.h"
-#include "../sys/tihdr.h"
-#include "../sys/fcntl.h"
+#include "inet/common.h"
+#include "sys/tiuser.h"
+#include "sys/t_kuser.h"
+#include "sys/stropts.h"
+#include "sys/stream.h"
+#include "sys/tihdr.h"
+#include "sys/fcntl.h"
#ifdef AFS_SUN58_ENV
-#include "../netinet/ip6.h"
+#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 "../netinet/udp.h"
+#include "inet/ip.h"
+#include "inet/ip_if.h"
+#include "netinet/udp.h"
/*
* Function pointers for kernel socket routines
(struct sonode *, struct nmsghdr *, struct uio *) = NULL;
int (*sockfs_sosetsockopt)
(struct sonode *, int, int, void *, int) = NULL;
+int (*sockfs_sounbind)
+ (struct sonode *, int);
+void (*sockfs_sockfree)
+ (struct sonode *);
-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(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
return NULL;
}
}
+ if (sockfs_sounbind == NULL) {
+ sockfs_sounbind = (int (*)())modlookup("sockfs", "sounbind");
+ if (sockfs_sounbind == NULL)
+ return NULL;
+ }
+ if (sockfs_sockfree == NULL) {
+ sockfs_sockfree = (void (*)())modlookup("sockfs", "sockfree");
+ if (sockfs_sockfree == NULL)
+ return NULL;
+ }
accessvp = sockfs_solookup(AF_INET, SOCK_DGRAM, 0, "/dev/udp", &error);
if (accessvp == NULL) {
return (struct osi_socket *)so;
}
-int osi_FreeSocket(asocket)
- register struct osi_socket *asocket;
+int osi_FreeSocket(register struct osi_socket *asocket)
{
extern int rxk_ListenerPid;
struct sonode *so = (struct sonode *)asocket;
- vnode_t *vp = SOTOV(so);
+ struct sockaddr_in taddr;
+ struct iovec dvec;
+ char c;
AFS_STATCNT(osi_FreeSocket);
- if (rxk_ListenerPid)
- kill(rxk_ListenerPid, SIGUSR1);
+
+ taddr.sin_family = AF_INET;
+ taddr.sin_port = rx_port;
+ taddr.sin_addr.s_addr = htonl(0x7f000001);
+
+ dvec.iov_base = &c;
+ dvec.iov_len = 1;
+
+ while (rxk_ListenerPid) {
+ osi_NetSend(rx_socket, &taddr, &dvec, 1, 1, 0);
+ afs_osi_Sleep(&rxk_ListenerPid);
+ }
+
+ sockfs_sounbind(so, 0);
+ sockfs_sockfree(so);
return 0;
}
-int osi_NetSend(asocket, addr, dvec, nvecs, asize, istack)
- struct osi_socket *asocket;
- struct sockaddr_in *addr;
- struct iovec dvec[];
- int nvecs;
- afs_int32 asize;
- int istack;
+int osi_NetSend(osi_socket asocket, struct sockaddr_in *addr,
+ struct iovec *dvec, int nvecs, afs_int32 asize, int istack)
{
struct sonode *so = (struct sonode *)asocket;
struct nmsghdr msg;
return error;
}
-int osi_NetReceive(asocket, addr, dvec, nvecs, alength)
- struct osi_socket *asocket;
- struct sockaddr_in *addr;
- struct iovec *dvec;
- int nvecs;
- int *alength;
-{
- struct sonode *so = (struct sonode *)asocket;
+int osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec,
+ int nvecs, int *alength)
+{
+ struct sonode *asocket = (struct sonode *)so;
struct nmsghdr msg;
struct uio uio;
struct iovec iov[RX_MAXIOVECS];
uio.uio_limit = 0;
uio.uio_resid = *alength;
- error = sockfs_sorecvmsg(so, &msg, &uio);
+ error = sockfs_sorecvmsg(asocket, &msg, &uio);
if (error == 0) {
if (msg.msg_name == NULL) {
error = -1;
} else {
- bcopy(msg.msg_name, addr, msg.msg_namelen);
+ memcpy(addr, msg.msg_name, msg.msg_namelen);
kmem_free(msg.msg_name, msg.msg_namelen);
*alength = *alength - uio.uio_resid;
}
#else /* AFS_SUN56_ENV */
-#include "../inet/common.h"
-#include "../sys/tiuser.h"
-#include "../sys/t_kuser.h"
-#include "../sys/ioctl.h"
-#include "../sys/stropts.h"
-#include "../sys/stream.h"
-#include "../sys/strsubr.h"
-#include "../sys/vnode.h"
-#include "../sys/stropts.h"
-#include "../sys/tihdr.h"
-#include "../sys/timod.h"
-#include "../sys/fcntl.h"
-#include "../sys/debug.h"
-#include "../inet/common.h"
-#include "../inet/mi.h"
-#include "../netinet/udp.h"
+#include "inet/common.h"
+#include "sys/tiuser.h"
+#include "sys/t_kuser.h"
+#include "sys/ioctl.h"
+#include "sys/stropts.h"
+#include "sys/stream.h"
+#include "sys/strsubr.h"
+#include "sys/vnode.h"
+#include "sys/stropts.h"
+#include "sys/tihdr.h"
+#include "sys/timod.h"
+#include "sys/fcntl.h"
+#include "sys/debug.h"
+#include "inet/common.h"
+#include "inet/mi.h"
+#include "netinet/udp.h"
extern dev_t afs_udp_rdev;
t_kclose(udp_tiptr, 0);
return (struct osi_socket *)0;
}
- if (bcmp(reqp->addr.buf, rspp->addr.buf, rspp->addr.len)) {
+ if (memcmp(reqp->addr.buf, rspp->addr.buf, rspp->addr.len)) {
t_kfree(udp_tiptr, (char *)reqp, T_BIND);
t_kfree(udp_tiptr, (char *)rspp, T_BIND);
t_kclose(udp_tiptr, 0);
}
-int osi_FreeSocket(asocket)
- register struct osi_socket *asocket;
+int osi_FreeSocket(register struct osi_socket *asocket)
{
extern int rxk_ListenerPid;
TIUSER *udp_tiptr = (TIUSER *) asocket;
AFS_STATCNT(osi_FreeSocket);
- if (rxk_ListenerPid)
+ if (rxk_ListenerPid) {
kill(rxk_ListenerPid, SIGUSR1);
+ afs_osi_Sleep(&rxk_ListenerPid);
+ }
return 0;
}
-int osi_NetSend(asocket, addr, dvec, nvecs, asize, istack)
- register struct osi_socket *asocket;
- struct iovec dvec[];
- int nvecs;
- register afs_int32 asize;
- struct sockaddr_in *addr;
- int istack;
+int osi_NetSend(osi_socket asocket, struct sockaddr_in *addr,
+ struct iovec *dvec, int nvecs, afs_int32 asize, int istack)
{
int i;
int code;
}
/* Copy the data into the buffer */
- bcopy((char *)dvec[0].iov_base, (char *)bp->b_wptr, dvec[0].iov_len);
+ memcpy((char *)bp->b_wptr, (char *)dvec[0].iov_base, dvec[0].iov_len);
bp->b_datap->db_type = M_DATA;
bp->b_wptr += dvec[0].iov_len;
}
/* Copy the data into the buffer */
- bcopy((char *)dvec[i].iov_base, (char *)dbp->b_wptr, dvec[i].iov_len);
+ memcpy((char *)dbp->b_wptr, (char *)dvec[i].iov_base, dvec[i].iov_len);
dbp->b_datap->db_type = M_DATA;
dbp->b_wptr += dvec[i].iov_len;
udreq->addr.buf = (char *)kmem_alloc(sizeof(struct sockaddr_in), KM_SLEEP);
udreq->opt.len = 0;
udreq->opt.maxlen = 0;
- bcopy((char *)&sin, udreq->addr.buf, sizeof(struct sockaddr_in));
+ memcpy(udreq->addr.buf, (char *)&sin, sizeof(struct sockaddr_in));
udreq->udata.udata_mp = bp;
udreq->udata.len = asize;
}
-int osi_NetReceive(asocket, addr, dvec, nvecs, alength)
- struct osi_socket *asocket;
- struct sockaddr_in *addr;
- struct iovec *dvec;
- int nvecs;
- int *alength;
+int osi_NetReceive(struct osi_socket *asocket, struct sockaddr_in *addr,
+ struct iovec *dvec, int nvecs, int *alength)
{
int i;
TIUSER *udp_tiptr = (TIUSER *) asocket;
/*
* Save the source address
*/
- bcopy(udreq->addr.buf, (char *)addr, sizeof(struct sockaddr_in));
+ memcpy((char *)addr, udreq->addr.buf, sizeof(struct sockaddr_in));
/*
* Copy out the message buffers, take care not to overflow
while (dbp != NULL && tlen > 0) {
blen = dbp->b_wptr - dbp->b_rptr;
if (blen > tlen) {
- bcopy((char *)dbp->b_rptr, tbase, tlen);
+ memcpy(tbase, (char *)dbp->b_rptr, tlen);
length -= tlen;
dbp->b_rptr += tlen;
tlen = 0;
} else {
- bcopy((char *)dbp->b_rptr, tbase, blen);
+ memcpy(tbase, (char *)dbp->b_rptr, blen);
length -= blen;
tlen -= blen;
tbase += blen;