refactoring double vlans
diff --git a/olt.py b/olt.py
index 96851ee..3bed782 100644
--- a/olt.py
+++ b/olt.py
@@ -762,6 +762,19 @@
         do_barrier(self.controller)
         verify_no_errors(self.controller)
 
+class RemoveRuleTest(base_tests.SimpleDataPlane):
+
+    def runTest(self):
+        logging.info("Testing Rule removal")
+        pass
+
+
+class MultipleDoubleTaggingForwarding(base_tests.SimpleDataPlane):
+
+    def runTests(self):
+        logging.info("Testing multiple Q-in-Q rules")
+        pass
+
 
 class DoubleVlanTest(base_tests.SimpleDataPlane):
     def runTest(self):
@@ -771,139 +784,11 @@
         c_vlan_id = 100
         s_vlan_id = 102
         # upstream flow rule
-        match = ofp.match()
-        match.oxm_list.append(ofp.oxm.in_port(onu_port))
-        match.oxm_list.append(ofp.oxm.vlan_vid(value=ofp.OFPVID_PRESENT))
-        match.oxm_list.append(ofp.oxm.vlan_pcp(value=0))
+        installDoubleTaggingRule(s_vlan_id, c_vlan_id, self.controller)
 
-        # push inner vlan (c-vlan) for upstream
-        request = ofp.message.flow_add(
-            table_id=test_param_get("table", 0),
-            cookie=42,
-            match=match,
-            instructions=[
-                ofp.instruction.apply_actions(
-                    actions=[
-                        ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))]),
-                ofp.instruction.goto_table(1)],
-            buffer_id=ofp.OFP_NO_BUFFER,
-            priority=1000)
-
-        self.controller.message_send(request)
-        do_barrier(self.controller)
-        verify_no_errors(self.controller)
-
-        # push outer vlan (s-vlan) for upstream
-        match = ofp.match()
-        match.oxm_list.append(ofp.oxm.in_port(onu_port))
-        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))
-        match.oxm_list.append(ofp.oxm.vlan_pcp(0))
-
-        request = ofp.message.flow_add(
-            table_id=test_param_get("table", 1),
-            cookie=43,
-            match=match,
-            instructions=[
-                ofp.instruction.apply_actions(
-                    actions=[
-                        ofp.action.push_vlan(ethertype=0x8100),
-                        ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | s_vlan_id)),
-                        ofp.action.set_field(ofp.oxm.vlan_pcp(0)),
-                        ofp.action.output(port=olt_port)]),
-            ],
-            buffer_id=ofp.OFP_NO_BUFFER,
-            priority=1000)
-
-        self.controller.message_send(request)
-        do_barrier(self.controller)
-        verify_no_errors(self.controller)
-
-        # strip outer vlan (s-vlan) for downstream
-        match = ofp.match()
-        match.oxm_list.append(ofp.oxm.in_port(olt_port))
-        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | s_vlan_id))
-        match.oxm_list.append(ofp.oxm.vlan_pcp(0))
-        request = ofp.message.flow_add(
-            table_id=test_param_get("table", 0),
-            cookie=44,
-            match=match,
-            instructions=[
-                ofp.instruction.apply_actions(
-                    actions=[ofp.action.pop_vlan()]),
-                ofp.instruction.goto_table(1)],
-            buffer_id=ofp.OFP_NO_BUFFER,
-            priority=1000)
-
-        self.controller.message_send(request)
-        do_barrier(self.controller)
-        verify_no_errors(self.controller)
-
-        # rewrite inner vlan (c-vlan) to default (0) for downstream
-        match = ofp.match()
-        match.oxm_list.append(ofp.oxm.in_port(olt_port))
-        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))
-        match.oxm_list.append(ofp.oxm.vlan_pcp(0))
-
-        request = ofp.message.flow_add(
-            table_id=test_param_get("table", 1),
-            cookie=45,
-            match=match,
-            instructions=[
-                ofp.instruction.apply_actions(
-                    actions=[
-                        ofp.action.pop_vlan(),
-                        ofp.action.output(port=onu_port)])
-            ],
-            buffer_id=ofp.OFP_NO_BUFFER,
-            priority=1000)
-
-        self.controller.message_send(request)
-        do_barrier(self.controller)
-        verify_no_errors(self.controller)
         # It takes some time for flows to propagate down to the data plane
-
         time.sleep(10)
-        incorrectTagPkt = simple_udp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=100, vlan_pcp=0)
-        untaggedPkt = simple_udp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=0, vlan_pcp=0)
-
-        '''
-		FIXME: hack because OLT does _not_ tag packets correctly
-			it ignores the eth_type in the push_vlan action
-			and always slaps on 0x8100 even though the 
-			down stream flow must be 0x88a8.
-	    '''
-        doubleTaggedPkt = double_vlan_udp_packet(pktlen=104, dl_vlan_enable=True,
-                                                 c_vlan_vid=c_vlan_id,
-                                                 s_vlan_vid=s_vlan_id,
-                                                 c_vlan_pcp=0, s_vlan_pcp=0, eth_type=0x88a8)
-
-        upstreamDoubleTaggedPkt = double_vlan_udp_packet(pktlen=104, dl_vlan_enable=True,
-                                                         c_vlan_vid=c_vlan_id,
-                                                         s_vlan_vid=s_vlan_id,
-                                                         c_vlan_pcp=0, s_vlan_pcp=0)
-
-        # test upstream untagged packet got double tag at OLT
-        logging.info(str(doubleTaggedPkt))
-
-        self.dataplane.send(onu_port, str(untaggedPkt))
-        verify_packet(self, upstreamDoubleTaggedPkt, olt_port)
-
-        # test downstream doubletagged packet got untagged at ONU
-        self.dataplane.send(olt_port, str(doubleTaggedPkt))
-        verify_packet(self, untaggedPkt, onu_port)
-
-        # test upstream doubletagged packet got dropped
-        self.dataplane.send(onu_port, str(doubleTaggedPkt))
-        verify_no_packet(self, upstreamDoubleTaggedPkt, olt_port)
-
-        # test downstream untagged packet got dropped at ONU
-        self.dataplane.send(olt_port, str(untaggedPkt))
-        verify_no_packet(self, untaggedPkt, onu_port)
-
-        # test upstream icorrectly tagged packet; should get dropped
-        self.dataplane.send(onu_port, str(incorrectTagPkt))
-
-        verify_no_packet(self, upstreamDoubleTaggedPkt, olt_port)
+        testPacketFlow(self, c_vlan_id, s_vlan_id)
 
         time.sleep(2)
 
@@ -918,142 +803,142 @@
 
     def runTest(self):
         logging.info("Running cycling vlan test")
-        self.cookie = 42
 
         for stag in xrange(2, 4000, 100):
             for ctag in xrange(2, 4000, 100):
                 delete_all_flows(self.controller)
                 time.sleep(5)
-                self.installDoubleTaggingRule(stag, ctag)
-                self.vlan_pairs = (stag, ctag)
+                installDoubleTaggingRule(stag, ctag, self.controller)
                 time.sleep(5)
-                self.testPacketFlow()
+                testPacketFlow(self, ctag, stag)
 
-    def testPacketFlow(self):
-        (s_vlan_id, c_vlan_id) = self.vlan_pairs
+def testPacketFlow(test, c_vlan_id, s_vlan_id):
 
-        incorrectTagPkt = simple_udp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=100, vlan_pcp=0)
-        untaggedPkt = simple_udp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=0, vlan_pcp=0)
+    incorrectTagPkt = simple_udp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=100, vlan_pcp=0)
+    untaggedPkt = simple_udp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=0, vlan_pcp=0)
 
-        upstreamDoubleTaggedPkt = double_vlan_udp_packet(pktlen=104, dl_vlan_enable=True,
-                                                         c_vlan_vid=c_vlan_id,
-                                                         s_vlan_vid=s_vlan_id,
-                                                         c_vlan_pcp=0, s_vlan_pcp=0)
+    upstreamDoubleTaggedPkt = double_vlan_udp_packet(pktlen=104, dl_vlan_enable=True,
+                                                     c_vlan_vid=c_vlan_id,
+                                                     s_vlan_vid=s_vlan_id,
+                                                     c_vlan_pcp=0, s_vlan_pcp=0)
 
-        logging.info("Testing s-tag %d, c-tag %d" % (s_vlan_id, c_vlan_id))
+    logging.info("Testing s-tag %d, c-tag %d" % (s_vlan_id, c_vlan_id))
 
-        self.dataplane.send(onu_port, str(untaggedPkt))
-        verify_packet(self, upstreamDoubleTaggedPkt, olt_port)
+    test.dataplane.send(onu_port, str(untaggedPkt))
+    verify_packet(test, upstreamDoubleTaggedPkt, olt_port)
 
-        # test downstream doubletagged packet got untagged at ONU
-        self.dataplane.send(olt_port, str(upstreamDoubleTaggedPkt))
-        verify_packet(self, untaggedPkt, onu_port)
+    # test downstream doubletagged packet got untagged at ONU
+    test.dataplane.send(olt_port, str(upstreamDoubleTaggedPkt))
+    verify_packet(test, untaggedPkt, onu_port)
 
-        # test upstream doubletagged packet got dropped
-        self.dataplane.send(onu_port, str(upstreamDoubleTaggedPkt))
-        verify_no_packet(self, upstreamDoubleTaggedPkt, olt_port)
+    # test upstream doubletagged packet got dropped
+    test.dataplane.send(onu_port, str(upstreamDoubleTaggedPkt))
+    verify_no_packet(test, upstreamDoubleTaggedPkt, olt_port)
 
-        # test downstream untagged packet got dropped at ONU
-        self.dataplane.send(olt_port, str(untaggedPkt))
-        verify_no_packet(self, untaggedPkt, onu_port)
+    # test downstream untagged packet got dropped at ONU
+    test.dataplane.send(olt_port, str(untaggedPkt))
+    verify_no_packet(test, untaggedPkt, onu_port)
 
-        # test upstream icorrectly tagged packet; should get dropped
-        self.dataplane.send(onu_port, str(incorrectTagPkt))
-        verify_no_packet(self, upstreamDoubleTaggedPkt, olt_port)
+    # test upstream icorrectly tagged packet; should get dropped
+    test.dataplane.send(onu_port, str(incorrectTagPkt))
+    verify_no_packet(test, upstreamDoubleTaggedPkt, olt_port)
 
 
-    def installDoubleTaggingRule(self, s_vlan_id, c_vlan_id):
-        # upstream flow rule
-        match = ofp.match()
-        match.oxm_list.append(ofp.oxm.in_port(onu_port))
-        match.oxm_list.append(ofp.oxm.vlan_vid(value=ofp.OFPVID_PRESENT))
-        match.oxm_list.append(ofp.oxm.vlan_pcp(value=0))
-        self.cookie += 1
+def installDoubleTaggingRule(s_vlan_id, c_vlan_id, controller, cookie  = 42):
+    # upstream flow rule
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.in_port(onu_port))
+    match.oxm_list.append(ofp.oxm.vlan_vid(value=ofp.OFPVID_PRESENT))
+    match.oxm_list.append(ofp.oxm.vlan_pcp(value=0))
+    cookie += 1
 
-        # push inner vlan (c-vlan) for upstream
-        request = ofp.message.flow_add(
-            table_id=test_param_get("table", 0),
-            cookie=self.cookie,
-            match=match,
-            instructions=[
-                ofp.instruction.apply_actions(
-                    actions=[
-                        ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))]),
-                ofp.instruction.goto_table(1)],
-            buffer_id=ofp.OFP_NO_BUFFER,
-            priority=1000)
+    # push inner vlan (c-vlan) for upstream
+    request = ofp.message.flow_add(
+        table_id=test_param_get("table", 0),
+        cookie=self.cookie,
+        match=match,
+        instructions=[
+            ofp.instruction.apply_actions(
+                actions=[
+                    ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))]),
+            ofp.instruction.goto_table(1)],
+        buffer_id=ofp.OFP_NO_BUFFER,
+        priority=1000)
 
-        self.controller.message_send(request)
-        do_barrier(self.controller)
-        verify_no_errors(self.controller)
+    controller.message_send(request)
+    do_barrier(self.controller)
+    verify_no_errors(self.controller)
 
-        # push outer vlan (s-vlan) for upstream
-        match = ofp.match()
-        match.oxm_list.append(ofp.oxm.in_port(onu_port))
-        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))
-        match.oxm_list.append(ofp.oxm.vlan_pcp(0))
-        self.cookie += 1
+    # push outer vlan (s-vlan) for upstream
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.in_port(onu_port))
+    match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))
+    match.oxm_list.append(ofp.oxm.vlan_pcp(0))
+    cookie += 1
 
-        request = ofp.message.flow_add(
-            table_id=test_param_get("table", 1),
-            cookie=self.cookie,
-            match=match,
-            instructions=[
-                ofp.instruction.apply_actions(
-                    actions=[
-                        ofp.action.push_vlan(ethertype=0x8100),
-                        ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | s_vlan_id)),
-                        ofp.action.set_field(ofp.oxm.vlan_pcp(0)),
-                        ofp.action.output(port=olt_port)]),
-            ],
-            buffer_id=ofp.OFP_NO_BUFFER,
-            priority=1000)
+    request = ofp.message.flow_add(
+        table_id=test_param_get("table", 1),
+        cookie=self.cookie,
+        match=match,
+        instructions=[
+            ofp.instruction.apply_actions(
+                actions=[
+                    ofp.action.push_vlan(ethertype=0x8100),
+                    ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | s_vlan_id)),
+                    ofp.action.set_field(ofp.oxm.vlan_pcp(0)),
+                    ofp.action.output(port=olt_port)]),
+        ],
+        buffer_id=ofp.OFP_NO_BUFFER,
+        priority=1000)
 
-        self.controller.message_send(request)
-        do_barrier(self.controller)
-        verify_no_errors(self.controller)
-        self.cookie += 1
+    controller.message_send(request)
+    do_barrier(self.controller)
+    verify_no_errors(self.controller)
+    cookie += 1
 
-        # strip outer vlan (s-vlan) for downstream
-        match = ofp.match()
-        match.oxm_list.append(ofp.oxm.in_port(olt_port))
-        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | s_vlan_id))
-        match.oxm_list.append(ofp.oxm.vlan_pcp(0))
-        request = ofp.message.flow_add(
-            table_id=test_param_get("table", 0),
-            cookie=self.cookie,
-            match=match,
-            instructions=[
-                ofp.instruction.apply_actions(
-                    actions=[ofp.action.pop_vlan()]),
-                ofp.instruction.goto_table(1)],
-            buffer_id=ofp.OFP_NO_BUFFER,
-            priority=1000)
+    # strip outer vlan (s-vlan) for downstream
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.in_port(olt_port))
+    match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | s_vlan_id))
+    match.oxm_list.append(ofp.oxm.vlan_pcp(0))
+    request = ofp.message.flow_add(
+        table_id=test_param_get("table", 0),
+        cookie=self.cookie,
+        match=match,
+        instructions=[
+            ofp.instruction.apply_actions(
+                actions=[ofp.action.pop_vlan()]),
+            ofp.instruction.goto_table(1)],
+        buffer_id=ofp.OFP_NO_BUFFER,
+        priority=1000)
 
-        self.controller.message_send(request)
-        do_barrier(self.controller)
-        verify_no_errors(self.controller)
+    controller.message_send(request)
+    do_barrier(self.controller)
+    verify_no_errors(self.controller)
 
-        # rewrite inner vlan (c-vlan) to default (0) for downstream
-        match = ofp.match()
-        match.oxm_list.append(ofp.oxm.in_port(olt_port))
-        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))
-        match.oxm_list.append(ofp.oxm.vlan_pcp(0))
-        self.cookie += 1
+    # rewrite inner vlan (c-vlan) to default (0) for downstream
+    match = ofp.match()
+    match.oxm_list.append(ofp.oxm.in_port(olt_port))
+    match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))
+    match.oxm_list.append(ofp.oxm.vlan_pcp(0))
+    cookie += 1
 
-        request = ofp.message.flow_add(
-            table_id=test_param_get("table", 1),
-            cookie=self.cookie,
-            match=match,
-            instructions=[
-                ofp.instruction.apply_actions(
-                    actions=[
-                        ofp.action.pop_vlan(),
-                        ofp.action.output(port=onu_port)])
-            ],
-            buffer_id=ofp.OFP_NO_BUFFER,
-            priority=1000)
+    request = ofp.message.flow_add(
+        table_id=test_param_get("table", 1),
+        cookie=self.cookie,
+        match=match,
+        instructions=[
+            ofp.instruction.apply_actions(
+                actions=[
+                    ofp.action.pop_vlan(),
+                    ofp.action.output(port=onu_port)])
+        ],
+        buffer_id=ofp.OFP_NO_BUFFER,
+        priority=1000)
 
-        self.controller.message_send(request)
-        do_barrier(self.controller)
-        verify_no_errors(self.controller)
+    controller.message_send(request)
+    do_barrier(self.controller)
+    verify_no_errors(self.controller)
+
+
+