1EXTRA_CMD_ARGS="--nss" 2 3# adds a class and qdisc for a zone 4# $1: dev 5# $2: zone identifier 6add_zone() { 7 local dev=$1 8 local zone=$2 9 local classid=$(sb_gen_zone_classid ${zone}) 10 local weight=$(sb_get_zone_weight ${dev} ${zone}) 11 local rate=$(sb_get_zone_rate ${dev} ${zone}) 12 13 # the zone class specifies the interzone weight for this zone 14 tc class add dev ${dev} \ 15 parent ${BF_HANDLE_MAJOR}: \ 16 classid ${BF_HANDLE_MAJOR}:${classid} \ 17 nssbf rate 1000mbit burst 1000kb quantum ${weight} mtu 1514 18 [ $? = 0 ] || return $? 19 20 # if we have an upper bw limit, add a tbl 21 if [ -n "${rate}" ] && [ "${rate}" -gt 0 ]; then 22 local burst 23 local tblclassid=$(sb_gen_zone_tbl_classid ${zone}) 24 25 # add the tbl 26 let burst=${rate}/10 27 tc qdisc add dev ${dev} \ 28 parent ${BF_HANDLE_MAJOR}:${classid} \ 29 handle ${tblclassid}: \ 30 nsstbl rate ${rate} burst ${burst} mtu 1514 31 [ $? = 0 ] || return $? 32 33 # add the qdisc for background & classified 34 tc qdisc add dev ${dev} \ 35 parent ${tblclassid}:1 \ 36 handle ${classid}: \ 37 nssbf 38 [ $? = 0 ] || return $? 39 else 40 # add the qdisc for background & classified 41 tc qdisc add dev ${dev} \ 42 parent ${BF_HANDLE_MAJOR}:${classid} \ 43 handle ${classid}: \ 44 nssbf 45 [ $? = 0 ] || return $? 46 fi 47 48 # zone background 49 tc class add dev ${dev} \ 50 parent ${classid}: \ 51 classid ${classid}:${CLASSID_BACKGROUND} \ 52 nssbf rate 1000mbit burst 1000kb \ 53 mtu 1514 quantum ${BACKGROUND_WEIGHT} 54 [ $? = 0 ] || return $? 55 56 # zone classified 57 tc class add dev ${dev} \ 58 parent ${classid}: \ 59 classid ${classid}:${CLASSID_CLASSIFIED} \ 60 nssbf rate 1000mbit burst 1000kb \ 61 mtu 1514 quantum ${COMMITTED_WEIGHT} 62 [ $? = 0 ] || return $? 63} 64 65# sets up the qdisc structures on an interface 66# Note: this only sets a default rate on the root class, not necessarily the 67# correct rate; qdiscman handles this when it starts up 68# 69# $1: dev 70setup_iface() { 71 local dev=$1 72 tc qdisc add dev ${dev} root \ 73 handle ${PRIO_HANDLE_MAJOR}: \ 74 nssprio bands 3 75 [ $? = 0 ] || return $? 76 # interactive for localhost OUTPUT. the target qdisc is not limited 77 # by streamboost and is used for two cases (see iptables rules): 78 # 1. localhost to LAN so the UI is responsive. 79 # 2. localhost to WAN for the bandwidth tester ports only so the 80 # tester can measure accurately. 81 add_interactive_qdisc ${dev} \ 82 "${PRIO_HANDLE_MAJOR}:3" \ 83 "${OUTPUT_HANDLE_MAJOR}:" "nsscodel" 84 [ $? = 0 ] || return $? 85 # base nsstbl under which all streamboost classes appear 86 tc qdisc add dev ${dev} \ 87 parent ${PRIO_HANDLE_MAJOR}:2 \ 88 handle ${TBF_HANDLE_MAJOR}: \ 89 nsstbl rate 1000mbit burst 1000kb mtu 1514 90 [ $? = 0 ] || return $? 91 92 # subprio used to split out the guest network 93 tc qdisc add dev ${dev} \ 94 parent ${TBF_HANDLE_MAJOR}:1 \ 95 handle ${SUBPRIO_HANDLE_MAJOR}: \ 96 nssprio bands 2 97 98 # schroot 99 tc qdisc add dev ${dev} \ 100 parent ${SUBPRIO_HANDLE_MAJOR}:1 \ 101 handle ${SCHROOT_HANDLE_MAJOR}: \ 102 nssbf 103 [ $? = 0 ] || return $? 104 105 # global background 106 tc class add dev ${dev} \ 107 parent ${SCHROOT_HANDLE_MAJOR}: \ 108 classid ${SCHROOT_HANDLE_MAJOR}:${CLASSID_BACKGROUND} \ 109 nssbf rate 1000mbit burst 1000kb mtu 1514 110 [ $? = 0 ] || return $? 111 112 # default for unclassified flows 113 tc class add dev ${dev} \ 114 parent ${SCHROOT_HANDLE_MAJOR}: \ 115 classid ${SCHROOT_HANDLE_MAJOR}:${CLASSID_DEFAULT} \ 116 nssbf rate 1000mbit burst 1000kb mtu 1514 117 [ $? = 0 ] || return $? 118 add_interactive_qdisc ${dev} \ 119 "${SCHROOT_HANDLE_MAJOR}:${CLASSID_DEFAULT}" \ 120 "${CLASSID_DEFAULT}:" "nsscodel" "set_default" 121 [ $? = 0 ] || return $? 122 123 # localhost class for traffic originating from the router to the WAN 124 tc class add dev ${dev} \ 125 parent ${SCHROOT_HANDLE_MAJOR}: \ 126 classid ${SCHROOT_HANDLE_MAJOR}:${CLASSID_LOCALHOST} \ 127 nssbf rate 1000mbit burst 1000kb mtu 1514 128 [ $? = 0 ] || return $? 129 add_interactive_qdisc ${dev} \ 130 "${SCHROOT_HANDLE_MAJOR}:${CLASSID_LOCALHOST}" \ 131 "${CLASSID_LOCALHOST}:" "nsscodel" 132 [ $? = 0 ] || return $? 133 134 # "cheat" is for things like ICMP acceleration 135 tc class add dev ${dev} \ 136 parent ${SCHROOT_HANDLE_MAJOR}: \ 137 classid ${SCHROOT_HANDLE_MAJOR}:${CLASSID_ELEVATED_CHEAT} \ 138 nssbf rate 1000mbit burst 1000kb mtu 1514 139 [ $? = 0 ] || return $? 140 add_interactive_qdisc ${dev} \ 141 "${SCHROOT_HANDLE_MAJOR}:${CLASSID_ELEVATED_CHEAT}" \ 142 "${CLASSID_ELEVATED_CHEAT}:" "nsscodel" 143 [ $? = 0 ] || return $? 144 145 # browser 146 tc class add dev ${dev} \ 147 parent ${SCHROOT_HANDLE_MAJOR}: \ 148 classid ${SCHROOT_HANDLE_MAJOR}:${CLASSID_ELEVATED_BROWSER} \ 149 nssbf rate 1000mbit burst 1000kb mtu 1514 150 [ $? = 0 ] || return $? 151 add_interactive_qdisc ${dev} \ 152 "${SCHROOT_HANDLE_MAJOR}:${CLASSID_ELEVATED_BROWSER}" \ 153 "${CLASSID_ELEVATED_BROWSER}:" "nsscodel" 154 [ $? = 0 ] || return $? 155 156 # dns 157 tc class add dev ${dev} \ 158 parent ${SCHROOT_HANDLE_MAJOR}: \ 159 classid ${SCHROOT_HANDLE_MAJOR}:${CLASSID_ELEVATED_DNS} \ 160 nssbf rate 1000mbit burst 1000kb 161 [ $? = 0 ] || return $? 162 add_interactive_qdisc ${dev} \ 163 "${SCHROOT_HANDLE_MAJOR}:${CLASSID_ELEVATED_DNS}" \ 164 "${CLASSID_ELEVATED_DNS}:" "nsscodel" 165 [ $? = 0 ] || return $? 166 167 # guest network 168 tc qdisc add dev ${dev} \ 169 parent ${SUBPRIO_HANDLE_MAJOR}:2 \ 170 handle ${GUEST_HANDLE_MAJOR}: \ 171 nsstbl burst 500kbit mtu 1514 rate ${GUEST_BANDWIDTH_LIMIT:-5mbit} 172 [ $? = 0 ] || return $? 173 add_interactive_qdisc ${dev} \ 174 "${GUEST_HANDLE_MAJOR}:1" \ 175 "${CLASSID_GUEST}:" "nsscodel" 176 [ $? = 0 ] || return $? 177 178 # if we're configured for more than just a single default zone, then 179 # we add a qdisc for each zone under the classified qdisc so that the 180 # parent of each flow will be one of these zone qdiscs depending on 181 # which zone the flow's device is configured. else, we do nothing 182 # special here and the classified qdisc is the parent for all flows. 183 local zonecount=$(sb_get_zone_count) 184 if [ -z "${zonecount}" ] || [ "${zonecount}" -le 1 ]; then 185 # normal qdisc structure, no zones 186 187 # 188 # global classified 189 # 190 tc class add dev ${dev} \ 191 parent ${SCHROOT_HANDLE_MAJOR}: \ 192 classid ${SCHROOT_HANDLE_MAJOR}:${CLASSID_CLASSIFIED} \ 193 nssbf rate 1000mbit burst 1000kb mtu 1514 194 [ $? = 0 ] || return $? 195 tc qdisc add dev ${dev} \ 196 parent ${SCHROOT_HANDLE_MAJOR}:${CLASSID_CLASSIFIED} \ 197 handle ${BF_HANDLE_MAJOR}: \ 198 nssbf 199 [ $? = 0 ] || return $? 200 else 201 local maxzoneid=$(sb_get_max_zone_id) 202 # zoned setup 203 # 204 # first we add the zone root at a weight which combines the 205 # background and classified qdiscs. to that we attach one 206 # zone qdisc per zone. each zone qdisc has a limiter so that 207 # we can support per-zone max rates and then a classified and 208 # background qdisc with the usual weights 209 210 # add the zone root 211 local weight=$((${COMMITTED_WEIGHT}+${BACKGROUND_WEIGHT})) 212 tc class add dev ${dev} \ 213 parent ${SCHROOT_HANDLE_MAJOR}: \ 214 classid ${SCHROOT_HANDLE_MAJOR}:${CLASSID_ZONE_ROOT} \ 215 nssbf rate 1000mbit burst 1000kb \ 216 quantum ${weight} mtu 1514 217 [ $? = 0 ] || return $? 218 tc qdisc add dev ${dev} \ 219 parent ${SCHROOT_HANDLE_MAJOR}:${CLASSID_ZONE_ROOT} \ 220 handle ${BF_HANDLE_MAJOR}: \ 221 nssbf 222 [ $? = 0 ] || return $? 223 224 # add each zone to the zone root 225 local zone=0 226 while [ "${zone}" -le "${maxzoneid}" ]; do 227 if [ $(sb_zone_is_configured ${zone}) = "0" ]; then 228 add_zone ${dev} ${zone} 229 fi 230 let zone=zone+1 231 done 232 fi 233} 234 235# 236# sets up iptables rules 237# 238# $1: iptables executable, e.g., 'iptables' or 'ip6tables' 239# $2: 'A' or 'D' depending on whether to add all rules or delete them 240generic_iptables() { 241 local ipt=$1 242 local cmd=$2 243 local guest_rules=no 244 245 [ "${ipt}" = "iptables" ] && [ "$GUEST_DHCP_ENABLE" = "yes" -o "$2" = "D" ] && guest_rules="yes" 246 247 # All packets from localhost to LAN are marked to skip BWC 248 ${ipt} -t mangle -${cmd} OUTPUT -o $LAN_IFACE -j CLASSIFY \ 249 --set-class ${OUTPUT_HANDLE_MAJOR}:0 250 251 # If this is from localhost AND is using the aperture source 252 # ports, set the class to avoid BWC. 253 ${ipt} -t mangle -${cmd} OUTPUT ! -o $LAN_IFACE -p tcp -m multiport \ 254 --source-ports 321:353 -j CLASSIFY \ 255 --set-class ${OUTPUT_HANDLE_MAJOR}:0 256 ${ipt} -t mangle -${cmd} OUTPUT ! -o $LAN_IFACE -p tcp -m multiport \ 257 --source-ports 321:353 -j RETURN 258 259 # All packets from localhost to WAN are marked 260 # Note the !LAN_IFACE logic allows us to catch any potential 261 # PPPoE interface as well 262 ${ipt} -t mangle -${cmd} OUTPUT ! -o $LAN_IFACE -j CLASSIFY \ 263 --set-class ${CLASSID_LOCALHOST}:0 264 265 # Guest network traffic goes somewhere else - only IPv4 is supported 266 [ "${guest_rules}" = "yes" ] && { 267 local bypass=$(ipaddr_netmask_to_cidr ${GUEST_DHCP_IPADDR} ${GUEST_DHCP_NETMASK}) 268 local mark=$(printf "0x%04x%04x" 0x${BF_HANDLE_MAJOR} 0x${CLASSID_GUEST}) 269 ${ipt} -t mangle -${cmd} FORWARD ! -o $LAN_IFACE -s ${bypass} \ 270 -j CLASSIFY --set-class "${CLASSID_GUEST}":0 271 ${ipt} -t mangle -${cmd} FORWARD ! -o $LAN_IFACE -s ${bypass} \ 272 -j RETURN 273 ${ipt} -t mangle -${cmd} FORWARD -o $LAN_IFACE -d ${bypass} \ 274 -j CLASSIFY --set-class "${CLASSID_GUEST}":0 275 ${ipt} -t mangle -${cmd} FORWARD -o $LAN_IFACE -d ${bypass} \ 276 -j RETURN 277 } 278 279 # Mark all forwarded packets with the global default 280 # XXX - This is not compatible with the inter-op concessions for our 281 # CS release. ANY mark set from another source will cause SB to not 282 # perform marking. - BenM 283 # ${ipt} -t mangle -${cmd} FORWARD -j CLASSIFY \ 284 # --set-class ${CLASSID_DEFAULT}:0 285 286 # Forwarded ICMP packets go to their own queue 287 ${ipt} -t mangle -${cmd} FORWARD -p icmp -m limit --limit 2/second \ 288 -j CLASSIFY --set-class ${CLASSID_ELEVATED_CHEAT}:0 289 290 # DNS Elevation 291 ${ipt} -t mangle -${cmd} POSTROUTING -p udp --dport 53 \ 292 -j CLASSIFY --set-class ${CLASSID_ELEVATED_DNS}:0 293 ${ipt} -t mangle -${cmd} POSTROUTING -p udp --dport 53 \ 294 -j RETURN 295 296 # TCP Elevation 297 ${ipt} -t mangle -${cmd} POSTROUTING -p tcp \ 298 -m conntrack --ctorigdstport 80 -m connbytes --connbytes 0:39 \ 299 --connbytes-dir both --connbytes-mode packets -j CLASSIFY \ 300 --set-class ${CLASSID_ELEVATED_BROWSER}:0 301 ${ipt} -t mangle -${cmd} POSTROUTING -p tcp \ 302 -m conntrack --ctorigdstport 80 -m connbytes --connbytes 0:39 \ 303 --connbytes-dir both --connbytes-mode packets -j RETURN 304 305 # Restore the CONNMARK to the packet 306 ${ipt} -t mangle -${cmd} POSTROUTING -j CONNMARK --restore-mark 307 # Further, restore the mark to priority since filters don't work. 308 # Note, mark2prio only overwrites prio with the connmark if the prio 309 # is zero so that it won't stomp on the CLASSIFY target. 310 ${ipt} -t mangle -${cmd} POSTROUTING -j mark2prio 311} 312 313setup_iptables () { 314 # call iptables to add rules 315 generic_iptables iptables A 316 generic_iptables ip6tables A 317} 318 319teardown_iptables () { 320 # call iptables to delete rules 321 generic_iptables iptables D 322 generic_iptables ip6tables D 323} 324