summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGert Doering <gert@mobile.greenie.muc.de>2011-12-30 21:08:49 +0100
committerDavid Sommerseth <davids@redhat.com>2012-01-04 11:46:49 +0100
commit9140223643f7d9bdfd2214304a7bd6ab4b662f97 (patch)
tree1c89b6f77e8d6adc6970c457728b0e3b9612223b
parent1d5c4433cdb7ab0a9d9f7496e6dc2cee189d375f (diff)
downloadopenvpn-9140223643f7d9bdfd2214304a7bd6ab4b662f97.tar.gz
openvpn-9140223643f7d9bdfd2214304a7bd6ab4b662f97.tar.xz
openvpn-9140223643f7d9bdfd2214304a7bd6ab4b662f97.zip
Fix build-up of duplicate IPv6 routes on reconnect.
options.c: extend pre_pull_save() and pre_pull_restore() to save/restore options->routes_ipv6 as well options.h: add routes_ipv6 to "struct options_pre_pull" route.h, route.c: add clone_route_ipv6_option_list() and copy_route_ipv6_option_list() helper functions Signed-off-by: Gert Doering <gert@greenie.muc.de> Acked-by: David Sommerseth <davids@redhat.com> Signed-off-by: David Sommerseth <davids@redhat.com>
-rw-r--r--options.c13
-rw-r--r--options.h3
-rw-r--r--route.c19
-rw-r--r--route.h3
4 files changed, 38 insertions, 0 deletions
diff --git a/options.c b/options.c
index 736495e..a186276 100644
--- a/options.c
+++ b/options.c
@@ -2778,6 +2778,11 @@ pre_pull_save (struct options *o)
o->pre_pull->routes = clone_route_option_list(o->routes, &o->gc);
o->pre_pull->routes_defined = true;
}
+ if (o->routes_ipv6)
+ {
+ o->pre_pull->routes_ipv6 = clone_route_ipv6_option_list(o->routes_ipv6, &o->gc);
+ o->pre_pull->routes_ipv6_defined = true;
+ }
#ifdef ENABLE_CLIENT_NAT
if (o->client_nat)
{
@@ -2806,6 +2811,14 @@ pre_pull_restore (struct options *o)
else
o->routes = NULL;
+ if (pp->routes_ipv6_defined)
+ {
+ rol6_check_alloc (o);
+ copy_route_ipv6_option_list (o->routes_ipv6, pp->routes_ipv6);
+ }
+ else
+ o->routes_ipv6 = NULL;
+
#ifdef ENABLE_CLIENT_NAT
if (pp->client_nat_defined)
{
diff --git a/options.h b/options.h
index 06c4dcb..03fd197 100644
--- a/options.h
+++ b/options.h
@@ -68,6 +68,9 @@ struct options_pre_pull
bool routes_defined;
struct route_option_list *routes;
+ bool routes_ipv6_defined;
+ struct route_ipv6_option_list *routes_ipv6;
+
#ifdef ENABLE_CLIENT_NAT
bool client_nat_defined;
struct client_nat_option_list *client_nat;
diff --git a/route.c b/route.c
index be23a89..1f0b096 100644
--- a/route.c
+++ b/route.c
@@ -108,6 +108,15 @@ clone_route_option_list (const struct route_option_list *src, struct gc_arena *a
return ret;
}
+struct route_ipv6_option_list *
+clone_route_ipv6_option_list (const struct route_ipv6_option_list *src, struct gc_arena *a)
+{
+ const size_t rl_size = array_mult_safe (sizeof(struct route_ipv6_option), src->capacity, sizeof(struct route_ipv6_option_list));
+ struct route_ipv6_option_list *ret = gc_malloc (rl_size, false, a);
+ memcpy (ret, src, rl_size);
+ return ret;
+}
+
void
copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src)
{
@@ -117,6 +126,16 @@ copy_route_option_list (struct route_option_list *dest, const struct route_optio
memcpy (dest, src, src_size);
}
+void
+copy_route_ipv6_option_list (struct route_ipv6_option_list *dest,
+ const struct route_ipv6_option_list *src)
+{
+ const size_t src_size = array_mult_safe (sizeof(struct route_ipv6_option), src->capacity, sizeof(struct route_ipv6_option_list));
+ if (src->n > dest->capacity)
+ msg (M_FATAL, PACKAGE_NAME " ROUTE: (copy) number of route options in src (%d) is greater than route list capacity in dest (%d)", src->n, dest->capacity);
+ memcpy (dest, src, src_size);
+}
+
struct route_list *
new_route_list (const int max_routes, struct gc_arena *a)
{
diff --git a/route.h b/route.h
index 9953478..58c7ef4 100644
--- a/route.h
+++ b/route.h
@@ -211,7 +211,10 @@ struct route_option_list *new_route_option_list (const int max_routes, struct gc
struct route_ipv6_option_list *new_route_ipv6_option_list (const int max_routes, struct gc_arena *a);
struct route_option_list *clone_route_option_list (const struct route_option_list *src, struct gc_arena *a);
+struct route_ipv6_option_list *clone_route_ipv6_option_list (const struct route_ipv6_option_list *src, struct gc_arena *a);
void copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src);
+void copy_route_ipv6_option_list (struct route_ipv6_option_list *dest,
+ const struct route_ipv6_option_list *src);
struct route_list *new_route_list (const int max_routes, struct gc_arena *a);
struct route_ipv6_list *new_route_ipv6_list (const int max_routes, struct gc_arena *a);