예제 #1
0
    def test_table_direct_with_group_id(self):
        te = sh.TableEntry("ExactOne")
        te.match["header_test.field32"] = "10.0.0.0"
        with self.assertRaisesRegex(UserError, "does not support groups"):
            te.group_id = 1

        with self.assertRaisesRegex(UserError, "does not support groups"):
            te = sh.TableEntry("ExactOne")(group_id=1)
예제 #2
0
    def test_table_indirect_with_direct_action(self):
        te = sh.TableEntry("IndirectWS")
        te.match["header_test.field32"] = "10.0.0.0"
        with self.assertRaisesRegex(UserError, "does not support direct actions"):
            te.action = sh.Action("actionA")

        with self.assertRaisesRegex(UserError, "does not support direct actions"):
            te = sh.TableEntry("IndirectWS")(action="actionA")
예제 #3
0
def stopShell():
    shell_lock.acquire()
    try:
        te = sh.TableEntry('control_out_port.ipv4_check_checksum')(
            action='DoMirror')
        sh.TableEntry('control_out_port.ipv4_check_checksum').read(
            lambda t: t.delete())
        sh.teardown()
        print("disconnected")
    finally:
        shell_lock.release()
예제 #4
0
    def test_direct_meter_entry_invalid(self):
        ce = sh.DirectMeterEntry("ExactOne_meter")
        with self.assertRaisesRegex(UserError, "table_entry must be an instance of TableEntry"):
            ce.table_entry = 0xbad
        with self.assertRaisesRegex(UserError, "This DirectMeterEntry is for table"):
            ce.table_entry = sh.TableEntry("TernaryOne")
        with self.assertRaisesRegex(UserError, "Direct meters are not index-based"):
            ce.index = 1

        te = sh.TableEntry("LpmOne")(action="actionA")
        with self.assertRaisesRegex(UserError, "Table has no direct meter"):
            te.meter_config.cir = 100
예제 #5
0
    def test_direct_counter_entry_2(self):
        te = sh.TableEntry("ExactOne")(action="actionA")
        te.match["header_test.field32"] = "10.0.0.0"
        te.action["param"] = "aa:bb:cc:dd:ee:ff"
        te.counter_data.packet_count = 100
        expected_entry = """
table_id: 33582705
match {
  field_id: 1
  exact {
    value: "\\x0a\\x00\\x00\\x00"
  }
}
action {
  action {
    action_id: 16783703
    params {
      param_id: 1
      value: "\\xaa\\xbb\\xcc\\xdd\\xee\\xff"
    }
  }
}
counter_data {
  packet_count: 100
}
"""
        expected_req = self.make_write_request(p4runtime_pb2.Update.INSERT,
                                               P4RuntimeEntity.table_entry,
                                               expected_entry)
        te.insert()
        self.servicer.Write.assert_called_once_with(ProtoCmp(expected_req),
                                                    ANY)

        self.simple_read_check(expected_req.updates[0].entity, te,
                               P4RuntimeEntity.table_entry)
예제 #6
0
    def test_table_entry_lpm(self, input_, value, length):
        te = sh.TableEntry("LpmOne")(action="actionA")
        te.match["header_test.field32"] = input_
        te.action["param"] = "aa:bb:cc:dd:ee:ff"
        te.insert()

        # Cannot use format here because it would require escaping all braces,
        # which would make wiriting tests much more annoying
        expected_entry = """
table_id: 33567650
match {
  field_id: 1
  lpm {
    value: "%s"
    prefix_len: %s
  }
}
action {
  action {
    action_id: 16783703
    params {
      param_id: 1
      value: "\\xaa\\xbb\\xcc\\xdd\\xee\\xff"
    }
  }
}
""" % (value, length)

        expected_req = self.make_write_request(p4runtime_pb2.Update.INSERT,
                                               P4RuntimeEntity.table_entry,
                                               expected_entry)

        self.servicer.Write.assert_called_once_with(ProtoCmp(expected_req),
                                                    ANY)
예제 #7
0
    def test_table_entry_range(self):
        te = sh.TableEntry("RangeOne")(action="actionA")
        te.match["header_test.field32"] = "0..1024"
        te.action["param"] = "aa:bb:cc:dd:ee:ff"
        te.insert()

        expected_entry = """
table_id: 33603558
match {
  field_id: 1
  range {
    low: "\\x00"
    high: "\\x04\\x00"
  }
}
action {
  action {
    action_id: 16783703
    params {
      param_id: 1
      value: "\\xaa\\xbb\\xcc\\xdd\\xee\\xff"
    }
  }
}
"""

        expected_req = self.make_write_request(p4runtime_pb2.Update.INSERT,
                                               P4RuntimeEntity.table_entry,
                                               expected_entry)

        self.servicer.Write.assert_called_once_with(ProtoCmp(expected_req),
                                                    ANY)
