4 Copyright (C) 2006-2008 Jonathan Zarate
5 Copyright (C) 2011 Deon 'PrinceAMD' Thomas
6 rate limit & connection limit by conanxu
12 static const char *qoslimitfn
= "/etc/qoslimit";
23 void address_checker (int * address_type
, char *ipaddr_old
, char *ipaddr
)
25 char * second_part
, *last_dot
;
26 int length_to_minus
, length_to_dot
;
28 second_part
= strchr(ipaddr_old
, '-');
29 if (second_part
!= NULL
) {
31 *address_type
= IP_RANGE
;
32 if (strchr(second_part
+1, '.') != NULL
) {
34 strcpy (ipaddr
, ipaddr_old
);
38 last_dot
= strrchr(ipaddr_old
, '.');
39 length_to_minus
= second_part
- ipaddr_old
;
40 length_to_dot
= last_dot
- ipaddr_old
;
41 strncpy(ipaddr
, ipaddr_old
, length_to_minus
+ 1);
42 strncpy(ipaddr
+ length_to_minus
+ 1, ipaddr
, length_to_dot
+ 1);
43 strcpy(ipaddr
+ length_to_minus
+ length_to_dot
+ 2, second_part
+1);
47 /* mac address of ipaddres */
48 if (strlen(ipaddr_old
) != 17) {
50 *address_type
= IP_ADDRESS
;
54 *address_type
= MAC_ADDRESS
;
56 strcpy (ipaddr
, ipaddr_old
);
60 void ipt_qoslimit(int chain
)
65 char *ibw
,*obw
;//bandwidth
66 char seq
[4];//mark number
69 char ipaddr
[30];//ip address
70 char *dlrate
,*dlceil
;//guaranteed rate & maximum rate for download
71 char *ulrate
,*ulceil
;//guaranteed rate & maximum rate for upload
72 char *priority
;//priority
73 char *lanipaddr
; //lan ip address
74 char *lanmask
; //lan netmask
75 char *tcplimit
,*udplimit
;//tcp connection limit & udp packets per second
76 char *laninface
; // lan interface
78 char *qosl_dtcp
,*qosl_dudp
;
82 if (!nvram_get_int("qosl_enable")) return;
84 //read qos1rules from nvram
85 g
= buf
= strdup(nvram_safe_get("qosl_rules"));
87 ibw
= nvram_safe_get("qos_ibw"); // Read from QOS setting - KRP
88 obw
= nvram_safe_get("qos_obw"); // Read from QOS setting - KRP
90 lanipaddr
= nvram_safe_get("lan_ipaddr");
91 lanmask
= nvram_safe_get("lan_netmask");
92 laninface
= nvram_safe_get("lan_ifname");
94 qosl_dtcp
= nvram_safe_get("qosl_dtcp");
95 qosl_dudp
= nvram_safe_get("qosl_dudp");
101 "-A PREROUTING -j IMQ -i %s --todev 1\n"
102 "-A POSTROUTING -j IMQ -o %s --todev 2\n"
103 ,laninface
,laninface
);
104 if (nvram_get_int("qosl_denable") == 1) {
106 "-A POSTROUTING ! -s %s/%s -j MARK --set-mark 100\n"
107 "-A PREROUTING ! -d %s/%s -j MARK --set-mark 100\n"
116 if (nvram_get_int("qosl_denable") == 1) {
117 if (nvram_get_int("qosl_dtcp") > 0) {
119 "-A PREROUTING -s %s/%s -p tcp --syn -m connlimit --connlimit-above %s -j DROP\n"
120 ,lanipaddr
,lanmask
,qosl_dtcp
);
123 if (nvram_get_int("qosl_dudp") > 0) {
125 "-A PREROUTING -s %s/%s -p udp -m limit --limit %s/sec -j ACCEPT\n"
126 ,lanipaddr
,lanmask
,qosl_dudp
);
133 ipaddr_old<dlrate<dlceil<ulrate<ulceil<priority<tcplimit<udplimit
135 if ((p
= strsep(&g
, ">")) == NULL
) break;
136 i
= vstrsep(p
, "<", &ipaddr_old
, &dlrate
, &dlceil
, &ulrate
, &ulceil
, &priority
, &tcplimit
, &udplimit
);
139 priority_num
= atoi(priority
);
140 if ((priority_num
< 0) || (priority_num
> 5)) continue;
142 if (!strcmp(ipaddr_old
,"")) continue;
144 address_checker (&address_type
, ipaddr_old
, ipaddr
);
145 sprintf(seq
,"%d",iSeq
);
148 if (!strcmp(dlceil
,"")) strcpy(dlceil
, dlrate
);
149 if (strcmp(dlrate
,"") && strcmp(dlceil
, "")) {
151 switch (address_type
)
155 "-A POSTROUTING ! -s %s/%s -d %s -j MARK --set-mark %s\n"
156 ,lanipaddr
,lanmask
,ipaddr
,seq
);
162 "-A POSTROUTING ! -s %s/%s -m iprange --dst-range %s -j MARK --set-mark %s\n"
163 ,lanipaddr
,lanmask
,ipaddr
,seq
);
169 if (!strcmp(ulceil
,"")) strcpy(ulceil
, ulrate
);
170 if (strcmp(ulrate
,"") && strcmp(ulceil
, "")) {
172 switch (address_type
)
176 "-A PREROUTING -s %s ! -d %s/%s -j MARK --set-mark %s\n"
177 ,ipaddr
,lanipaddr
,lanmask
,seq
);
181 "-A PREROUTING -m mac --mac-source %s ! -d %s/%s -j MARK --set-mark %s\n"
182 ,ipaddr
,lanipaddr
,lanmask
,seq
);
186 "-A PREROUTING -m iprange --src-range %s ! -d %s/%s -j MARK --set-mark %s\n"
187 ,ipaddr
,lanipaddr
,lanmask
,seq
);
193 if(atoi(tcplimit
) > 0){
195 switch (address_type
)
199 "-A PREROUTING -s %s -p tcp --syn -m connlimit --connlimit-above %s -j DROP\n"
204 "-A PREROUTING -m mac --mac-source %s -p tcp --syn -m connlimit --connlimit-above %s -j DROP\n"
209 "-A PREROUTING -m iprange --src-range %s -p tcp --syn -m connlimit --connlimit-above %s -j DROP\n"
215 if(atoi(udplimit
) > 0){
217 switch (address_type
)
221 "-A PREROUTING -s %s -p udp -m limit --limit %s/sec -j ACCEPT\n"
226 "-A PREROUTING -m mac --mac-source %s -p udp -m limit --limit %s/sec -j ACCEPT\n"
231 "-A PREROUTING -m iprange --src-range %s -p udp -m limit --limit %s/sec -j ACCEPT\n"
241 // read nvram into files
242 void start_qoslimit(void)
248 char *ibw
,*obw
;//bandwidth
249 char seq
[4];//mark number
252 char ipaddr
[30];//ip address
253 char *dlrate
,*dlceil
;//guaranteed rate & maximum rate for download
254 char *ulrate
,*ulceil
;//guaranteed rate & maximum rate for upload
255 char *priority
;//priority
256 char *lanipaddr
; //lan ip address
257 char *lanmask
; //lan netmask
258 char *tcplimit
,*udplimit
;//tcp connection limit & udp packets per second
260 char *ddlr
,*ddlc
,*dulr
,*dulc
; //download / upload - rate / ceiling
265 if (!nvram_get_int("qosl_enable")) return;
267 //read qosl rules from nvram
268 g
= buf
= strdup(nvram_safe_get("qosl_rules"));
270 ibw
= nvram_safe_get("qos_ibw"); // Read from QOS setting - KRP
271 obw
= nvram_safe_get("qos_obw"); // Read from QOS setting - KRP
273 lanipaddr
= nvram_safe_get("lan_ipaddr");
274 lanmask
= nvram_safe_get("lan_netmask");
276 ddlr
= nvram_safe_get("qosl_ddlr"); //Default download rate
277 ddlc
= nvram_safe_get("qosl_ddlc"); //Default download ceiling
278 dulr
= nvram_safe_get("qosl_dulr"); //Default upload rate
279 dulc
= nvram_safe_get("qosl_dulc"); //Default upload ceiling
281 if ((tc
= fopen(qoslimitfn
, "w")) == NULL
) return;
285 "ip link set imq1 up\n"
286 "ip link set imq2 up\n"
288 "tc qdisc del dev imq1 root 2>/dev/null\n"
289 "tc qdisc del dev imq2 root 2>/dev/null\n"
290 "tc qdisc del dev br0 root 2>/dev/null\n" //fix me [why should mac get filter here??]
292 "TCAM=\"tc class add dev br0\"\n" //fix me
293 "TFAM=\"tc filter add dev br0\"\n" //fix me
294 "TQAM=\"tc qdisc add dev br0\"\n" //fix me
296 "TCA=\"tc class add dev imq2\"\n"
297 "TFA=\"tc filter add dev imq2\"\n"
298 "TQA=\"tc qdisc add dev imq2\"\n"
300 "SFQ=\"sfq perturb 10\"\n"
302 "TCAU=\"tc class add dev imq1\"\n"
303 "TFAU=\"tc filter add dev imq1\"\n"
304 "TQAU=\"tc qdisc add dev imq1\"\n"
306 "tc qdisc add dev imq2 root handle 1: htb\n"
307 "tc class add dev imq2 parent 1: classid 1:1 htb rate %skbit\n"
309 "tc qdisc add dev br0 root handle 1: htb\n"
310 "tc class add dev br0 parent 1: classid 1:1 htb rate %skbit\n"
312 "tc qdisc add dev imq1 root handle 1: htb\n"
313 "tc class add dev imq1 parent 1: classid 1:1 htb rate %skbit\n"
318 if ((nvram_get_int("qosl_denable") == 1) && strcmp(ddlr
,"") && strcmp(dulr
,"")) {
319 if (!strcmp(ddlc
,"")) strcpy(ddlc
, ddlr
);
320 if (!strcmp(dulc
,"")) strcpy(dulc
, dulr
);
322 "$TCA parent 1:1 classid 1:100 htb rate %skbit ceil %skbit prio 3\n"
323 "$TQA parent 1:100 handle 100: $SFQ\n"
324 "$TFA parent 1:0 prio 3 protocol ip handle 100 fw flowid 1:100\n"
326 "$TCAU parent 1:1 classid 1:100 htb rate %skbit ceil %skbit prio 3\n"
327 "$TQAU parent 1:100 handle 100: $SFQ\n"
328 "$TFAU parent 1:0 prio 3 protocol ip handle 100 fw flowid 1:100\n"
336 ipaddr_old<dlrate<dlceil<ulrate<ulceil<priority<tcplimit<udplimit
338 if ((p
= strsep(&g
, ">")) == NULL
) break;
339 i
= vstrsep(p
, "<", &ipaddr_old
, &dlrate
, &dlceil
, &ulrate
, &ulceil
, &priority
, &tcplimit
, &udplimit
);
341 priority_num
= atoi(priority
);
342 if ((priority_num
< 0) || (priority_num
> 5)) continue;
343 if (!strcmp(ipaddr_old
,"")) continue;
345 address_checker(&address_type
, ipaddr_old
, ipaddr
);
346 sprintf(seq
,"%d",iSeq
);
348 if (!strcmp(dlceil
,"")) strcpy(dlceil
, dlrate
);
349 if (strcmp(dlrate
,"") && strcmp(dlceil
, "")) {
350 if (address_type
!= MAC_ADDRESS
) {
352 "$TCA parent 1:1 classid 1:%s htb rate %skbit ceil %skbit prio %s\n"
353 "$TQA parent 1:%s handle %s: $SFQ\n"
354 "$TFA parent 1:0 prio %s protocol ip handle %s fw flowid 1:%s\n"
356 ,seq
,dlrate
,dlceil
,priority
360 else if (address_type
== MAC_ADDRESS
) {
361 sscanf(ipaddr
, "%02X:%02X:%02X:%02X:%02X:%02X",&s
[0],&s
[1],&s
[2],&s
[3],&s
[4],&s
[5]);
364 "$TCAM parent 1:1 classid 1:%s htb rate %skbit ceil %skbit prio %s\n"
365 "$TQAM parent 1:%s handle %s: $SFQ\n"
366 "$TFAM parent 1:0 protocol ip prio %s u32 match u16 0x0800 0xFFFF at -2 match u32 0x%02X%02X%02X%02X 0xFFFFFFFF at -12 match u16 0x%02X%02X 0xFFFF at -14 flowid 1:%s\n"
368 ,seq
,dlrate
,dlceil
,priority
370 ,priority
,s
[2],s
[3],s
[4],s
[5],s
[0],s
[1],seq
);
374 if (!strcmp(ulceil
,"")) strcpy(ulceil
, dlrate
);
375 if (strcmp(ulrate
,"") && strcmp(ulceil
, "")) {
377 "$TCAU parent 1:1 classid 1:%s htb rate %skbit ceil %skbit prio %s\n"
378 "$TQAU parent 1:%s handle %s: $SFQ\n"
379 "$TFAU parent 1:0 prio %s protocol ip handle %s fw flowid 1:%s\n"
381 ,seq
,ulrate
,ulceil
,priority
389 chmod(qoslimitfn
, 0700);
392 eval((char *)qoslimitfn
, "start");
395 void stop_qoslimit(void)
398 char *s
= "/tmp/stop_qoslimittc.sh";
400 if ((f
= fopen(s
, "w")) == NULL
) return;
404 "tc qdisc del dev imq2 root\n"
405 "tc qdisc del dev imq1 root\n"
406 "tc qdisc del dev br0 root\n" //fix me
407 "ip link set imq1 down\n"
408 "ip link set imq2 down\n" //take imq's down - Toastman
416 eval((char *)s
, "stop");
420 PREROUTING (mn) ----> x ----> FORWARD (f) ----> + ----> POSTROUTING (n)
424 INPUT (f) OUTPUT (mnf)