4 Copyright (C) 2006-2008 Jonathan Zarate
5 rate limit & connection limit by conanxu
6 2011 modified by Victek & Shibby for 2.6 kernel
13 static const char *qoslimitfn
= "/etc/qoslimit";
24 void address_checker (int * address_type
, char *ipaddr_old
, char *ipaddr
)
26 char * second_part
, *last_dot
;
27 int length_to_minus
, length_to_dot
;
29 second_part
= strchr(ipaddr_old
, '-');
30 if (second_part
!= NULL
) {
32 *address_type
= IP_RANGE
;
33 if (strchr(second_part
+1, '.') != NULL
) {
35 strcpy (ipaddr
, ipaddr_old
);
39 last_dot
= strrchr(ipaddr_old
, '.');
40 length_to_minus
= second_part
- ipaddr_old
;
41 length_to_dot
= last_dot
- ipaddr_old
;
42 strncpy(ipaddr
, ipaddr_old
, length_to_minus
+ 1);
43 strncpy(ipaddr
+ length_to_minus
+ 1, ipaddr
, length_to_dot
+ 1);
44 strcpy(ipaddr
+ length_to_minus
+ length_to_dot
+ 2, second_part
+1);
48 /* mac address of ipaddres */
49 if (strlen(ipaddr_old
) != 17) {
51 *address_type
= IP_ADDRESS
;
55 *address_type
= MAC_ADDRESS
;
57 strcpy (ipaddr
, ipaddr_old
);
61 void ipt_qoslimit(int chain
)
66 char *ibw
,*obw
;//bandwidth
67 char seq
[4];//mark number
70 char ipaddr
[30];//ip address
71 char *dlrate
,*dlceil
;//guaranteed rate & maximum rate for download
72 char *ulrate
,*ulceil
;//guaranteed rate & maximum rate for upload
73 char *priority
;//priority
74 char *lanipaddr
; //lan ip address
75 char *lanmask
; //lan netmask
76 char *tcplimit
,*udplimit
;//tcp connection limit & udp packets per second
78 char *qosl_tcp
,*qosl_udp
;
82 if (!nvram_get_int("new_qoslimit_enable")) return;
84 //read qos1rules from nvram
85 g
= buf
= strdup(nvram_safe_get("new_qoslimit_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");
93 qosl_tcp
= nvram_safe_get("qosl_tcp");
94 qosl_udp
= nvram_safe_get("qosl_udp");
99 if (nvram_get_int("qosl_enable") == 1) {
101 "-A POSTROUTING ! -s %s/%s -d %s/%s -j MARK --set-mark 100\n"
102 "-A PREROUTING -s %s/%s ! -d %s/%s -j MARK --set-mark 100\n"
103 ,lanipaddr
,lanmask
,lanipaddr
,lanmask
104 ,lanipaddr
,lanmask
,lanipaddr
,lanmask
);
108 if (nvram_get_int("limit_br1_enable") == 1) {
110 char *lan1_ipaddr
; //lan1 ip address
111 char *lan1_mask
; //lan1 netmask
113 lan1_ipaddr
= nvram_safe_get("lan1_ipaddr");
114 lan1_mask
= nvram_safe_get("lan1_netmask");
117 "-A POSTROUTING -d %s/%s -j MARK --set-mark 401\n"
118 "-A PREROUTING -s %s/%s -j MARK --set-mark 501\n"
119 ,lan1_ipaddr
,lan1_mask
120 ,lan1_ipaddr
,lan1_mask
);
124 if (nvram_get_int("limit_br2_enable") == 1) {
126 char *lan2_ipaddr
; //lan2 ip address
127 char *lan2_mask
; //lan2 netmask
129 lan2_ipaddr
= nvram_safe_get("lan2_ipaddr");
130 lan2_mask
= nvram_safe_get("lan2_netmask");
133 "-A POSTROUTING -d %s/%s -j MARK --set-mark 601\n"
134 "-A PREROUTING -s %s/%s -j MARK --set-mark 701\n"
135 ,lan2_ipaddr
,lan2_mask
136 ,lan2_ipaddr
,lan2_mask
);
139 if (nvram_get_int("limit_br3_enable") == 1) {
141 char *lan3_ipaddr
; //lan3 ip address
142 char *lan3_mask
; //lan3 netmask
144 lan3_ipaddr
= nvram_safe_get("lan3_ipaddr");
145 lan3_mask
= nvram_safe_get("lan3_netmask");
148 "-A POSTROUTING -d %s/%s -j MARK --set-mark 801\n"
149 "-A PREROUTING -s %s/%s -j MARK --set-mark 901\n"
150 ,lan3_ipaddr
,lan3_mask
151 ,lan3_ipaddr
,lan3_mask
);
158 if (nvram_get_int("qosl_enable") == 1) {
159 if (nvram_get_int("qosl_tcp") > 0) {
161 "-A PREROUTING -s %s/%s -p tcp --syn -m connlimit --connlimit-above %s -j DROP\n"
162 ,lanipaddr
,lanmask
,qosl_tcp
);
165 if (nvram_get_int("qosl_udp") > 0) {
167 "-A PREROUTING -s %s/%s -p udp -m limit --limit %s/sec -j ACCEPT\n"
168 ,lanipaddr
,lanmask
,qosl_udp
);
175 ipaddr_old<dlrate<dlceil<ulrate<ulceil<priority<tcplimit<udplimit
177 if ((p
= strsep(&g
, ">")) == NULL
) break;
178 i
= vstrsep(p
, "<", &ipaddr_old
, &dlrate
, &dlceil
, &ulrate
, &ulceil
, &priority
, &tcplimit
, &udplimit
);
181 priority_num
= atoi(priority
);
182 if ((priority_num
< 0) || (priority_num
> 5)) continue;
184 if (!strcmp(ipaddr_old
,"")) continue;
186 address_checker (&address_type
, ipaddr_old
, ipaddr
);
187 sprintf(seq
,"%d",iSeq
);
190 if (!strcmp(dlceil
,"")) strcpy(dlceil
, dlrate
);
191 if (strcmp(dlrate
,"") && strcmp(dlceil
, "")) {
193 switch (address_type
)
197 "-A POSTROUTING ! -s %s/%s -d %s -j MARK --set-mark %s\n"
198 ,lanipaddr
,lanmask
,ipaddr
,seq
);
204 "-A POSTROUTING ! -s %s/%s -m iprange --dst-range %s -j MARK --set-mark %s\n"
205 ,lanipaddr
,lanmask
,ipaddr
,seq
);
211 if (!strcmp(ulceil
,"")) strcpy(ulceil
, ulrate
);
212 if (strcmp(ulrate
,"") && strcmp(ulceil
, "")) {
214 switch (address_type
)
218 "-A PREROUTING -s %s ! -d %s/%s -j MARK --set-mark %s\n"
219 ,ipaddr
,lanipaddr
,lanmask
,seq
);
223 "-A PREROUTING -m mac --mac-source %s ! -d %s/%s -j MARK --set-mark %s\n"
224 ,ipaddr
,lanipaddr
,lanmask
,seq
);
228 "-A PREROUTING -m iprange --src-range %s ! -d %s/%s -j MARK --set-mark %s\n"
229 ,ipaddr
,lanipaddr
,lanmask
,seq
);
235 if(atoi(tcplimit
) > 0){
237 switch (address_type
)
241 "-A PREROUTING -s %s -p tcp --syn -m connlimit --connlimit-above %s -j DROP\n"
246 "-A PREROUTING -m mac --mac-source %s -p tcp --syn -m connlimit --connlimit-above %s -j DROP\n"
251 "-A PREROUTING -m iprange --src-range %s -p tcp --syn -m connlimit --connlimit-above %s -j DROP\n"
257 if(atoi(udplimit
) > 0){
259 switch (address_type
)
263 "-A PREROUTING -s %s -p udp -m limit --limit %s/sec -j ACCEPT\n"
268 "-A PREROUTING -m mac --mac-source %s -p udp -m limit --limit %s/sec -j ACCEPT\n"
273 "-A PREROUTING -m iprange --src-range %s -p udp -m limit --limit %s/sec -j ACCEPT\n"
283 // read nvram into files
284 void new_qoslimit_start(void)
290 char *ibw
,*obw
;//bandwidth
291 char seq
[4];//mark number
294 char ipaddr
[30];//ip address
295 char *dlrate
,*dlceil
;//guaranteed rate & maximum rate for download
296 char *ulrate
,*ulceil
;//guaranteed rate & maximum rate for upload
297 char *priority
;//priority
298 char *lanipaddr
; //lan ip address
299 char *lanmask
; //lan netmask
300 char *tcplimit
,*udplimit
;//tcp connection limit & udp packets per second
302 char *dlr
,*dlc
,*ulr
,*ulc
; //download / upload - rate / ceiling
305 char *waniface
; //shibby
308 if (!nvram_get_int("new_qoslimit_enable")) return;
310 //read qos1rules from nvram
311 g
= buf
= strdup(nvram_safe_get("new_qoslimit_rules"));
313 ibw
= nvram_safe_get("qos_ibw");
314 obw
= nvram_safe_get("qos_obw");
316 lanipaddr
= nvram_safe_get("lan_ipaddr");
317 lanmask
= nvram_safe_get("lan_netmask");
318 waniface
= nvram_safe_get("wan_iface"); //shibby
320 dlr
= nvram_safe_get("qosl_dlr"); //Qos limit download rate
321 dlc
= nvram_safe_get("qosl_dlc"); //download ceiling
322 ulr
= nvram_safe_get("qosl_ulr"); //upload rate
323 ulc
= nvram_safe_get("qosl_ulc"); //upload ceiling
325 if ((tc
= fopen(qoslimitfn
, "w")) == NULL
) return;
329 "tc qdisc del dev br0 root 2>/dev/null\n"
330 "tc qdisc del dev %s root 2>/dev/null\n"
332 "TCA=\"tc class add dev br0\"\n"
333 "TFA=\"tc filter add dev br0\"\n"
334 "TQA=\"tc qdisc add dev br0\"\n"
336 "SFQ=\"sfq perturb 10\"\n"
338 "TCAU=\"tc class add dev %s\"\n"
339 "TFAU=\"tc filter add dev %s\"\n"
340 "TQAU=\"tc qdisc add dev %s\"\n"
342 "tc qdisc add dev br0 root handle 1: htb\n"
343 "tc class add dev br0 parent 1: classid 1:1 htb rate %skbit\n"
345 "tc qdisc add dev %s root handle 2: htb\n"
346 "tc class add dev %s parent 2: classid 2:1 htb rate %skbit\n"
357 if ((nvram_get_int("qosl_enable") == 1) && strcmp(dlr
,"") && strcmp(ulr
,"")) {
358 if (!strcmp(dlc
,"")) strcpy(dlc
, dlr
);
359 if (!strcmp(ulc
,"")) strcpy(ulc
, ulr
);
361 "$TCA parent 1:1 classid 1:100 htb rate %skbit ceil %skbit prio 3\n"
362 "$TQA parent 1:100 handle 100: $SFQ\n"
363 "$TFA parent 1:0 prio 3 protocol ip handle 100 fw flowid 1:100\n"
365 "$TCAU parent 2:1 classid 2:100 htb rate %skbit ceil %skbit prio 3\n"
366 "$TQAU parent 2:100 handle 100: $SFQ\n"
367 "$TFAU parent 2:0 prio 3 protocol ip handle 100 fw flowid 2:100\n"
375 ipaddr_old<dlrate<dlceil<ulrate<ulceil<priority<tcplimit<udplimit
377 if ((p
= strsep(&g
, ">")) == NULL
) break;
378 i
= vstrsep(p
, "<", &ipaddr_old
, &dlrate
, &dlceil
, &ulrate
, &ulceil
, &priority
, &tcplimit
, &udplimit
);
381 priority_num
= atoi(priority
);
382 if ((priority_num
< 0) || (priority_num
> 5)) continue;
384 if (!strcmp(ipaddr_old
,"")) continue;
386 address_checker(&address_type
, ipaddr_old
, ipaddr
);
387 sprintf(seq
,"%d",iSeq
);
389 if (!strcmp(dlceil
,"")) strcpy(dlceil
, dlrate
);
390 if (strcmp(dlrate
,"") && strcmp(dlceil
, "")) {
391 if (address_type
!= MAC_ADDRESS
) {
393 "$TCA parent 1:1 classid 1:%s htb rate %skbit ceil %skbit prio %s\n"
394 "$TQA parent 1:%s handle %s: $SFQ\n"
395 "$TFA parent 1:0 prio %s protocol ip handle %s fw flowid 1:%s\n"
397 ,seq
,dlrate
,dlceil
,priority
401 else if (address_type
== MAC_ADDRESS
) {
402 sscanf(ipaddr
, "%02X:%02X:%02X:%02X:%02X:%02X",&s
[0],&s
[1],&s
[2],&s
[3],&s
[4],&s
[5]);
405 "$TCA parent 1:1 classid 1:%s htb rate %skbit ceil %skbit prio %s\n"
406 "$TQA parent 1:%s handle %s: $SFQ\n"
407 "$TFA 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"
409 ,seq
,dlrate
,dlceil
,priority
411 ,priority
,s
[2],s
[3],s
[4],s
[5],s
[0],s
[1],seq
);
415 if (!strcmp(ulceil
,"")) strcpy(ulceil
, dlrate
);
416 if (strcmp(ulrate
,"") && strcmp(ulceil
, "")) {
418 "$TCAU parent 2:1 classid 2:%s htb rate %skbit ceil %skbit prio %s\n"
419 "$TQAU parent 2:%s handle %s: $SFQ\n"
420 "$TFAU parent 2:0 prio %s protocol ip handle %s fw flowid 2:%s\n"
422 ,seq
,ulrate
,ulceil
,priority
429 /* shibby - limit br1 */
430 if (nvram_get_int("limit_br1_enable") == 1) {
432 char *dlr_1
,*dlc_1
,*ulr_1
,*ulc_1
,*prio_1
;
434 dlr_1
= nvram_safe_get("limit_br1_dlr"); //Qos limit download rate
435 dlc_1
= nvram_safe_get("limit_br1_dlc"); //download ceiling
436 ulr_1
= nvram_safe_get("limit_br1_ulr"); //upload rate
437 ulc_1
= nvram_safe_get("limit_br1_ulc"); //upload ceiling
438 prio_1
= nvram_safe_get("limit_br1_prio"); //priority
440 if (!strcmp(dlc_1
,"")) strcpy(dlc_1
, dlr_1
);
441 if (!strcmp(ulc_1
,"")) strcpy(ulc_1
, ulr_1
);
445 "TCA1=\"tc class add dev br1\"\n"
446 "TFA1=\"tc filter add dev br1\"\n"
447 "TQA1=\"tc qdisc add dev br1\"\n"
448 "tc qdisc del dev br1 root\n"
449 "tc qdisc add dev br1 root handle 4: htb\n"
450 "tc class add dev br1 parent 4: classid 4:1 htb rate %skbit\n"
451 "$TCA1 parent 4:1 classid 4:401 htb rate %skbit ceil %skbit prio %s\n"
452 "$TQA1 parent 4:401 handle 401: $SFQ\n"
453 "$TFA1 parent 4:0 prio %s protocol ip handle 401 fw flowid 4:401\n"
460 "$TCAU parent 2:1 classid 2:501 htb rate %skbit ceil %skbit prio %s\n"
461 "$TQAU parent 2:501 handle 501: $SFQ\n"
462 "$TFAU parent 2:0 prio %s protocol ip handle 501 fw flowid 2:501\n"
467 /* shibby - limit br2 */
468 if (nvram_get_int("limit_br2_enable") == 1) {
470 char *dlr_2
,*dlc_2
,*ulr_2
,*ulc_2
,*prio_2
;
472 dlr_2
= nvram_safe_get("limit_br2_dlr"); //Qos limit download rate
473 dlc_2
= nvram_safe_get("limit_br2_dlc"); //download ceiling
474 ulr_2
= nvram_safe_get("limit_br2_ulr"); //upload rate
475 ulc_2
= nvram_safe_get("limit_br2_ulc"); //upload ceiling
476 prio_2
= nvram_safe_get("limit_br2_prio"); //priority
478 if (!strcmp(dlc_2
,"")) strcpy(dlc_2
, dlr_2
);
479 if (!strcmp(ulc_2
,"")) strcpy(ulc_2
, ulr_2
);
483 "TCA2=\"tc class add dev br2\"\n"
484 "TFA2=\"tc filter add dev br2\"\n"
485 "TQA2=\"tc qdisc add dev br2\"\n"
486 "tc qdisc del dev br2 root\n"
487 "tc qdisc add dev br2 root handle 6: htb\n"
488 "tc class add dev br2 parent 6: classid 6:1 htb rate %skbit\n"
489 "$TCA2 parent 6:1 classid 6:601 htb rate %skbit ceil %skbit prio %s\n"
490 "$TQA2 parent 6:601 handle 601: $SFQ\n"
491 "$TFA2 parent 6:0 prio %s protocol ip handle 601 fw flowid 6:601\n"
498 "$TCAU parent 2:1 classid 2:701 htb rate %skbit ceil %skbit prio %s\n"
499 "$TQAU parent 2:701 handle 701: $SFQ\n"
500 "$TFAU parent 2:0 prio %s protocol ip handle 701 fw flowid 2:701\n"
505 /* shibby - limit br3 */
506 if (nvram_get_int("limit_br3_enable") == 1) {
508 char *dlr_3
,*dlc_3
,*ulr_3
,*ulc_3
,*prio_3
;
510 dlr_3
= nvram_safe_get("limit_br3_dlr"); //Qos limit download rate
511 dlc_3
= nvram_safe_get("limit_br3_dlc"); //download ceiling
512 ulr_3
= nvram_safe_get("limit_br3_ulr"); //upload rate
513 ulc_3
= nvram_safe_get("limit_br3_ulc"); //upload ceiling
514 prio_3
= nvram_safe_get("limit_br3_prio"); //priority
516 if (!strcmp(dlc_3
,"")) strcpy(dlc_3
, dlr_3
);
517 if (!strcmp(ulc_3
,"")) strcpy(ulc_3
, ulr_3
);
521 "TCA3=\"tc class add dev br3\"\n"
522 "TFA3=\"tc filter add dev br3\"\n"
523 "TQA3=\"tc qdisc add dev br3\"\n"
524 "tc qdisc del dev br3 root\n"
525 "tc qdisc add dev br3 root handle 8: htb\n"
526 "tc class add dev br3 parent 8: classid 8:1 htb rate %skbit\n"
527 "$TCA3 parent 8:1 classid 8:801 htb rate %skbit ceil %skbit prio %s\n"
528 "$TQA3 parent 8:801 handle 801: $SFQ\n"
529 "$TFA3 parent 8:0 prio %s protocol ip handle 801 fw flowid 8:801\n"
536 "$TCAU parent 2:1 classid 2:901 htb rate %skbit ceil %skbit prio %s\n"
537 "$TQAU parent 2:901 handle 901: $SFQ\n"
538 "$TFAU parent 2:0 prio %s protocol ip handle 901 fw flowid 2:901\n"
545 chmod(qoslimitfn
, 0700);
548 eval((char *)qoslimitfn
, "start");
551 void new_qoslimit_stop(void)
554 char *s
= "/tmp/qoslimittc_stop.sh";
557 waniface
= nvram_safe_get("wan_iface"); //shibby
559 if ((f
= fopen(s
, "w")) == NULL
) return;
563 "tc qdisc del dev %s root\n"
564 "tc qdisc del dev br0 root\n"
572 eval((char *)s
, "stop");
576 PREROUTING (mn) ----> x ----> FORWARD (f) ----> + ----> POSTROUTING (n)
580 INPUT (f) OUTPUT (mnf)