Page MenuHomeFreeBSD

D37605.id113838.diff
No OneTemporary

D37605.id113838.diff

diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c
--- a/sys/net/if_ovpn.c
+++ b/sys/net/if_ovpn.c
@@ -174,6 +174,8 @@
#define OVPN_COUNTER_SIZE (sizeof(struct ovpn_counters)/sizeof(uint64_t))
RB_HEAD(ovpn_kpeers, ovpn_kpeer);
+RB_HEAD(ovpn_kpeers_by_ip, ovpn_kpeer);
+RB_HEAD(ovpn_kpeers_by_ip6, ovpn_kpeer);
struct ovpn_softc {
int refcount;
@@ -182,6 +184,8 @@
struct socket *so;
int peercount;
struct ovpn_kpeers peers;
+ struct ovpn_kpeers_by_ip peers_by_ip;
+ struct ovpn_kpeers_by_ip6 peers_by_ip6;
/* Pending notification */
struct buf_ring *notifring;
@@ -192,6 +196,10 @@
};
static struct ovpn_kpeer *ovpn_find_peer(struct ovpn_softc *, uint32_t);
+static struct ovpn_kpeer *ovpn_find_peer_by_ip(struct ovpn_softc *,
+ const struct in_addr);
+static struct ovpn_kpeer *ovpn_find_peer_by_ip6(struct ovpn_softc *,
+ const struct in6_addr *);
static bool ovpn_udp_input(struct mbuf *, int, struct inpcb *,
const struct sockaddr *, void *);
static int ovpn_transmit_to_peer(struct ifnet *, struct mbuf *,
@@ -200,10 +208,23 @@
static int ovpn_get_af(struct mbuf *);
static void ovpn_free_kkey_dir(struct ovpn_kkey_dir *);
static bool ovpn_check_replay(struct ovpn_kkey_dir *, uint32_t);
-static int ovpn_peer_compare(struct ovpn_kpeer *, struct ovpn_kpeer *);
+static int ovpn_peer_compare(const struct ovpn_kpeer *,
+ const struct ovpn_kpeer *);
+static int ovpn_peer_compare_by_ip(const struct ovpn_kpeer *,
+ const struct ovpn_kpeer *);
+static int ovpn_peer_compare_by_ip6(const struct ovpn_kpeer *,
+ const struct ovpn_kpeer *);
static RB_PROTOTYPE(ovpn_kpeers, ovpn_kpeer, tree, ovpn_peer_compare);
static RB_GENERATE(ovpn_kpeers, ovpn_kpeer, tree, ovpn_peer_compare);
+static RB_PROTOTYPE(ovpn_kpeers_by_ip, ovpn_kpeer, tree,
+ ovpn_peer_compare_by_ip);
+static RB_GENERATE(ovpn_kpeers_by_ip, ovpn_kpeer, tree,
+ ovpn_peer_compare_by_ip);
+static RB_PROTOTYPE(ovpn_kpeers_by_ip6, ovpn_kpeer, tree,
+ ovpn_peer_compare_by_ip6);
+static RB_GENERATE(ovpn_kpeers_by_ip6, ovpn_kpeer, tree,
+ ovpn_peer_compare_by_ip6);
#define OVPN_MTU_MIN 576
#define OVPN_MTU_MAX (IP_MAXPACKET - sizeof(struct ip) - \
@@ -267,11 +288,24 @@
"Use netisr_queue() rather than netisr_dispatch().");
static int
-ovpn_peer_compare(struct ovpn_kpeer *a, struct ovpn_kpeer *b)
+ovpn_peer_compare(const struct ovpn_kpeer *a, const struct ovpn_kpeer *b)
{
return (a->peerid - b->peerid);
}
+static int
+ovpn_peer_compare_by_ip(const struct ovpn_kpeer *a, const struct ovpn_kpeer *b)
+{
+ return (memcmp(&a->vpn4, &b->vpn4, sizeof(a->vpn4)));
+}
+
+static int
+ovpn_peer_compare_by_ip6(const struct ovpn_kpeer *a,
+ const struct ovpn_kpeer *b)
+{
+ return (memcmp(&a->vpn6, &b->vpn6, sizeof(a->vpn6)));
+}
+
static struct ovpn_kpeer *
ovpn_find_peer(struct ovpn_softc *sc, uint32_t peerid)
{
@@ -596,8 +630,14 @@
if (sc->so == NULL)
sc->so = so;
- /* Insert the peer into the list. */
+ /* Insert the peer into the lists. */
RB_INSERT(ovpn_kpeers, &sc->peers, peer);
+ if (nvlist_exists_binary(nvl, "vpn_ipv4")) {
+ RB_INSERT(ovpn_kpeers_by_ip, &sc->peers_by_ip, peer);
+ }
+ if (nvlist_exists_binary(nvl, "vpn_ipv6")) {
+ RB_INSERT(ovpn_kpeers_by_ip6, &sc->peers_by_ip6, peer);
+ }
sc->peercount++;
soref(sc->so);
@@ -608,6 +648,12 @@
}
if (ret != 0) {
RB_REMOVE(ovpn_kpeers, &sc->peers, peer);
+ if (nvlist_exists_binary(nvl, "vpn_ipv4")) {
+ RB_REMOVE(ovpn_kpeers_by_ip, &sc->peers_by_ip, peer);
+ }
+ if (nvlist_exists_binary(nvl, "vpn_ipv6")) {
+ RB_REMOVE(ovpn_kpeers_by_ip6, &sc->peers_by_ip6, peer);
+ }
sc->peercount--;
goto error_locked;
}
@@ -633,7 +679,7 @@
static int
_ovpn_del_peer(struct ovpn_softc *sc, struct ovpn_kpeer *peer)
{
- struct ovpn_kpeer *tmp __diagused;
+ struct ovpn_kpeer *tmp;
OVPN_WASSERT(sc);
CURVNET_ASSERT_SET();
@@ -643,6 +689,13 @@
tmp = RB_REMOVE(ovpn_kpeers, &sc->peers, peer);
MPASS(tmp != NULL);
+ tmp = ovpn_find_peer_by_ip(sc, peer->vpn4);
+ if (tmp)
+ RB_REMOVE(ovpn_kpeers_by_ip, &sc->peers_by_ip, tmp);
+ tmp = ovpn_find_peer_by_ip6(sc, &peer->vpn6);
+ if (tmp)
+ RB_REMOVE(ovpn_kpeers_by_ip6, &sc->peers_by_ip6, tmp);
+
sc->peercount--;
ovpn_peer_release_ref(peer, true);
@@ -1628,17 +1681,13 @@
static struct ovpn_kpeer *
ovpn_find_peer_by_ip(struct ovpn_softc *sc, const struct in_addr addr)
{
- struct ovpn_kpeer *peer = NULL;
+ struct ovpn_kpeer peer;
OVPN_ASSERT(sc);
- /* TODO: Add a second RB so we can look up by IP. */
- RB_FOREACH(peer, ovpn_kpeers, &sc->peers) {
- if (addr.s_addr == peer->vpn4.s_addr)
- return (peer);
- }
+ memcpy(&peer.vpn4, &addr, sizeof(addr));
- return (peer);
+ return (RB_FIND(ovpn_kpeers_by_ip, &sc->peers_by_ip, &peer));
}
#endif
@@ -1646,17 +1695,13 @@
static struct ovpn_kpeer *
ovpn_find_peer_by_ip6(struct ovpn_softc *sc, const struct in6_addr *addr)
{
- struct ovpn_kpeer *peer = NULL;
+ struct ovpn_kpeer peer;
OVPN_ASSERT(sc);
- /* TODO: Add a third RB so we can look up by IPv6 address. */
- RB_FOREACH(peer, ovpn_kpeers, &sc->peers) {
- if (memcmp(addr, &peer->vpn6, sizeof(*addr)) == 0)
- return (peer);
- }
+ memcpy(&peer.vpn6, addr, sizeof(*addr));
- return (peer);
+ return (RB_FIND(ovpn_kpeers_by_ip6, &sc->peers_by_ip6, &peer));
}
#endif

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 16, 11:58 AM (16 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14658287
Default Alt Text
D37605.id113838.diff (5 KB)

Event Timeline