Module: kamailio Branch: master Commit: 47a9423e2a5174a679905d6da6ef4fa0048e4fb1 URL: https://github.com/kamailio/kamailio/commit/47a9423e2a5174a679905d6da6ef4fa0...
Author: Xenofon Karamanos xk@gilawa.com Committer: Henning Westerholt hw@gilawa.com Date: 2025-07-14T15:42:47+02:00
permissions: Perform LPM to find the longest matching subnet
---
Modified: src/modules/permissions/hash.c
---
Diff: https://github.com/kamailio/kamailio/commit/47a9423e2a5174a679905d6da6ef4fa0... Patch: https://github.com/kamailio/kamailio/commit/47a9423e2a5174a679905d6da6ef4fa0...
---
diff --git a/src/modules/permissions/hash.c b/src/modules/permissions/hash.c index 753cf9051fa..aeb8dce2d23 100644 --- a/src/modules/permissions/hash.c +++ b/src/modules/permissions/hash.c @@ -699,6 +699,8 @@ int match_subnet_table(struct subnet *table, unsigned int grp, ip_addr_t *addr, { unsigned int count, i; avp_value_t val; + int best_idx = -1; + unsigned int best_mask = 0;
count = table[PERM_MAX_SUBNETS].grp;
@@ -713,18 +715,25 @@ int match_subnet_table(struct subnet *table, unsigned int grp, ip_addr_t *addr, if(((table[i].port == port) || (table[i].port == 0)) && (ip_addr_match_net(addr, &table[i].subnet, table[i].mask) == 0)) { - if(tag_avp.n && table[i].tag.s) { - val.s = table[i].tag; - if(add_avp(tag_avp_type | AVP_VAL_STR, tag_avp, val) != 0) { - LM_ERR("setting of tag_avp failed\n"); - return -1; - } + if(table[i].mask > best_mask) { + best_mask = table[i].mask; + best_idx = i; } - return 1; } i++; }
+ if(best_idx >= 0) { + if(tag_avp.n && table[best_idx].tag.s) { + val.s = table[best_idx].tag; + if(add_avp(tag_avp_type | AVP_VAL_STR, tag_avp, val) != 0) { + LM_ERR("setting of tag_avp failed\n"); + return -1; + } + } + return 1; + } + return -1; }
@@ -739,6 +748,8 @@ int find_group_in_subnet_table( { unsigned int count, i; avp_value_t val; + int best_idx = -1; + unsigned int best_mask = 0;
count = table[PERM_MAX_SUBNETS].grp;
@@ -747,18 +758,25 @@ int find_group_in_subnet_table( if(((table[i].port == port) || (table[i].port == 0)) && (ip_addr_match_net(addr, &table[i].subnet, table[i].mask) == 0)) { - if(tag_avp.n && table[i].tag.s) { - val.s = table[i].tag; - if(add_avp(tag_avp_type | AVP_VAL_STR, tag_avp, val) != 0) { - LM_ERR("setting of tag_avp failed\n"); - return -1; - } + if(table[i].mask > best_mask) { + best_mask = table[i].mask; + best_idx = i; } - return table[i].grp; } i++; }
+ if(best_idx >= 0) { + if(tag_avp.n && table[best_idx].tag.s) { + val.s = table[best_idx].tag; + if(add_avp(tag_avp_type | AVP_VAL_STR, tag_avp, val) != 0) { + LM_ERR("setting of tag_avp failed\n"); + return -1; + } + } + return table[best_idx].grp; + } + return -1; }