Skip to content

Commit

Permalink
client changes for packetIO
Browse files Browse the repository at this point in the history
  • Loading branch information
satish153 committed Oct 24, 2023
1 parent 366f328 commit 78a2310
Showing 1 changed file with 71 additions and 0 deletions.
71 changes: 71 additions & 0 deletions clients/p4rt-ctl/p4rt-ctl.in
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import struct
import sys
import threading
import time
import fcntl
import select
from functools import wraps

import google.protobuf.text_format
Expand Down Expand Up @@ -660,6 +662,26 @@ class P4RuntimeClient:
pass
return None

def get_packet_in(self, timeout=3):
msg = self.get_stream_packet("packet", timeout)
if msg is not None:
return msg.packet

def send_packet_out(self, payload):
packet_out = p4runtime_pb2.PacketOut()
packet_out.payload = payload
packet_out_req = p4runtime_pb2.StreamMessageRequest()
packet_out_req.packet.CopyFrom(packet_out)
self.stream_out_q.put(packet_out_req)

# Continously poll for pkts from the server
def pktio_rx(self, tap_device):
print("Waiting for Rx pkts...")
while True:
pkt = self.get_packet_in()
if pkt is not None:
tap_device.write(pkt.payload)

@parse_p4runtime_error
def get_p4info(self):
req = p4runtime_pb2.GetForwardingPipelineConfigRequest()
Expand Down Expand Up @@ -769,6 +791,54 @@ def p4ctl_show(client, bridge):
def p4ctl_set_pipe(client, bridge, device_config, p4info):
client.set_fwd_pipe_config(p4info, device_config)

TUNSETIFF = 0x400454CA
IFF_TAP = 0x0002
IFF_NO_PI = 0x1000
MAX_FRAME_SIZE = 1500
SELECT_TIMEOUT = 0.1

class TapDevice:
def __init__(self, tap_name):
try:
self.tap = os.open("/dev/net/tun", os.O_RDWR)

# Configure the TAP interface.
ifr = struct.pack('16sH', tap_name.encode(), IFF_TAP | IFF_NO_PI)
fcntl.ioctl(self.tap, TUNSETIFF, ifr)

# Bring the TAP interface up.
os.system(f"sudo ip link set dev {tap_name} up")

print(f"Created TAP device {tap_name}")
except Exception as e:
print(f"Error creating TAP interface: {e}")

# Continuously reads pkts from TAP port and sends them out to the server
def read(self, client):
while True:
readable, _, _ = select.select([self.tap], [], [], SELECT_TIMEOUT)
if self.tap in readable:
# read pkt from tap port
data = os.read(self.tap, MAX_FRAME_SIZE)

# send the packet to the server
client.send_packet_out(data)

# Sends pkts to the tap port
def write(self, data):
os.write(self.tap, data)

# Thread function to read pkts from TAP port
def read_from_tap(tap, client):
print("Tx thread polling on TAP port")
tap.read(client)

@with_client
def p4ctl_start_pktio(client, bridge):
tap_device = TapDevice("pktioTap0")
tx_thread = threading.Thread(target=read_from_tap, args=(tap_device,client))
tx_thread.start()
client.pktio_rx(tap_device)

@with_client
def p4ctl_get_pipe(client, bridge):
Expand Down Expand Up @@ -1611,6 +1681,7 @@ def p4ctl_reset_counter_entry(client, bridge, cnt_tbl_name, flow):
all_commands = {
"show": (p4ctl_show, 1),
"set-pipe": (p4ctl_set_pipe, 3),
"start-pktio": (p4ctl_start_pktio, 1),
"get-pipe": (p4ctl_get_pipe, 1),
"add-entry": (p4ctl_add_entry, 3),
"modify-entry": (p4ctl_mod_entry, 3),
Expand Down

0 comments on commit 78a2310

Please sign in to comment.