-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
client changes for packetIO #321
Changes from all commits
61ab005
2cd4c14
5b401d3
9bf65a4
c975e85
c2ce53f
1f1d884
e8c6feb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -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) | ||
|
||
# Continuously poll for pkts from the server | ||
def pktio_rx(self, tap_device): | ||
print("Waiting for Rx packets...") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want to have a print statement inside a continuous poll function? This will spam and slow down There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you asking about Output of start-pktio looks like below:
|
||
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() | ||
|
@@ -769,6 +791,60 @@ def p4ctl_show(client, bridge): | |
def p4ctl_set_pipe(client, bridge, device_config, p4info): | ||
client.set_fwd_pipe_config(p4info, device_config) | ||
|
||
class TapDevice: | ||
def __init__(self, tap_name): | ||
|
||
self.tap_name = tap_name | ||
|
||
# constants derived from | ||
# https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/if_tun.h#L34 | ||
TUNSETIFF = 0x400454CA | ||
satish153 marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use a macro to define these contstants instead and add a comment that it's from linux/if_tun.h? https://peps.python.org/pep-0591/ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same comment applicable for all the values below There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I understand, uppercase variable names are used to indicate that a variable's value should be treated as constant. I understand the variable is not truly immutable but that's the convention used to declare consts. Thanks for the reference on using 'Final'. I now, learnt that there is a way to enforce immutability. However, it involves importing an additional module which might be a overkill in this specific case. |
||
IFF_TAP = 0x0002 | ||
IFF_NO_PI = 0x1000 | ||
try: | ||
self.tap = os.open("/dev/net/tun", os.O_RDWR) | ||
satish153 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Configure the TAP interface. | ||
ifr = struct.pack('16sH', self.tap_name.encode(), IFF_TAP | IFF_NO_PI) | ||
fcntl.ioctl(self.tap, TUNSETIFF, ifr) | ||
|
||
print(f"Created TAP device {self.tap_name}") | ||
except Exception as e: | ||
print(f"Error creating TAP interface: {e}") | ||
if self.tap is not None: | ||
os.close(self.tap) | ||
|
||
# Continuously reads pkts from TAP port and sends them out to the server | ||
def read(self, client): | ||
MAX_FRAME_SIZE = 1500 | ||
SELECT_TIMEOUT = 0.1 | ||
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): | ||
try: | ||
tap_device = TapDevice("pktioTap0") | ||
tx_thread = threading.Thread(target=read_from_tap, args=(tap_device,client)) | ||
tx_thread.start() | ||
client.pktio_rx(tap_device) | ||
except Exception as e: | ||
print(f"Error: Failed to start packetIo {e}") | ||
|
||
@with_client | ||
def p4ctl_get_pipe(client, bridge): | ||
|
@@ -1611,6 +1687,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), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
p4runtime==1.3.0 | ||
fcntl | ||
select |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When manifest is updated with this SHA, please update ACC scripts as well to include fcntl and select python packages
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok