ifnet-flags-20060118
[openafs.git] / src / rx / rx_kcommon.c
index 64b7293..f3a5f0b 100644 (file)
@@ -26,10 +26,11 @@ RCSID
 #include "afsint.h"
 
 #ifndef RXK_LISTENER_ENV
-int (*rxk_PacketArrivalProc) (register struct rx_packet * ahandle, register struct sockaddr_in * afrom, char *arock, afs_int32 asize); /* set to packet allocation procedure */
-int (*rxk_GetPacketProc) (char **ahandle, int asize);
+int (*rxk_PacketArrivalProc) (struct rx_packet * ahandle, struct sockaddr_in * afrom, struct socket *arock, afs_int32 asize);  /* set to packet allocation procedure */
+int (*rxk_GetPacketProc) (struct rx_packet **ahandle, int asize);
 #endif
 
+osi_socket *rxk_NewSocketHost(afs_uint32 ahost, short aport);
 extern struct interfaceAddr afs_cb_interface;
 
 rxk_ports_t rxk_ports;
@@ -44,6 +45,11 @@ static int myNetMTUs[ADDRSPERSITE];
 static int numMyNetAddrs = 0;
 #endif
 
+#if defined(AFS_DARWIN80_ENV)
+#define sobind sock_bind
+#define soclose sock_close
+#endif
+
 /* add a port to the monitored list, port # is in network order */
 static int
 rxk_AddPort(u_short aport, char *arock)
@@ -102,16 +108,21 @@ rxk_shutdownPorts(void)
 }
 
 osi_socket
-rxi_GetUDPSocket(u_short port)
+rxi_GetHostUDPSocket(u_int host, u_short port)
 {
-    struct osi_socket *sockp;
-    sockp = (struct osi_socket *)rxk_NewSocket(port);
-    if (sockp == (struct osi_socket *)0)
+    osi_socket *sockp;
+    sockp = (osi_socket *)rxk_NewSocketHost(host, port);
+    if (sockp == (osi_socket *)0)
        return OSI_NULLSOCKET;
     rxk_AddPort(port, (char *)sockp);
     return (osi_socket) sockp;
 }
 
+osi_socket
+rxi_GetUDPSocket(u_short port)
+{
+    return rxi_GetHostUDPSocket(htonl(INADDR_ANY), port);
+}
 
 void
 osi_Panic(msg, a1, a2, a3)
@@ -120,9 +131,10 @@ osi_Panic(msg, a1, a2, a3)
     if (!msg)
        msg = "Unknown AFS panic";
 
-    printf(msg, a1, a2, a3);
-#ifdef AFS_LINUX20_ENV
-    *((char *)0xffffffff) = 42;
+    dpf((msg, a1, a2, a3));
+#ifdef AFS_LINUX24_ENV
+    printk("AFS BUG at %s\n", msg); 
+    * ((char *) 0) = 0; 
 #else
     panic(msg);
 #endif
@@ -278,9 +290,9 @@ rx_ServerProc(void)
 #ifndef RXK_LISTENER_ENV
 /* asize includes the Rx header */
 static int
-MyPacketProc(char **ahandle, int asize)
+MyPacketProc(struct rx_packet **ahandle, int asize)
 {
-    register struct rx_packet *tp;
+    struct rx_packet *tp;
 
     /* If this is larger than we expected, increase rx_maxReceiveDataSize */
     /* If we can't scrounge enough cbufs, then we have to drop the packet,
@@ -310,27 +322,28 @@ MyPacketProc(char **ahandle, int asize)
        rx_stats.bogusPacketOnRead++;
        MUTEX_EXIT(&rx_stats_mutex);
        /* I DON"T LIKE THIS PRINTF -- PRINTFS MAKE THINGS VERY VERY SLOOWWW */
-       printf("rx: packet dropped: bad ulen=%d\n", asize);
+       dpf(("rx: packet dropped: bad ulen=%d\n", asize));
        tp = NULL;
     }
 
     if (!tp)
        return -1;
     /* otherwise we have a packet, set appropriate values */
