summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Grishenko <themiron@mail.ru>2021-04-08 01:25:03 +0500
committerVladislav Grishenko <themiron@mail.ru>2021-04-08 01:25:03 +0500
commit3b74e1088af7b525880b386136c0330bbed377a0 (patch)
treed790468d33fcdee96b5e1a5a0007ad585d0e117b
parent0ae932e8e39a4cfc88dc2102789791e376fe21cf (diff)
downloadaccel-ppp-3b74e1088af7b525880b386136c0330bbed377a0.tar.gz
accel-ppp-3b74e1088af7b525880b386136c0330bbed377a0.zip
ippool, ipv6pool: fix iterating over circular pools
-rw-r--r--accel-pppd/extra/ippool.c51
-rw-r--r--accel-pppd/extra/ipv6pool.c77
2 files changed, 63 insertions, 65 deletions
diff --git a/accel-pppd/extra/ippool.c b/accel-pppd/extra/ippool.c
index 2b3ef3f..7a91cf4 100644
--- a/accel-pppd/extra/ippool.c
+++ b/accel-pppd/extra/ippool.c
@@ -332,38 +332,39 @@ static void generate_pool_net30(struct ippool_t *p)
static struct ipv4db_item_t *get_ip(struct ap_session *ses)
{
struct ippool_item_t *it;
- struct ippool_t *p;
+ struct ippool_t *pool, *start;
if (ses->ipv4_pool_name)
- p = find_pool(ses->ipv4_pool_name, 0);
+ pool = find_pool(ses->ipv4_pool_name, 0);
else
- p = def_pool;
+ pool = def_pool;
- if (!p)
+ if (!pool)
return NULL;
-again:
- 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(&p->lock);
+ start = pool;
+ do {
+ spin_lock(&pool->lock);
+ if (!list_empty(&pool->items)) {
+ it = list_entry(pool->items.next, typeof(*it), entry);
+ list_del(&it->entry);
+ } else
+ it = NULL;
+ spin_unlock(&pool->lock);
- if (it) {
- if (ses->ctrl->ppp)
- it->it.addr = conf_gw_ip_address;
- else
- it->it.addr = 0;
+ if (it) {
+ if (ses->ctrl->ppp)
+ it->it.addr = conf_gw_ip_address;
+ else
+ it->it.addr = 0;
- it->it.mask = 0;
+ it->it.mask = 0;
- return &it->it;
- } else if (p->next) {
- p = p->next;
- goto again;
- }
+ return &it->it;
+ }
+
+ pool = pool->next;
+ } while (pool && pool != start);
return NULL;
}
@@ -639,9 +640,7 @@ static void ippool_init2(void)
else if (!opt->val || strchr(opt->name, ','))
add_range(pool, &pool->tunnel_list, opt->name, generate);
- if (pool == next)
- log_warn("ippool: %s: same next pool\n", opt->raw);
- else if (next)
+ if (next)
pool->next = next;
}
}
diff --git a/accel-pppd/extra/ipv6pool.c b/accel-pppd/extra/ipv6pool.c
index 5ca85f1..3494a91 100644
--- a/accel-pppd/extra/ipv6pool.c
+++ b/accel-pppd/extra/ipv6pool.c
@@ -249,7 +249,7 @@ static struct ipv6db_item_t *get_ip(struct ap_session *ses)
{
struct ippool_item_t *it;
struct ipv6db_addr_t *a;
- struct ippool_t *pool;
+ struct ippool_t *pool, *start;
if (ses->ipv6_pool_name)
pool = find_pool(IPPOOL_ADDRESS, ses->ipv6_pool_name, 0);
@@ -259,30 +259,31 @@ static struct ipv6db_item_t *get_ip(struct ap_session *ses)
if (!pool)
return NULL;
-again:
- spin_lock(&pool->lock);
- if (!list_empty(&pool->items)) {
- it = list_entry(pool->items.next, typeof(*it), entry);
- list_del(&it->entry);
- } else
- it = NULL;
- spin_unlock(&pool->lock);
-
- if (it) {
- a = list_entry(it->it.addr_list.next, typeof(*a), entry);
- if (a->prefix_len == 128) {
- memcpy(&it->it.intf_id, conf_gw_addr.s6_addr + 8, 8);
- memcpy(&it->it.peer_intf_id, a->addr.s6_addr + 8, 8);
- } else {
- it->it.intf_id = 0;
- it->it.peer_intf_id = 0;
+ start = pool;
+ do {
+ spin_lock(&pool->lock);
+ if (!list_empty(&pool->items)) {
+ it = list_entry(pool->items.next, typeof(*it), entry);
+ list_del(&it->entry);
+ } else
+ it = NULL;
+ spin_unlock(&pool->lock);
+
+ if (it) {
+ a = list_entry(it->it.addr_list.next, typeof(*a), entry);
+ if (a->prefix_len == 128) {
+ memcpy(&it->it.intf_id, conf_gw_addr.s6_addr + 8, 8);
+ memcpy(&it->it.peer_intf_id, a->addr.s6_addr + 8, 8);
+ } else {
+ it->it.intf_id = 0;
+ it->it.peer_intf_id = 0;
+ }
+
+ return &it->it;
}
- return &it->it;
- } else if (pool->next) {
pool = pool->next;
- goto again;
- }
+ } while (pool && pool != start);
return NULL;
}
@@ -299,28 +300,28 @@ static void put_ip(struct ap_session *ses, struct ipv6db_item_t *it)
static struct ipv6db_prefix_t *get_dp(struct ap_session *ses)
{
struct dppool_item_t *it;
- struct ippool_t *pool;
+ struct ippool_t *pool, *start;
if (ses->dpv6_pool_name)
pool = find_pool(IPPOOL_PREFIX, ses->dpv6_pool_name, 0);
else
pool = def_dppool;
-again:
- spin_lock(&pool->lock);
- if (!list_empty(&pool->items)) {
- it = list_entry(pool->items.next, typeof(*it), entry);
- list_del(&it->entry);
- } else
- it = NULL;
- spin_unlock(&pool->lock);
+ start = pool;
+ do {
+ spin_lock(&pool->lock);
+ if (!list_empty(&pool->items)) {
+ it = list_entry(pool->items.next, typeof(*it), entry);
+ list_del(&it->entry);
+ } else
+ it = NULL;
+ spin_unlock(&pool->lock);
+
+ if (it)
+ return &it->it;
- if (it)
- return &it->it;
- else if (pool->next) {
pool = pool->next;
- goto again;
- }
+ } while (pool && pool != start);
return NULL;
}
@@ -495,9 +496,7 @@ static void ippool_init2(void)
add_prefix(type, pool, val);
- if (pool == next)
- log_warn("ipv6_pool: %s: same next pool\n", opt->raw);
- else if (next)
+ if (next)
pool->next = next;
}