summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2002-06-10 23:06:56 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2002-06-10 23:06:56 +0000
commit423957fd9ca5294d045595202dfb2441640e4072 (patch)
tree6add31c185e02fdc048c335656662d089e12c29b
parent32bd120e6d450297ab48b3a73d3bf306ad15e3a1 (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.c112
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: