summaryrefslogtreecommitdiff
path: root/accel-pppd/radius
diff options
context:
space:
mode:
authorGuillaume Nault <g.nault@alphalink.fr>2018-02-20 18:50:25 +0100
committerDmitry Kozlov <xeb@mail.ru>2018-02-21 22:25:20 +0300
commit8ab2f623fa1d11a2aaec35226cb7a1456fc257d8 (patch)
tree093d82941fa97d7726bd5e1870c69b1e346aa8a1 /accel-pppd/radius
parentc99e2092e9ad048e61110fd094d72e3d55cb49bc (diff)
downloadaccel-ppp-8ab2f623fa1d11a2aaec35226cb7a1456fc257d8.tar.gz
accel-ppp-8ab2f623fa1d11a2aaec35226cb7a1456fc257d8.zip
radius: add support for route priority (metric) in Framed-Route
Let an optional route priority (aka metric) be defined in RADIUS Framed-Route attributes. The priority is an integer placed at the end of the route string. This is backward compatible with the previous format and also conforms with the recommended format defined by RFC 2865 (although we don't allow multiple metrics). Framed-Route format is: <network> [<gateway> [<priority>]] For example, 'Framed-Route = "192.0.2.0/24 203.0.113.1 8"' will let the following route be installed (assuming 203.0.113.1 is routed through eth0): $ ip route show [...] 192.0.2.0/24 via 203.0.113.1 dev eth0 metric 8 It's possible to use the unspecified gateway (0.0.0.0) if one wants to set a priority without specifying a gateway address. Finally, route deletion now also takes the priority into account, in order to avoid removing a different route accidentally. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
Diffstat (limited to 'accel-pppd/radius')
-rw-r--r--accel-pppd/radius/radius.c16
-rw-r--r--accel-pppd/radius/radius_p.h1
2 files changed, 14 insertions, 3 deletions
diff --git a/accel-pppd/radius/radius.c b/accel-pppd/radius/radius.c
index b8706015..5c650b28 100644
--- a/accel-pppd/radius/radius.c
+++ b/accel-pppd/radius/radius.c
@@ -62,6 +62,7 @@ static void parse_framed_route(struct radius_pd_t *rpd, const char *attr)
{
char str[32];
char *ptr;
+ long int prio = 0;
in_addr_t dst;
in_addr_t gw;
int mask;
@@ -118,6 +119,14 @@ static void parse_framed_route(struct radius_pd_t *rpd, const char *attr)
gw = 0;
else
goto out_err;
+
+ /* Parse priority, if any */
+ if (*ptr) {
+ for (++ptr; *ptr && *ptr != ' '; ptr++);
+ if (*ptr == ' ')
+ if (u_readlong(&prio, ptr + 1, 0, UINT32_MAX) < 0)
+ goto out_err;
+ }
} else {
mask = 32;
gw = 0;
@@ -127,6 +136,7 @@ static void parse_framed_route(struct radius_pd_t *rpd, const char *attr)
fr->dst = dst;
fr->mask = mask;
fr->gw = gw;
+ fr->prio = prio;
fr->next = rpd->fr;
rpd->fr = fr;
@@ -444,11 +454,11 @@ static void ses_started(struct ap_session *ses)
}
for (fr = rpd->fr; fr; fr = fr->next) {
- if (iproute_add(fr->gw ? 0 : rpd->ses->ifindex, 0, fr->dst, fr->gw, 3, fr->mask)) {
+ if (iproute_add(fr->gw ? 0 : rpd->ses->ifindex, 0, fr->dst, fr->gw, 3, fr->mask, fr->prio)) {
char dst[17], gw[17];
u_inet_ntoa(fr->dst, dst);
u_inet_ntoa(fr->gw, gw);
- log_ppp_warn("radius: failed to add route %s/%i%s\n", dst, fr->mask, gw);
+ log_ppp_warn("radius: failed to add route %s/%i %s %u\n", dst, fr->mask, gw, fr->prio);
}
}
@@ -472,7 +482,7 @@ static void ses_finishing(struct ap_session *ses)
for (fr = rpd->fr; fr; fr = fr->next) {
if (fr->gw)
- iproute_del(0, fr->dst, 3, fr->mask);
+ iproute_del(0, fr->dst, 3, fr->mask, fr->prio);
}
if (rpd->acct_started || rpd->acct_req)
diff --git a/accel-pppd/radius/radius_p.h b/accel-pppd/radius/radius_p.h
index cdbb57b8..1ce31c03 100644
--- a/accel-pppd/radius/radius_p.h
+++ b/accel-pppd/radius/radius_p.h
@@ -29,6 +29,7 @@ struct framed_route {
in_addr_t dst;
int mask;
in_addr_t gw;
+ uint32_t prio;
struct framed_route *next;
};