[BACK]Return to in6_gif.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / netinet6

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/netinet6/in6_gif.c between version 1.13 and 1.14

version 1.13, 2000/03/01 12:49:45 version 1.14, 2000/04/19 06:30:56
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
   /*      $KAME: in6_gif.c,v 1.34 2000/04/19 04:51:58 itojun Exp $        */
   
 /*  /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.   * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.   * All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions   * modification, are permitted provided that the following conditions
  * are met:   * are met:
Line 15 
Line 16 
  * 3. Neither the name of the project nor the names of its contributors   * 3. Neither the name of the project nor the names of its contributors
  *    may be used to endorse or promote products derived from this software   *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.   *    without specific prior written permission.
  *   *
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND   * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Line 33 
Line 34 
  * in6_gif.c   * in6_gif.c
  */   */
   
   #if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(__NetBSD__)
 #include "opt_inet.h"  #include "opt_inet.h"
   #endif
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/systm.h>  #include <sys/systm.h>
Line 41 
Line 44 
 #include <sys/sockio.h>  #include <sys/sockio.h>
 #include <sys/mbuf.h>  #include <sys/mbuf.h>
 #include <sys/errno.h>  #include <sys/errno.h>
   #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
 #include <sys/ioctl.h>  #include <sys/ioctl.h>
 #include <sys/protosw.h>  #endif
   
   #if defined(__FreeBSD__) && __FreeBSD__ >= 3
   #include <sys/malloc.h>
   #endif
   
 #include <net/if.h>  #include <net/if.h>
 #include <net/route.h>  #include <net/route.h>
Line 52 
Line 60 
 #ifdef INET  #ifdef INET
 #include <netinet/ip.h>  #include <netinet/ip.h>
 #endif  #endif
   #include <netinet/ip_encap.h>
 #ifdef INET6  #ifdef INET6
 #include <netinet/ip6.h>  #include <netinet/ip6.h>
 #include <netinet6/ip6_var.h>  #include <netinet6/ip6_var.h>
 #include <netinet6/in6_gif.h>  #include <netinet6/in6_gif.h>
   #include <netinet6/in6_var.h>
 #endif  #endif
 #include <netinet/ip_ecn.h>  #include <netinet/ip_ecn.h>
   
Line 194  in6_gif_output(ifp, family, m, rt)
Line 204  in6_gif_output(ifp, family, m, rt)
                         m_freem(m);                          m_freem(m);
                         return ENETUNREACH;                          return ENETUNREACH;
                 }                  }
   
                   /* if it constitutes infinite encapsulation, punt. */
                   if (sc->gif_ro.ro_rt->rt_ifp == ifp) {
                           m_freem(m);
                           return ENETUNREACH;     /*XXX*/
                   }
 #if 0  #if 0
                 ifp->if_mtu = sc->gif_ro6.ro_rt->rt_ifp->if_mtu                  ifp->if_mtu = sc->gif_ro6.ro_rt->rt_ifp->if_mtu
                         - sizeof(struct ip6_hdr);                          - sizeof(struct ip6_hdr);
 #endif  #endif
         }          }
   
   #ifdef IPV6_MINMTU
           /*
            * force fragmentation to minimum MTU, to avoid path MTU discovery.
            * it is too painful to ask for resend of inner packet, to achieve
            * path MTU discovery for encapsulated packets.
            */
           return(ip6_output(m, 0, &sc->gif_ro6, IPV6_MINMTU, 0, NULL));
   #else
         return(ip6_output(m, 0, &sc->gif_ro6, 0, 0, NULL));          return(ip6_output(m, 0, &sc->gif_ro6, 0, 0, NULL));
   #endif
 }  }
   
 int in6_gif_input(mp, offp, proto)  int in6_gif_input(mp, offp, proto)
