From 88f898d1f5d34b9b1562b885be342d3a07eecf33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20K=C3=B6ppeler?= Date: Sun, 23 Jul 2023 17:47:46 +0200 Subject: [PATCH 1/2] PSA eBPF: Commands: Clone Command Implements cloning functionality. Usage in P4RROT: Clone([UdpDstPort.handle], table_name="clone_table", action_name="assign_clone") Control Plane needs to fill the table and the clone-sessions. For example: nikss-ctl clone-session create pipe 1 id 123 nikss-ctl clone-session add-member pipe 1 id 123 egress-port 2 instance 1 nikss-ctl clone-session add-member pipe 1 id 123 egress-port 3 instance 2 nikss-ctl clone-session get pipe 1 id 123 nikss-ctl table add pipe 1 ebpfIngress_clone_table action name ebpfIngress_assign_clone key 5555 data 123 --- src/p4rrot/psa_ebpf/commands.py | 56 +++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/p4rrot/psa_ebpf/commands.py b/src/p4rrot/psa_ebpf/commands.py index 4c80dc3..51c0d1f 100644 --- a/src/p4rrot/psa_ebpf/commands.py +++ b/src/p4rrot/psa_ebpf/commands.py @@ -3,6 +3,7 @@ from p4rrot.standard_fields import * from p4rrot.generator_tools import * from p4rrot.checks import * +from p4rrot.core.commands import * import random class AssignRandomValue(Command): @@ -85,3 +86,58 @@ def get_generated_code(self): def execute(self, test_env): pass + + +class Clone(Command): + def __init__(self, keys, table_name=None, action_name=None, env=None): + self.keys = keys + self.env = env + if table_name is None: + self.table_name = "clone_table" + UID.get() + else: + self.table_name=table_name + + if action_name is None: + self.action_name = "setter_action_" + UID.get() + else: + self.action_name = action_name + + + def check(self): + pass + + def get_generated_code(self): + gc = GeneratedCode() + decl = gc.get_decl() + decl.writeln(f"action {self.action_name}(CloneSessionId_t clone_session) {{") + decl.increase_indent() + decl.writeln("ostd.clone_session_id = clone_session;") + decl.writeln("ostd.clone = true;") + decl.decrease_indent() + decl.writeln("}") + + + apply = gc.get_apply() + match = [] + for key in self.keys: + match.append(self.env.get_varinfo(key)) + actions = [self.action_name, "NoAction"] + + try: + key = [ + {"name": part_key["handle"], "match_type": "exact"} for part_key in match + ] + except TypeError: + key = [ + {"name": part_key.get_handle(), "match_type": "exact"} for part_key in match + ] + size = 256 + const_entries = [] + default_action = "NoAction" + eval_table = Table( + self.table_name, actions, key, size, const_entries, default_action + ) + gc.concat(eval_table.get_generated_code()) + apply.writeln("{}.apply();".format(self.table_name)) + + return gc From 9c9e883ab6549e6f91548419cb4cdf67c0af8d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20K=C3=B6ppeler?= Date: Sun, 20 Aug 2023 11:42:31 +0200 Subject: [PATCH 2/2] PSA eBPF: Adding Clone Testcase --- tests/psa_ebpf/clone/.gitignore | 4 ++++ tests/psa_ebpf/clone/codegen.py | 39 +++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/psa_ebpf/clone/.gitignore create mode 100644 tests/psa_ebpf/clone/codegen.py diff --git a/tests/psa_ebpf/clone/.gitignore b/tests/psa_ebpf/clone/.gitignore new file mode 100644 index 0000000..05cb342 --- /dev/null +++ b/tests/psa_ebpf/clone/.gitignore @@ -0,0 +1,4 @@ +*.p4 +*.bc +*.c +*.o \ No newline at end of file diff --git a/tests/psa_ebpf/clone/codegen.py b/tests/psa_ebpf/clone/codegen.py new file mode 100644 index 0000000..4b899bc --- /dev/null +++ b/tests/psa_ebpf/clone/codegen.py @@ -0,0 +1,39 @@ +import sys +sys.path.append('../../../src/') + +from p4rrot.generator_tools import * +from p4rrot.known_types import * +from p4rrot.standard_fields import * +from p4rrot.core.commands import * +from p4rrot.tcp_fields import * +from p4rrot.psa_ebpf.commands import * + + + +UID.reset() +fp = FlowProcessor( + istruct = [], + ostruct = [], + standard_fields = [UdpDstPort] +) + + + +( +fp +.add(Clone([UdpDstPort.handle], table_name="clone_table", action_name="assign_clone")) +) + + + +fs = FlowSelector( + 'IPV4_UDP', + [(UdpDstPort,5555)], + fp + ) + + +solution = Solution() +solution.add_flow_processor(fp) +solution.add_flow_selector(fs) +solution.get_generated_code().dump('template')