2 #include <linux/rtnetlink.h>
3 #include <netinet/ip6.h>
9 /* set up throttling based on RADIUS reply */
12 * lcp:interface-config#1=service-policy input N
13 * lcp:interface-config#2=service-policy output N
16 * throttle=yes (use throttle_speed from config)
20 int plugin_api_version
= PLUGIN_API_VERSION
;
21 static struct pluginfuncs
*f
= 0;
23 #define THROTTLE_KEY "lcp:interface-config"
25 int plugin_radius_response(struct param_radius_response
*data
)
27 if (!strncmp(data
->key
, THROTTLE_KEY
, sizeof(THROTTLE_KEY
) - 1))
29 char *sp
= strchr(data
->value
, ' ');
33 if (!sp
|| sp
- data
->value
< 4 ||
34 strncmp("service-policy", data
->value
, sp
- data
->value
))
37 while (*sp
== ' ') sp
++;
40 if (!(sp
= strchr(data
->value
, ' ')) ||
41 (strncmp("input", data
->value
, sp
- data
->value
) &&
42 strncmp("output", data
->value
, sp
- data
->value
)))
44 f
->log(3, f
->get_id_by_session(data
->s
), data
->s
->tunnel
,
45 " Not throttling user (invalid type %.*s)\n",
46 sp
- data
->value
, data
->value
);
53 while (*sp
== ' ') sp
++;
56 if ((rate
= strtol(data
->value
, &sp
, 10)) < 0 || *sp
)
58 f
->log(3, f
->get_id_by_session(data
->s
), data
->s
->tunnel
,
59 " Not throttling user (invalid rate %s)\n",
67 data
->s
->throttle_in
= rate
;
68 f
->log(3, f
->get_id_by_session(data
->s
), data
->s
->tunnel
,
69 " Throttling user input to %dkb/s\n", rate
);
73 data
->s
->throttle_out
= rate
;
74 f
->log(3, f
->get_id_by_session(data
->s
), data
->s
->tunnel
,
75 " Throttling user output to %dkb/s\n", rate
);
78 else if (!strcmp(data
->key
, "throttle"))
83 if ((rate
= strtol(data
->value
, &e
, 10)) < 0 || *e
)
86 if (!strcmp(data
->value
, "yes"))
88 unsigned long *ts
= f
->getconfig("throttle_speed", UNSIGNED_LONG
);
92 else if (!strcmp(data
->value
, "no"))
100 f
->log(3, f
->get_id_by_session(data
->s
), data
->s
->tunnel
,
101 " Throttling user to %dkb/s\n", rate
);
103 f
->log(3, f
->get_id_by_session(data
->s
), data
->s
->tunnel
,
104 " Not throttling user\n");
106 data
->s
->throttle_in
= data
->s
->throttle_out
= rate
;
109 return PLUGIN_RET_OK
;
112 int plugin_radius_reset(struct param_radius_reset
*data
)
114 f
->throttle(f
->get_id_by_session(data
->s
), 0, 0);
115 return PLUGIN_RET_OK
;
118 int plugin_radius_account(struct param_radius_account
*data
)
120 if (data
->s
->throttle_in
|| data
->s
->throttle_out
)
122 uint8_t *p
= *data
->packet
;
125 if (data
->s
->throttle_in
)
127 *p
= 26; // vendor-specific
128 *(uint32_t *) (p
+ 2) = htonl(9); // Cisco
129 p
[6] = 1; // Cisco-AVPair
130 p
[7] = 2 + sprintf((char *) p
+ 8,
131 "lcp:interface-config#%d=service-policy input %d", i
++,
132 data
->s
->throttle_in
);
138 if (data
->s
->throttle_out
)
140 *p
= 26; // vendor-specific
141 *(uint32_t *) (p
+ 2) = htonl(9); // Cisco
142 p
[6] = 1; // Cisco-AVPair
143 p
[7] = 2 + sprintf((char *) p
+ 8,
144 "lcp:interface-config#%d=service-policy output %d", i
++,
145 data
->s
->throttle_out
);
154 return PLUGIN_RET_OK
;
157 int plugin_init(struct pluginfuncs
*funcs
)
159 return ((f
= funcs
)) ? 1 : 0;