예제 #8
0
    def test_direct_counter_entry_invalid(self):
        ce = sh.DirectCounterEntry("ExactOne_counter")
        with self.assertRaisesRegex(UserError, "table_entry must be an instance of TableEntry"):
            ce.table_entry = 0xbad
        with self.assertRaisesRegex(UserError, "This DirectCounterEntry is for table"):
            ce.table_entry = sh.TableEntry("TernaryOne")
        with self.assertRaisesRegex(UserError, "Direct counters are not index-based"):
            ce.index = 1

        te = sh.TableEntry("LpmOne")(action="actionA")
        with self.assertRaisesRegex(UserError, "Table has no direct counter"):
            te.counter_data.packet_count = 100

        te = sh.TableEntry("ExactOne")(action="actionA")
        with self.assertRaisesRegex(UserError, "Counter 'ExactOne_counter' is of type 'PACKETS"):
            te.counter_data.byte_count = 100
예제 #9
0
    def test_table_entry_optional(self):
        te = sh.TableEntry("OptionalOne")(action="actionA")
        te.match["header_test.field32"] = "0x123456"
        te.action["param"] = "aa:bb:cc:dd:ee:ff"
        te.insert()

        expected_entry = """
table_id: 33611248
match {
  field_id: 1
  optional {
    value: "\\x12\\x34\\x56"
  }
}
action {
  action {
    action_id: 16783703
    params {
      param_id: 1
      value: "\\xaa\\xbb\\xcc\\xdd\\xee\\xff"
    }
  }
}
"""
        expected_req = self.make_write_request(p4runtime_pb2.Update.INSERT,
                                               P4RuntimeEntity.table_entry,
                                               expected_entry)

        self.servicer.Write.assert_called_once_with(ProtoCmp(expected_req),
                                                    ANY)
예제 #10
0
    def test_string_match_ekey(self):
        te = sh.TableEntry("StringMatchKeyTable")(action="actionA")
        te.match["f13"] = "16"
        te.action["param"] = "aa:bb:cc:dd:ee:ff"
        te.insert()

        expected_entry = """
table_id: 33554507
match {
  field_id: 1
  exact {
    value: "16"
  }
}
action {
  action {
    action_id: 16783703
    params {
      param_id: 1
      value: "\\xaa\\xbb\\xcc\\xdd\\xee\\xff"
    }
  }
}
"""

        expected_req = self.make_write_request(p4runtime_pb2.Update.INSERT,
                                               P4RuntimeEntity.table_entry,
                                               expected_entry)

        self.servicer.Write.assert_called_once_with(ProtoCmp(expected_req),
                                                    ANY)
예제 #11
0
    def test_table_entry_ternary(self, input_, value, mask):
        te = sh.TableEntry("TernaryOne")(action="actionA")
        te.match["header_test.field32"] = input_
        te.action["param"] = "aa:bb:cc:dd:ee:ff"
        te.insert()

        expected_entry = """
table_id: 33584148
match {
  field_id: 1
  ternary {
    value: "%s"
    mask: "%s"
  }
}
action {
  action {
    action_id: 16783703
    params {
      param_id: 1
      value: "\\xaa\\xbb\\xcc\\xdd\\xee\\xff"
    }
  }
}
""" % (value, mask)

        expected_req = self.make_write_request(p4runtime_pb2.Update.INSERT,
                                               P4RuntimeEntity.table_entry,
                                               expected_entry)

        self.servicer.Write.assert_called_once_with(ProtoCmp(expected_req),
                                                    ANY)
예제 #12
0
    def test_table_indirect_oneshot(self):
        te = sh.TableEntry("IndirectWS")
        te.match["header_test.field32"] = "10.0.0.0"
        a1 = sh.Action("actionA")
        a1["param"] = "aa:bb:cc:dd:ee:ff"
        a2 = sh.Action("actionB")
        a2["param"] = "10"
        te.oneshot.add(a1).add(a2, weight=2)

        expected_entry = """
table_id: 33586946
match {
  field_id: 1
  exact {
    value: "\\x0a\\x00\\x00\\x00"
  }
}
action {
  action_profile_action_set {
    action_profile_actions {
      action {
        action_id: 16783703
        params {
          param_id: 1
          value: "\\xaa\\xbb\\xcc\\xdd\\xee\\xff"
        }
      }
      weight: 1
      watch: 0
    }
    action_profile_actions {
      action {
        action_id: 16809468
        params {
          param_id: 1
          value: "\\x0a"
        }
      }
      weight: 2
      watch: 0
    }
  }
}
"""

        te.insert()

        expected_req = self.make_write_request(p4runtime_pb2.Update.INSERT,
                                               P4RuntimeEntity.table_entry,
                                               expected_entry)
        self.servicer.Write.assert_called_once_with(ProtoCmp(expected_req),
                                                    ANY)

        self.simple_read_check(expected_req.updates[0].entity, te,
                               P4RuntimeEntity.table_entry)
