Deleted Added
full compact
0a1,3
> /* $FreeBSD: head/sys/net/if_gif.c 62587 2000-07-04 16:35:15Z itojun $ */
> /* $KAME: if_gif.c,v 1.28 2000/06/20 12:30:03 jinmei Exp $ */
>
28,29d30
< *
< * $FreeBSD: head/sys/net/if_gif.c 57903 2000-03-11 11:17:24Z shin $
32,35d32
< /*
< * gif.c
< */
<
48a46
> #include <sys/protosw.h>
72a71
> #include <netinet6/ip6protosw.h>
74a74
> #include <netinet/ip_encap.h>
77a78,79
> #include "bpf.h"
> #define NBPFILTER NBPF
80a83,84
> #if NGIF > 0
>
81a86,92
> static int gif_encapcheck __P((const struct mbuf *, int, int, void *));
> #ifdef INET
> extern struct protosw in_gif_protosw;
> #endif
> #ifdef INET6
> extern struct ip6protosw in6_gif_protosw;
> #endif
86,87c97,98
< int ngif = NGIF + 1; /* number of interfaces. +1 for stf. */
< struct gif_softc *gif = 0;
---
> static int ngif; /* number of interfaces */
> static struct gif_softc *gif = 0;
88a100,112
> #ifndef MAX_GIF_NEST
> /*
> * This macro controls the upper limitation on nesting of gif tunnels.
> * Since, setting a large value to this macro with a careless configuration
> * may introduce system crash, we don't allow any nestings by default.
> * If you need to configure nested gif tunnels, you can define this macro
> * in your kernel configuration file. However, if you do so, please be
> * careful to configure the tunnels so that it won't make a loop.
> */
> #define MAX_GIF_NEST 1
> #endif
> static int max_gif_nesting = MAX_GIF_NEST;
>
95a120
> ngif = NGIF;
98c123
< for (i = 0; i < ngif - 1; sc++, i++) { /* leave last one for stf */
---
> for (i = 0; i < ngif; sc++, i++) {
100a126,148
>
> sc->encap_cookie4 = sc->encap_cookie6 = NULL;
> #ifdef INET
> sc->encap_cookie4 = encap_attach_func(AF_INET, -1,
> gif_encapcheck, &in_gif_protosw, sc);
> if (sc->encap_cookie4 == NULL) {
> printf("%s: attach failed\n", if_name(&sc->gif_if));
> continue;
> }
> #endif
> #ifdef INET6
> sc->encap_cookie6 = encap_attach_func(AF_INET6, -1,
> gif_encapcheck, (struct protosw *)&in6_gif_protosw, sc);
> if (sc->encap_cookie6 == NULL) {
> if (sc->encap_cookie4) {
> encap_detach(sc->encap_cookie4);
> sc->encap_cookie4 = NULL;
> }
> printf("%s: attach failed\n", if_name(&sc->gif_if));
> continue;
> }
> #endif
>
106c154
< sc->gif_if.if_snd.ifq_maxlen = ifqmaxlen;
---
> sc->gif_if.if_snd.ifq_maxlen = IFQ_MAXLEN;
107a156,157
> #if NBPFILTER > 0
> #ifdef HAVE_OLD_BPF
108a159,162
> #else
> bpfattach(&sc->gif_if.if_bpf, &sc->gif_if, DLT_NULL, sizeof(u_int));
> #endif
> #endif
110,119d163
< sc->gif_if.if_name = "stf";
< sc->gif_if.if_unit = 0;
< sc->gif_if.if_mtu = GIF_MTU;
< sc->gif_if.if_flags = IFF_MULTICAST;
< sc->gif_if.if_ioctl = gif_ioctl;
< sc->gif_if.if_output = gif_output;
< sc->gif_if.if_type = IFT_GIF;
< sc->gif_if.if_snd.ifq_maxlen = ifqmaxlen;
< if_attach(&sc->gif_if);
< bpfattach(&sc->gif_if, DLT_NULL, sizeof(u_int));
123a168,224
> static int
> gif_encapcheck(m, off, proto, arg)
> const struct mbuf *m;
> int off;
> int proto;
> void *arg;
> {
> struct ip ip;
> struct gif_softc *sc;
>
> sc = (struct gif_softc *)arg;
> if (sc == NULL)
> return 0;
>
> if ((sc->gif_if.if_flags & IFF_UP) == 0)
> return 0;
>
> /* no physical address */
> if (!sc->gif_psrc || !sc->gif_pdst)
> return 0;
>
> switch (proto) {
> #ifdef INET
> case IPPROTO_IPV4:
> break;
> #endif
> #ifdef INET6
> case IPPROTO_IPV6:
> break;
> #endif
> default:
> return 0;
> }
>
> /* LINTED const cast */
> m_copydata((struct mbuf *)m, 0, sizeof(ip), (caddr_t)&ip);
>
> switch (ip.ip_v) {
> #ifdef INET
> case 4:
> if (sc->gif_psrc->sa_family != AF_INET ||
> sc->gif_pdst->sa_family != AF_INET)
> return 0;
> return gif_encapcheck4(m, off, proto, arg);
> #endif
> #ifdef INET6
> case 6:
> if (sc->gif_psrc->sa_family != AF_INET6 ||
> sc->gif_pdst->sa_family != AF_INET6)
> return 0;
> return gif_encapcheck6(m, off, proto, arg);
> #endif
> default:
> return 0;
> }
> }
>
134d234
< int calllimit = 10; /* XXX: adhoc */
143c243
< if (++called >= calllimit) {
---
> if (++called > max_gif_nesting) {
150a251
>
159a261
> #if NBPFILTER > 0
174c276,277
<
---
>
> #ifdef HAVE_OLD_BPF
175a279,281
> #else
> bpf_mtap(ifp->if_bpf, &m0);
> #endif
177c283,284
< ifp->if_opackets++;
---
> #endif
> ifp->if_opackets++;
179a287,288
> /* XXX should we check if our outer source is legal? */
>
192c301
< m_freem(m);
---
> m_freem(m);
217,219c326,328
< if (m->m_pkthdr.rcvif)
< m->m_pkthdr.rcvif = gifp;
<
---
> m->m_pkthdr.rcvif = gifp;
>
> #if NBPFILTER > 0
230c339
<
---
>
234c343,344
<
---
>
> #ifdef HAVE_OLD_BPF
235a346,348
> #else
> bpf_mtap(gifp->if_bpf, &m0);
> #endif
236a350
> #endif /*NBPFILTER > 0*/
285c399
<
---
> /* XXX how should we handle IPv6 scope on SIOC[GS]IFPHYADDR? */
295,296c409,413
< struct sockaddr *sa, *dst, *src;
<
---
> struct sockaddr *dst, *src;
> struct sockaddr *sa;
> int i;
> struct gif_softc *sc2;
>
300c417
<
---
>
307a425
> #ifdef SIOCSIFMTU /* xxx */
309a428
>
319a439
> #endif /* SIOCSIFMTU */
325,327c445,446
< switch (ifr->ifr_addr.sa_family) {
< #ifdef INET
< case AF_INET:
---
> switch (cmd) {
> case SIOCSIFPHYADDR:
332,355d450
<
< /* only one gif can have dst = INADDR_ANY */
< #define satosaddr(sa) (((struct sockaddr_in *)(sa))->sin_addr.s_addr)
<
< #ifdef INET6
< if (bcmp(ifp->if_name, "stf", 3) == 0)
< satosaddr(dst) = INADDR_BROADCAST;
< #endif
<
< if (satosaddr(dst) == INADDR_ANY) {
< int i;
< struct gif_softc *sc2;
<
< for (i = 0, sc2 = gif; i < ngif; i++, sc2++) {
< if (sc2 == sc) continue;
< if (sc2->gif_pdst &&
< satosaddr(sc2->gif_pdst)
< == INADDR_ANY) {
< error = EADDRNOTAVAIL;
< goto bad;
< }
< }
< }
< size = sizeof(struct sockaddr_in);
357d451
< #endif /* INET */
359c453
< case AF_INET6:
---
> case SIOCSIFPHYADDR_IN6:
363a458,460
> break;
> #endif
> }
365,366c462,478
< /* only one gif can have dst = in6addr_any */
< #define satoin6(sa) (&((struct sockaddr_in6 *)(sa))->sin6_addr)
---
> for (i = 0; i < ngif; i++) {
> sc2 = gif + i;
> if (sc2 == sc)
> continue;
> if (!sc2->gif_pdst || !sc2->gif_psrc)
> continue;
> if (sc2->gif_pdst->sa_family != dst->sa_family ||
> sc2->gif_pdst->sa_len != dst->sa_len ||
> sc2->gif_psrc->sa_family != src->sa_family ||
> sc2->gif_psrc->sa_len != src->sa_len)
> continue;
> /* can't configure same pair of address onto two gifs */
> if (bcmp(sc2->gif_pdst, dst, dst->sa_len) == 0 &&
> bcmp(sc2->gif_psrc, src, src->sa_len) == 0) {
> error = EADDRNOTAVAIL;
> goto bad;
> }
368,381c480,490
< if (IN6_IS_ADDR_UNSPECIFIED(satoin6(dst))) {
< int i;
< struct gif_softc *sc2;
<
< for (i = 0, sc2 = gif; i < ngif; i++, sc2++) {
< if (sc2 == sc) continue;
< if (sc2->gif_pdst &&
< IN6_IS_ADDR_UNSPECIFIED(
< satoin6(sc2->gif_pdst)
< )) {
< error = EADDRNOTAVAIL;
< goto bad;
< }
< }
---
> /* can't configure multiple multi-dest interfaces */
> #define multidest(x) \
> (((struct sockaddr_in *)(x))->sin_addr.s_addr == INADDR_ANY)
> #ifdef INET6
> #define multidest6(x) \
> (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)(x))->sin6_addr))
> #endif
> if (dst->sa_family == AF_INET &&
> multidest(dst) && multidest(sc2->gif_pdst)) {
> error = EADDRNOTAVAIL;
> goto bad;
382a492,513
> #ifdef INET6
> if (dst->sa_family == AF_INET6 &&
> multidest6(dst) && multidest6(sc2->gif_pdst)) {
> error = EADDRNOTAVAIL;
> goto bad;
> }
> #endif
> }
>
> if (src->sa_family != dst->sa_family ||
> src->sa_len != dst->sa_len) {
> error = EINVAL;
> break;
> }
> switch (src->sa_family) {
> #ifdef INET
> case AF_INET:
> size = sizeof(struct sockaddr_in);
> break;
> #endif
> #ifdef INET6
> case AF_INET6:
385c516
< #endif /* INET6 */
---
> #endif
387c518
< error = EPROTOTYPE;
---
> error = EAFNOSUPPORT;
388a520,522
> }
> if (src->sa_len != size) {
> error = EINVAL;
391,394d524
< if (sc->gif_psrc != NULL)
< free((caddr_t)sc->gif_psrc, M_IFADDR);
< if (sc->gif_pdst != NULL)
< free((caddr_t)sc->gif_pdst, M_IFADDR);
395a526,527
> if (sc->gif_psrc)
> free((caddr_t)sc->gif_psrc, M_IFADDR);
397d528
< bzero((caddr_t)sa, size);
400a532,533
> if (sc->gif_pdst)
> free((caddr_t)sc->gif_pdst, M_IFADDR);
402d534
< bzero((caddr_t)sa, size);
406,408c538,539
< ifp->if_flags |= (IFF_UP|IFF_RUNNING);
< {
< int s;
---
> ifp->if_flags |= IFF_UP;
> if_up(ifp); /* send up RTM_IFINFO */
410,414c541
< s = splnet();
< if_up(ifp); /* send up RTM_IFINFO */
< splx(s);
< }
<
---
> error = 0;
416a544,557
> #ifdef SIOCDIFPHYADDR
> case SIOCDIFPHYADDR:
> if (sc->gif_psrc) {
> free((caddr_t)sc->gif_psrc, M_IFADDR);
> sc->gif_psrc = NULL;
> }
> if (sc->gif_pdst) {
> free((caddr_t)sc->gif_pdst, M_IFADDR);
> sc->gif_pdst = NULL;
> }
> /* change the IFF_UP flag as well? */
> break;
> #endif
>
446c587
<
---
>
477a619
> /* if_ioctl() takes care of it */
486a629
> #endif /*NGIF > 0*/