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
81 if (!nvram_get_int("qosl_enable")) return;
83 //read qos1rules from nvram
84 g
= buf
= strdup(nvram_safe_get("qosl_rules"));
86 ibw
= nvram_safe_get("qos_ibw"); // Read from QOS setting - KRP
87 obw
= nvram_safe_get("qos_obw"); // Read from QOS setting - KRP
89 lanipaddr
= nvram_safe_get("lan_ipaddr");
90 lanmask
= nvram_safe_get("lan_netmask");
91 laninface
= nvram_safe_get("lan_ifname");
98 "-A PREROUTING -j IMQ -i %s --todev 1\n"
99 "-A POSTROUTING -j IMQ -o %s --todev 2\n"
100 ,laninface
,laninface
);
105 ipaddr_old<dlrate<dlceil<ulrate<ulceil<priority<tcplimit<udplimit
107 if ((p
= strsep(&g
, ">")) == NULL
) break;
108 i
= vstrsep(p
, "<", &ipaddr_old
, &dlrate
, &dlceil
, &ulrate
, &ulceil
, &priority
, &tcplimit
, &udplimit
);
111 priority_num
= atoi(priority
);
112 if ((priority_num
< 0) || (priority_num
> 5)) continue;
114 if (!strcmp(ipaddr_old
,"")) continue;
116 address_checker (&address_type
, ipaddr_old
, ipaddr
);
117 sprintf(seq
,"%d",iSeq
);
120 if (!strcmp(dlceil
,"")) strcpy(dlceil
, dlrate
);
121 if (strcmp(dlrate
,"") && strcmp(dlceil
, "")) {
123 switch (address_type
)
127 "-A POSTROUTING ! -s %s/%s -d %s -j MARK --set-mark %s\n"
128 ,lanipaddr
,lanmask
,ipaddr
,seq
);
134 "-A POSTROUTING ! -s %s/%s -m iprange --dst-range %s -j MARK --set-mark %s\n"
135 ,lanipaddr
,lanmask
,ipaddr
,seq
);
141 if (!strcmp(ulceil
,"")) strcpy(ulceil
, ulrate
);
142 if (strcmp(ulrate
,"") && strcmp(ulceil
, "")) {
144 switch (address_type
)
148 "-A PREROUTING -s %s ! -d %s/%s -j MARK --set-mark %s\n"
149 ,ipaddr
,lanipaddr
,lanmask
,seq
);
153 "-A PREROUTING -m mac --mac-source %s ! -d %s/%s -j MARK --set-mark %s\n"
154 ,ipaddr
,lanipaddr
,lanmask
,seq
);
158 "-A PREROUTING -m iprange --src-range %s ! -d %s/%s -j MARK --set-mark %s\n"
159 ,ipaddr
,lanipaddr
,lanmask
,seq
);
165 if(atoi(tcplimit
) > 0){
167 switch (address_type
)
171 "-A PREROUTING -s %s -p tcp --syn -m connlimit --connlimit-above %s -j DROP\n"
176 "-A PREROUTING -m mac --mac-source %s -p tcp --syn -m connlimit --connlimit-above %s -j DROP\n"
181 "-A PREROUTING -m iprange --src-range %s -p tcp --syn -m connlimit --connlimit-above %s -j DROP\n"
187 if(atoi(udplimit
) > 0){
189 switch (address_type
)
193 "-A PREROUTING -s %s -p udp -m limit --limit %s/sec -j ACCEPT\n"
198 "-A PREROUTING -m mac --mac-source %s -p udp -m limit --limit %s/sec -j ACCEPT\n"
203 "-A PREROUTING -m iprange --src-range %s -p udp -m limit --limit %s/sec -j ACCEPT\n"
213 // read nvram into files
214 void start_qoslimit(void)
220 char *ibw
,*obw
;//bandwidth
221 char seq
[4];//mark number
224 char ipaddr
[30];//ip address
225 char *dlrate
,*dlceil
;//guaranteed rate & maximum rate for download
226 char *ulrate
,*ulceil
;//guaranteed rate & maximum rate for upload
227 char *priority
;//priority
228 char *lanipaddr
; //lan ip address
229 char *lanmask
; //lan netmask
230 char *tcplimit
,*udplimit
;//tcp connection limit & udp packets per second
236 if (!nvram_get_int("qosl_enable")) return;
238 //read qosl rules from nvram
239 g
= buf
= strdup(nvram_safe_get("qosl_rules"));
241 ibw
= nvram_safe_get("qos_ibw"); // Read from QOS setting - KRP
242 obw
= nvram_safe_get("qos_obw"); // Read from QOS setting - KRP
244 lanipaddr
= nvram_safe_get("lan_ipaddr");
245 lanmask
= nvram_safe_get("lan_netmask");
247 if ((tc
= fopen(qoslimitfn
, "w")) == NULL
) return;
251 "ip link set imq1 up\n"
252 "ip link set imq2 up\n"
254 "tc qdisc del dev imq1 root 2>/dev/null\n"
255 "tc qdisc del dev imq2 root 2>/dev/null\n"
256 "tc qdisc del dev br0 root 2>/dev/null\n" //fix me [why should mac get filter here??]
258 "TCAM=\"tc class add dev br0\"\n" //fix me
259 "TFAM=\"tc filter add dev br0\"\n" //fix me
260 "TQAM=\"tc qdisc add dev br0\"\n" //fix me
262 "TCA=\"tc class add dev imq2\"\n"
263 "TFA=\"tc filter add dev imq2\"\n"
264 "TQA=\"tc qdisc add dev imq2\"\n"
266 "SFQ=\"sfq perturb 10\"\n"
268 "TCAU=\"tc class add dev imq1\"\n"
269 "TFAU=\"tc filter add dev imq1\"\n"
270 "TQAU=\"tc qdisc add dev imq1\"\n"
272 "tc qdisc add dev imq2 root handle 1: htb\n"
273 "tc class add dev imq2 parent 1: classid 1:1 htb rate %skbit\n"
275 "tc qdisc add dev br0 root handle 1: htb\n"
276 "tc class add dev br0 parent 1: classid 1:1 htb rate %skbit\n"
278 "tc qdisc add dev imq1 root handle 1: htb\n"
279 "tc class add dev imq1 parent 1: classid 1:1 htb rate %skbit\n"
286 ipaddr_old<dlrate<dlceil<ulrate<ulceil<priority<tcplimit<udplimit
288 if ((p
= strsep(&g
, ">")) == NULL
) break;
289 i
= vstrsep(p
, "<", &ipaddr_old
, &dlrate
, &dlceil
, &ulrate
, &ulceil
, &priority
, &tcplimit
, &udplimit
);
291 priority_num
= atoi(priority
);
292 if ((priority_num
< 0) || (priority_num
> 5)) continue;
293 if (!strcmp(ipaddr_old
,"")) continue;
295 address_checker(&address_type
, ipaddr_old
, ipaddr
);
296 sprintf(seq
,"%d",iSeq
);
298 if (!strcmp(dlceil
,"")) strcpy(dlceil
, dlrate
);
299 if (strcmp(dlrate
,"") && strcmp(dlceil
, "")) {
300 if (address_type
!= MAC_ADDRESS
) {
302 "$TCA parent 1:1 classid 1:%s htb rate %skbit ceil %skbit prio %s\n"
303 "$TQA parent 1:%s handle %s: $SFQ\n"
304 "$TFA parent 1:0 prio %s protocol ip handle %s fw flowid 1:%s\n"
306 ,seq
,dlrate
,dlceil
,priority
310 else if (address_type
== MAC_ADDRESS
) {
311 sscanf(ipaddr
, "%02X:%02X:%02X:%02X:%02X:%02X",&s
[0],&s
[1],&s
[2],&s
[3],&s
[4],&s
[5]);
314 "$TCAM parent 1:1 classid 1:%s htb rate %skbit ceil %skbit prio %s\n"
315 "$TQAM parent 1:%s handle %s: $SFQ\n"
316 "$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"
318 ,seq
,dlrate
,dlceil
,priority
320 ,priority
,s
[2],s
[3],s
[4],s
[5],s
[0],s
[1],seq
);
324 if (!strcmp(ulceil
,"")) strcpy(ulceil
, dlrate
);
325 if (strcmp(ulrate
,"") && strcmp(ulceil
, "")) {
327 "$TCAU parent 1:1 classid 1:%s htb rate %skbit ceil %skbit prio %s\n"
328 "$TQAU parent 1:%s handle %s: $SFQ\n"
329 "$TFAU parent 1:0 prio %s protocol ip handle %s fw flowid 1:%s\n"
331 ,seq
,ulrate
,ulceil
,priority
339 chmod(qoslimitfn
, 0700);
342 eval((char *)qoslimitfn
, "start");
345 void stop_qoslimit(void)
348 char *s
= "/tmp/stop_qoslimittc.sh";
350 if ((f
= fopen(s
, "w")) == NULL
) return;
354 "tc qdisc del dev imq2 root\n"
355 "tc qdisc del dev imq1 root\n"
356 "tc qdisc del dev br0 root\n" //fix me
357 "ip link set imq1 down\n"
358 "ip link set imq2 down\n" //take imq's down - Toastman
366 eval((char *)s
, "stop");
370 PREROUTING (mn) ----> x ----> FORWARD (f) ----> + ----> POSTROUTING (n)
374 INPUT (f) OUTPUT (mnf)