BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / net / route.c
index 192c964..2d69294 100644 (file)
@@ -1,35 +1,61 @@
 /*
 /*
- * Copyright (c) 1980, 1986 Regents of the University of California.
+ * Copyright (c) 1980, 1986, 1991 Regents of the University of California.
  * All rights reserved.
  *
  * All rights reserved.
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
  *
- *     @(#)route.c     7.19 (Berkeley) %G%
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)route.c     7.22 (Berkeley) 6/27/91
  */
  */
-#include "machine/reg.h"
 #include "param.h"
 #include "systm.h"
 #include "param.h"
 #include "systm.h"
-#include "user.h"
 #include "proc.h"
 #include "mbuf.h"
 #include "socket.h"
 #include "socketvar.h"
 #include "domain.h"
 #include "protosw.h"
 #include "proc.h"
 #include "mbuf.h"
 #include "socket.h"
 #include "socketvar.h"
 #include "domain.h"
 #include "protosw.h"
-#include "errno.h"
 #include "ioctl.h"
 
 #include "if.h"
 #include "af.h"
 #include "route.h"
 #include "raw_cb.h"
 #include "ioctl.h"
 
 #include "if.h"
 #include "af.h"
 #include "route.h"
 #include "raw_cb.h"
+
 #include "../netinet/in.h"
 #include "../netinet/in_var.h"
 
 #include "../netinet/in.h"
 #include "../netinet/in_var.h"
 
+#ifdef NS
 #include "../netns/ns.h"
 #include "../netns/ns.h"
+#endif
 #include "machine/mtpr.h"
 #include "netisr.h"
 #include "machine/mtpr.h"
 #include "netisr.h"
+
 #define        SA(p) ((struct sockaddr *)(p))
 
 int    rttrash;                /* routes not in table but not freed */
 #define        SA(p) ((struct sockaddr *)(p))
 
 int    rttrash;                /* routes not in table but not freed */
@@ -39,10 +65,13 @@ int rthashsize = RTHASHSIZ; /* for netstat, etc. */
 static int rtinits_done = 0;
 struct radix_node_head *ns_rnhead, *in_rnhead;
 struct radix_node *rn_match(), *rn_delete(), *rn_addroute();
 static int rtinits_done = 0;
 struct radix_node_head *ns_rnhead, *in_rnhead;
 struct radix_node *rn_match(), *rn_delete(), *rn_addroute();
+
 rtinitheads()
 {
        if (rtinits_done == 0 &&
 rtinitheads()
 {
        if (rtinits_done == 0 &&
+#ifdef NS
            rn_inithead(&ns_rnhead, 16, AF_NS) &&
            rn_inithead(&ns_rnhead, 16, AF_NS) &&
+#endif
            rn_inithead(&in_rnhead, 32, AF_INET))
                rtinits_done = 1;
 }
            rn_inithead(&in_rnhead, 32, AF_INET))
                rtinits_done = 1;
 }
@@ -200,9 +229,10 @@ done:
 /*
 * Routing table ioctl interface.
 */
 /*
 * Routing table ioctl interface.
 */
-rtioctl(req, data)
+rtioctl(req, data, p)
        int req;
        caddr_t data;
        int req;
        caddr_t data;
+       struct proc *p;
 {
 #ifndef COMPAT_43
        return (EOPNOTSUPP);
 {
 #ifndef COMPAT_43
        return (EOPNOTSUPP);
@@ -218,7 +248,7 @@ rtioctl(req, data)
        else
                return (EINVAL);
 
        else
                return (EINVAL);
 
-       if (error = suser(u.u_cred, &u.u_acflag))
+       if (error = suser(p->p_ucred, &p->p_acflag))
                return (error);
 #if BYTE_ORDER != BIG_ENDIAN
        if (entry->rt_dst.sa_family == 0 && entry->rt_dst.sa_len < 16) {
                return (error);
 #if BYTE_ORDER != BIG_ENDIAN
        if (entry->rt_dst.sa_family == 0 && entry->rt_dst.sa_len < 16) {
@@ -271,7 +301,7 @@ ifa_ifwithroute(flags, dst, gateway)
 int    flags;
 struct sockaddr        *dst, *gateway;
 {
 int    flags;
 struct sockaddr        *dst, *gateway;
 {
-       struct ifaddr *ifa;
+       register struct ifaddr *ifa;
        if ((flags & RTF_GATEWAY) == 0) {
                /*
                 * If we are adding a route to an interface,
        if ((flags & RTF_GATEWAY) == 0) {
                /*
                 * If we are adding a route to an interface,
@@ -295,6 +325,20 @@ struct sockaddr    *dst, *gateway;
        }
        if (ifa == 0)
                ifa = ifa_ifwithnet(gateway);
        }
        if (ifa == 0)
                ifa = ifa_ifwithnet(gateway);
+       if (ifa == 0) {
+               struct rtentry *rt = rtalloc1(dst, 0);
+               if (rt == 0)
+                       return (0);
+               rt->rt_refcnt--;
+               if ((ifa = rt->rt_ifa) == 0)
+                       return (0);
+       }
+       if (ifa->ifa_addr->sa_family != dst->sa_family) {
+               struct ifaddr *oifa = ifa, *ifaof_ifpforaddr();
+               ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);
+               if (ifa == 0)
+                       ifa = oifa;
+       }
        return (ifa);
 }
 
        return (ifa);
 }