libsodium: Needed for Dnscrypto-proxy Release 1.3.0
[tomato.git] / release / src / router / rc / new_qoslimit.c
blob29e4d9a6f840f1c00391d6a62693c1b15d5b134e
1 /*
3 Tomato Firmware
4 Copyright (C) 2006-2008 Jonathan Zarate
5 rate limit & connection limit by conanxu
6 2011 modified by Victek & Shibby for 2.6 kernel
7 last changed: 20110210
8 */
10 #include "rc.h"
12 #include <sys/stat.h>
13 static const char *qoslimitfn = "/etc/qoslimit";
15 /*int chain
16 1 = MANGLE
17 2 = NAT
20 #define IP_ADDRESS 0
21 #define MAC_ADDRESS 1
22 #define IP_RANGE 2
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) {
31 /* ip range */
32 *address_type = IP_RANGE;
33 if (strchr(second_part+1, '.') != NULL) {
34 /* long notation */
35 strcpy (ipaddr, ipaddr_old);
37 else {
38 /* short notation */
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);
47 else {
48 /* mac address of ipaddres */
49 if (strlen(ipaddr_old) != 17) {
50 /* IP_ADDRESS */
51 *address_type = IP_ADDRESS;
53 else {
54 /* MAC ADDRESS */
55 *address_type = MAC_ADDRESS;
57 strcpy (ipaddr, ipaddr_old);
61 void ipt_qoslimit(int chain)
63 char *buf;
64 char *g;
65 char *p;
66 char *ibw,*obw;//bandwidth
67 char seq[4];//mark number
68 int iSeq = 10;
69 char *ipaddr_old;
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
77 int priority_num;
78 char *qosl_tcp,*qosl_udp;
79 int i, address_type;
81 //qos1 is enable
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");
96 //MANGLE
97 if (chain == 1)
99 if (nvram_get_int("qosl_enable") == 1) {
100 ipt_write(
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);
107 //shibby br1
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");
116 ipt_write(
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);
123 //shibby br2
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");
132 ipt_write(
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);
138 //shibby br3
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");
147 ipt_write(
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);
155 //NAT
156 if (chain == 2)
158 if (nvram_get_int("qosl_enable") == 1) {
159 if (nvram_get_int("qosl_tcp") > 0) {
160 ipt_write(
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) {
166 ipt_write(
167 "-A PREROUTING -s %s/%s -p udp -m limit --limit %s/sec -j ACCEPT\n"
168 ,lanipaddr,lanmask,qosl_udp);
173 while (g) {
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);
179 if (i!=8) continue;
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);
188 iSeq++;
190 if (!strcmp(dlceil,"")) strcpy(dlceil, dlrate);
191 if (strcmp(dlrate,"") && strcmp(dlceil, "")) {
192 if(chain == 1) {
193 switch (address_type)
195 case IP_ADDRESS:
196 ipt_write(
197 "-A POSTROUTING ! -s %s/%s -d %s -j MARK --set-mark %s\n"
198 ,lanipaddr,lanmask,ipaddr,seq);
199 break;
200 case MAC_ADDRESS:
201 break;
202 case IP_RANGE:
203 ipt_write(
204 "-A POSTROUTING ! -s %s/%s -m iprange --dst-range %s -j MARK --set-mark %s\n"
205 ,lanipaddr,lanmask,ipaddr,seq);
206 break;
211 if (!strcmp(ulceil,"")) strcpy(ulceil, ulrate);
212 if (strcmp(ulrate,"") && strcmp(ulceil, "")) {
213 if (chain == 1) {
214 switch (address_type)
216 case IP_ADDRESS:
217 ipt_write(
218 "-A PREROUTING -s %s ! -d %s/%s -j MARK --set-mark %s\n"
219 ,ipaddr,lanipaddr,lanmask,seq);
220 break;
221 case MAC_ADDRESS:
222 ipt_write(
223 "-A PREROUTING -m mac --mac-source %s ! -d %s/%s -j MARK --set-mark %s\n"
224 ,ipaddr,lanipaddr,lanmask,seq);
225 break;
226 case IP_RANGE:
227 ipt_write(
228 "-A PREROUTING -m iprange --src-range %s ! -d %s/%s -j MARK --set-mark %s\n"
229 ,ipaddr,lanipaddr,lanmask,seq);
230 break;
235 if(atoi(tcplimit) > 0){
236 if (chain == 2) {
237 switch (address_type)
239 case IP_ADDRESS:
240 ipt_write(
241 "-A PREROUTING -s %s -p tcp --syn -m connlimit --connlimit-above %s -j DROP\n"
242 ,ipaddr,tcplimit);
243 break;
244 case MAC_ADDRESS:
245 ipt_write(
246 "-A PREROUTING -m mac --mac-source %s -p tcp --syn -m connlimit --connlimit-above %s -j DROP\n"
247 ,ipaddr,tcplimit);
248 break;
249 case IP_RANGE:
250 ipt_write(
251 "-A PREROUTING -m iprange --src-range %s -p tcp --syn -m connlimit --connlimit-above %s -j DROP\n"
252 ,ipaddr,tcplimit);
253 break;
257 if(atoi(udplimit) > 0){
258 if (chain == 2) {
259 switch (address_type)
261 case IP_ADDRESS:
262 ipt_write(
263 "-A PREROUTING -s %s -p udp -m limit --limit %s/sec -j ACCEPT\n"
264 ,ipaddr,udplimit);
265 break;
266 case MAC_ADDRESS:
267 ipt_write(
268 "-A PREROUTING -m mac --mac-source %s -p udp -m limit --limit %s/sec -j ACCEPT\n"
269 ,ipaddr,udplimit);
270 break;
271 case IP_RANGE:
272 ipt_write(
273 "-A PREROUTING -m iprange --src-range %s -p udp -m limit --limit %s/sec -j ACCEPT\n"
274 ,ipaddr,udplimit);
275 break;
280 free(buf);
283 // read nvram into files
284 void new_qoslimit_start(void)
286 FILE *tc;
287 char *buf;
288 char *g;
289 char *p;
290 char *ibw,*obw;//bandwidth
291 char seq[4];//mark number
292 int iSeq = 10;
293 char *ipaddr_old;
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
301 int priority_num;
302 char *dlr,*dlc,*ulr,*ulc; //download / upload - rate / ceiling
303 int i, address_type;
304 int s[6];
305 char *waniface; //shibby
307 //qos1 is enable
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;
327 fprintf(tc,
328 "#!/bin/sh\n"
329 "tc qdisc del dev br0 root 2>/dev/null\n"
330 "tc qdisc del dev %s root 2>/dev/null\n"
331 "\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"
335 "\n"
336 "SFQ=\"sfq perturb 10\"\n"
337 "\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"
341 "\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"
344 "\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"
347 "\n"
348 ,waniface
349 ,waniface
350 ,waniface
351 ,waniface
352 ,ibw
353 ,waniface
354 ,waniface,obw
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);
360 fprintf(tc,
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"
364 "\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"
368 "\n"
369 ,dlr,dlc
370 ,ulr,ulc);
373 while (g) {
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);
379 if (i!=8) continue;
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);
388 iSeq++;
389 if (!strcmp(dlceil,"")) strcpy(dlceil, dlrate);
390 if (strcmp(dlrate,"") && strcmp(dlceil, "")) {
391 if (address_type != MAC_ADDRESS) {
392 fprintf(tc,
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"
396 "\n"
397 ,seq,dlrate,dlceil,priority
398 ,seq,seq
399 ,priority,seq,seq);
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]);
404 fprintf(tc,
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"
408 "\n"
409 ,seq,dlrate,dlceil,priority
410 ,seq,seq
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, "")) {
417 fprintf(tc,
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"
421 "\n"
422 ,seq,ulrate,ulceil,priority
423 ,seq,seq
424 ,priority,seq,seq);
427 free(buf);
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);
443 //download for br1
444 fprintf(tc,
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"
454 ,ibw
455 ,dlr_1,dlc_1,prio_1
456 ,prio_1);
458 //upload from br1
459 fprintf(tc,
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"
463 ,ulr_1,ulc_1,prio_1
464 ,prio_1);
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);
481 //download for br2
482 fprintf(tc,
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"
492 ,ibw
493 ,dlr_2,dlc_2,prio_2
494 ,prio_2);
496 //upload from br2
497 fprintf(tc,
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"
501 ,ulr_2,ulc_2,prio_2
502 ,prio_2);
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);
519 //download for br3
520 fprintf(tc,
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"
530 ,ibw
531 ,dlr_3,dlc_3,prio_3
532 ,prio_3);
534 //upload from br3
535 fprintf(tc,
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"
539 ,ulr_3,ulc_3,prio_3
540 ,prio_3);
544 fclose(tc);
545 chmod(qoslimitfn, 0700);
547 //fake start
548 eval((char *)qoslimitfn, "start");
551 void new_qoslimit_stop(void)
553 FILE *f;
554 char *s = "/tmp/qoslimittc_stop.sh";
555 char *waniface;
557 waniface = nvram_safe_get("wan_iface"); //shibby
559 if ((f = fopen(s, "w")) == NULL) return;
561 fprintf(f,
562 "#!/bin/sh\n"
563 "tc qdisc del dev %s root\n"
564 "tc qdisc del dev br0 root\n"
565 "\n"
566 ,waniface
569 fclose(f);
570 chmod(s, 0700);
571 //fake stop
572 eval((char *)s, "stop");
576 PREROUTING (mn) ----> x ----> FORWARD (f) ----> + ----> POSTROUTING (n)
577 QD | ^
580 INPUT (f) OUTPUT (mnf)