Add routing stuff
authorMichael Spang <mspang@csclub.uwaterloo.ca>
Mon, 8 Mar 2010 01:09:32 +0000 (20:09 -0500)
committerMichael Spang <mspang@csclub.uwaterloo.ca>
Mon, 8 Mar 2010 01:12:22 +0000 (20:12 -0500)
orionroutes.py [deleted file]
routing/interfaces [new file with mode: 0644]
routing/orionroutes.py [new file with mode: 0755]
routing/setup-routing [new file with mode: 0644]
routing/update-orion-routes [new file with mode: 0755]

diff --git a/orionroutes.py b/orionroutes.py
deleted file mode 100755 (executable)
index 22674e5..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-#!/usr/bin/python
-
-# Configuration
-ORION_TABLE =   1 # from /etc/iproute2/rt_tables
-ORION_REALMS =  1 # from /etc/iproute2/rt_realms
-ORION_VIAS =    [ "66.97.23.33", "66.97.28.65", "129.97.1.46" ]
-ORION_GW =      "129.97.134.1"
-ORION_SRC =     "129.97.134.42"
-ORION_IFACE =   "eth0"
-
-# Don't touch anything beyond here
-
-import sys, re, iplib, SubnetTree
-from ctypes import *
-
-NETLINK_ROUTE =         0
-AF_UNSPEC =             0
-RT_SCOPE_UNIVERSE =     0
-RTPROT_STATIC =         4
-NLM_F_REPLACE =         0x100
-
-def die(msg):
-    sys.stderr.write("orionroutes.py: %s\n" % msg)
-    sys.exit(1)
-
-try:
-    libnl = cdll.LoadLibrary("libnl.so.1")
-    nl_geterror = CFUNCTYPE(c_char_p) (("nl_geterror", libnl), None)
-    nl_handle_alloc = CFUNCTYPE(c_void_p) (("nl_handle_alloc", libnl), None)
-    nl_connect = CFUNCTYPE(c_int, c_void_p, c_int) \
-        (("nl_connect", libnl), ((1, "handle", None), (1, "type", NETLINK_ROUTE)))
-    rtnl_route_alloc = CFUNCTYPE(c_void_p) (("rtnl_route_alloc", libnl), None)
-    rtnl_link_alloc_cache = CFUNCTYPE(c_void_p, c_void_p) \
-        (("rtnl_link_alloc_cache", libnl), ((1, "handle", None), ))
-    rtnl_link_name2i = CFUNCTYPE(c_int, c_void_p, c_char_p) \
-        (("rtnl_link_name2i", libnl), ((1, "cache", None), (1, "iface", -1)))
-    rtnl_route_set_oif = CFUNCTYPE(c_void_p, c_void_p, c_int) \
-        (("rtnl_route_set_oif", libnl), ((1, "route", None), (1, "iface", -1)))
-    nl_cache_free = CFUNCTYPE(None, c_void_p) \
-        (("nl_cache_free", libnl), ((1, "cache", None), ))
-    nl_addr_parse = CFUNCTYPE(c_void_p, c_char_p, c_int) \
-        (("nl_addr_parse", libnl), ((1, "dst", None), (1, "family", AF_UNSPEC)))
-    rtnl_route_set_dst = CFUNCTYPE(c_int, c_void_p, c_void_p) \
-        (("rtnl_route_set_dst", libnl), ((1, "route", None), (1, "dst", None)))
-    rtnl_route_set_pref_src = CFUNCTYPE(c_int, c_void_p, c_void_p) \
-        (("rtnl_route_set_pref_src", libnl), ((1, "route", None), (1, "src", None)))
-    nl_addr_put = CFUNCTYPE(None, c_void_p) \
-        (("nl_addr_put", libnl), ((1, "addr", None), ))
-    rtnl_route_set_gateway = CFUNCTYPE(c_int, c_void_p, c_void_p) \
-        (("rtnl_route_set_gateway", libnl), ((1, "route", None), (1, "gw", None)))
-    rtnl_route_set_table = CFUNCTYPE(None, c_void_p, c_int) \
-        (("rtnl_route_set_table", libnl), ((1, "route", None), (1, "table", -1)))
-    rtnl_route_set_scope = CFUNCTYPE(None, c_void_p, c_int) \
-        (("rtnl_route_set_scope", libnl), ((1, "route", None), (1, "scope", -1)))
-    rtnl_route_set_protocol = CFUNCTYPE(None, c_void_p, c_int) \
-        (("rtnl_route_set_protocol", libnl), ((1, "route", None), (1, "proto", -1)))
-    rtnl_route_set_realms = CFUNCTYPE(None, c_void_p, c_int) \
-        (("rtnl_route_set_realms", libnl), ((1, "route", None), (1, "realms", -1)))
-    rtnl_route_add = CFUNCTYPE(c_int, c_void_p, c_void_p, c_int) \
-        (("rtnl_route_add", libnl), ((1, "handle", None), (1, "route", None), (1, "flags", 0)))
-    rtnl_route_put = CFUNCTYPE(None, c_void_p) \
-        (("rtnl_route_put", libnl), ((1, "route", None), ))
-    nl_handle_destroy = CFUNCTYPE(None, c_void_p) \
-        (("nl_handle_destroy", libnl), ((1, "handle", None), ))
-    rtnl_route_alloc_cache = CFUNCTYPE(c_void_p, c_void_p) \
-        (("rtnl_route_alloc_cache", libnl), ((1, "handle", None), ))
-    nl_cache_get_first = CFUNCTYPE(c_void_p, c_void_p) \
-        (("nl_cache_get_first", libnl), ((1, "cache", None), ))
-    rtnl_route_get_table = CFUNCTYPE(c_int, c_void_p) \
-        (("rtnl_route_get_table", libnl), ((1, "route", None), ))
-    rtnl_route_get_dst = CFUNCTYPE(c_void_p, c_void_p) \
-        (("rtnl_route_get_dst", libnl), ((1, "route", None), ))
-    nl_addr2str = CFUNCTYPE(c_char_p, c_void_p, c_char_p, c_int) \
-        (("nl_addr2str", libnl), ((1, "addr", None), (1, "buffer", None), (1, "size", 0)))
-    rtnl_route_del = CFUNCTYPE(c_int, c_void_p, c_void_p, c_int) \
-        (("rtnl_route_del", libnl), ((1, "handle", None), (1, "route", None), (1, "flags", 0)))
-    nl_cache_get_next = CFUNCTYPE(c_void_p, c_void_p) \
-        (("nl_cache_get_next", libnl), ((1, "object", None), ))
-except Exception,e:
-    die("Failed to load libnl: %s" % e)
-
-def nl_die(func):
-    die("%s: %s" % (func, nl_geterror()))
-
-cidr_re = re.compile("(B{0,1})\\s+([0-9.]+)/{0,1}(\\d*)(.*)")
-via_re = re.compile(".*?via ([0-9.]+)")
-
-ips = [[] for i in range(33)]
-last_bits = 0
-count = 0
-for line in sys.stdin.readlines():
-    cidr = cidr_re.match(line)
-    if cidr == None:
-        continue
-    cidr = cidr.groups()
-    if cidr[2] != '':
-        last_bits = cidr[2]
-    if cidr[0] != 'B':
-        continue
-    via = via_re.match(cidr[3])
-    if via == None or via.group(1) not in ORION_VIAS:
-        continue
-    ips[int(last_bits)].append(int(iplib.IPv4Address(cidr[1])))
-    count = count + 1
-
-if count < 10: # we should never have less than 10 routes
-    die("Not enough routes (got %d)" % count)
-
-cidrs = []
-for bits in range(32, 1, -1):
-    ips[bits].sort()
-    last_ip = 0
-    for ip in ips[bits]:
-        if ip != last_ip and (ip ^ last_ip) == (1 << (32 - bits)):
-            ips[bits - 1].append(ip & (((1 << (bits - 1)) - 1) << (32 - (bits - 1))))
-            last_ip = 0
-        elif last_ip != 0:
-            cidrs.append((iplib.IPv4Address(last_ip), bits))
-        last_ip = ip
-    if last_ip != 0:
-        cidrs.append((iplib.IPv4Address(last_ip), bits))
-
-nlh = nl_handle_alloc()
-if nlh == None: nl_die("nl_handle_alloc")
-if nl_connect(nlh, NETLINK_ROUTE) < 0: nl_die("nl_connect")
-
-link_cache = rtnl_link_alloc_cache(nlh)
-if link_cache == None: nl_die("rtnl_link_alloc")
-iface = rtnl_link_name2i(link_cache, ORION_IFACE)
-if iface < 0: nl_die("rtnl_link_name2i")
-nl_cache_free(link_cache)
-
-cidrs.sort(lambda (ip1, bits1), (ip2, bits2): cmp(ip1, ip2) if bits1 == bits2 else (bits1 - bits2))
-tree = SubnetTree.SubnetTree()
-for (ip, bits) in cidrs:
-    if str(ip) not in tree:
-        cidr = "%s/%s" % (ip, bits)
-        tree[cidr] = None
-
-        route = rtnl_route_alloc()
-        if route == None: nl_die("rtnl_route_alloc")
-
-        dstaddr = nl_addr_parse(cidr, AF_UNSPEC)
-        if dstaddr == None: nl_die("nl_addr_parse(%s)" % cidr)
-        if rtnl_route_set_dst(route, dstaddr) < 0: nl_die("rtnl_route_set_dst")
-        nl_addr_put(dstaddr)
-
-        srcaddr = nl_addr_parse(ORION_SRC, AF_UNSPEC)
-        if srcaddr == None: nl_die("nl_addr_parse(%s)" % ORION_SRC)
-        if rtnl_route_set_pref_src(route, srcaddr) < 0: nl_die("nl_route_set_pref_src")
-        nl_addr_put(srcaddr)
-
-        gwaddr = nl_addr_parse(ORION_GW, AF_UNSPEC)
-        if gwaddr == None: nl_die("nl_addr_parse(%s)" % ORION_GW)
-        if rtnl_route_set_gateway(route, gwaddr) < 0: nl_die("nl_route_set_gateway")
-        nl_addr_put(gwaddr)
-
-        rtnl_route_set_oif(route, iface)
-        rtnl_route_set_table(route, ORION_TABLE)
-        rtnl_route_set_scope(route, RT_SCOPE_UNIVERSE)
-        rtnl_route_set_protocol(route, RTPROT_STATIC)
-        rtnl_route_set_realms(route, ORION_REALMS)
-
-        if rtnl_route_add(nlh, route, NLM_F_REPLACE) < 0: nl_die("rtnl_route_add(dst=%s)" % cidr)
-        rtnl_route_put(route)
-
-route_cache = rtnl_route_alloc_cache(nlh)
-if route_cache == None: nl_die("rtnl_route_alloc_cache")
-dstaddr_s = create_string_buffer(100)
-
-route = nl_cache_get_first(route_cache)
-while route != None:
-    table = rtnl_route_get_table(route)
-    if table != ORION_TABLE:
-        route = nl_cache_get_next(route)
-        continue
-
-    dstaddr = rtnl_route_get_dst(route)
-    if dstaddr == None:
-        continue
-    if nl_addr2str(dstaddr, dstaddr_s, sizeof(dstaddr_s)) == None: nl_die("nl_addr2str")
-    dstaddr = str(repr(dstaddr_s.value)).strip('\'').split('/')[0]
-
-    if dstaddr not in tree:
-        rtnl_route_del(nlh, route, 0)
-
-    route = nl_cache_get_next(route)
-
-nl_cache_free(route_cache)
-
-nl_handle_destroy(nlh)
diff --git a/routing/interfaces b/routing/interfaces
new file mode 100644 (file)
index 0000000..9ae14b7
--- /dev/null
@@ -0,0 +1,32 @@
+# This file describes the network interfaces available on your system
+# and how to activate them. For more information, see interfaces(5).
+
+# The loopback network interface
+auto lo
+iface lo inet loopback
+
+# The routes added here will not be visible to the 'route' command; you
+# should use 'ip route show table foo' instead.
+
+auto eth0
+iface eth0 inet static
+       address 129.97.134.42
+       netmask 255.255.255.0
+       gateway 129.97.134.1
+       up   ip rule add from all lookup campus prio 1
+       down ip rule del from all lookup campus prio 1
+       up   ip rule add from all lookup orion prio 2
+       down ip rule del from all lookup orion prio 2
+       up   ip route add 129.97.0.0/16  via 129.97.134.1 dev eth0 table campus realm campus
+       down ip route del 129.97.0.0/16  via 129.97.134.1 dev eth0 table campus realm campus
+       up   ip route add 10.0.0.0/8     via 129.97.134.1 dev eth0 table campus realm campus
+       down ip route del 10.0.0.0/8     via 129.97.134.1 dev eth0 table campus realm campus
+       up   ip route add 172.16.0.0/20  via 129.97.134.1 dev eth0 table campus realm campus
+       down ip route del 172.16.0.0/20  via 129.97.134.1 dev eth0 table campus realm campus
+       up   ip route add 192.168.0.0/16 via 129.97.134.1 dev eth0 table campus realm campus
+       down ip route del 192.168.0.0/16 via 129.97.134.1 dev eth0 table campus realm campus
+
+auto eth0:mirror
+iface eth0:mirror inet static
+       address 129.97.134.71
+       netmask 255.255.255.0
diff --git a/routing/orionroutes.py b/routing/orionroutes.py
new file mode 100755 (executable)
index 0000000..2126cb9
--- /dev/null
@@ -0,0 +1,194 @@
+#!/usr/bin/python
+
+# This file updates the orion routing table.
+# Put it at /usr/local/sbin/orionroutes.py
+
+# Configuration
+ORION_TABLE =   1 # from /etc/iproute2/rt_tables
+ORION_REALMS =  1 # from /etc/iproute2/rt_realms
+ORION_VIAS =    [ "66.97.23.33", "66.97.28.65", "129.97.1.46" ]
+ORION_GW =      "129.97.134.1"
+ORION_SRC =     "129.97.134.42"
+ORION_IFACE =   "eth0"
+
+# Don't touch anything beyond here
+
+import sys, re, iplib, SubnetTree
+from ctypes import *
+
+NETLINK_ROUTE =         0
+AF_UNSPEC =             0
+RT_SCOPE_UNIVERSE =     0
+RTPROT_STATIC =         4
+NLM_F_REPLACE =         0x100
+
+def die(msg):
+    sys.stderr.write("orionroutes.py: %s\n" % msg)
+    sys.exit(1)
+
+try:
+    libnl = cdll.LoadLibrary("libnl.so.1")
+    nl_geterror = CFUNCTYPE(c_char_p) (("nl_geterror", libnl), None)
+    nl_handle_alloc = CFUNCTYPE(c_void_p) (("nl_handle_alloc", libnl), None)
+    nl_connect = CFUNCTYPE(c_int, c_void_p, c_int) \
+        (("nl_connect", libnl), ((1, "handle", None), (1, "type", NETLINK_ROUTE)))
+    rtnl_route_alloc = CFUNCTYPE(c_void_p) (("rtnl_route_alloc", libnl), None)
+    rtnl_link_alloc_cache = CFUNCTYPE(c_void_p, c_void_p) \
+        (("rtnl_link_alloc_cache", libnl), ((1, "handle", None), ))
+    rtnl_link_name2i = CFUNCTYPE(c_int, c_void_p, c_char_p) \
+        (("rtnl_link_name2i", libnl), ((1, "cache", None), (1, "iface", -1)))
+    rtnl_route_set_oif = CFUNCTYPE(c_void_p, c_void_p, c_int) \
+        (("rtnl_route_set_oif", libnl), ((1, "route", None), (1, "iface", -1)))
+    nl_cache_free = CFUNCTYPE(None, c_void_p) \
+        (("nl_cache_free", libnl), ((1, "cache", None), ))
+    nl_addr_parse = CFUNCTYPE(c_void_p, c_char_p, c_int) \
+        (("nl_addr_parse", libnl), ((1, "dst", None), (1, "family", AF_UNSPEC)))
+    rtnl_route_set_dst = CFUNCTYPE(c_int, c_void_p, c_void_p) \
+        (("rtnl_route_set_dst", libnl), ((1, "route", None), (1, "dst", None)))
+    rtnl_route_set_pref_src = CFUNCTYPE(c_int, c_void_p, c_void_p) \
+        (("rtnl_route_set_pref_src", libnl), ((1, "route", None), (1, "src", None)))
+    nl_addr_put = CFUNCTYPE(None, c_void_p) \
+        (("nl_addr_put", libnl), ((1, "addr", None), ))
+    rtnl_route_set_gateway = CFUNCTYPE(c_int, c_void_p, c_void_p) \
+        (("rtnl_route_set_gateway", libnl), ((1, "route", None), (1, "gw", None)))
+    rtnl_route_set_table = CFUNCTYPE(None, c_void_p, c_int) \
+        (("rtnl_route_set_table", libnl), ((1, "route", None), (1, "table", -1)))
+    rtnl_route_set_scope = CFUNCTYPE(None, c_void_p, c_int) \
+        (("rtnl_route_set_scope", libnl), ((1, "route", None), (1, "scope", -1)))
+    rtnl_route_set_protocol = CFUNCTYPE(None, c_void_p, c_int) \
+        (("rtnl_route_set_protocol", libnl), ((1, "route", None), (1, "proto", -1)))
+    rtnl_route_set_realms = CFUNCTYPE(None, c_void_p, c_int) \
+        (("rtnl_route_set_realms", libnl), ((1, "route", None), (1, "realms", -1)))
+    rtnl_route_add = CFUNCTYPE(c_int, c_void_p, c_void_p, c_int) \
+        (("rtnl_route_add", libnl), ((1, "handle", None), (1, "route", None), (1, "flags", 0)))
+    rtnl_route_put = CFUNCTYPE(None, c_void_p) \
+        (("rtnl_route_put", libnl), ((1, "route", None), ))
+    nl_handle_destroy = CFUNCTYPE(None, c_void_p) \
+        (("nl_handle_destroy", libnl), ((1, "handle", None), ))
+    rtnl_route_alloc_cache = CFUNCTYPE(c_void_p, c_void_p) \
+        (("rtnl_route_alloc_cache", libnl), ((1, "handle", None), ))
+    nl_cache_get_first = CFUNCTYPE(c_void_p, c_void_p) \
+        (("nl_cache_get_first", libnl), ((1, "cache", None), ))
+    rtnl_route_get_table = CFUNCTYPE(c_int, c_void_p) \
+        (("rtnl_route_get_table", libnl), ((1, "route", None), ))
+    rtnl_route_get_dst = CFUNCTYPE(c_void_p, c_void_p) \
+        (("rtnl_route_get_dst", libnl), ((1, "route", None), ))
+    nl_addr2str = CFUNCTYPE(c_char_p, c_void_p, c_char_p, c_int) \
+        (("nl_addr2str", libnl), ((1, "addr", None), (1, "buffer", None), (1, "size", 0)))
+    rtnl_route_del = CFUNCTYPE(c_int, c_void_p, c_void_p, c_int) \
+        (("rtnl_route_del", libnl), ((1, "handle", None), (1, "route", None), (1, "flags", 0)))
+    nl_cache_get_next = CFUNCTYPE(c_void_p, c_void_p) \
+        (("nl_cache_get_next", libnl), ((1, "object", None), ))
+except Exception,e:
+    die("Failed to load libnl: %s" % e)
+
+def nl_die(func):
+    die("%s: %s" % (func, nl_geterror()))
+
+cidr_re = re.compile("(B{0,1})\\s+([0-9.]+)/{0,1}(\\d*)(.*)")
+via_re = re.compile(".*?via ([0-9.]+)")
+
+ips = [[] for i in range(33)]
+last_bits = 0
+count = 0
+for line in sys.stdin.readlines():
+    cidr = cidr_re.match(line)
+    if cidr == None:
+        continue
+    cidr = cidr.groups()
+    if cidr[2] != '':
+        last_bits = cidr[2]
+    if cidr[0] != 'B':
+        continue
+    via = via_re.match(cidr[3])
+    if via == None or via.group(1) not in ORION_VIAS:
+        continue
+    ips[int(last_bits)].append(int(iplib.IPv4Address(cidr[1])))
+    count = count + 1
+
+if count < 10: # we should never have less than 10 routes
+    die("Not enough routes (got %d)" % count)
+
+cidrs = []
+for bits in range(32, 1, -1):
+    ips[bits].sort()
+    last_ip = 0
+    for ip in ips[bits]:
+        if ip != last_ip and (ip ^ last_ip) == (1 << (32 - bits)):
+            ips[bits - 1].append(ip & (((1 << (bits - 1)) - 1) << (32 - (bits - 1))))
+            last_ip = 0
+        elif last_ip != 0:
+            cidrs.append((iplib.IPv4Address(last_ip), bits))
+        last_ip = ip
+    if last_ip != 0:
+        cidrs.append((iplib.IPv4Address(last_ip), bits))
+
+nlh = nl_handle_alloc()
+if nlh == None: nl_die("nl_handle_alloc")
+if nl_connect(nlh, NETLINK_ROUTE) < 0: nl_die("nl_connect")
+
+link_cache = rtnl_link_alloc_cache(nlh)
+if link_cache == None: nl_die("rtnl_link_alloc")
+iface = rtnl_link_name2i(link_cache, ORION_IFACE)
+if iface < 0: nl_die("rtnl_link_name2i")
+nl_cache_free(link_cache)
+
+cidrs.sort(lambda (ip1, bits1), (ip2, bits2): cmp(ip1, ip2) if bits1 == bits2 else (bits1 - bits2))
+tree = SubnetTree.SubnetTree()
+for (ip, bits) in cidrs:
+    if str(ip) not in tree:
+        cidr = "%s/%s" % (ip, bits)
+        tree[cidr] = None
+
+        route = rtnl_route_alloc()
+        if route == None: nl_die("rtnl_route_alloc")
+
+        dstaddr = nl_addr_parse(cidr, AF_UNSPEC)
+        if dstaddr == None: nl_die("nl_addr_parse(%s)" % cidr)
+        if rtnl_route_set_dst(route, dstaddr) < 0: nl_die("rtnl_route_set_dst")
+        nl_addr_put(dstaddr)
+
+        srcaddr = nl_addr_parse(ORION_SRC, AF_UNSPEC)
+        if srcaddr == None: nl_die("nl_addr_parse(%s)" % ORION_SRC)
+        if rtnl_route_set_pref_src(route, srcaddr) < 0: nl_die("nl_route_set_pref_src")
+        nl_addr_put(srcaddr)
+
+        gwaddr = nl_addr_parse(ORION_GW, AF_UNSPEC)
+        if gwaddr == None: nl_die("nl_addr_parse(%s)" % ORION_GW)
+        if rtnl_route_set_gateway(route, gwaddr) < 0: nl_die("nl_route_set_gateway")
+        nl_addr_put(gwaddr)
+
+        rtnl_route_set_oif(route, iface)
+        rtnl_route_set_table(route, ORION_TABLE)
+        rtnl_route_set_scope(route, RT_SCOPE_UNIVERSE)
+        rtnl_route_set_protocol(route, RTPROT_STATIC)
+        rtnl_route_set_realms(route, ORION_REALMS)
+
+        if rtnl_route_add(nlh, route, NLM_F_REPLACE) < 0: nl_die("rtnl_route_add(dst=%s)" % cidr)
+        rtnl_route_put(route)
+
+route_cache = rtnl_route_alloc_cache(nlh)
+if route_cache == None: nl_die("rtnl_route_alloc_cache")
+dstaddr_s = create_string_buffer(100)
+
+route = nl_cache_get_first(route_cache)
+while route != None:
+    table = rtnl_route_get_table(route)
+    if table != ORION_TABLE:
+        route = nl_cache_get_next(route)
+        continue
+
+    dstaddr = rtnl_route_get_dst(route)
+    if dstaddr == None:
+        continue
+    if nl_addr2str(dstaddr, dstaddr_s, sizeof(dstaddr_s)) == None: nl_die("nl_addr2str")
+    dstaddr = str(repr(dstaddr_s.value)).strip('\'').split('/')[0]
+
+    if dstaddr not in tree:
+        rtnl_route_del(nlh, route, 0)
+
+    route = nl_cache_get_next(route)
+
+nl_cache_free(route_cache)
+
+nl_handle_destroy(nlh)
diff --git a/routing/setup-routing b/routing/setup-routing
new file mode 100644 (file)
index 0000000..199636d
--- /dev/null
@@ -0,0 +1,10 @@
+# This file configures the packet scheduler
+
+tc qdisc  del dev eth0 parent root
+tc qdisc  add dev eth0 parent root handle 1: htb default 2 r2q 10000
+tc class  add dev eth0 parent 1:   classid 1:1 htb rate 1000Mbit
+tc class  add dev eth0 parent 1:1  classid 1:2 htb rate 100Mbit
+tc class  add dev eth0 parent 1:1  classid 1:3 htb rate 200Mbit
+tc class  add dev eth0 parent 1:1  classid 1:4 htb rate 700Mbit ceil 1000Mbit
+tc filter add dev eth0 parent 1:   protocol ip pref 2 route to orion  flowid 1:3
+tc filter add dev eth0 parent 1:   protocol ip pref 1 route to campus flowid 1:4
diff --git a/routing/update-orion-routes b/routing/update-orion-routes
new file mode 100755 (executable)
index 0000000..394745e
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+# This file updates the orion routing table.
+# Put it at /usr/local/sbin/update-orion-routes.
+
+wget --quiet -O - http://noc.uwaterloo.ca/~ns-owner/ext-routes.txt | /usr/local/sbin/orionroutes.py