From 5906dd362a937d7efab1d337a2c6c5931fb3a79e Mon Sep 17 00:00:00 2001 From: mc36 Date: Fri, 17 Jan 2020 17:50:57 +0100 Subject: [PATCH] adding ipv6 support and del/modify to p4runtime_lib --- utils/p4runtime_lib/convert.py | 19 +++++++++++++++++++ utils/p4runtime_lib/switch.py | 27 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) mode change 100644 => 100755 utils/p4runtime_lib/convert.py mode change 100644 => 100755 utils/p4runtime_lib/switch.py diff --git a/utils/p4runtime_lib/convert.py b/utils/p4runtime_lib/convert.py old mode 100644 new mode 100755 index 0375e1747..f8b073407 --- a/utils/p4runtime_lib/convert.py +++ b/utils/p4runtime_lib/convert.py @@ -1,3 +1,4 @@ +#!/usr/bin/python2 # Copyright 2017-present Open Networking Foundation # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,15 +36,25 @@ def decodeMac(encoded_mac_addr): return ':'.join(s.encode('hex') for s in encoded_mac_addr) ip_pattern = re.compile('^(\d{1,3}\.){3}(\d{1,3})$') +ipv6_pattern = re.compile('^(?:(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-fA-F]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,1}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,2}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,3}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:[0-9a-fA-F]{1,4})):)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,4}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,5}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,6}(?:(?:[0-9a-fA-F]{1,4})))?::))))$') def matchesIPv4(ip_addr_string): return ip_pattern.match(ip_addr_string) is not None +# enable ipv6 +def matchesIPv6(ip_addr_string): + return ipv6_pattern.match(ip_addr_string) is not None def encodeIPv4(ip_addr_string): return socket.inet_aton(ip_addr_string) +def encodeIPv6(ip_addr_string): + return socket.inet_pton(socket.AF_INET6,ip_addr_string) + def decodeIPv4(encoded_ip_addr): return socket.inet_ntoa(encoded_ip_addr) +def decodeIPv6(encoded_ip_addr): + return socket.inet_ntop(encoded_ip_addr) + def bitwidthToBytes(bitwidth): return int(math.ceil(bitwidth / 8.0)) @@ -68,9 +79,13 @@ def encode(x, bitwidth): encoded_bytes = encodeMac(x) elif matchesIPv4(x): encoded_bytes = encodeIPv4(x) + elif matchesIPv6(x): + encoded_bytes = encodeIPv6(x) else: # Assume that the string is already encoded encoded_bytes = x + # using encode IPV6 + # encoded_bytes = encodeIPv6(x) elif type(x) == int: encoded_bytes = encodeNum(x, bitwidth) else: @@ -104,6 +119,10 @@ def encode(x, bitwidth): assert(not matchesIPv4('1000.0.0.1')) assert(not matchesIPv4('10001')) + assert(matchesIPv6('::1234')) + assert(matchesIPv6('1234::')) + assert(matchesIPv6('1234::1234')) + assert(encode(mac, 6 * 8) == enc_mac) assert(encode(ip, 4 * 8) == enc_ip) assert(encode(num, 5 * 8) == enc_num) diff --git a/utils/p4runtime_lib/switch.py b/utils/p4runtime_lib/switch.py old mode 100644 new mode 100755 index a7c4f7a94..a997ba614 --- a/utils/p4runtime_lib/switch.py +++ b/utils/p4runtime_lib/switch.py @@ -99,6 +99,33 @@ def WriteTableEntry(self, table_entry, dry_run=False): print "P4Runtime Write:", request else: self.client_stub.Write(request) + # Modify + def ModifyTableEntry(self, table_entry, dry_run=False): + request = p4runtime_pb2.WriteRequest() + request.device_id = self.device_id + request.election_id.low = 1 + update = request.updates.add() + # Assign Modify Type for it + update.type = p4runtime_pb2.Update.MODIFY + update.entity.table_entry.CopyFrom(table_entry) + if dry_run: + print "P4Runtime Modify: ", request + else: + self.client_stub.Write(request) + + # Delete + def DeleteTableEntry(self, table_entry, dry_run=False): + request = p4runtime_pb2.WriteRequest() + request.device_id = self.device_id + request.election_id.low = 1 + update = request.updates.add() + # Assign DELETE Type for it + update.type = p4runtime_pb2.Update.DELETE + update.entity.table_entry.CopyFrom(table_entry) + if dry_run: + print "P4Runtime Delete: ", request + else: + self.client_stub.Write(request) def ReadTableEntries(self, table_id=None, dry_run=False): request = p4runtime_pb2.ReadRequest()