-    *ahandle = (char *)tp;
+    *ahandle = tp;
     return 0;
 }
 
 static int
-MyArrivalProc(register struct rx_packet *ahandle,
-             register struct sockaddr_in *afrom, char *arock,
+MyArrivalProc(struct rx_packet *ahandle,
+             struct sockaddr_in *afrom,
+             struct socket *arock,
              afs_int32 asize)
 {
     /* handle basic rx packet */
     ahandle->length = asize - RX_HEADER_SIZE;
     rxi_DecodePacketHeader(ahandle);
     ahandle =
-       rxi_ReceivePacket(ahandle, (struct socket *)arock,
+       rxi_ReceivePacket(ahandle, arock,
                          afrom->sin_addr.s_addr, afrom->sin_port, NULL,
                          NULL);
 
@@ -386,7 +399,7 @@ rxi_InitPeerParams(register struct rx_peer *pp)
        pp->ifMTU = RX_REMOTE_PACKET_SIZE;
     }
 #else /* AFS_USERSPACE_IP_ADDR */
-    struct ifnet *ifn;
+    AFS_IFNET_T ifn;
 
 #if !defined(AFS_SGI62_ENV)
     if (numMyNetAddrs == 0)
@@ -399,7 +412,7 @@ rxi_InitPeerParams(register struct rx_peer *pp)
        /* pp->timeout.usec = 0; */
        pp->ifMTU = MIN(RX_MAX_PACKET_SIZE, rx_MyMaxSendSize);
 #ifdef IFF_POINTOPOINT
-       if (ifn->if_flags & IFF_POINTOPOINT) {
+       if (ifnet_flags(ifn) & IFF_POINTOPOINT) {
            /* wish we knew the bit rate and the chunk size, sigh. */
            pp->timeout.sec = 4;
            pp->ifMTU = RX_PP_PACKET_SIZE;
@@ -407,8 +420,8 @@ rxi_InitPeerParams(register struct rx_peer *pp)
 #endif /* IFF_POINTOPOINT */
        /* Diminish the packet size to one based on the MTU given by
         * the interface. */
-       if (ifn->if_mtu > (RX_IPUDP_SIZE + RX_HEADER_SIZE)) {
-           rxmtu = ifn->if_mtu - RX_IPUDP_SIZE;
+       if (ifnet_mtu(ifn) > (RX_IPUDP_SIZE + RX_HEADER_SIZE)) {
+           rxmtu = ifnet_mtu(ifn) - RX_IPUDP_SIZE;
            if (rxmtu < pp->ifMTU)
                pp->ifMTU = rxmtu;
        }
@@ -489,7 +502,7 @@ shutdown_rxkernel(void)
            rxk_shutdownPorts();
            return;
        }
-    printf("shutdown_rxkernel: no udp proto");
+    dpf(("shutdown_rxkernel: no udp proto"));
 }
 #endif /* !AIX && !SUN && !NCR  && !UKERNEL */
 
@@ -510,7 +523,7 @@ rxi_GetcbiInfo(void)
     memset((void *)mtus, 0, sizeof(mtus));
 
     for (i = 0; i < afs_cb_interface.numberOfInterfaces; i++) {
-        if (!afs_cb_interface.mtu[i]) 
+       if (!afs_cb_interface.mtu[i])
            afs_cb_interface.mtu[i] = htonl(1500);
        rxmtu = (ntohl(afs_cb_interface.mtu[i]) - RX_IPUDP_SIZE);
        ifinaddr = ntohl(afs_cb_interface.addr_in[i]);
@@ -609,16 +622,53 @@ rxi_GetIFInfo(void)
     int i = 0;
     int different = 0;
 
-    register struct ifnet *ifn;
     register int rxmtu, maxmtu;
     afs_uint32 addrs[ADDRSPERSITE];
     int mtus[ADDRSPERSITE];
-    struct ifaddr *ifad;       /* ifnet points to a if_addrlist of ifaddrs */
     afs_uint32 ifinaddr;
+#if defined(AFS_DARWIN80_ENV)
+    errno_t t;
+    int cnt=0;
+    ifaddr_t *ifads, ifad;
+    register ifnet_t ifn;
+    struct sockaddr sout;
+    struct sockaddr_in *sin;
+#else
+    struct ifaddr *ifad;       /* ifnet points to a if_addrlist of ifaddrs */
+    register struct ifnet *ifn;
+#endif
 
     memset(addrs, 0, sizeof(addrs));
     memset(mtus, 0, sizeof(mtus));
 
+#if defined(AFS_DARWIN80_ENV)
+    t = ifnet_get_address_list_family(NULL, &ifads, AF_INET);
+    if (t == 0) {
+       rxmtu = ifnet_mtu(ifn) - RX_IPUDP_SIZE;
+       while((ifads[cnt] != NULL) && cnt < ADDRSPERSITE) {
+           t = ifaddr_address(ifads[cnt], &sout, sizeof(sout));
+           sin = (struct sockaddr_in *)&sout;
+           ifinaddr = ntohl(sin->sin_addr.s_addr);
+           if (myNetAddrs[i] != ifinaddr) {
+               different++;
+           }
+           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;
+           if ((ifinaddr != 0x7f000001) && (maxmtu > rx_maxReceiveSize)) {
+               rx_maxReceiveSize = MIN(RX_MAX_PACKET_SIZE, maxmtu);
+               rx_maxReceiveSize =
+                   MIN(rx_maxReceiveSize, rx_maxReceiveSizeUser);
+           }
+           cnt++;
+       }
+       ifnet_free_address_list(ifads);
+    }
+#else
 #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
     TAILQ_FOREACH(ifn, &ifnet, if_link) {
        if (i >= ADDRSPERSITE)
@@ -664,6 +714,7 @@ rxi_GetIFInfo(void)
            }
        }
     }
+#endif
 
     rx_maxJumboRecvSize =
        RX_HEADER_SIZE + rxi_nDgramPackets * RX_JUMBOBUFFERSIZE +
@@ -682,19 +733,39 @@ rxi_GetIFInfo(void)
 
 #if defined(AFS_DARWIN60_ENV) || defined(AFS_XBSD_ENV)
 /* Returns ifnet which best matches address */
+#ifdef AFS_DARWIN80_ENV
+ifnet_t
+#else
 struct ifnet *
+#endif
 rxi_FindIfnet(afs_uint32 addr, afs_uint32 * maskp)
 {
-    struct sockaddr_in s;
+    struct sockaddr_in s, sr;
+#ifdef AFS_DARWIN80_ENV
+    ifaddr_t ifad;
+#else
     struct ifaddr *ifad;
+#endif
 
     s.sin_family = AF_INET;
     s.sin_addr.s_addr = addr;
+#ifdef AFS_DARWIN80_ENV
+    ifad = ifaddr_withnet((struct sockaddr *)&s);
+#else
     ifad = ifa_ifwithnet((struct sockaddr *)&s);
+#endif
 
+#ifdef AFS_DARWIN80_ENV
+    if (ifad && maskp) {
+       ifaddr_netmask(ifad, (struct sockaddr *)&sr, sizeof(sr));
+       *maskp = sr.sin_addr.s_addr;
+    }
+    return (ifad ? ifaddr_ifnet(ifad) : NULL);
+#else
     if (ifad && maskp)
        *maskp = ((struct sockaddr_in *)ifad->ifa_netmask)->sin_addr.s_addr;
     return (ifad ? ifad->ifa_ifp : NULL);
+#endif
 }
 
 #else /* DARWIN60 || XBSD */
@@ -755,11 +826,15 @@ rxi_FindIfnet(afs_uint32 addr, afs_uint32 * maskp)
 /* rxk_NewSocket creates a new socket on the specified port. The port is
  * in network byte order.
  */
-struct osi_socket *
-rxk_NewSocket(short aport)
+osi_socket *
+rxk_NewSocketHost(afs_uint32 ahost, short aport)
 {
     register afs_int32 code;
+#ifdef AFS_DARWIN80_ENV
+    socket_t newSocket;
+#else
     struct socket *newSocket;
+#endif
 #if (!defined(AFS_HPUX1122_ENV) && !defined(AFS_FBSD50_ENV))
     struct mbuf *nam;
 #endif
@@ -780,19 +855,22 @@ rxk_NewSocket(short aport)
 #if (defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)) && defined(KERNEL_FUNNEL)
     thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
 #endif
+    AFS_ASSERT_GLOCK();
+    AFS_GUNLOCK();
 #if    defined(AFS_HPUX102_ENV)
 #if     defined(AFS_HPUX110_ENV)
     /* we need a file associated with the socket so sosend in NetSend 
-       will not fail */
+     * will not fail */
     /* blocking socket */
     code = socreate(AF_INET, &newSocket, SOCK_DGRAM, 0, 0);
     fp = falloc();
-    if (!fp) goto bad;
+    if (!fp)
+       goto bad;
     fp->f_flag = FREAD | FWRITE;
     fp->f_type = DTYPE_SOCKET;
-    fp->f_ops  = &socketops;
+    fp->f_ops = &socketops;
 
-    fp->f_data = (void *) newSocket;
+    fp->f_data = (void *)newSocket;
     newSocket->so_fp = (void *)fp;
 
 #else /* AFS_HPUX110_ENV */
@@ -805,15 +883,18 @@ rxk_NewSocket(short aport)
                    afs_osi_credp, curthread);
 #elif defined(AFS_FBSD40_ENV)
     code = socreate(AF_INET, &newSocket, SOCK_DGRAM, IPPROTO_UDP, curproc);
+#elif defined(AFS_DARWIN80_ENV)
+    code = sock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, NULL, &newSocket);
 #else
     code = socreate(AF_INET, &newSocket, SOCK_DGRAM, 0);
 #endif /* AFS_HPUX102_ENV */
     if (code)
        goto bad;
 
+    memset(&myaddr, 0, sizeof myaddr);
     myaddr.sin_family = AF_INET;
     myaddr.sin_port = aport;
-    myaddr.sin_addr.s_addr = 0;
+    myaddr.sin_addr.s_addr = ahost;
 #ifdef STRUCT_SOCKADDR_HAS_SA_LEN
     myaddr.sin_len = sizeof(myaddr);
 #endif
@@ -839,12 +920,30 @@ rxk_NewSocket(short aport)
 
     freeb(bindnam);
 #else /* AFS_HPUX110_ENV */
+#if defined(AFS_DARWIN80_ENV)
+    { 
+       int buflen = 50000;
+       int i,code2;
+       for (i=0;i<2;i++) {
+           code = sock_setsockopt(newSocket, SOL_SOCKET, SO_SNDBUF,
+                                  &buflen, sizeof(buflen));
+           code2 = sock_setsockopt(newSocket, SOL_SOCKET, SO_RCVBUF,
+                                  &buflen, sizeof(buflen));
+           if (!code && !code2)
+               break;
+           if (i == 2)
+             osi_Panic("osi_NewSocket: last attempt to reserve 32K failed!\n");
+           buflen = 32766;
+       }
+    }
+#else
     code = soreserve(newSocket, 50000, 50000);
     if (code) {
        code = soreserve(newSocket, 32766, 32766);
        if (code)
            osi_Panic("osi_NewSocket: last attempt to reserve 32K failed!\n");
     }
+#endif
 #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
 #if defined(AFS_FBSD50_ENV)
     code = sobind(newSocket, (struct sockaddr *)&myaddr, curthread);
@@ -854,8 +953,9 @@ rxk_NewSocket(short aport)
     code = sobind(newSocket, (struct sockaddr *)&myaddr);
 #endif
     if (code) {
-       printf("sobind fails (%d)\n", (int)code);
+       dpf(("sobind fails (%d)\n", (int)code));
        soclose(newSocket);
+       AFS_GLOCK();
        goto bad;
     }
 #else /* defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) */
@@ -880,7 +980,7 @@ rxk_NewSocket(short aport)
     code = sobind(newSocket, nam);
 #endif
     if (code) {
-       printf("sobind fails (%d)\n", (int)code);
+       dpf(("sobind fails (%d)\n", (int)code));
        soclose(newSocket);
 #ifndef AFS_SGI65_ENV
        m_freem(nam);
@@ -890,18 +990,25 @@ rxk_NewSocket(short aport)
 #endif /* else AFS_DARWIN_ENV */
 #endif /* else AFS_HPUX110_ENV */
 
+    AFS_GLOCK();
 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
 #endif
-    return (struct osi_socket *)newSocket;
+    return (osi_socket *)newSocket;
 
   bad:
+    AFS_GLOCK();
 #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
 #endif
-    return (struct osi_socket *)0;
+    return (osi_socket *)0;
 }
 
+osi_socket *
+rxk_NewSocket(short aport)
+{
+    return rxk_NewSocketHost(0, aport);
+}
 
 /* free socket allocated by rxk_NewSocket */
 int
@@ -913,11 +1020,11 @@ rxk_FreeSocket(register struct socket *asocket)
 #endif
 #ifdef AFS_HPUX110_ENV
     if (asocket->so_fp) {
-       struct file * fp = asocket->so_fp;
+       struct file *fp = asocket->so_fp;
 #if !defined(AFS_HPUX1123_ENV)
        /* 11.23 still has falloc, but not FPENTRYFREE ! 
-          so for now if we shutdown, we will waist a file 
-          structure */
+        * so for now if we shutdown, we will waist a file 
+        * structure */
        FPENTRYFREE(fp);
        asocket->so_fp = NULL;
 #endif
@@ -946,9 +1053,7 @@ afs_rxevent_daemon(void)
        AFS_GUNLOCK();
 #endif /* RX_ENABLE_LOCKS */
        NETPRI;
-       AFS_RXGLOCK();
        rxevent_RaiseEvents(&temp);
-       AFS_RXGUNLOCK();
        USERPRI;
 #ifdef RX_ENABLE_LOCKS
        AFS_GLOCK();
@@ -1117,13 +1222,14 @@ rxk_Listener(void)
 #ifdef AFS_XBSD_ENV
     rxk_ListenerPid = curproc->p_pid;
 #endif /* AFS_FBSD_ENV */
-#if defined(AFS_DARWIN_ENV)
+#ifdef AFS_DARWIN80_ENV
+    rxk_ListenerPid = proc_selfpid();
+#elif defined(AFS_DARWIN_ENV)
     rxk_ListenerPid = current_proc()->p_pid;
 #endif
 #if defined(RX_ENABLE_LOCKS) && !defined(AFS_SUN5_ENV)
     AFS_GUNLOCK();
 #endif /* RX_ENABLE_LOCKS && !AFS_SUN5_ENV */
-
     while (afs_termState != AFSOP_STOP_RXK_LISTENER) {
        if (rxp) {
            rxi_RestoreDataBufs(rxp);
@@ -1133,9 +1239,7 @@ rxk_Listener(void)
                osi_Panic("rxk_Listener: No more Rx buffers!\n");
        }
        if (!(code = rxk_ReadPacket(rx_socket, rxp, &host, &port))) {
-           AFS_RXGLOCK();
            rxp = rxi_ReceivePacket(rxp, rx_socket, host, port, 0, 0);
-           AFS_RXGUNLOCK();
        }
     }