handle route caching here.
authorKeith Sklower <sklower@ucbvax.Berkeley.EDU>
Fri, 27 Sep 1985 06:54:37 +0000 (22:54 -0800)
committerKeith Sklower <sklower@ucbvax.Berkeley.EDU>
Fri, 27 Sep 1985 06:54:37 +0000 (22:54 -0800)
SCCS-vsn: sys/netns/ns_pcb.c 6.5

usr/src/sys/netns/ns_pcb.c

index 208fb37..bb4e04e 100644 (file)
@@ -3,7 +3,7 @@
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
- *     @(#)ns_pcb.c    6.4 (Berkeley) %G%
+ *     @(#)ns_pcb.c    6.5 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -94,8 +94,8 @@ ns_pcbconnect(nsp, nam)
        struct mbuf *nam;
 {
        struct ns_ifaddr *ia;
        struct mbuf *nam;
 {
        struct ns_ifaddr *ia;
-       struct sockaddr_ns *ifaddr;
        register struct sockaddr_ns *sns = mtod(nam, struct sockaddr_ns *);
        register struct sockaddr_ns *sns = mtod(nam, struct sockaddr_ns *);
+       register struct ns_addr *dst;
 
        if (nam->m_len != sizeof (*sns))
                return (EINVAL);
 
        if (nam->m_len != sizeof (*sns))
                return (EINVAL);
@@ -104,21 +104,20 @@ ns_pcbconnect(nsp, nam)
        if (sns->sns_port==0 || ns_nullhost(sns->sns_addr))
                return (EADDRNOTAVAIL);
        if (ns_nullhost(nsp->nsp_laddr) &&
        if (sns->sns_port==0 || ns_nullhost(sns->sns_addr))
                return (EADDRNOTAVAIL);
        if (ns_nullhost(nsp->nsp_laddr) &&
-           ((*(long *)&nsp->nsp_lastnet)!=ns_netof(sns->sns_addr))) {
-               ia = (struct ns_ifaddr *)ifa_ifwithnet((struct sockaddr *)sns);
-               if (ia == 0) {
-                       register struct route *ro;
-                       struct ifnet *ifp;
+           (!ns_neteq(nsp->nsp_lastdst, sns->sns_addr))) {
+               register struct route *ro;
+               struct ifnet *ifp;
+               ro = &nsp->nsp_route;
+               dst = &satons_addr(ro->ro_dst);
 
 
+               ia = ns_iaonnetof(&sns->sns_addr);
+               if (ia == 0) {
                        /* 
                         * If route is known or can be allocated now,
                         * our src addr is taken from the i/f, else punt.
                         */
                        /* 
                         * If route is known or can be allocated now,
                         * our src addr is taken from the i/f, else punt.
                         */
-                       ro = &nsp->nsp_route;
-#define        satosns(sa)     ((struct sockaddr_ns *)(sa))
                        if (ro->ro_rt &&
                        if (ro->ro_rt &&
-                               !ns_hosteq(satosns(&ro->ro_dst)->sns_addr,
-                                       sns->sns_addr)) {
+                               !ns_hosteq(*dst, sns->sns_addr)) {
                                RTFREE(ro->ro_rt);
                                ro->ro_rt = (struct rtentry *)0;
                        }
                                RTFREE(ro->ro_rt);
                                ro->ro_rt = (struct rtentry *)0;
                        }
@@ -126,8 +125,8 @@ ns_pcbconnect(nsp, nam)
                            (ifp = ro->ro_rt->rt_ifp) == (struct ifnet *)0) {
                                /* No route yet, so try to acquire one */
                                ro->ro_dst.sa_family = AF_NS;
                            (ifp = ro->ro_rt->rt_ifp) == (struct ifnet *)0) {
                                /* No route yet, so try to acquire one */
                                ro->ro_dst.sa_family = AF_NS;
-                               satosns(&ro->ro_dst)->sns_addr =
-                                       sns->sns_addr;
+                               *dst = sns->sns_addr;
+                               dst->x_port = 0;
                                rtalloc(ro);
                                if (ro->ro_rt == 0)
                                        ifp = (struct ifnet *)0;
                                rtalloc(ro);
                                if (ro->ro_rt == 0)
                                        ifp = (struct ifnet *)0;
@@ -143,10 +142,32 @@ ns_pcbconnect(nsp, nam)
                                ia = ns_ifaddr;
                        if (ia == 0)
                                return (EADDRNOTAVAIL);
                                ia = ns_ifaddr;
                        if (ia == 0)
                                return (EADDRNOTAVAIL);
+               } else if (ro->ro_rt) {
+                       if (ns_neteq(*dst, sns->sns_addr)) {
+                               /*
+                                * This assume that we have no GH
+                                * type routes.
+                                */
+                               if (ro->ro_rt->rt_flags & RTF_HOST) {
+                                       if (!ns_hosteq(*dst, sns->sns_addr))
+                                               goto re_route;
+
+                               }
+                               if ((ro->ro_rt->rt_flags & RTF_GATEWAY) == 0) {
+                                       dst->x_host = sns->sns_addr.x_host;
+                               }
+                               /* 
+                                * Otherwise, we go through the same gateway
+                                * and dst is already set up.
+                                */
+                       } else {
+                       re_route:
+                               RTFREE(ro->ro_rt);
+                               ro->ro_rt = (struct rtentry *)0;
+                       }
                }
                }
-               ifaddr = satosns(&ia->ia_addr);
-               nsp->nsp_laddr.x_net = ifaddr->sns_addr.x_net;
-               nsp->nsp_lastnet = sns->sns_addr.x_net;
+               nsp->nsp_laddr.x_net = satons_addr(ia->ia_addr).x_net;
+               nsp->nsp_lastdst = sns->sns_addr;
        }
        if (ns_pcblookup(&sns->sns_addr, nsp->nsp_lport, 0))
                return (EADDRINUSE);
        }
        if (ns_pcblookup(&sns->sns_addr, nsp->nsp_lport, 0))
                return (EADDRINUSE);