Example #1
0
const char *get_wan6face(void)
{
	switch (get_ipv6_service()) {
	case IPV6_NATIVE:
	case IPV6_NATIVE_DHCP:
		return get_wanface();
	case IPV6_ANYCAST_6TO4:
		return "v6to4";
	case IPV6_6IN4:
		return "v6in4";
	}
	return nvram_safe_get("ipv6_ifname");
}
Example #2
0
void start_qos(void)
{
	int i;
	char *buf, *g, *p, *qos;
	unsigned int rate;
	unsigned int ceil;
	unsigned int bw;
	unsigned int incomingBandwidthInKilobitsPerSecond;
	unsigned int mtu;
	unsigned int r2q;
	unsigned int qosDefaultClassId;
	unsigned int overhead;
	FILE *f;
	int x;
	int inuse;
	char s[256];
	int first;
	char burst_root[32];
	char burst_leaf[32];

	qosDefaultClassId = (nvram_get_int("qos_default") + 1) * 10;
	incomingBandwidthInKilobitsPerSecond = strtoul(nvram_safe_get("qos_ibw"), NULL, 10);
	
	// move me?
	x = nvram_get_int("ne_vegas");
#ifdef LINUX26
	if (x) {
		char alpha[10], beta[10], gamma[10];
		sprintf(alpha, "alpha=%d", nvram_get_int("ne_valpha"));
		sprintf(beta, "beta=%d", nvram_get_int("ne_vbeta"));
		sprintf(gamma, "gamma=%d", nvram_get_int("ne_vgamma"));
		modprobe("tcp_vegas", alpha, beta, gamma);
		f_write_string("/proc/sys/net/ipv4/tcp_congestion_control", "vegas", 0, 0);
	}
	else {
		modprobe_r("tcp_vegas");
		f_write_string("/proc/sys/net/ipv4/tcp_congestion_control", "cubic", FW_NEWLINE, 0);
	}
#else
	f_write_string("/proc/sys/net/ipv4/tcp_vegas_cong_avoid", x ? "1" : "0", 0, 0);
	if (x) {
		f_write_string("/proc/sys/net/ipv4/tcp_vegas_alpha", nvram_safe_get("ne_valpha"), 0, 0);
		f_write_string("/proc/sys/net/ipv4/tcp_vegas_beta", nvram_safe_get("ne_vbeta"), 0, 0);
		f_write_string("/proc/sys/net/ipv4/tcp_vegas_gamma", nvram_safe_get("ne_vgamma"), 0, 0);
	}
#endif

	if (!nvram_get_int("qos_enable")) return;

	if ((f = fopen(qosfn, "w")) == NULL) return;

	i = nvram_get_int("qos_burst0");
	if (i > 0) sprintf(burst_root, "burst %dk", i);
		else burst_root[0] = 0;
	i = nvram_get_int("qos_burst1");
	if (i > 0) sprintf(burst_leaf, "burst %dk", i);
		else burst_leaf[0] = 0;

	mtu = strtoul(nvram_safe_get("wan_mtu"), NULL, 10);
	bw = strtoul(nvram_safe_get("qos_obw"), NULL, 10);
	overhead = strtoul(nvram_safe_get("atm_overhead"), NULL, 10);
	r2q = 10;

	if ((bw * 1000) / (8 * r2q) < mtu) {
		r2q = (bw * 1000) / (8 * mtu);
		if (r2q < 1) r2q = 1;
	} else if ((bw * 1000) / (8 * r2q) > 60000) {
		r2q = (bw * 1000) / (8 * 60000) + 1;
	}

	x = nvram_get_int("qos_pfifo");
	if (x == 1) {
		qos = "pfifo limit 256";
	} else if (x == 2) {
		qos = "codel";
	} else if (x == 3) {
		qos = "fq_codel";
	} else {
		qos = "sfq perturb 10";
	}
	if (overhead == 0) {
		fprintf(f,
			"#!/bin/sh\n"
			"WAN_DEV=%s\n"
			"IMQ_DEV=%s\n"
			"TQA=\"tc qdisc add dev $WAN_DEV\"\n"
			"TCA=\"tc class add dev $WAN_DEV\"\n"
			"TFA=\"tc filter add dev $WAN_DEV\"\n"
			"TQA_IMQ=\"tc qdisc add dev $IMQ_DEV\"\n"
			"TCA_IMQ=\"tc class add dev $IMQ_DEV\"\n"
			"TFA_IMQ=\"tc filter add dev $IMQ_DEV\"\n"
			"Q=\"%s\"\n"
			"\n"
			"case \"$1\" in\n"
			"start)\n"
			"\ttc qdisc del dev $WAN_DEV root 2>/dev/null\n"
			"\t$TQA root handle 1: htb default %u r2q %u\n"
			"\t$TCA parent 1: classid 1:1 htb rate %ukbit ceil %ukbit %s\n",
				get_wanface(),
				qosImqDeviceString,
				qos,
				qosDefaultClassId, r2q,
				bw, bw, burst_root);
	} else {
		fprintf(f,
			"#!/bin/sh\n"
			"WAN_DEV=%s\n"
			"IMQ_DEV=%s\n"
			"TQA=\"tc qdisc add dev $WAN_DEV\"\n"
			"TCA=\"tc class add dev $WAN_DEV\"\n"
			"TFA=\"tc filter add dev $WAN_DEV\"\n"
			"TQA_IMQ=\"tc qdisc add dev $IMQ_DEV\"\n"
			"TCA_IMQ=\"tc class add dev $IMQ_DEV\"\n"
			"TFA_IMQ=\"tc filter add dev $IMQ_DEV\"\n"
			"Q=\"%s\"\n"
			"\n"
			"case \"$1\" in\n"
			"start)\n"
			"\ttc qdisc del dev $WAN_DEV root 2>/dev/null\n"
			"\t$TQA root handle 1: htb default %u r2q %u\n"
			"\t$TCA parent 1: classid 1:1 htb rate %ukbit ceil %ukbit %s overhead %u linklayer atm\n",
				get_wanface(),
				qosImqDeviceString,
				qos,
				qosDefaultClassId, r2q,
				bw, bw, burst_root, overhead);
		}

	inuse = nvram_get_int("qos_inuse");

	g = buf = strdup(nvram_safe_get("qos_orates"));
	for (i = 0; i < 10; ++i) {
		if ((!g) || ((p = strsep(&g, ",")) == NULL)) break;

		if ((inuse & (1 << i)) == 0) continue;

		// check if we've got a percentage definition in the form of "rate-ceiling"
		if ((sscanf(p, "%u-%u", &rate, &ceil) != 2) || (rate < 1)) continue;	// 0=off

		if (ceil > 0) sprintf(s, "ceil %ukbit ", calc(bw, ceil));
			else s[0] = 0;
		x = (i + 1) * 10;

		if (overhead == 0) {
			fprintf(f,
				"# egress %d: %u-%u%%\n"
				"\t$TCA parent 1:1 classid 1:%d htb rate %ukbit %s %s prio %d quantum %u\n"
				"\t$TQA parent 1:%d handle %d: $Q\n"
				"\t$TFA parent 1: prio %d handle %d fw flowid 1:%d\n",
					i, rate, ceil,
					x, calc(bw, rate), s, burst_leaf, i+1, mtu,
					x, x,
					x, i + 1, x);
		} else {
			fprintf(f,
				"# egress %d: %u-%u%%\n"
				"\t$TCA parent 1:1 classid 1:%d htb rate %ukbit %s %s prio %d quantum %u overhead %u linklayer atm\n"
				"\t$TQA parent 1:%d handle %d: $Q\n"
				"\t$TFA parent 1: prio %d handle %d fw flowid 1:%d\n",
					i, rate, ceil,
					x, calc(bw, rate), s, burst_leaf, i+1, mtu, overhead,
					x, x,
					x, i + 1, x);
		}
	}
	free(buf);

//		"\t$TFA parent 1: prio 10 protocol ip u32 match ip tos 0x10 0xff flowid :10\n"	// TOS EF -> Highest


/*
		if (nvram_match("qos_ack", "1")) {
			fprintf(f,
				"\n"
				"\t$TFA parent 1: prio 15 protocol ip u32 "
				"match ip protocol 6 0xff "		// TCP
				"match u8 0x05 0x0f at 0 "		// IP header length
				"match u16 0x0000 0xffc0 at 2 "	// total length (0-63)
				"match u8 0x10 0xff at 33 "		// ACK only
				"flowid 1:10\n");
		}
		if (nvram_match("qos_icmp", "1")) {
			fputs("\n\t$TFA parent 1: prio 14 protocol ip u32 match ip protocol 1 0xff flowid 1:10\n", f);
		}
*/

/*
	if (nvram_get_int("qos_ack")) {
		fprintf(f,
			"\n"
			"\t$TFA parent 1: prio 14 protocol ip u32 "
			"match ip protocol 6 0xff "			// TCP
			"match u8 0x05 0x0f at 0 "			// IP header length
			"match u16 0x0000 0xff80 at 2 "		// total length (0-127)
			"match u8 0x10 0xff at 33 "			// ACK only
			"flowid 1:10\n");
	}

	if (nvram_get_int("qos_syn")) {
		//	10000 = ACK
		//	00010 = SYN

		fprintf(f,
			"\n"
			"\t$TFA parent 1: prio 15 protocol ip u32 "
			"match ip protocol 6 0xff "			// TCP
			"match u8 0x05 0x0f at 0 "			// IP header length
			"match u16 0x0000 0xff80 at 2 "		// total length (0-127)
			"match u8 0x02 0xff at 33 "			// SYN only
			"flowid 1:10\n"
			"\n"
			"\t$TFA parent 1: prio 16 protocol ip u32 "
			"match ip protocol 6 0xff "			// TCP
			"match u8 0x05 0x0f at 0 "			// IP header length
			"match u16 0x0000 0xff80 at 2 "		// total length (0-127)
			"match u8 0x12 0xff at 33 "			// SYN,ACK
			"flowid 1:10\n");
	}

	if (nvram_get_int("qos_fin")) {
		//	10000 = ACK
		//	00001 = FIN

		fprintf(f,
			"\n"
			"\t$TFA parent 1: prio 17 protocol ip u32 "
			"match ip protocol 6 0xff "			// TCP
			"match u8 0x05 0x0f at 0 "			// IP header length
			"match u8 0x11 0xff at 33 "			// ACK,FIN
			"flowid 1:10\n"
			"\n"
			"\t$TFA parent 1: prio 18 protocol ip u32 "
			"match ip protocol 6 0xff "			// TCP
			"match u8 0x05 0x0f at 0 "			// IP header length
			"match u8 0x01 0xff at 33 "			// FIN
			"flowid 1:10\n");
	}

	if (nvram_get_int("qos_rst")) {
		//	10000 = ACK
		//	00100 = RST
		fprintf(f,
			"\n"
			"\t$TFA parent 1: prio 19 protocol ip u32 "
			"match ip protocol 6 0xff "			// TCP
			"match u8 0x05 0x0f at 0 "			// IP header length
			"match u8 0x14 0xff at 33 "			// ACK,RST
			"flowid 1:10\n"
			"\n"
			"\t$TFA parent 1: prio 20 protocol ip u32 "
			"match ip protocol 6 0xff "			// TCP
			"match u8 0x05 0x0f at 0 "			// IP header length
			"match u8 0x04 0xff at 33 "			// RST
			"flowid 1:10\n");
	}


	if (nvram_get_int("qos_icmp")) {
		fputs("\n\t$TFA parent 1: prio 13 protocol ip u32 match ip protocol 1 0xff flowid 1:10\n", f);
	}
*/

	/*
		10000 = ACK
		00100 = RST
		00010 = SYN
		00001 = FIN
	*/

	if (nvram_get_int("qos_ack")) {
		fprintf(f,
			"\n"
			"\t$TFA parent 1: prio 14 u32 "
			"match ip protocol 6 0xff "			// TCP
			"match u8 0x05 0x0f at 0 "			// IP header length
//			"match u16 0x0000 0xff80 at 2 "		// total length (0-127)
			"match u16 0x0000 0xffc0 at 2 "		// total length (0-63)
			"match u8 0x10 0xff at 33 "			// ACK only
			"flowid 1:10\n");
	}

	if (nvram_get_int("qos_syn")) {
		fprintf(f,
			"\n"
			"\t$TFA parent 1: prio 15 u32 "
			"match ip protocol 6 0xff "			// TCP
			"match u8 0x05 0x0f at 0 "			// IP header length
			"match u16 0x0000 0xffc0 at 2 "		// total length (0-63)
			"match u8 0x02 0x02 at 33 "			// SYN,*
			"flowid 1:10\n");
	}

	if (nvram_get_int("qos_fin")) {
		fprintf(f,
			"\n"
			"\t$TFA parent 1: prio 17 u32 "
			"match ip protocol 6 0xff "			// TCP
			"match u8 0x05 0x0f at 0 "			// IP header length
			"match u16 0x0000 0xffc0 at 2 "		// total length (0-63)
			"match u8 0x01 0x01 at 33 "			// FIN,*
			"flowid 1:10\n");
	}

	if (nvram_get_int("qos_rst")) {
		fprintf(f,
			"\n"
			"\t$TFA parent 1: prio 19 u32 "
			"match ip protocol 6 0xff "			// TCP
			"match u8 0x05 0x0f at 0 "			// IP header length
			"match u16 0x0000 0xffc0 at 2 "		// total length (0-63)
			"match u8 0x04 0x04 at 33 "			// RST,*
			"flowid 1:10\n");
	}

	if (nvram_get_int("qos_icmp")) {
		fputs("\n\t$TFA parent 1: prio 13 u32 match ip protocol 1 0xff flowid 1:10\n", f);
	}


	////
	//// INCOMING TRAFFIC SHAPING
	////
	
	first = 1;
	overhead = strtoul(nvram_safe_get("atm_overhead"), NULL, 10);

	g = buf = strdup(nvram_safe_get("qos_irates"));
	
	for (i = 0; i < 10; ++i)
	{	
		if ((!g) || ((p = strsep(&g, ",")) == NULL))
		{
			break;
		}
		
		if ((inuse & (1 << i)) == 0)
		{
			continue;
		}

		// check if we've got a percentage definition in the form of "rate-ceiling"
		if ((sscanf(p, "%u-%u", &rate, &ceil) != 2) || (rate < 1))
		{
			continue;	// 0=off
		}
		
		// class ID
		unsigned int classid = ((unsigned int)i + 1) * 10;
		
		// priority
		unsigned int priority = (unsigned int)i + 1;			//prios 1-10 - Toastman
		
		// rate in kb/s
		unsigned int rateInKilobitsPerSecond =
			calc(incomingBandwidthInKilobitsPerSecond, rate);
		
		// ceiling in kb/s
		unsigned int ceilingInKilobitsPerSecond =
			calc(incomingBandwidthInKilobitsPerSecond, ceil);

		// burst rate (2% of the classes' rate) - don't know if we should use this
//Commented out KDB 20130531 - produces compiler warning about being unused!
//		unsigned int burstRateInBitsPerSecond =
//			(rateInKilobitsPerSecond * 1000) / 50;

		r2q = 10;
		if ((incomingBandwidthInKilobitsPerSecond * 1000) / (8 * r2q) < mtu) 
		{
			r2q = (incomingBandwidthInKilobitsPerSecond * 1000) / (8 * mtu);
			if (r2q < 1) r2q = 1;
		} 
		else if ((incomingBandwidthInKilobitsPerSecond * 1000) / (8 * r2q) > 60000) 
		{
			r2q = (incomingBandwidthInKilobitsPerSecond * 1000) / (8 * 60000) + 1;
		}

		if (first)
		{
			first = 0;
			fprintf(f,
				"\n"
				"\ttc qdisc del dev $I ingress 2>/dev/null\n"
				"\t$TQA handle ffff: ingress\n");
			if (overhead == 0) {
				fprintf(f,
				"\n"
				"\tip link set $IMQ_DEV up\n"
				"\ttc qdisc del dev $IMQ_DEV 2>/dev/null\n"
				"\t$TQA_IMQ handle 1: root htb default %u r2q %u\n"
				"\t$TCA_IMQ parent 1: classid 1:1 htb rate %ukbit ceil %ukbit\n",
				qosDefaultClassId, r2q,
				incomingBandwidthInKilobitsPerSecond,
				incomingBandwidthInKilobitsPerSecond);
			} else {
				fprintf(f,
					"\n"
					"\tip link set $IMQ_DEV up\n"
					"\ttc qdisc del dev $IMQ_DEV 2>/dev/null\n"
					"\t$TQA_IMQ handle 1: root htb default %u r2q %u\n"
					"\t$TCA_IMQ parent 1: classid 1:1 htb rate %ukbit ceil %ukbit overhead %u linklayer atm\n",
					qosDefaultClassId, r2q,
					incomingBandwidthInKilobitsPerSecond,
					incomingBandwidthInKilobitsPerSecond, overhead);
				}

			fprintf(f,
			"\n"
			"\t$TFA parent ffff: prio 10 u32 match ip %s action mirred egress redirect dev $IMQ_DEV\n", (nvram_get_int("qos_udp") == 1) ? "protocol 6 0xff" : "dst 0.0.0.0/0");
		}
		
		fprintf(
			f,
			"\n"
			"\t# class id %u: rate %ukbit ceil %ukbit\n",
			classid, rateInKilobitsPerSecond, ceilingInKilobitsPerSecond);

		if (overhead == 0) {
			fprintf(
				f,
				"\t$TCA_IMQ parent 1:1 classid 1:%u htb rate %ukbit ceil %ukbit prio %u quantum %u\n",
				classid, rateInKilobitsPerSecond, ceilingInKilobitsPerSecond, priority, mtu);
		} else {
			fprintf(
				f,
				"\t$TCA_IMQ parent 1:1 classid 1:%u htb rate %ukbit ceil %ukbit prio %u quantum %u overhead %u linklayer atm\n",
				classid, rateInKilobitsPerSecond, ceilingInKilobitsPerSecond, priority, mtu, overhead);
			}

		fprintf(
			f,
			"\t$TQA_IMQ parent 1:%u handle %u: $Q\n",
			classid, classid);

		fprintf(
			f,
			"\t$TFA_IMQ parent 1: prio %u handle %u fw flowid 1:%u \n",           
			classid, priority, classid);
	}

	free(buf);

	//// write commands which adds rule to forward traffic to IMQ device
	fputs(
		"\n"
		"\t# set up the IMQ device (otherwise this won't work) to limit the incoming data\n"
		"\tip link set $IMQ_DEV up\n",
		f);

	fprintf(f,
		"\t;;\n"
		"stop)\n"
		"\tip link set $IMQ_DEV down\n"
		"\ttc qdisc del dev $WAN_DEV root 2>/dev/null\n"
		"\ttc qdisc del dev $IMQ_DEV root 2>/dev/null\n"
		"\ttc filter del dev $WAN_DEV parent ffff: prio 10 u32 match ip %s action mirred egress redirect dev $IMQ_DEV 2>/dev/null\n"
		"\t;;\n"
		"*)\n"
		"\techo \"...\"\n"
		"\techo \"... OUTGOING QDISCS AND CLASSES FOR $WAN_DEV\"\n"
		"\techo \"...\"\n"
		"\ttc -s -d qdisc ls dev $WAN_DEV\n"
		"\techo\n"
		"\ttc -s -d class ls dev $WAN_DEV\n"
		"\techo\n"
		"\techo \"...\"\n"
		"\techo \"... INCOMING QDISCS AND CLASSES FOR $WAN_DEV (routed through $IMQ_DEV)\"\n"
		"\techo \"...\"\n"
		"\ttc -s -d qdisc ls dev $IMQ_DEV\n"
		"\techo\n"
		"\ttc -s -d class ls dev $IMQ_DEV\n"
		"\techo\n"
		"esac\n",
		(nvram_get_int("qos_udp") == 1) ? "protocol 6 0xff" : "dst 0.0.0.0/0");

	fclose(f);
	chmod(qosfn, 0700);
	eval((char *)qosfn, "start");
}
Example #3
0
int svqos_iptables(void)
{
	char *qos_pkts = nvram_safe_get("svqos_pkts");
	char *qos_svcs = nvram_safe_get("svqos_svcs");
	char name[32], type[32], data[32], level[32], pkt_filter[4];

	char *wshaper_dev = nvram_get("wshaper_dev");
	char *wan_dev = get_wanface();

	char nullmask[24];
	strcpy(nullmask, qos_nfmark(0));

	insmod("ipt_mark");
	insmod("xt_mark");
	insmod("ipt_CONNMARK");
	insmod("xt_CONNMARK");
	insmod("ipt_mac");
	insmod("xt_mac");

#if !(defined(ARCH_broadcom) && !defined(HAVE_BCMMODERN))
	// if kernel version later then 2.4, overwrite all old tc filter

	sysprintf("tc filter del dev %s pref %d", wan_dev, 1);
	sysprintf("tc filter del dev %s pref %d", wan_dev, 3);
	sysprintf("tc filter del dev %s pref %d", wan_dev, 5);
	sysprintf("tc filter del dev %s pref %d", wan_dev, 8);
	sysprintf("tc filter del dev %s pref %d", wan_dev, 9);

	sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", wan_dev, get_tcfmark(100), 100);
	sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", wan_dev, get_tcfmark(10), 10);
	sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", wan_dev, get_tcfmark(20), 20);
	sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", wan_dev, get_tcfmark(30), 30);
	sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", wan_dev, get_tcfmark(40), 40);

	sysprintf("tc filter del dev %s pref %d", "imq0", 1);
	sysprintf("tc filter del dev %s pref %d", "imq0", 3);
	sysprintf("tc filter del dev %s pref %d", "imq0", 5);
	sysprintf("tc filter del dev %s pref %d", "imq0", 8);
	sysprintf("tc filter del dev %s pref %d", "imq0", 9);

	sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq0", get_tcfmark(100), 100);
	sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq0", get_tcfmark(10), 10);
	sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq0", get_tcfmark(20), 20);
	sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq0", get_tcfmark(30), 30);
	sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq0", get_tcfmark(40), 40);

	if (nvram_match("wshaper_dev", "LAN")) {
		sysprintf("tc filter del dev %s pref %d", "imq1", 1);
		sysprintf("tc filter del dev %s pref %d", "imq1", 3);
		sysprintf("tc filter del dev %s pref %d", "imq1", 5);
		sysprintf("tc filter del dev %s pref %d", "imq1", 8);
		sysprintf("tc filter del dev %s pref %d", "imq1", 9);

		sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq1", get_tcfmark(100), 100);
		sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq1", get_tcfmark(10), 10);
		sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq1", get_tcfmark(20), 20);
		sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq1", get_tcfmark(30), 30);
		sysprintf("tc filter add dev %s protocol ip parent 1: u32 match mark %s flowid 1:%d", "imq1", get_tcfmark(40), 40);
	}
#endif

#ifdef HAVE_OPENDPI
	insmod("/lib/opendpi/xt_opendpi.ko");
#endif
	insmod("ipt_layer7");
	insmod("xt_layer7");

	// set-up mark/filter tables

	system2("iptables -t mangle -F SVQOS_SVCS");
	system2("iptables -t mangle -X SVQOS_SVCS");
	system2("iptables -t mangle -N SVQOS_SVCS");

	system2("iptables -t mangle -F FILTER_OUT");
	system2("iptables -t mangle -X FILTER_OUT");
	system2("iptables -t mangle -N FILTER_OUT");
	system2("iptables -t mangle -A FILTER_OUT -j CONNMARK --restore");
	sysprintf("iptables -t mangle -A FILTER_OUT -m mark --mark %s -j SVQOS_SVCS", nullmask);

	system2("iptables -t mangle -F FILTER_IN");
	system2("iptables -t mangle -X FILTER_IN");
	system2("iptables -t mangle -N FILTER_IN");
	system2("iptables -t mangle -A FILTER_IN -j CONNMARK --restore");
	sysprintf("iptables -t mangle -A FILTER_IN -m mark --mark %s -j SVQOS_SVCS", nullmask);

	sysprintf("iptables -t mangle -D PREROUTING -j FILTER_IN");
	sysprintf("iptables -t mangle -I PREROUTING -j FILTER_IN");
	sysprintf("iptables -t mangle -D POSTROUTING -j FILTER_OUT");
	sysprintf("iptables -t mangle -I POSTROUTING -j FILTER_OUT");

	system2("iptables -t mangle -A POSTROUTING -m dscp --dscp ! 0 -j DSCP --set-dscp 0");

	if (!strcmp(wshaper_dev, "WAN")) {
		sysprintf("iptables -t mangle -D INPUT -i %s -j IMQ --todev 0", wan_dev);
		sysprintf("iptables -t mangle -A INPUT -i %s -j IMQ --todev 0", wan_dev);
		sysprintf("iptables -t mangle -D FORWARD -i %s -j IMQ --todev 0", wan_dev);
		sysprintf("iptables -t mangle -A FORWARD -i %s -j IMQ --todev 0", wan_dev);
	}
	if (!strcmp(wshaper_dev, "LAN")) {
		if (!client_bridged_enabled()
		    && nvram_invmatch("wan_proto", "disabled")) {
			sysprintf("iptables -t mangle -D INPUT -i %s -j IMQ --todev 0", wan_dev);
			sysprintf("iptables -t mangle -A INPUT -i %s -j IMQ --todev 0", wan_dev);
			sysprintf("iptables -t mangle -D FORWARD -i %s -j IMQ --todev 0", wan_dev);
			sysprintf("iptables -t mangle -A FORWARD -i %s -j IMQ --todev 0", wan_dev);

			sysprintf("iptables -t mangle -D INPUT -i ! %s -j IMQ --todev 1", wan_dev);
			sysprintf("iptables -t mangle -A INPUT -i ! %s -j IMQ --todev 1", wan_dev);
			sysprintf("iptables -t mangle -D FORWARD -i ! %s -o ! %s -j IMQ --todev 1", wan_dev, wan_dev);
			sysprintf("iptables -t mangle -A FORWARD -i ! %s -o ! %s -j IMQ --todev 1", wan_dev, wan_dev);
		} else {
			sysprintf("iptables -t mangle -D INPUT -j IMQ --todev 1");
			sysprintf("iptables -t mangle -A INPUT -j IMQ --todev 1");
			sysprintf("iptables -t mangle -D FORWARD -j IMQ --todev 1");
			sysprintf("iptables -t mangle -A FORWARD -j IMQ --todev 1");
		}
	}

	/* add openvpn filter rules */
#ifdef HAVE_AQOS
#ifdef HAVE_OPENVPN
	if (nvram_invmatch("openvpn_enable", "0") || nvram_invmatch("openvpncl_enable", "0")) {
		char iflist[256];
		static char word[256];
		char *next;
		bool unbridged_tap = 0;

		insmod("xt_dscp");
		insmod("xt_DSCP");

		system2("iptables -t mangle -F VPN_IN");
		system2("iptables -t mangle -X VPN_IN");
		system2("iptables -t mangle -N VPN_IN");
		system2("iptables -t mangle -A VPN_IN -j CONNMARK --save");

		system2("iptables -t mangle -F VPN_OUT");
		system2("iptables -t mangle -X VPN_OUT");
		system2("iptables -t mangle -N VPN_OUT");

		system2("iptables -t mangle -F VPN_DSCP");
		system2("iptables -t mangle -X VPN_DSCP");
		system2("iptables -t mangle -N VPN_DSCP");
		sysprintf("iptables -t mangle -A VPN_DSCP -m dscp --dscp 10 -j MARK --set-mark %s", qos_nfmark(100));
		sysprintf("iptables -t mangle -A VPN_DSCP -m dscp --dscp 1 -j MARK --set-mark %s", qos_nfmark(10));
		sysprintf("iptables -t mangle -A VPN_DSCP -m dscp --dscp 2 -j MARK --set-mark %s", qos_nfmark(20));
		sysprintf("iptables -t mangle -A VPN_DSCP -m dscp --dscp 3 -j MARK --set-mark %s", qos_nfmark(30));
		sysprintf("iptables -t mangle -A VPN_DSCP -m dscp --dscp 4 -j MARK --set-mark %s", qos_nfmark(40));
		system2("iptables -t mangle -A VPN_DSCP -m dscp --dscp ! 0 -j DSCP --set-dscp 0");
		system2("iptables -t mangle -A VPN_DSCP -j RETURN");

		// look for present tun-devices
		if (getifcount("tun")) {
			system2("iptables -t mangle -I PREROUTING 2 -i tun+ -j VPN_IN");
			system2("iptables -t mangle -I INPUT 1 -i tun+ -j IMQ --todev 0");
			system2("iptables -t mangle -I FORWARD 1 -i tun+ -j IMQ --todev 0");
			system2("iptables -t mangle -I POSTROUTING 1 -o tun+ -j VPN_OUT");
		}
		// look for present tap-devices
		if (getifcount("tap")) {
			writeproc("/proc/sys/net/bridge/bridge-nf-call-arptables", "1");
			writeproc("/proc/sys/net/bridge/bridge-nf-call-ip6tables", "1");
			writeproc("/proc/sys/net/bridge/bridge-nf-call-iptables", "1");

			insmod("xt_physdev");
			insmod("ebtables");

			getIfList(iflist, "tap");
			foreach(word, iflist, next) {
				if (is_in_bridge(word)) {
					sysprintf("iptables -t mangle -I PREROUTING 2 -m physdev --physdev-in %s -j VPN_IN", word);
					sysprintf("iptables -t mangle -I INPUT 1 -m physdev --physdev-in %s -j IMQ --todev 0", word);
					sysprintf("iptables -t mangle -I FORWARD 1 -m physdev --physdev-in %s -j IMQ --todev 0", word);
					sysprintf("iptables -t mangle -I POSTROUTING -m physdev --physdev-out %s -j VPN_OUT", word);
				} else
					unbridged_tap = 1;
			}

			if (unbridged_tap) {
				system2("iptables -t mangle -I PREROUTING 2 -i tap+ -j VPN_IN");
				system2("iptables -t mangle -I INPUT 1 -i tap+ -j IMQ --todev 0");
				system2("iptables -t mangle -I FORWARD 1 -i tap+ -j IMQ --todev 0");
				system2("iptables -t mangle -I POSTROUTING 1 -o tap+ -j VPN_OUT");
			}
		}