summaryrefslogtreecommitdiff
path: root/accel-pppd
diff options
context:
space:
mode:
authorKozlov Dmitry <xeb@mail.ru>2011-12-27 12:23:09 +0400
committerKozlov Dmitry <xeb@mail.ru>2011-12-27 12:23:09 +0400
commit8f8c2e0deb97d434cee9a03ac7411ee9e37ac542 (patch)
tree3d4fdb49a73fb24efe44e2d76c9bb1de5f95f38f /accel-pppd
parentee41cba691ab9f6461f4933461cf82be161333de (diff)
downloadaccel-ppp-8f8c2e0deb97d434cee9a03ac7411ee9e37ac542.tar.gz
accel-ppp-8f8c2e0deb97d434cee9a03ac7411ee9e37ac542.zip
radius, ippool: implemented Framed-Pool attribute
Diffstat (limited to 'accel-pppd')
-rw-r--r--accel-pppd/accel-ppp.conf6
-rw-r--r--accel-pppd/accel-ppp.conf.510
-rw-r--r--accel-pppd/extra/ippool.c121
-rw-r--r--accel-pppd/ppp/ppp.c10
-rw-r--r--accel-pppd/ppp/ppp.h2
-rw-r--r--accel-pppd/radius/radius.c6
6 files changed, 121 insertions, 34 deletions
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf
index 1903d94..7219ba3 100644
--- a/accel-pppd/accel-ppp.conf
+++ b/accel-pppd/accel-ppp.conf
@@ -99,9 +99,9 @@ verbose=1
[ip-pool]
gw-ip-address=192.168.0.1
192.168.0.2-255
-192.168.1.1-255
-192.168.2.1-255
-192.168.3.1-255
+192.168.1.1-255,pool1
+192.168.2.1-255,pool2
+192.168.3.1-255,pool3
192.168.4.0/24
[log]
diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5
index 0e241a2..955f167 100644
--- a/accel-pppd/accel-ppp.conf.5
+++ b/accel-pppd/accel-ppp.conf.5
@@ -466,20 +466,20 @@ Specifies single IP address to be used as local address of ppp interfaces.
.BI "gw=" range
Specifies range of local address of ppp interfaces if form:
.br
-.B x.x.x.x/mask
+.B x.x.x.x/mask[,pool_name]
(for example 10.0.0.0/8)
.br
-.B x.x.x.x-y
+.B x.x.x.x-y[,pool_name]
(for example 10.0.0.1-254)
.TP
.BI "tunnel=" range
Specifies range of remote address of ppp interfaces if form:
.br
-.B x.x.x.x/mask
+.B x.x.x.x/mask[,pool_name]
.br
-.B x.x.x.x-y
+.B x.x.x.x-y[,pool_name]
.TP
-.BI "x.x.x.x/mask or x.x.x.x-y"
+.BI "x.x.x.x/mask[,pool_name] or x.x.x.x-y[,pool_name]"
Also specifies range of remote address of ppp interfaces.
.TP
.SH [ipv6-pool]
diff --git a/accel-pppd/extra/ippool.c b/accel-pppd/extra/ippool.c
index d49f0f4..7579784 100644
--- a/accel-pppd/extra/ippool.c
+++ b/accel-pppd/extra/ippool.c
@@ -11,9 +11,20 @@
#include "memdebug.h"
+struct ippool_t
+{
+ struct list_head entry;
+ char *name;
+ struct list_head gw_list;
+ struct list_head tunnel_list;
+ struct list_head items;
+ spinlock_t lock;
+};
+
struct ippool_item_t
{
struct list_head entry;
+ struct ippool_t *pool;
struct ipv4db_item_t it;
};
@@ -23,14 +34,45 @@ struct ipaddr_t
in_addr_t addr;
};
-static LIST_HEAD(gw_list);
-static LIST_HEAD(tunnel_list);
-static LIST_HEAD(ippool);
-static spinlock_t pool_lock = SPINLOCK_INITIALIZER;
static struct ipdb_t ipdb;
static in_addr_t conf_gw_ip_address;
static int cnt;
+static LIST_HEAD(pool_list);
+static struct ippool_t *def_pool;
+
+struct ippool_t *create_pool(const char *name)
+{
+ struct ippool_t *p = malloc(sizeof(*p));
+
+ memset(p, 0, sizeof(*p));
+ if (name)
+ p->name = strdup(name);
+ INIT_LIST_HEAD(&p->gw_list);
+ INIT_LIST_HEAD(&p->tunnel_list);
+ INIT_LIST_HEAD(&p->items);
+ spinlock_init(&p->lock);
+
+ if (name)
+ list_add_tail(&p->entry, &pool_list);
+
+ return p;
+}
+
+struct ippool_t *find_pool(const char *name, int create)
+{
+ struct ippool_t *p;
+
+ list_for_each_entry(p, &pool_list, entry) {
+ if (!strcmp(p->name, name))
+ return p;
+ }
+
+ if (create)
+ return create_pool(name);
+
+ return NULL;
+}
static void parse_gw_ip_address(const char *val)
{
@@ -98,11 +140,12 @@ static void add_range(struct list_head *list, const char *name)
uint32_t i,startip, endip;
struct ipaddr_t *ip;
- if (parse1(name, &startip, &endip))
+ if (parse1(name, &startip, &endip)) {
if (parse2(name, &startip, &endip)) {
fprintf(stderr, "ippool: cann't parse '%s'\n", name);
_exit(EXIT_FAILURE);
}
+ }
for (i = startip; i <= endip; i++) {
ip = malloc(sizeof(*ip));
@@ -112,25 +155,25 @@ static void add_range(struct list_head *list, const char *name)
}
}
-static void generate_pool(void)
+static void generate_pool(struct ippool_t *p)
{
struct ippool_item_t *it;
struct ipaddr_t *addr = NULL;
struct ipaddr_t *peer_addr;
while (1) {
- if (list_empty(&tunnel_list))
+ if (list_empty(&p->tunnel_list))
break;
else {
- peer_addr = list_entry(tunnel_list.next, typeof(*peer_addr), entry);
+ peer_addr = list_entry(p->tunnel_list.next, typeof(*peer_addr), entry);
list_del(&peer_addr->entry);
}
if (!conf_gw_ip_address) {
- if (list_empty(&gw_list))
+ if (list_empty(&p->gw_list))
break;
else {
- addr = list_entry(gw_list.next, typeof(*addr), entry);
+ addr = list_entry(p->gw_list.next, typeof(*addr), entry);
list_del(&addr->entry);
}
}
@@ -141,6 +184,7 @@ static void generate_pool(void)
break;
}
+ it->pool = p;
it->it.owner = &ipdb;
if (conf_gw_ip_address)
it->it.addr = conf_gw_ip_address;
@@ -149,21 +193,30 @@ static void generate_pool(void)
it->it.peer_addr = peer_addr->addr;
- list_add_tail(&it->entry, &ippool);
+ list_add_tail(&it->entry, &p->items);
}
}
static struct ipv4db_item_t *get_ip(struct ppp_t *ppp)
{
struct ippool_item_t *it;
+ struct ippool_t *p;
+
+ if (ppp->ipv4_pool_name)
+ p = find_pool(ppp->ipv4_pool_name, 0);
+ else
+ p = def_pool;
+
+ if (!p)
+ return NULL;
- spin_lock(&pool_lock);
- if (!list_empty(&ippool)) {
- it = list_entry(ippool.next, typeof(*it), entry);
+ spin_lock(&p->lock);
+ if (!list_empty(&p->items)) {
+ it = list_entry(p->items.next, typeof(*it), entry);
list_del(&it->entry);
} else
it = NULL;
- spin_unlock(&pool_lock);
+ spin_unlock(&p->lock);
return it ? &it->it : NULL;
}
@@ -172,9 +225,9 @@ static void put_ip(struct ppp_t *ppp, struct ipv4db_item_t *it)
{
struct ippool_item_t *pit = container_of(it, typeof(*pit), it);
- spin_lock(&pool_lock);
- list_add_tail(&pit->entry, &ippool);
- spin_unlock(&pool_lock);
+ spin_lock(&pit->pool->lock);
+ list_add_tail(&pit->entry, &pit->pool->items);
+ spin_unlock(&pit->pool->lock);
}
static struct ipdb_t ipdb = {
@@ -186,22 +239,38 @@ static void ippool_init(void)
{
struct conf_sect_t *s = conf_get_section("ip-pool");
struct conf_option_t *opt;
+ struct ippool_t *p;
+ char *pool_name;
if (!s)
return;
-
+
+ def_pool = create_pool(NULL);
+
list_for_each_entry(opt, &s->items, entry) {
if (!strcmp(opt->name, "gw-ip-address"))
parse_gw_ip_address(opt->val);
- else if (!strcmp(opt->name, "gw"))
- add_range(&gw_list, opt->val);
- else if (!strcmp(opt->name, "tunnel"))
- add_range(&tunnel_list, opt->val);
- else if (!opt->val)
- add_range(&tunnel_list, opt->name);
+ else {
+ if (opt->val)
+ pool_name = strchr(opt->val, ',');
+ else
+ pool_name = strchr(opt->name, ',');
+
+ p = pool_name ? find_pool(pool_name + 1, 1) : def_pool;
+
+ if (!strcmp(opt->name, "gw"))
+ add_range(&p->gw_list, opt->val);
+ else if (!strcmp(opt->name, "tunnel"))
+ add_range(&p->tunnel_list, opt->val);
+ else if (!opt->val)
+ add_range(&p->tunnel_list, opt->name);
+ }
}
- generate_pool();
+ generate_pool(def_pool);
+
+ list_for_each_entry(p, &pool_list, entry)
+ generate_pool(p);
ipdb_register(&ipdb);
}
diff --git a/accel-pppd/ppp/ppp.c b/accel-pppd/ppp/ppp.c
index 0848689..acda84e 100644
--- a/accel-pppd/ppp/ppp.c
+++ b/accel-pppd/ppp/ppp.c
@@ -239,6 +239,16 @@ static void destablish_ppp(struct ppp_t *ppp)
_free(ppp->username);
ppp->username = NULL;
}
+
+ if (ppp->ipv4_pool_name) {
+ _free(ppp->ipv4_pool_name);
+ ppp->ipv4_pool_name = NULL;
+ }
+
+ if (ppp->ipv6_pool_name) {
+ _free(ppp->ipv6_pool_name);
+ ppp->ipv6_pool_name = NULL;
+ }
if (ppp_shutdown && !ppp_stat.starting && !ppp_stat.active && !ppp_stat.finishing)
kill(getpid(), SIGTERM);
diff --git a/accel-pppd/ppp/ppp.h b/accel-pppd/ppp/ppp.h
index 5246a3e..3ec15d9 100644
--- a/accel-pppd/ppp/ppp.h
+++ b/accel-pppd/ppp/ppp.h
@@ -105,6 +105,8 @@ struct ppp_t
char *username;
struct ipv4db_item_t *ipv4;
struct ipv6db_item_t *ipv6;
+ char *ipv4_pool_name;
+ char *ipv6_pool_name;
struct ppp_ctrl_t *ctrl;
diff --git a/accel-pppd/radius/radius.c b/accel-pppd/radius/radius.c
index 15e5e68..370572a 100644
--- a/accel-pppd/radius/radius.c
+++ b/accel-pppd/radius/radius.c
@@ -113,6 +113,12 @@ int rad_proc_attrs(struct rad_req_t *req)
a->addr = attr->val.ipv6prefix.prefix;
list_add_tail(&a->entry, &req->rpd->ipv6_dp.prefix_list);
break;
+ case Framed_Pool:
+ req->rpd->ppp->ipv4_pool_name = _strdup(attr->val.string);
+ break;
+ case Framed_IPv6_Pool:
+ req->rpd->ppp->ipv6_pool_name = _strdup(attr->val.string);
+ break;
}
}