Skip to content

Commit

Permalink
Add P4UnderlayRoutingTable
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmyzhai committed Feb 20, 2025
1 parent 0457800 commit 8cf2e03
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 17 deletions.
100 changes: 88 additions & 12 deletions dash-pipeline/utils/dash_pipeline_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ def read(self, table_id, match_list = None, priority = None):
for entity in response.entities:
yield entity.table_entry

def write(self, entry, update_type):
req = p4runtime_pb2.WriteRequest()
req.device_id = 0
update = req.updates.add()
update.type = update_type
update.entity.table_entry.CopyFrom(entry)
self.stub.Write(req)


class P4InternalConfigTable(P4Table):
def __init__(self, target=None):
Expand Down Expand Up @@ -144,12 +152,7 @@ def set(self,
if not changed:
return # none of change

req = p4runtime_pb2.WriteRequest()
req.device_id = 0
update = req.updates.add()
update.type = p4runtime_pb2.Update.MODIFY
update.entity.table_entry.CopyFrom(entry)
self.stub.Write(req)
self.write(entry, p4runtime_pb2.Update.MODIFY)
return

# Add one entry
Expand Down Expand Up @@ -190,12 +193,7 @@ def set(self,
else: # default value
param.value = b'\x00'

req = p4runtime_pb2.WriteRequest()
req.device_id = 0
update = req.updates.add()
update.type = p4runtime_pb2.Update.INSERT
update.entity.table_entry.CopyFrom(entry)
self.stub.Write(req)
self.write(entry, p4runtime_pb2.Update.INSERT)


class P4FlowTable(P4Table):
Expand Down Expand Up @@ -283,3 +281,81 @@ def verify_flow(eni_mac, vnet_id, packet, existed = True):

def verify_no_flow(eni_mac, vnet_id, packet):
verify_flow(eni_mac, vnet_id, packet, existed = False)


class P4UnderlayRoutingTable(P4Table):
def __init__(self, target=None):
super(P4UnderlayRoutingTable, self).__init__(target)
self.p4info_table_underlay = self.p4info.get_table("dash_ingress.underlay.underlay_routing")

def get(self,
ip_prefix :str = None, # ipv6 string, ::x.x.x.x for ipv4
ip_prefix_len :int = 128): # in bits
match = p4runtime_pb2.FieldMatch()
match.field_id = 1
match.lpm.value = socket.inet_pton(socket.AF_INET6, ip_prefix)
match.lpm.prefix_len = ip_prefix_len

for entry in self.read(self.p4info_table_underlay.preamble.id, [match]):
return entry

return None

def set(self,
ip_prefix :str = None, # ipv6 string, ::x.x.x.x for ipv4
ip_prefix_len :int = 128, # in bits
packet_action :int = 1, # ACTION_FORWARD
next_hop_id :int = 0): # port 0

entry = self.get(ip_prefix, ip_prefix_len)
if entry:
changed = 0

param = entry.action.action.params[0]
byte_data = packet_action.to_bytes(2, byteorder='big')
if byte_data != param.value:
param.value = byte_data
changed += 1

param = entry.action.action.params[1]
byte_data = next_hop_id.to_bytes(2, byteorder='big')
if byte_data != param.value:
param.value = byte_data
changed += 1

if not changed:
return # none of change

self.write(entry, p4runtime_pb2.Update.MODIFY)
return

# Add one entry
entry = p4runtime_pb2.TableEntry()
entry.table_id = self.p4info_table_underlay.preamble.id
match = entry.match.add()
match.field_id = 1
match.lpm.value = socket.inet_pton(socket.AF_INET6, ip_prefix)
match.lpm.prefix_len = ip_prefix_len

action_pkt_act = self.p4info.get_action("dash_ingress.underlay.pkt_act")
entry.action.action.action_id = action_pkt_act.preamble.id
action = entry.action.action

param = action.params.add()
param.param_id = 1
param.value = packet_action.to_bytes(2, byteorder='big')

param = action.params.add()
param.param_id = 2
param.value = next_hop_id.to_bytes(2, byteorder='big')

self.write(entry, p4runtime_pb2.Update.INSERT)

def unset(self,
ip_prefix :str = None, # ipv6 string, ::x.x.x.x for ipv4
ip_prefix_len :int = 128): # in bits
entry = self.get(ip_prefix, ip_prefix_len)
if entry:
self.write(entry, p4runtime_pb2.Update.DELETE)
else:
print(f'Route entry for {ip_prefix}/{ip_prefix_len} not found.')
18 changes: 13 additions & 5 deletions test/test-cases/functional/ptf/saidashvnet_sanity.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from sai_thrift.sai_headers import *
from sai_base_test import *
from dash_pipeline_utils import use_flow, get_mac, mac_in_bytes, P4InternalConfigTable
from dash_pipeline_utils import use_flow, get_mac, mac_in_bytes, \
P4InternalConfigTable, P4UnderlayRoutingTable

@use_flow
class SaiThriftVnetOutboundUdpPktTest(SaiHelperSimplified):
Expand Down Expand Up @@ -31,6 +32,10 @@ def setUp(self):
P4InternalConfigTable().set(neighbor_mac = mac_in_bytes(self.neighbor_mac),
mac = mac_in_bytes(self.dut_mac))

underlay_routing = P4UnderlayRoutingTable()
underlay_routing.set(ip_prefix = '::'+self.dst_pa_ip, ip_prefix_len = 128, next_hop_id = 1)
assert(underlay_routing.get(ip_prefix = '::'+self.dst_pa_ip, ip_prefix_len = 128))

# Flag to indicate whether configureVnet were successful or not.
self.configured = False

Expand Down Expand Up @@ -252,7 +257,7 @@ def trafficTest(self):
print("\tSending outbound packet...")
send_packet(self, 0, vxlan_pkt)
print("\tVerifying packet...")
verify_packet(self, self.pkt_exp, 0)
verify_packet(self, self.pkt_exp, 1)
print ("SaiThriftVnetOutboundUdpPktTest OK")

def runTest(self):
Expand Down Expand Up @@ -292,6 +297,11 @@ def tearDown(self):
P4InternalConfigTable().set(neighbor_mac = b'\x00\x00\x00\x00\x00\x00',
mac = b'\x00\x00\x00\x00\x00\x00')

# remove underlay route for dst_pa_ip
underlay_routing = P4UnderlayRoutingTable()
underlay_routing.unset(ip_prefix = '::'+self.dst_pa_ip, ip_prefix_len = 128)
assert(underlay_routing.get(ip_prefix = '::'+self.dst_pa_ip, ip_prefix_len = 128) == None)


class SaiThriftVnetOutboundUdpV6PktTest(SaiThriftVnetOutboundUdpPktTest):
""" Test saithrift vnet outbound ipv6"""
Expand All @@ -308,8 +318,6 @@ def setUp(self):
self.ca_prefix_addr = "2000:aaaa::"
self.ca_prefix_mask = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0"
self.dst_ca_ip = "2000:aaaa::232"
self.dst_pa_ip = "172.16.1.30"
self.src_vm_pa_ip = "172.16.1.2"

# SAI attribute name
self.ip_addr_family_attr = 'ip6'
Expand Down Expand Up @@ -408,5 +416,5 @@ def trafficTest(self):
print("\tSending outbound packet...")
send_packet(self, 0, vxlan_pkt)
print("\tVerifying packet...")
verify_packet(self, self.pkt_exp, 0)
verify_packet(self, self.pkt_exp, 1)
print ("SaiThriftVnetOutboundUdpV6PktTest OK")

0 comments on commit 8cf2e03

Please sign in to comment.