예제 #13
0
def analyzeCongestion():
    congestion_lock.acquire()
    if still_congested[0][0]:
        print("Congestion found on port", still_congested[0][1])
        print("Setting up P4Runtime entry to match on port")
        shell_lock.acquire()
        try:
            te = sh.TableEntry('control_out_port.ipv4_check_checksum')(
                action='DoMirror')
            te.match['standard_metadata.egress_port'] = hex(
                still_congested[0][1])
            te.match['headers.ip.ipv4.hdr_checksum'] = '0x7f00&&&0x7f00'
            te.action['analyzer_port'] = '0x04'
            te.priority = 1
            te.insert()
        finally:
            shell_lock.release()
    else:
        print("No Congestion found")
    congestion_lock.release()
예제 #14
0
    def test_table_metadata(self):
        te = sh.TableEntry("ExactOne")(action="actionA")
        te.metadata = b"abcdef\x00\xff"
        te.insert()

        expected_entry = """
table_id: 33582705
action {
  action {
    action_id: 16783703
  }
}
metadata: "abcdef\\x00\\xff"
"""

        expected_req = self.make_write_request(p4runtime_pb2.Update.INSERT,
                                               P4RuntimeEntity.table_entry,
                                               expected_entry)
        self.servicer.Write.assert_called_once_with(ProtoCmp(expected_req),
                                                    ANY)
예제 #15
0
    def test_table_idle_timeout(self):
        te = sh.TableEntry("ExactOne")(action="actionA")
        te.idle_timeout_ns = 100
        te.insert()

        expected_entry = """
table_id: 33582705
action {
  action {
    action_id: 16783703
  }
}
idle_timeout_ns: 100
"""

        expected_req = self.make_write_request(p4runtime_pb2.Update.INSERT,
                                               P4RuntimeEntity.table_entry,
                                               expected_entry)
        self.servicer.Write.assert_called_once_with(ProtoCmp(expected_req),
                                                    ANY)
예제 #16
0
 def test_table_entry_lpm_dont_care(self):
     te = sh.TableEntry("LpmOne")
     with self.assertRaisesRegex(UserError, "LPM don't care match"):
         te.match["header_test.field32"] = "10.0.0.0/0"
예제 #17
0
import p4runtime_sh.shell as sh

# you can omit the config argument if the switch is already configured with the
# correct P4 dataplane.
sh.setup(device_id=1,
         grpc_addr='172.17.0.2:50001',
         election_id=(1, 0),
         config=sh.FwdPipeConfig('/tmp/cfg/mri.p4.p4info.txt',
                                 '/tmp/cfg/mri.json'))

# see p4runtime_sh/test.py for more examples
te = sh.TableEntry("MyEgress.swtrace")(action="MyEgress.add_swtrace")
te.action["swid"] = ("1")
te.insert()

te = sh.TableEntry("MyIngress.ipv4_lpm")(action="MyIngress.ipv4_forward")
te.match["hdr.ipv4.dstAddr"] = ("10.0.0.1")
te.action["dstAddr"] = ("9a:96:b1:20:bf:84")
te.action["port"] = ("1")
te.insert()

te = sh.TableEntry("MyIngress.ipv4_lpm")(action="MyIngress.ipv4_forward")
te.match["hdr.ipv4.dstAddr"] = ("10.0.0.2")
te.action["dstAddr"] = ("de:cb:66:ce:75:8e")
te.action["port"] = ("2")
te.insert()
# ...

sh.teardown()
예제 #18
0
    def test_table_indirect(self):
        member = sh.ActionProfileMember("ActProfWS")(member_id=1,
                                                     action="actionA")
        member.action["param"] = "aa:bb:cc:dd:ee:ff"
        group = sh.ActionProfileGroup("ActProfWS")(group_id=1)
        group.add(member.member_id)

        expected_member = """
action_profile_id: 285237193
member_id: 1
action {
  action_id: 16783703
  params {
    param_id: 1
    value: "\\xaa\\xbb\\xcc\\xdd\\xee\\xff"
  }
}
"""

        expected_group = """
action_profile_id: 285237193
group_id: 1
members {
  member_id: 1
  weight: 1
}
"""

        expected_entry_1 = """
table_id: 33586946
match {
  field_id: 1
  exact {
    value: "\\x0a\\x00\\x00\\x00"
  }
}
action {
  action_profile_member_id: 1
}
"""

        expected_entry_2 = """
table_id: 33586946
match {
  field_id: 1
  exact {
    value: "\\x0a\\x00\\x00\\x00"
  }
}
action {
  action_profile_group_id: 1
}
"""

        expected_req = self.make_write_request(
            p4runtime_pb2.Update.INSERT, P4RuntimeEntity.action_profile_member,
            expected_member)
        member.insert()
        self.servicer.Write.assert_called_with(ProtoCmp(expected_req), ANY)

        expected_req = self.make_write_request(
            p4runtime_pb2.Update.INSERT, P4RuntimeEntity.action_profile_group,
            expected_group)
        group.insert()
        self.servicer.Write.assert_called_with(ProtoCmp(expected_req), ANY)

        te = sh.TableEntry("IndirectWS")
        te.match["header_test.field32"] = "10.0.0.0"
        te.member_id = member.member_id
        te.insert()

        expected_req = self.make_write_request(p4runtime_pb2.Update.INSERT,
                                               P4RuntimeEntity.table_entry,
                                               expected_entry_1)
        self.servicer.Write.assert_called_with(ProtoCmp(expected_req), ANY)

        te.group_id = group.group_id
        te.modify()

        expected_req = self.make_write_request(p4runtime_pb2.Update.MODIFY,
                                               P4RuntimeEntity.table_entry,
                                               expected_entry_2)
        self.servicer.Write.assert_called_with(ProtoCmp(expected_req), ANY)
