summaryrefslogtreecommitdiff
path: root/sys/net/if_gre.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2018-02-16 02:41:08 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2018-02-16 02:41:08 +0000
commit4d20004c4c5ebc69f26c4d65ab9430a33451ef2e (patch)
treedd45e2a07ff63d9f9fbbe1b85d7133e04b272f0c /sys/net/if_gre.c
parentabd4814543f89e606b56dc0caa7f7b1f7b4230fd (diff)
put egre back in a tree
it's new so there's no existing configs to be compat with.
Diffstat (limited to 'sys/net/if_gre.c')
-rw-r--r--sys/net/if_gre.c97
1 files changed, 47 insertions, 50 deletions
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c
index 1a76d97178f..a42eef45cf8 100644
--- a/sys/net/if_gre.c
+++ b/sys/net/if_gre.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_gre.c,v 1.102 2018/02/16 01:28:07 dlg Exp $ */
+/* $OpenBSD: if_gre.c,v 1.103 2018/02/16 02:41:07 dlg Exp $ */
/* $NetBSD: if_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */
/*
@@ -50,6 +50,7 @@
#include <sys/errno.h>
#include <sys/timeout.h>
#include <sys/queue.h>
+#include <sys/tree.h>
#include <crypto/siphash.h>
@@ -142,8 +143,6 @@ union gre_addr {
};
struct gre_tunnel {
- TAILQ_ENTRY(gre_tunnel) t_entry;
-
uint32_t t_key_mask;
#define GRE_KEY_NONE htonl(0x00000000U)
#define GRE_KEY_ENTROPY htonl(0xffffff00U)
@@ -161,8 +160,6 @@ struct gre_tunnel {
sa_family_t t_af;
};
-TAILQ_HEAD(gre_list, gre_tunnel);
-
static inline int
gre_cmp(const struct gre_tunnel *, const struct gre_tunnel *);
@@ -189,9 +186,11 @@ static int gre_tunnel_ioctl(struct ifnet *, struct gre_tunnel *,
*/
struct gre_softc {
- struct gre_tunnel sc_tunnel; /* must be first */
struct ifnet sc_if;
+ struct gre_tunnel sc_tunnel;
+ TAILQ_ENTRY(gre_softc) sc_entry;
+
struct timeout sc_ka_send;
struct timeout sc_ka_hold;
@@ -207,6 +206,8 @@ struct gre_softc {
int sc_ka_recvtm;
};
+TAILQ_HEAD(gre_list, gre_softc);
+
struct gre_keepalive {
uint32_t gk_uptime;
uint32_t gk_random;
@@ -248,10 +249,16 @@ static void gre_keepalive_hold(void *);
struct egre_softc {
struct gre_tunnel sc_tunnel; /* must be first */
+ RBT_ENTRY(egre_softc) sc_entry;
+
struct arpcom sc_ac;
struct ifmedia sc_media;
};
+RBT_HEAD(egre_tree, egre_softc);
+
+RBT_PROTOTYPE(egre_tree, egre_softc, sc_entry, egre_cmp);
+
static int egre_clone_create(struct if_clone *, int);
static int egre_clone_destroy(struct ifnet *);
@@ -264,13 +271,10 @@ static int egre_up(struct egre_softc *);
static int egre_down(struct egre_softc *);
static int egre_input(const struct gre_tunnel *, struct mbuf *, int);
-static struct egre_softc *
- egre_find(const struct gre_tunnel *);
-
struct if_clone egre_cloner =
IF_CLONE_INITIALIZER("egre", egre_clone_create, egre_clone_destroy);
-struct gre_list egre_list = TAILQ_HEAD_INITIALIZER(gre_list);
+struct egre_tree egre_tree = RBT_INITIALIZER();
/*
* It is not easy to calculate the right value for a GRE MTU.
@@ -334,7 +338,7 @@ gre_clone_create(struct if_clone *ifc, int unit)
#endif
NET_LOCK();
- TAILQ_INSERT_TAIL(&gre_list, &sc->sc_tunnel, t_entry);
+ TAILQ_INSERT_TAIL(&gre_list, sc, sc_entry);
NET_UNLOCK();
return (0);
@@ -349,7 +353,7 @@ gre_clone_destroy(struct ifnet *ifp)
if (ISSET(ifp->if_flags, IFF_RUNNING))
gre_down(sc);
- TAILQ_REMOVE(&gre_list, &sc->sc_tunnel, t_entry);
+ TAILQ_REMOVE(&gre_list, sc, sc_entry);
NET_UNLOCK();
if_detach(ifp);
@@ -389,10 +393,6 @@ egre_clone_create(struct if_clone *ifc, int unit)
if_attach(ifp);
ether_ifattach(ifp);
- NET_LOCK();
- TAILQ_INSERT_TAIL(&egre_list, &sc->sc_tunnel, t_entry);
- NET_UNLOCK();
-
return (0);
}
@@ -404,8 +404,6 @@ egre_clone_destroy(struct ifnet *ifp)
NET_LOCK();
if (ISSET(ifp->if_flags, IFF_RUNNING))
egre_down(sc);
-
- TAILQ_REMOVE(&egre_list, &sc->sc_tunnel, t_entry);
NET_UNLOCK();
ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
@@ -462,14 +460,12 @@ gre_input6(struct mbuf **mp, int *offp, int type, int af)
static struct gre_softc *
gre_find(const struct gre_tunnel *key)
{
- struct gre_tunnel *t;
struct gre_softc *sc;
- TAILQ_FOREACH(t, &gre_list, t_entry) {
- if (gre_cmp(key, t) != 0)
+ TAILQ_FOREACH(sc, &gre_list, sc_entry) {
+ if (gre_cmp(key, &sc->sc_tunnel) != 0)
continue;
- sc = (struct gre_softc *)t;
if (!ISSET(sc->sc_if.if_flags, IFF_RUNNING))
continue;
@@ -669,26 +665,6 @@ decline:
return (-1);
}
-static struct egre_softc *
-egre_find(const struct gre_tunnel *key)
-{
- struct gre_tunnel *t;
- struct egre_softc *sc;
-
- TAILQ_FOREACH(t, &egre_list, t_entry) {
- if (gre_cmp(key, t) != 0)
- continue;
-
- sc = (struct egre_softc *)t;
- if (!ISSET(sc->sc_ac.ac_if.if_flags, IFF_RUNNING))
- continue;
-
- return (sc);
- }
-
- return (NULL);
-}
-
static int
egre_input(const struct gre_tunnel *key, struct mbuf *m, int hlen)
{
@@ -697,7 +673,7 @@ egre_input(const struct gre_tunnel *key, struct mbuf *m, int hlen)
struct mbuf *n;
int off;
- sc = egre_find(key);
+ sc = RBT_FIND(egre_tree, &egre_tree, (const struct egre_softc *)key);
if (sc == NULL)
return (-1);
@@ -1260,8 +1236,7 @@ egre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
switch(cmd) {
case SIOCSIFADDR:
- ifp->if_flags |= IFF_UP;
- /* FALLTHROUGH */
+ break;
case SIOCSIFFLAGS:
if (ISSET(ifp->if_flags, IFF_UP)) {
if (!ISSET(ifp->if_flags, IFF_RUNNING))
@@ -1286,8 +1261,18 @@ egre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCGLIFPHYTTL:
ifr->ifr_ttl = (int)sc->sc_tunnel.t_ttl;
- break;
+ case SIOCSVNETID:
+ case SIOCDVNETID:
+ case SIOCSLIFPHYADDR:
+ case SIOCDIFPHYADDR:
+ case SIOCSLIFPHYRTABLE:
+ if (ISSET(ifp->if_flags, IFF_RUNNING)) {
+ error = EBUSY;
+ break;
+ }
+
+ /* FALLTHROUGH */
default:
error = gre_tunnel_ioctl(ifp, &sc->sc_tunnel, cmd, data);
if (error == ENOTTY)
@@ -1301,9 +1286,6 @@ egre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
static int
gre_up(struct gre_softc *sc)
{
- if (sc->sc_tunnel.t_af == AF_UNSPEC)
- return (ENXIO);
-
NET_ASSERT_LOCKED();
SET(sc->sc_if.if_flags, IFF_RUNNING);
@@ -1653,8 +1635,14 @@ gre_del_vnetid(struct gre_tunnel *tunnel)
static int
egre_up(struct egre_softc *sc)
{
+ if (sc->sc_tunnel.t_af == AF_UNSPEC)
+ return (EDESTADDRREQ);
+
NET_ASSERT_LOCKED();
+ if (RBT_INSERT(egre_tree, &egre_tree, sc) != NULL)
+ return (EADDRINUSE);
+
SET(sc->sc_ac.ac_if.if_flags, IFF_RUNNING);
return (0);
@@ -1667,6 +1655,8 @@ egre_down(struct egre_softc *sc)
CLR(sc->sc_ac.ac_if.if_flags, IFF_RUNNING);
+ RBT_REMOVE(egre_tree, &egre_tree, sc);
+
/* barrier? */
return (0);
@@ -1729,7 +1719,7 @@ gre_ip_cmp(int af, const union gre_addr *a, const union gre_addr *b)
return (0);
}
-static inline int
+static int
gre_cmp(const struct gre_tunnel *a, const struct gre_tunnel *b)
{
uint32_t ka, kb;
@@ -1784,3 +1774,10 @@ gre_cmp(const struct gre_tunnel *a, const struct gre_tunnel *b)
return (0);
}
+static int
+egre_cmp(const struct egre_softc *a, const struct egre_softc *b)
+{
+ return (gre_cmp(&a->sc_tunnel, &b->sc_tunnel));
+}
+
+RBT_GENERATE(egre_tree, egre_softc, sc_entry, egre_cmp);