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"); }
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"); }
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"); } }