예제 #19
0
                        type=int,
                        required=False,
                        default=0,
                        help='The device ID (default 0)')
    parser.add_argument('-n',
                        '--table-name',
                        help='The table name to clean',
                        type=str,
                        required=True)
    return parser.parse_args()


if __name__ == '__main__':
    """
    Clears all entries from a P4 table
    """
    args = get_args()
    logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

    logger.info('Connecting to switch at [%s]', args.grpc_addr)
    sh.setup(device_id=args.dev_id, grpc_addr=args.grpc_addr)

    logger.info('Retrieving table entry - [%s]', args.table_name)
    table_entry = sh.TableEntry(args.table_name)
    logger.info('Table entry to clear - [%s]', table_entry)
    table_entry.read(lambda te: logger.info('Deleting - [%s]', te))
    table_entry.read(lambda te: te.delete())
    logger.info('Table [%s] cleared', args.table_name)

    sh.teardown()
예제 #20
0
 def test_table_entry_range_invalid(self):
     te = sh.TableEntry("RangeOne")
     with self.assertRaisesRegex(UserError, "Invalid range match"):
         te.match["header_test.field32"] = "77..22"
예제 #21
0
 def test_table_entry_range_dont_care(self):
     te = sh.TableEntry("RangeOne")
     with self.assertRaisesRegex(UserError, "range don't care match"):
         te.match["header_test.field32"] = "0..255.255.255.255"
예제 #22
0
 def get_te():
     te = sh.TableEntry("ExactOne")(action="actionA")
     te.match["header_test.field32"] = "0x0"
     te.action["param"] = "00:00:11:00:22:33"
     return te
예제 #23
0
 def test_table_entry_ternary_dont_care(self):
     te = sh.TableEntry("TernaryOne")
     with self.assertRaisesRegex(UserError, "ternary don't care match"):
         te.match["header_test.field32"] = "10.0.0.0&&&0.0.0.0"
예제 #24
0
        ]

entries =   filtering_entries + \
            spgw_entries + \
            forwarding_entries + \
            acl_entries + \
            next_entries + \
            []

print("deleting entries from any previous run")


tables = sh.P4Objects(context.P4Type.table)
count = 0
for table in tables:
    for te in sh.TableEntry(table.name).read():
        count += 1
        te.delete()
print("Deleted %d entries" % count)


print("installing entries")
for i, entry in enumerate(entries):
    print("installing %d" % i)
    try:
        te = sh.TableEntry(entry["table"])(action=entry["action"])
        for key, val in entry["keys"].items():  te.match[key] = val
        for arg,val in entry["args"].items():   te.action[arg] = val
        priority = entry.get("priority", None)
        if priority != None: te.priority = priority
        te.insert()
예제 #25
0
# ======================================#
'''
This is the P4Runtime shell-related setup. We are using p4runtime-shell
open-souce code from the git found at https://github.com/p4lang/p4runtime-shell
and installed on the lab's Collector.
the setup & teardown should only be done once!
'''
if not connection_set[0]:
    shell_lock.acquire()
    try:
        sh.setup(device_id=0,
                 grpc_addr='132.68.36.62:50051',
                 election_id=(0, 1),
                 config=sh.FwdPipeConfig('/tmp/OurMirror.p4info',
                                         '/tmp/OurMirror.bin'))
        te = sh.TableEntry('control_out_port.ipv4_check_checksum')(
            action='DoMirror')
        connection_set[0] = True
        print("connection acomplished")
    finally:
        shell_lock.release()

# ======================================#


def clear():
    # for windows
    if name == 'nt':
        _ = system('cls')

        # for mac and linux(here, os.name is 'posix')
    else: