diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2002-06-10 23:06:56 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2002-06-10 23:06:56 +0000 |
commit | 423957fd9ca5294d045595202dfb2441640e4072 (patch) | |
tree | 6add31c185e02fdc048c335656662d089e12c29b | |
parent | 32bd120e6d450297ab48b3a73d3bf306ad15e3a1 (diff) |
- stop abusing IFF_UP.
- do not use L3 address pair for L2.5 address pair. configure L2.5 address
pair by using "ifconfig tunnel".
- IFF_LINK2 is not needed, as it is just a reverse of IFF_LINK0.
- do not modify IFF_LINK1 when you modify protocol type.
chris ok
-rw-r--r-- | sys/net/if_gre.c | 112 |
1 files changed, 44 insertions, 68 deletions
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index 78c558334a4..f75b207bdfe 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_gre.c,v 1.21 2002/06/09 18:00:08 itojun Exp $ */ +/* $OpenBSD: if_gre.c,v 1.22 2002/06/10 23:06:55 itojun Exp $ */ /* $NetBSD: if_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */ /* @@ -99,8 +99,6 @@ before changing if state to up to find the correct value */ -#define LINK_MASK (IFF_LINK0|IFF_LINK1|IFF_LINK2) - struct gre_softc *gre = 0; int ngre = 0; @@ -148,6 +146,7 @@ greattach(n) sc->sc_if.if_opackets = 0; sc->g_dst.s_addr = sc->g_src.s_addr = INADDR_ANY; sc->g_proto = IPPROTO_GRE; + sc->sc_if.if_flags |= IFF_LINK0; if_attach(&sc->sc_if); @@ -175,13 +174,21 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct mobile_h mob_h; struct m_tag *mtag; + if ((ifp->if_flags & IFF_UP) == 0 || + sc->g_src.s_addr == INADDR_ANY || sc->g_dst.s_addr == INADDR_ANY) { + m_freem(m); + error = ENETDOWN; + goto end; + } + /* Try to limit infinite recursion through misconfiguration. */ for (mtag = m_tag_find(m, PACKET_TAG_GRE, NULL); mtag; mtag = m_tag_find(m, PACKET_TAG_GRE, mtag)) { if (!bcmp((caddr_t)(mtag + 1), &ifp, sizeof(struct ifnet *))) { IF_DROP(&ifp->if_snd); m_freem(m); - return (EIO); /* Use the same as in if_gif.c */ + error = EIO; + goto end; } } @@ -189,7 +196,8 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, if (mtag == NULL) { IF_DROP(&ifp->if_snd); m_freem(m); - return (ENOBUFS); + error = ENOBUFS; + goto end; } bcopy(&ifp, (caddr_t)(mtag + 1), sizeof(struct ifnet *)); m_tag_prepend(m, mtag); @@ -203,7 +211,8 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, if (ip_mobile_allow == 0) { IF_DROP(&ifp->if_snd); m_freem(m); - return (EACCES); + error = EACCES; + goto end; } if (dst->sa_family == AF_INET) { @@ -218,7 +227,8 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, m = m_pullup(m, sizeof(struct ip)); if (m == NULL) { IF_DROP(&ifp->if_snd); - return (ENOBUFS); + error = ENOBUFS; + goto end; } else inp = mtod(m, struct ip *); @@ -227,7 +237,8 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, sizeof(inp->ip_hl << 2)); if (m == NULL) { IF_DROP(&ifp->if_snd); - return (ENOBUFS); + error = ENOBUFS; + goto end; } } } @@ -263,7 +274,8 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, if (m0 == NULL) { IF_DROP(&ifp->if_snd); m_freem(m); - return (ENOBUFS); + error = ENOBUFS; + goto end; } M_MOVE_HDR(m0, m); @@ -294,13 +306,15 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, } else { /* AF_INET */ IF_DROP(&ifp->if_snd); m_freem(m); - return (EINVAL); + error = EINVAL; + goto end; } } else if (sc->g_proto == IPPROTO_GRE) { if (gre_allow == 0) { IF_DROP(&ifp->if_snd); m_freem(m); - return (EACCES); + error = EACCES; + goto end; } switch(dst->sa_family) { @@ -309,7 +323,8 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, m = m_pullup(m, sizeof(struct ip)); if (m == NULL) { IF_DROP(&ifp->if_snd); - return (ENOBUFS); + error = ENOBUFS; + goto end; } } @@ -329,20 +344,22 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, default: IF_DROP(&ifp->if_snd); m_freem(m); - return (EAFNOSUPPORT); + error = EAFNOSUPPORT; + goto end; } M_PREPEND(m, sizeof(struct greip), M_DONTWAIT); } else { - error = EINVAL; IF_DROP(&ifp->if_snd); m_freem(m); - return (error); + error = EINVAL; + goto end; } if (m == NULL) { IF_DROP(&ifp->if_snd); - return (ENOBUFS); + error = ENOBUFS; + goto end; } gh = mtod(m, struct greip *); @@ -368,6 +385,7 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, /* Send it off */ error = ip_output(m, NULL, &sc->route, 0, NULL, NULL); + end: if (error) ifp->if_oerrors++; return (error); @@ -377,9 +395,7 @@ int gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { - struct ifaddr *ifa = (struct ifaddr *) data; struct ifreq *ifr = (struct ifreq *) data; - struct in_ifaddr *ia = (struct in_ifaddr *) data; struct if_laddrreq *lifr = (struct if_laddrreq *)data; struct gre_softc *sc = ifp->if_softc; int s; @@ -391,53 +407,15 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) s = splimp(); switch(cmd) { case SIOCSIFADDR: + ifp->if_flags |= IFF_UP; + break; case SIOCSIFDSTADDR: - /* - * set tunnel endpoints in case that we "only" - * have ip over ip encapsulation. This allows to - * set tunnel endpoints with ifconfig. - */ - if (ifa->ifa_addr->sa_family == AF_INET) { - sa = ifa->ifa_addr; - sc->g_src = (satosin(sa))->sin_addr; - sc->g_dst = ia->ia_dstaddr.sin_addr; - if ((sc->g_src.s_addr != INADDR_ANY) && - (sc->g_dst.s_addr != INADDR_ANY)) { - if (sc->route.ro_rt != 0) { - /* free old route */ - RTFREE(sc->route.ro_rt); - sc->route.ro_rt = (struct rtentry *) 0; - } - - gre_compute_route(sc); - if (sc->route.ro_rt == 0) { - sc->g_src.s_addr = INADDR_ANY; - sc->g_dst.s_addr = INADDR_ANY; - splx(s); - return EIO; /* Is this is good ? */ - } - - ifp->if_flags |= IFF_UP; - } - } break; case SIOCSIFFLAGS: - if ((sc->g_dst.s_addr == INADDR_ANY) || - (sc->g_src.s_addr == INADDR_ANY)) - ifp->if_flags &= ~IFF_UP; - - switch(ifr->ifr_flags & LINK_MASK) { - case IFF_LINK0: - sc->g_proto = IPPROTO_GRE; - ifp->if_flags |= IFF_LINK0; - ifp->if_flags &= ~(IFF_LINK1|IFF_LINK2); - break; - case IFF_LINK2: - sc->g_proto = IPPROTO_MOBILE; - ifp->if_flags |= IFF_LINK2; - ifp->if_flags &= ~(IFF_LINK0|IFF_LINK1); - break; - } + if ((ifr->ifr_flags & IFF_LINK0) != 0) + sc->g_proto = IPPROTO_GRE; + else + sc->g_proto = IPPROTO_MOBILE; break; case SIOCADDMULTI: case SIOCDELMULTI: @@ -462,16 +440,14 @@ gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) sc->g_proto = ifr->ifr_flags; switch (sc->g_proto) { - case IPPROTO_GRE : + case IPPROTO_GRE: ifp->if_flags |= IFF_LINK0; - ifp->if_flags &= ~(IFF_LINK1|IFF_LINK2); break; - case IPPROTO_MOBILE : - ifp->if_flags |= IFF_LINK2; - ifp->if_flags &= ~(IFF_LINK1|IFF_LINK2); + case IPPROTO_MOBILE: + ifp->if_flags &= ~IFF_LINK0; break; default: - ifp->if_flags &= ~(IFF_LINK0|IFF_LINK1|IFF_LINK2); + return EPROTONOSUPPORT; } break; case GREGPROTO: |