fix copyright, this was done from scratch
[unix-history] / usr / src / sys / net / if_ethersubr.c
index fcc5ca6..1996513 100644 (file)
@@ -4,7 +4,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)if_ethersubr.c      7.13 (Berkeley) %G%
+ *     @(#)if_ethersubr.c      7.14 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -46,6 +46,7 @@
 
 u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 extern struct ifnet loif;
 
 u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 extern struct ifnet loif;
+#define senderr(e) { error = (e); goto bad;}
 
 /*
  * Ethernet output routine.
 
 /*
  * Ethernet output routine.
@@ -54,33 +55,53 @@ extern      struct ifnet loif;
  * packet leaves a multiple of 512 bytes of data in remainder.
  * Assumes that ifp is actually pointer to arpcom structure.
  */
  * packet leaves a multiple of 512 bytes of data in remainder.
  * Assumes that ifp is actually pointer to arpcom structure.
  */
-ether_output(ifp, m0, dst, rt)
+ether_output(ifp, m0, dst, rt0)
        register struct ifnet *ifp;
        struct mbuf *m0;
        struct sockaddr *dst;
        register struct ifnet *ifp;
        struct mbuf *m0;
        struct sockaddr *dst;
-       struct rtentry *rt;
+       struct rtentry *rt0;
 {
        short type;
        int s, error = 0;
        u_char edst[6];
 {
        short type;
        int s, error = 0;
        u_char edst[6];
-       struct in_addr idst;
        register struct mbuf *m = m0;
        register struct mbuf *m = m0;
+       register struct rtentry *rt;
        struct mbuf *mcopy = (struct mbuf *)0;
        register struct ether_header *eh;
        int usetrailers, off, len = m->m_pkthdr.len;
 #define        ac ((struct arpcom *)ifp)
 
        struct mbuf *mcopy = (struct mbuf *)0;
        register struct ether_header *eh;
        int usetrailers, off, len = m->m_pkthdr.len;
 #define        ac ((struct arpcom *)ifp)
 
-       if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
-               error = ENETDOWN;
-               goto bad;
-       }
+       if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
+               senderr(ENETDOWN);
        ifp->if_lastchange = time;
        ifp->if_lastchange = time;
+       if (rt = rt0) {
+               if ((rt->rt_flags & RTF_UP) == 0) {
+                       if (rt0 = rt = rtalloc1(dst, 1))
+                               rt->rt_refcnt--;
+                       else 
+                               return (EHOSTUNREACH);
+               }
+               if (rt->rt_flags & RTF_GATEWAY) {
+                       if (rt->rt_gwroute == 0)
+                               goto lookup;
+                       if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
+                               rtfree(rt); rt = rt0;
+                       lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1);
+                               if ((rt = rt->rt_gwroute) == 0)
+                                       return (EHOSTUNREACH);
+                       }
+               }
+               if (rt->rt_flags & RTF_REJECT)
+                       if (rt->rt_rmx.rmx_expire == 0 ||
+                           time.tv_sec < rt->rt_rmx.rmx_expire)
+                               return (rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
+       }
        switch (dst->sa_family) {
 
 #ifdef INET
        case AF_INET:
        switch (dst->sa_family) {
 
 #ifdef INET
        case AF_INET:
-               idst = ((struct sockaddr_in *)dst)->sin_addr;
-               if (!arpresolve(ac, m, &idst, edst, &usetrailers))
+               if (!arpresolve(ac, rt, m, (struct sockaddr_in *)dst,
+                               edst, &usetrailers))
                        return (0);     /* if not yet resolved */
                if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1))
                        mcopy = m_copy(m, 0, (int)M_COPYALL);
                        return (0);     /* if not yet resolved */
                if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1))
                        mcopy = m_copy(m, 0, (int)M_COPYALL);
@@ -114,29 +135,15 @@ ether_output(ifp, m0, dst, rt)
        case AF_ISO: {
                int     snpalen;
                struct  llc *l;
        case AF_ISO: {
                int     snpalen;
                struct  llc *l;
+               register struct sockaddr_dl *sdl;
 
 
-       iso_again:
-               if (rt && rt->rt_gateway && (rt->rt_flags & RTF_UP)) {
-                       if (rt->rt_flags & RTF_GATEWAY) {
-                               if (rt->rt_llinfo) {
-                                       rt = (struct rtentry *)rt->rt_llinfo;
-                                       goto iso_again;
-                               }
-                       } else {
-                               register struct sockaddr_dl *sdl = 
-                                       (struct sockaddr_dl *)rt->rt_gateway;
-                               if (sdl && sdl->sdl_family == AF_LINK
-                                   && sdl->sdl_alen > 0) {
-                                       bcopy(LLADDR(sdl), (char *)edst,
-                                                               sizeof(edst));
-                                       goto iso_resolved;
-                               }
-                       }
-               }
-               if ((error = iso_snparesolve(ifp, (struct sockaddr_iso *)dst,
-                                       (char *)edst, &snpalen)) > 0)
+               if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) &&
+                   sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) {
+                       bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst));
+               } else if (error =
+                           iso_snparesolve(ifp, (struct sockaddr_iso *)dst,
+                                           (char *)edst, &snpalen))
                        goto bad; /* Not Resolved */
                        goto bad; /* Not Resolved */
-       iso_resolved:
                if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&
                    (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
                        M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
                if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&
                    (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
                        M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
@@ -185,8 +192,7 @@ ether_output(ifp, m0, dst, rt)
        default:
                printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
                        dst->sa_family);
        default:
                printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
                        dst->sa_family);
-               error = EAFNOSUPPORT;
-               goto bad;
+               senderr(EAFNOSUPPORT);
        }
 
 gottrailertype:
        }
 
 gottrailertype:
@@ -208,10 +214,8 @@ gottype:
         * allocate another.
         */
        M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
         * allocate another.
         */
        M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
-       if (m == 0) {
-               error = ENOBUFS;
-               goto bad;
-       }
+       if (m == 0)
+               senderr(ENOBUFS);
        eh = mtod(m, struct ether_header *);
        type = htons((u_short)type);
        bcopy((caddr_t)&type,(caddr_t)&eh->ether_type,
        eh = mtod(m, struct ether_header *);
        type = htons((u_short)type);
        bcopy((caddr_t)&type,(caddr_t)&eh->ether_type,
@@ -227,8 +231,7 @@ gottype:
        if (IF_QFULL(&ifp->if_snd)) {
                IF_DROP(&ifp->if_snd);
                splx(s);
        if (IF_QFULL(&ifp->if_snd)) {
                IF_DROP(&ifp->if_snd);
                splx(s);
-               error = ENOBUFS;
-               goto bad;
+               senderr(ENOBUFS);
        }
        IF_ENQUEUE(&ifp->if_snd, m);
        if ((ifp->if_flags & IFF_OACTIVE) == 0)
        }
        IF_ENQUEUE(&ifp->if_snd, m);
        if ((ifp->if_flags & IFF_OACTIVE) == 0)
@@ -277,8 +280,9 @@ ether_input(ifp, eh, m)
                break;
 
        case ETHERTYPE_ARP:
                break;
 
        case ETHERTYPE_ARP:
-               arpinput((struct arpcom *)ifp, m);
-               return;
+               schednetisr(NETISR_ARP);
+               inq = &arpintrq;
+               break;
 #endif
 #ifdef NS
        case ETHERTYPE_NS:
 #endif
 #ifdef NS
        case ETHERTYPE_NS: