Example #1
0
    def test_clear_action_sets(self):
        rule1 = Rule(priority=0, match=self.ipv4_src2)
        rule1.instructions.write_actions.append("SET_FIELD", ("IPV4_SRC", 1))
        rule2 = Rule(priority=0, match=self.ipv4_src2)
        rule2.instructions.write_actions.append("SET_FIELD", ("IPV4_SRC", 2))
        rule3 = Rule(priority=0, match=self.ipv4_src2)
        rule3.instructions.write_actions.append("SET_FIELD", ("IPV4_DST", 2))
        rule4 = rule3.copy()
        rule4.instructions.clear_actions = True

        # Check overwrite occurs
        self.assertEqual(rule1 + rule2, rule2)
        self.assertEqual(rule2 + rule1, rule1)

        # Check adding a mix is supported
        expected = rule1.copy()
        expected.instructions.write_actions.append("SET_FIELD",
                                                   ("IPV4_DST", 2))
        self.assertEqual(rule1 + rule3, expected)
        # sanity check
        self.assertNotEqual(rule1, expected)

        # Check Clear works
        self.assertEqual(rule1 + rule4, rule4)
Example #2
0
    def test_metadata(self):
        rule1 = Rule(priority=0, match=self.ipv4_src2)
        rule1.instructions.write_metadata = (0xFEFCFDFA, None)
        rule2 = Rule(priority=0, match=self.ipv4_src2)
        rule2.instructions.write_metadata = (0x0000FFFF, None)
        # This is half the match as these are 64 byte
        rule3 = Rule(priority=0, match=self.ipv4_src2)
        rule3.instructions.write_metadata = (0xFEFCFDFA, 0xFFFFFFFF)
        rule4 = Rule(priority=0, match=self.ipv4_src2)
        rule4.instructions.write_metadata = (0x0000FFFF, 0xFFFFFFFF)
        rule5 = Rule(priority=0, match=self.ipv4_src2)
        rule5.instructions.write_metadata = (0xFEFCFDFA00000000,
                                             0xFFFFFFFF00000000)
        rule6 = Rule(priority=0, match=self.ipv4_src2)
        rule6.instructions.write_metadata = (0xFEFCFDFA0000FFFF,
                                             0xFFFFFFFFFFFFFFFF)
        rule7 = Rule(priority=0, match=self.ipv4_src2)
        rule7.instructions.write_metadata = (0x0, 0xFFFFFFFFFFFFFFF0)

        # Test cases
        self.assertEqual(rule1 + rule2, rule2)
        self.assertEqual(rule2 + rule1, rule1)
        self.assertEqual(rule1 + rule4, rule2)
        self.assertEqual(rule1 + rule3, rule1)
        self.assertEqual(rule3 + rule4, rule4)
        self.assertEqual(rule4 + rule5, rule6)
        self.assertEqual(rule5 + rule4, rule6)

        # Now check masking and matching
        # Check an invalid match will fail
        mrule1 = Rule(priority=0, match=self.meta_1)
        self.assertRaises(MergeException, lambda: rule1 + mrule1)

        # Merging partial metadata sets and matches
        #
        # The correct behaviour is to remove matching set values.
        # More correctly one should remove set bits, in the case of
        # metadata the result is a partial metadata match.
        #
        # Match:  *                         + Metadata=(1, None)
        # Action: WriteMeta:(0x0, 0xFF..F0) +
        #
        # Expecting:
        # Match:  Meta=(1,0xF)
        # Action: WriteMeta:(0x0, 0xFF..F0)

        expected = rule7.copy()
        expected.match.append('METADATA', 0x1, 0xF)
        self.assertEqual(rule7 + mrule1, expected)

        # Try a complex case
        d1 = Rule(priority=0, match=Match())
        d1.instructions.write_metadata = (0x10, 0x10)
        d2 = Rule(priority=0, match=Match())
        d2.instructions.write_metadata = (0x1, 0x1)
        d3 = Rule(priority=0, match=Match([('METADATA', 0x10, 0x10)]))
        d3.instructions.write_metadata = (0x100, 0x100)
        d4 = Rule(priority=0, match=Match([('METADATA', 0x111, 0x111)]))

        expected = Rule(priority=0, match=Match())
        expected.instructions.write_metadata = (0x111, 0x111)

        self.assertEqual(d1 + d2 + d3 + d4, expected)
        self.assertEqual((d1 + d2) + (d3 + d4), expected)
        self.assertEqual(d1 + (d2 + d3) + d4, expected)
        self.assertEqual(d1 + (d2 + (d3 + d4)), expected)

        # This should fail if table the first is set to 0
        d1.instructions.write_metadata = (0x00, 0x10)
        self.assertRaises(MergeException, lambda: d1 + d2 + d3 + d4)
        self.assertRaises(MergeException, lambda: (d1 + d2) + (d3 + d4))
        self.assertRaises(MergeException, lambda: d1 + (d2 + d3) + d4)
        self.assertRaises(MergeException, lambda: d1 + (d2 + (d3 + d4)))

        # Check original metadata match + set's intersection is calculated
        # correctly
        rule8 = Rule(priority=0, match=Match([("METADATA", 0x1, 0x1)]))
        rule8.instructions.write_metadata = (0x0, 0x2)
        rule9 = Rule(priority=0, match=Match([("METADATA", 0x0, None)]))
        self.assertRaises(MergeException, lambda: rule8 + rule9)

        rule10 = Rule(priority=0, match=Match([("METADATA", 0x1, None)]))
        expected = Rule(priority=0,
                        match=Match([("METADATA", 0x1, 0xFFFFFFFFFFFFFFFD)]))
        expected.instructions.write_metadata = (0x0, 0x2)
        self.assertEqual(rule8 + rule10, expected)