Oops,
my mail client insist on breaking lines. Sorry for that - this mail attaches
the patch in it's original form.
// Sven-Ola
Am Freitag, 1. Oktober 2010, um 10:51:32 schrieb Sven-Ola Tuecke:
> Signed-off-by: Sven-Ola Tuecke <sven-ola()gmx.de>
diff --git a/multi.c b/multi.c
index 5d15ea9..ab40e6c 100644
--- a/multi.c
+++ b/multi.c
@@ -974,6 +974,7 @@ multi_learn_addr (struct multi_context *m,
static struct multi_instance *
multi_get_instance_by_virtual_addr (struct multi_context *m,
const struct mroute_addr *addr,
+ bool dynamic_iroute,
bool cidr_routing)
{
struct multi_route *route;
@@ -1020,6 +1021,24 @@ multi_get_instance_by_virtual_addr (struct multi_context *m,
break;
}
}
+ if (!ret && dynamic_iroute)
+ {
+ const struct iroute *ir;
+
+ /* does address match a dynamic_iroute? */
+ for (ir = m->top.options.dynamic_iroutes; ir != NULL; ir = ir->next)
+ {
+ in_addr_t cmp_addr = ntohl(*(in_addr_t*)addr->addr);
+ ASSERT ((addr->type & MR_ADDR_MASK) == MR_ADDR_IPV4);
+ cmp_addr &= netbits_to_netmask (ir->netbits);
+ if (cmp_addr == ir->network)
+ {
+ multi_learn_addr (m, m->pending, addr, MULTI_ROUTE_CACHE|MULTI_ROUTE_AGEABLE);
+ ret = m->pending;
+ break;
+ }
+ }
+ }
mroute_helper_unlock (rh);
}
@@ -2100,7 +2119,7 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins
c->c2.to_tun.len = 0;
}
/* make sure that source address is associated with this client */
- else if (multi_get_instance_by_virtual_addr (m, &src, true) != m->pending)
+ else if (multi_get_instance_by_virtual_addr (m, &src, true, true) != m->pending)
{
msg (D_MULTI_DROPPED, "MULTI: bad source address from client [%s], packet dropped",
mroute_addr_print (&src, &gc));
@@ -2118,7 +2137,7 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins
else /* possible client to client routing */
{
ASSERT (!(mroute_flags & MROUTE_EXTRACT_BCAST));
- mi = multi_get_instance_by_virtual_addr (m, &dest, true);
+ mi = multi_get_instance_by_virtual_addr (m, &dest, false, true);
/* if dest addr is a known client, route to it */
if (mi)
@@ -2179,7 +2198,7 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins
}
else /* try client-to-client routing */
{
- mi = multi_get_instance_by_virtual_addr (m, &dest, false);
+ mi = multi_get_instance_by_virtual_addr (m, &dest, false, false);
/* if dest addr is a known client, route to it */
if (mi)
@@ -2302,7 +2321,7 @@ multi_process_incoming_tun (struct multi_context *m, const unsigned int mpp_flag
}
else
{
- multi_set_pending (m, multi_get_instance_by_virtual_addr (m, &dest, dev_type == DEV_TYPE_TUN));
+ multi_set_pending (m, multi_get_instance_by_virtual_addr (m, &dest, false, dev_type == DEV_TYPE_TUN));
if (m->pending)
{
diff --git a/options.c b/options.c
index 4aec5cb..5c5c4be 100644
--- a/options.c
+++ b/options.c
@@ -417,6 +417,9 @@ static const char usage_message[] =
"--iroute-ipv6 network/bits : Route IPv6 subnet to client.\n"
" Sets up internal routes only.\n"
" Only valid in a client-specific config file.\n"
+ "--dynamic-iroute network [netmask] : Define subnet for iroute autocreation.\n"
+ " Defines a range of IPs to be accepted behind clients.\n"
+ " Only useful with a learn-address script.\n"
"--disable : Client is disabled.\n"
" Only valid in a client-specific config file.\n"
"--client-cert-not-required : Don't require client certificate, client\n"
@@ -1150,6 +1153,7 @@ static void
option_iroute (struct options *o,
const char *network_str,
const char *netmask_str,
+ bool dynamic_iroute,
int msglevel)
{
struct iroute *ir;
@@ -1163,15 +1167,24 @@ option_iroute (struct options *o,
const in_addr_t netmask = getaddr (GETADDR_HOST_ORDER, netmask_str, 0, NULL, NULL);
if (!netmask_to_netbits (ir->network, netmask, &ir->netbits))
{
- msg (msglevel, "in --iroute %s %s : Bad network/subnet specification",
+ msg (msglevel, "in --%siroute %s %s : Bad network/subnet specification",
+ dynamic_iroute ? "auto" : "",
network_str,
netmask_str);
return;
}
}
- ir->next = o->iroutes;
- o->iroutes = ir;
+ if (dynamic_iroute)
+ {
+ ir->next = o->dynamic_iroutes;
+ o->dynamic_iroutes = ir;
+ }
+ else
+ {
+ ir->next = o->iroutes;
+ o->iroutes = ir;
+ }
}
static void
@@ -5377,7 +5390,18 @@ add_option (struct options *options,
{
netmask = p[2];
}
- option_iroute (options, p[1], netmask, msglevel);
+ option_iroute (options, p[1], netmask, false, msglevel);
+ }
+ else if (streq (p[0], "dynamic-iroute") && p[1])
+ {
+ const char *netmask = NULL;
+
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ if (p[2])
+ {
+ netmask = p[2];
+ }
+ option_iroute (options, p[1], netmask, true, msglevel);
}
else if (streq (p[0], "iroute-ipv6") && p[1])
{
diff --git a/options.h b/options.h
index 1ef96ca..70cac55 100644
--- a/options.h
+++ b/options.h
@@ -410,6 +410,7 @@ struct options
int n_bcast_buf;
int tcp_queue_limit;
struct iroute *iroutes;
+ struct iroute *dynamic_iroutes;
struct iroute_ipv6 *iroutes_ipv6; /* IPv6 */
bool push_ifconfig_defined;
in_addr_t push_ifconfig_local;