diff options
author | Kozlov Dmitry <xeb@mail.ru> | 2011-12-27 12:23:09 +0400 |
---|---|---|
committer | Kozlov Dmitry <xeb@mail.ru> | 2011-12-27 12:23:09 +0400 |
commit | 8f8c2e0deb97d434cee9a03ac7411ee9e37ac542 (patch) | |
tree | 3d4fdb49a73fb24efe44e2d76c9bb1de5f95f38f /accel-pppd/extra/ippool.c | |
parent | ee41cba691ab9f6461f4933461cf82be161333de (diff) | |
download | accel-ppp-8f8c2e0deb97d434cee9a03ac7411ee9e37ac542.tar.gz accel-ppp-8f8c2e0deb97d434cee9a03ac7411ee9e37ac542.zip |
radius, ippool: implemented Framed-Pool attribute
Diffstat (limited to 'accel-pppd/extra/ippool.c')
-rw-r--r-- | accel-pppd/extra/ippool.c | 121 |
1 files changed, 95 insertions, 26 deletions
diff --git a/accel-pppd/extra/ippool.c b/accel-pppd/extra/ippool.c index d49f0f44..75797846 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); } |