Line 208  int in6_gif_input(mp, offp, proto)
Line 233  int in6_gif_input(mp, offp, proto)
         int *offp, proto;          int *offp, proto;
 {  {
         struct mbuf *m = *mp;          struct mbuf *m = *mp;
         struct gif_softc *sc;  
         struct ifnet *gifp = NULL;          struct ifnet *gifp = NULL;
         struct ip6_hdr *ip6;          struct ip6_hdr *ip6;
         int i;  
         int af = 0;          int af = 0;
         u_int32_t otos;          u_int32_t otos;
   
         ip6 = mtod(m, struct ip6_hdr *);          ip6 = mtod(m, struct ip6_hdr *);
   
 #define satoin6(sa)     (((struct sockaddr_in6 *)(sa))->sin6_addr)          gifp = (struct ifnet *)encap_getarg(m);
         for (i = 0, sc = gif; i < ngif; i++, sc++) {  
                 if (sc->gif_psrc == NULL ||  
                     sc->gif_pdst == NULL ||  
                     sc->gif_psrc->sa_family != AF_INET6 ||  
                     sc->gif_pdst->sa_family != AF_INET6) {  
                         continue;  
                 }  
                 if ((sc->gif_if.if_flags & IFF_UP) == 0)  
                         continue;  
                 if ((sc->gif_if.if_flags & IFF_LINK0) &&  
                     IN6_ARE_ADDR_EQUAL(&satoin6(sc->gif_psrc), &ip6->ip6_dst) &&  
                     IN6_IS_ADDR_UNSPECIFIED(&satoin6(sc->gif_pdst))) {  
                         gifp = &sc->gif_if;  
                         continue;  
                 }  
                 if (IN6_ARE_ADDR_EQUAL(&satoin6(sc->gif_psrc), &ip6->ip6_dst) &&  
                     IN6_ARE_ADDR_EQUAL(&satoin6(sc->gif_pdst), &ip6->ip6_src)) {  
                         gifp = &sc->gif_if;  
                         break;  
                 }  
         }  
   
         if (gifp == NULL) {          if (gifp == NULL || (gifp->if_flags & IFF_UP) == 0) {
                 m_freem(m);                  m_freem(m);
                 ip6stat.ip6s_nogif++;                  ip6stat.ip6s_nogif++;
                 return IPPROTO_DONE;                  return IPPROTO_DONE;
         }          }
   
         otos = ip6->ip6_flow;          otos = ip6->ip6_flow;
         m_adj(m, *offp);          m_adj(m, *offp);
   
Line 293  int in6_gif_input(mp, offp, proto)
Line 295  int in6_gif_input(mp, offp, proto)
         gif_input(m, af, gifp);          gif_input(m, af, gifp);
         return IPPROTO_DONE;          return IPPROTO_DONE;
 }  }
   
   /*
    * we know that we are in IFF_UP, outer address available, and outer family
    * matched the physical addr family.  see gif_encapcheck().
    */
   int
   gif_encapcheck6(m, off, proto, arg)
           const struct mbuf *m;
           int off;
           int proto;
           void *arg;
   {
           struct ip6_hdr ip6;
           struct gif_softc *sc;
           struct sockaddr_in6 *src, *dst;
           int addrmatch;
   
           /* sanity check done in caller */
           sc = (struct gif_softc *)arg;
           src = (struct sockaddr_in6 *)sc->gif_psrc;
           dst = (struct sockaddr_in6 *)sc->gif_pdst;
   
           /* LINTED const cast */
           m_copydata((struct mbuf *)m, 0, sizeof(ip6), (caddr_t)&ip6);
   
           /* check for address match */
           addrmatch = 0;
           if (IN6_ARE_ADDR_EQUAL(&src->sin6_addr, &ip6.ip6_dst))
                   addrmatch |= 1;
           if (IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &ip6.ip6_src))
                   addrmatch |= 2;
           else if ((sc->gif_if.if_flags & IFF_LINK0) != 0 &&
                    IN6_IS_ADDR_UNSPECIFIED(&dst->sin6_addr)) {
                   addrmatch |= 2; /* we accept any source */
           }
           if (addrmatch != 3)
                   return 0;
   
           /* martian filters on outer source - done in ip6_input */
   
           /* ingress filters on outer source */
           if ((m->m_flags & M_PKTHDR) != 0 && m->m_pkthdr.rcvif) {
                   struct sockaddr_in6 sin6;
                   struct rtentry *rt;
   
                   bzero(&sin6, sizeof(sin6));
                   sin6.sin6_family = AF_INET6;
                   sin6.sin6_len = sizeof(struct sockaddr_in6);
                   sin6.sin6_addr = ip6.ip6_src;
                   /* XXX scopeid */
   #ifdef __FreeBSD__
                   rt = rtalloc1((struct sockaddr *)&sin6, 0, 0UL);
   #else
                   rt = rtalloc1((struct sockaddr *)&sin6, 0);
   #endif
                   if (!rt)
                           return 0;
                   if (rt->rt_ifp != m->m_pkthdr.rcvif) {
                           rtfree(rt);
                           return 0;
                   }
                   rtfree(rt);
           }
   
           /* prioritize: IFF_LINK0 mode is less preferred */
           return (sc->gif_if.if_flags & IFF_LINK0) ? 128 : 128 * 2;
   }

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14

CVSweb <webmaster@jp.NetBSD.org>