From cfd73a80b38bbaca5886ae63149b2c341f2b792a Mon Sep 17 00:00:00 2001 From: nupuruttarwar Date: Fri, 1 Dec 2023 11:15:16 -0800 Subject: [PATCH 01/31] Edits to the IPsec offload documentation Signed-off-by: nupuruttarwar --- docs/apps/ipsec-offload.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/apps/ipsec-offload.md b/docs/apps/ipsec-offload.md index 4f3df7cc..ba538cb2 100644 --- a/docs/apps/ipsec-offload.md +++ b/docs/apps/ipsec-offload.md @@ -44,10 +44,10 @@ to load the hardware FXP pipeline with the IPsec package. ### Configure and run infrap4d -To be able to program Security Association Database (SAD) entries using gNMI, -enable fixed function support in infrap4d. Follow the instructions in +Follow the instructions in [Running infrap4d](/guides/es2k/running-infrap4d.md) -to prepare system with generated TDI.json and context.json file references. +and prepare the system with generated TDI.json and context.json file references. +In order to offload IPsec, fixed function support must be enabled in infrap4d. The /usr/share/stratum/es2k/es2k_skip_p4.conf file must include the fixed function configuration reference. @@ -82,7 +82,7 @@ between local and peer system. This section provides detailed information on OpenConfig model and gNMI messages with the expected format. The strongSwan plugin has the following -details encoded. +details encoded, and user interaction is not needed. ### Config SAD message @@ -130,10 +130,10 @@ at `/ipsec-offload/ipsec-spi/rx-spi`. ### Key Expiry Notification message The [gRPC Notification message](https://github.com/ipdk-io/openconfig-public/blob/master/release/models/ipsec/openconfig-ipsec-offload.yang#L308) -at `/ipsec-offload` is used as a signal to trigger the +at `/ipsec-offload/sadb-expire` is used as a signal to trigger the re-keying mechanism in IKE protocol. A gNMI subscription stream is opened from the gNMI client listening to these notification messages originating in the target. Upon receiving this -notification, clients will initiate the re-keying mechanism to refresh +notification, client will initiate the re-keying mechanism to refresh the encyrption keys. From b0cb1dddfbe6dad9cdeb1e7c5c6ee95a7b1bf389 Mon Sep 17 00:00:00 2001 From: Sabeel Ansari Date: Thu, 30 Mar 2023 23:25:05 -0700 Subject: [PATCH 02/31] Fix typo Signed-off-by: Sabeel Ansari --- docs/apps/ipsec-offload.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/apps/ipsec-offload.md b/docs/apps/ipsec-offload.md index ba538cb2..e230ca72 100644 --- a/docs/apps/ipsec-offload.md +++ b/docs/apps/ipsec-offload.md @@ -136,4 +136,4 @@ re-keying mechanism in IKE protocol. A gNMI subscription stream is opened from the gNMI client listening to these notification messages originating in the target. Upon receiving this notification, client will initiate the re-keying mechanism to refresh -the encyrption keys. +the encryption keys. From dfad41252c5c5f2cf0d7d20ecc54f946e7639801 Mon Sep 17 00:00:00 2001 From: bharticemk Date: Sun, 3 Dec 2023 21:55:34 -0500 Subject: [PATCH 03/31] Correction in p4ctl_get_direct_pkt_mod_meter_entry for variable rename Signed-off-by: bharticemk --- clients/p4rt-ctl/p4rt-ctl.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/p4rt-ctl/p4rt-ctl.in b/clients/p4rt-ctl/p4rt-ctl.in index aa0b8de6..d2979b9f 100644 --- a/clients/p4rt-ctl/p4rt-ctl.in +++ b/clients/p4rt-ctl/p4rt-ctl.in @@ -1898,7 +1898,7 @@ def p4ctl_get_direct_pkt_mod_meter_entry(client, bridge, tbl_name, flow): raise Exception("Cannot find direct_meter_entry field in entity") te = helper.buildTableEntry( - table_name=cnt_tbl_name, + table_name=tbl_name, match_fields=key ) From d846cf99ec6920b3d7728dba1f88266e02e7c2eb Mon Sep 17 00:00:00 2001 From: Sabeel Ansari Date: Mon, 4 Dec 2023 12:37:39 -0800 Subject: [PATCH 04/31] Add note on OpenSSL version in TLS certs doc Signed-off-by: Sabeel Ansari --- docs/guides/security/using-tls-certificates.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/guides/security/using-tls-certificates.md b/docs/guides/security/using-tls-certificates.md index a53fcfc1..3d941695 100644 --- a/docs/guides/security/using-tls-certificates.md +++ b/docs/guides/security/using-tls-certificates.md @@ -24,6 +24,14 @@ COMMON_NAME= ./generate-certs.sh The system relies on mTLS (mutual TLS) for authentication. +### OpenSSL version + +The `/usr/share/stratum/generate-certs.sh` script uses the installed OpenSSL version to generate the certificates. + +OpenSSL 1.1.1x has reached EOL and usage should be discontinued. See the [OpenSSL security guide](openssl-guide.md) for details. + +Also, note that if running gRPC clients on remote system, both systems are running OpenSSL 3.x. Running an OpenSSL 1.1.1x client with a OpenSSL 3.x server has known to fail TLS handshakes to establish communication. + ## Installing certificates `infrap4d` will check for server certificates in the default location From d0efd7c6dae56ef7f06eb033970ce60f8a10e943 Mon Sep 17 00:00:00 2001 From: Sabeel Ansari Date: Mon, 4 Dec 2023 12:43:56 -0800 Subject: [PATCH 05/31] Fix language based on comments Signed-off-by: Sabeel Ansari --- docs/guides/security/using-tls-certificates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/security/using-tls-certificates.md b/docs/guides/security/using-tls-certificates.md index 3d941695..0ec5e761 100644 --- a/docs/guides/security/using-tls-certificates.md +++ b/docs/guides/security/using-tls-certificates.md @@ -30,7 +30,7 @@ The `/usr/share/stratum/generate-certs.sh` script uses the installed OpenSSL ver OpenSSL 1.1.1x has reached EOL and usage should be discontinued. See the [OpenSSL security guide](openssl-guide.md) for details. -Also, note that if running gRPC clients on remote system, both systems are running OpenSSL 3.x. Running an OpenSSL 1.1.1x client with a OpenSSL 3.x server has known to fail TLS handshakes to establish communication. +Also, note that if running gRPC clients on remote system, both systems should be running OpenSSL 3.x. Running an OpenSSL 1.1.1x client with a OpenSSL 3.x server has been known to fail TLS handshakes with `WRONG_VERSION_NUMBER` error when trying to establish communication. ## Installing certificates From 5e68d1024bccdc367820dd84326736a82390ebfc Mon Sep 17 00:00:00 2001 From: Sabeel Ansari Date: Tue, 5 Dec 2023 13:47:30 -0800 Subject: [PATCH 06/31] Add SDE_INSTALL lib path to LD_LIBARY_PATH only if directories exist Signed-off-by: Sabeel Ansari --- scripts/common/setup_env.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/common/setup_env.sh b/scripts/common/setup_env.sh index 25ff380f..b5f9eb4e 100755 --- a/scripts/common/setup_env.sh +++ b/scripts/common/setup_env.sh @@ -37,11 +37,12 @@ echo "${OS} : ${VER}" # Update SDE libraries export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${SDE_INSTALL}/lib -export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${SDE_INSTALL}/lib64 -if [ "$OS" = "Fedora" ]; then +if [ -d ${SDE_INSTALL}/lib64 ]; then export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${SDE_INSTALL}/lib64 -else +fi + +if [ -d ${SDE_INSTALL}/lib/x86_64-linux-gnu ]; then export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${SDE_INSTALL}/lib/x86_64-linux-gnu fi From 34120804910ca0e1ea87b19f1a8350da2234ed63 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 22 Nov 2023 08:50:15 -0500 Subject: [PATCH 07/31] LAG documentation Signed-off-by: root Signed-off-by: Kumar, Aashish --- .../lnw/es2k/es2k-linux-networking-lag.md | 336 ++++++++++++++++++ 1 file changed, 336 insertions(+) create mode 100644 docs/apps/lnw/es2k/es2k-linux-networking-lag.md diff --git a/docs/apps/lnw/es2k/es2k-linux-networking-lag.md b/docs/apps/lnw/es2k/es2k-linux-networking-lag.md new file mode 100644 index 00000000..62c89b62 --- /dev/null +++ b/docs/apps/lnw/es2k/es2k-linux-networking-lag.md @@ -0,0 +1,336 @@ + + +# Linux Networking with LAG (ES2K) + +This document explains how to run the Linux networking scenario with LAG(Link Aggregation Group) on ES2K. + +## Topology + +![Linux Networking Topology](es2k-ecmp-topology.png) + +Notes about topology: + +- Four Kernel netdevs are created by default by loading IDPF driver during ACC bring-up. You can also create more than Four netdevs. For that, we need to modify `acc_apf` parameter under `num_default_vport` in `/etc/dpcp/cfg/cp_init.cfg` on IMC before starting `run_default_init_app`. +- In `/etc/dpcp/cfg/cp_init.cfg` file also modify default `sem_num_pages` value to the value mentioned in `/opt/p4/p4sde/share/mev_reference_p4_files/linux_networking/README_P4_CP_NWS`. +- In `/etc/dpcp/cfg/cp_init.cfg` file also modify default `allow_change_mac_address` value to true. +- vlan1, vlan2, .... vlanN created using Linux commands and are on top of an IDPF Netdev. These VLAN ports should be equal to number of VM's that are spawned. +- br-int, VxLAN ports are created using ovs-vsctl command provided by the networking recipe and all the vlan ports are attached to br-int using ovs-vsctl command. +- Both physical ports P0 and P1 should be B2B connected to the Link Partner device and LAG should be configured on both the devices with the associated ports as LAG members using ip link command. + +System under test will have above topology running the networking recipe. Link Partner can have the networking recipe or legacy OvS or kernel VxLAN. Note the [Limitations](#limitations) section before setting up the topology. + +## Create P4 artifacts and start Infrap4d process + +- Use Linux networking p4 program present in the directory `/opt/p4/p4sde/share/mev_reference_p4_files/linux_networking` for this scenario. +- See [Running Infrap4d on Intel IPU E2100](/guides/es2k/running-infrap4d) for compiling `P4 artifacts`, `bringing up ACC` and running `infrap4d` on ACC. + +## Creating the topology + +The p4rt-ctl and ovs-vsctl utilities can be found in $P4CP_INSTALL/bin. + +### Set the forwarding pipeline + +Once the application is started, set the forwarding pipeline config using +P4Runtime Client `p4rt-ctl` set-pipe command + +```bash +$P4CP_INSTALL/bin/p4rt-ctl set-pipe br0 $OUTPUT_DIR/linux_networking.pb.bin \ + $OUTPUT_DIR/linux_networking.p4info.txt +``` + +Note: Assuming `linux_networking.pb.bin` and `linux_networking.p4info.txt` +along with other P4 artifacts are created as per the steps mentioned in previous section. + +### Configure VSI Group and add a netdev + +Use one of the IDPF netdevs on ACC to receive all control packets from overlay +VM's by assigning to a VSI group. VSI group 3 is dedicated for this configuration, +execute below devmem commands on IMC. + +```bash +# SEM_DIRECT_MAP_PGEN_CTRL: LSB 11-bit is for vsi which need to map into vsig +devmem 0x20292002a0 64 0x8000050000000008 + +# SEM_DIRECT_MAP_PGEN_DATA_VSI_GROUP : This will set vsi +# (set in SEM_DIRECT_MAP_PGEN_CTRL register LSB) into VSIG-3 +devmem 0x2029200388 64 0x3 + +# SEM_DIRECT_MAP_PGEN_CTRL: LSB 11-bit is for vsi which need to map into vsig +devmem 0x20292002a0 64 0xA000050000000008 +``` + +Note: Here VSI 8 has been used for receiving all control packets and added +to VSI group 3. This refers to HOST netdev VSIG 3 as per the topology +diagram. Modify this VSI based on your configuration. + +### Create Overlay network + +Option 1: Create VF's on HOST and spawn VM's on top of those VF's. +Example to create 4 VF's: echo 4 > /sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.0/sriov_numvfs + +```bash +# VM1 configuration +telnet +ip addr add 99.0.0.1/24 dev +ifconfig up + +# VM2 configuration +telnet +ip addr add 99.0.0.2/24 dev +ifconfig up +``` + +Option 2: If we are unable to spawn VM's on top of the VF's, for this use case we can also leverage kernel network namespaces. +Move each VF to a network namespace and assign IP addresses + +```bash +ip netns add VM0 +ip link set netns VM0 +ip netns exec VM0 ip addr add 99.0.0.1/24 dev +ip netns exec VM0 ifconfig up + +ip netns add VM1 +ip link set netns VM1 +ip netns exec VM1 ip addr add 99.0.0.2/24 dev +ip netns exec VM1 ifconfig up +``` + +### Start OvS as a separate process + +Legacy OvS is used as a control plane for source MAC learning of overlay VM's. OvS should be started as a seperate process. + +```bash +export RUN_OVS=/tmp +rm -rf $RUN_OVS/etc/openvswitch +rm -rf $RUN_OVS/var/run/openvswitch +mkdir -p $RUN_OVS/etc/openvswitch/ +mkdir -p $RUN_OVS/var/run/openvswitch + +ovsdb-tool create $RUN_OVS/etc/openvswitch/conf.db \ + /opt/p4/p4-cp-nws/share/openvswitch/vswitch.ovsschema + +ovsdb-server $RUN_OVS/etc/openvswitch/conf.db \ + --remote=punix:$RUN_OVS/var/run/openvswitch/db.sock \ + --remote=db:Open_vSwitch,Open_vSwitch,manager_options \ + --pidfile=$RUN_OVS/var/run/openvswitch/ovsdb-server.pid \ + --unixctl=$RUN_OVS/var/run/openvswitch/ovsdb-server.ctl \ + --detach + +ovs-vswitchd --detach \ + --pidfile=$RUN_OVS/var/run/openvswitch/ovs-vswitchd.pid \ + --no-chdir unix:$RUN_OVS/var/run/openvswitch/db.sock \ + --unixctl=$RUN_OVS/var/run/openvswitch/ovs-vswitchd.ctl \ + --mlockall \ + --log-file=/tmp/ovs-vswitchd.log + +alias ovs-vsctl="ovs-vsctl --db unix:$RUN_OVS/var/run/openvswitch/db.sock" +ovs-vsctl set Open_vSwitch . other_config:n-revalidator-threads=1 +ovs-vsctl set Open_vSwitch . other_config:n-handler-threads=1 + +ovs-vsctl show +``` + +### Create VLAN representers + +For each VM that is spawned for overlay network we need to have a port representer. +We create VLAN netdevs on top of the IPDF netdev which is assigned to VSI group 3 in step-2 mentioned above. + +```bash +ip link add link name vlan1 type vlan id 1 +ip link add link name vlan2 type vlan id 2 +ifconfig vlan1 up +ifconfig vlan2 up +``` + +Note: Here the assumption is, we have created 2 overlay VM's and creating 2 port representers for those VM's. +Port representer should always be in the format: `lowercase string 'vlan'+'vlanID'` + +### Create integration bridge and add ports to the bridge + +Create OvS bridge, VxLAN tunnel and assign ports to the bridge. + +```bash +ovs-vsctl add-br br-int +ifconfig br-int up + +ovs-vsctl add-port br-int vlan1 +ovs-vsctl add-port br-int vlan2 +ifconfig vlan1 up +ifconfig vlan2 up + +ovs-vsctl add-port br-int vxlan1 -- set interface vxlan1 type=vxlan \ + options:local_ip=30.1.1.1 options:remote_ip=40.1.1.1 options:dst_port=4789 +``` + +Note: Here we are creating VxLAN tunnel with VNI 0, you can create any VNI for tunneling. + +### Configure rules for overlay control packets + +Configure rules to send overlay control packets from a VM to its respective port representers. + +Below configuration assumes + +- Overlay VF1 has a VSI value 14 +- Overlay VF2 has a VSI value 15 + +These VSI values can be checked with `/usr/bin/cli_client -q -c` command +on IMC. This command provides VSI ID, Vport ID, and corresponding MAC +addresses for all: + +- IDPF netdevs on ACC +- VF's on HOST +- IDPF netdevs on HOST (if IDPF driver loaded by you on HOST) +- Netdevs on IMC + +```bash +# Rules for control packets coming from overlay VF (VSI-14). +# IPU will add a VLAN tag 1 and send to HOST1 (VSI-8). + +p4rt-ctl add-entry br0 linux_networking_control.handle_tx_from_host_to_ovs_and_ovs_to_wire_table \ + "vmeta.common.vsi=14,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.add_vlan_and_send_to_port(1,24)" +p4rt-ctl add-entry br0 linux_networking_control.handle_rx_loopback_from_host_to_ovs_table \ + "vmeta.common.vsi=14,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.set_dest(24)" +p4rt-ctl add-entry br0 linux_networking_control.vlan_push_mod_table \ + "vmeta.common.mod_blob_ptr=1,action=linux_networking_control.vlan_push(1,0,1)" + +# Rules for control packets coming from overlay VF (VSI-15). +# IPU will add a VLAN tag 2 and send to HOST1 (VSI-8). + +p4rt-ctl add-entry br0 linux_networking_control.handle_tx_from_host_to_ovs_and_ovs_to_wire_table \ + "vmeta.common.vsi=15,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.add_vlan_and_send_to_port(2,24)" +p4rt-ctl add-entry br0 linux_networking_control.handle_rx_loopback_from_host_to_ovs_table \ + "vmeta.common.vsi=15,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.set_dest(24)" +p4rt-ctl add-entry br0 linux_networking_control.vlan_push_mod_table \ + "vmeta.common.mod_blob_ptr=2,action=linux_networking_control.vlan_push(1,0,2)" + +# Rules for control packets coming from HOST1 (VSI-8). +# IPU will remove the VLAN tag 1 and send to overlay VF (VSI-14). + +p4rt-ctl add-entry br0 linux_networking_control.handle_tx_from_ovs_to_host_table \ + "vmeta.common.vsi=8,hdrs.dot1q_tag[vmeta.common.depth].hdr.vid=1,action=linux_networking_control.remove_vlan_and_send_to_port(1,30)" +p4rt-ctl add-entry br0 linux_networking_control.handle_rx_loopback_from_ovs_to_host_table \ + "vmeta.misc_internal.vm_to_vm_or_port_to_port[27:17]=14,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.set_dest(30)" +p4rt-ctl add-entry br0 linux_networking_control.vlan_pop_mod_table \ + "vmeta.common.mod_blob_ptr=1,action=linux_networking_control.vlan_pop" + +# Rules for control packets coming from HOST1 (VSI-8). +# IPU will remove the VLAN tag 2 and send to overlay VF (VSI-15). + +p4rt-ctl add-entry br0 linux_networking_control.handle_tx_from_ovs_to_host_table \ + "vmeta.common.vsi=8,hdrs.dot1q_tag[vmeta.common.depth].hdr.vid=2,action=linux_networking_control.remove_vlan_and_send_to_port(2,31)" +p4rt-ctl add-entry br0 linux_networking_control.handle_rx_loopback_from_ovs_to_host_table \ + "vmeta.misc_internal.vm_to_vm_or_port_to_port[27:17]=15,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.set_dest(31)" +p4rt-ctl add-entry br0 linux_networking_control.vlan_pop_mod_table \ + "vmeta.common.mod_blob_ptr=2,action=linux_networking_control.vlan_pop" +``` + +### Configure rules for underlay control packets + +Configure rules to send underlay control packets from IDPF netdev to physical port. + +Below configuration assumes + +- Underlay IDPF netdev has a VSI value 10 for first LAG member +- First physical port will have a port ID of 0 +- Underlay IDPF netdev has a VSI value 11 for second LAG member +- Second physical port will have a port ID of 1 + +```bash +# Configuration for control packets between physical port 0 to underlay IDPF netdev VSI-10 +p4rt-ctl add-entry br0 linux_networking_control.handle_rx_from_wire_to_ovs_table \ + "vmeta.common.port_id=0,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.set_dest(26)" + +# Configuration for control packets between underlay IDPF netdev VSI-10 to physical port 0 +p4rt-ctl add-entry br0 linux_networking_control.handle_tx_from_host_to_ovs_and_ovs_to_wire_table \ + "vmeta.common.vsi=10,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.set_dest(0)" + +# Configuration for control packets between physical port 1 to underlay IDPF netdev VSI-11 +p4rt-ctl add-entry br0 linux_networking_control.handle_rx_from_wire_to_ovs_table \ + "vmeta.common.port_id=1,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.set_dest(27)" + +# Configuration for control packets between underlay IDPF netdev VSI-11 to physical port 1 +p4rt-ctl add-entry br0 linux_networking_control.handle_tx_from_host_to_ovs_and_ovs_to_wire_table \ + "vmeta.common.vsi=11,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.set_dest(1)" +``` + +### LAG configuration + +Create a LAG interface and add 2 IDPF netdevs as LAG members in it. Assign IP to the LAG interface. + +Below configuration assumes + +- Underlay IDPF netdev has a VSI value 10 for first LAG member +- Underlay IDPF netdev has a VSI value 11 for second LAG member + +```bash +ip link add bond0 type bond miimon 100 mode active-backup +ip link set down +ip link set master bond0 +ip link set down +ip link set master bond0 +ip link set bond0 up +ifconfig bond0 40.1.1.1/24 up +ip route change 40.1.1.0/24 via 40.1.1.2 dev bond0 +``` + +Sample link partner underlay configuration. +Create a LAG interface and assign IP to the LAG interface +Assuming ens785f0np0 and ens785f1np1 ports are B2B connected to MEV. + +```bash +ip link add bond0 type bond miimon 100 mode active-backup +ip link set ens785f0np0 down +ip link set ens785f0np0 master bond0 +ip link set ens785f1np1 down +ip link set ens785f1np1 master bond0 +ip link set bond0 up +ifconfig bond0 40.1.1.2/24 up + +ip link add vxlan0 type vxlan id 0 dstport 4789 remote 40.1.1.1 local 40.1.1.2 dev bond0 +ip addr add 40.1.1.2/24 dev bond0 +ip addr add 99.0.0.3/24 dev vxlan0 +ip link set vxlan0 up +ip link set bond0 up +``` + +### Test the ping scenarios + +- Verify the underlay ping is working fine via the active path. +- Verify the overlay ping between VM's on same host is working fine via the active path. +- Note the active link by using the command "cat /proc/net/bonding/bond0" on both MEV host and LP device. +- Shut the active link on both MEV host and its peer Link Partner. +- Verify the switchover happened from active to backup interface. +- Verify both underlay and overlay ping are working fine and taking a backup path. + +## Limitations + +Current Linux Networking support for the networking recipe has following limitations: + +- All VLAN interfaces created on top of IDPF netdev, should always be in lowercase format "vlan+vlan_id" +Ex: vlan1, vlan2, vlan3 ... vlan4094. +- Set the pipeline before adding br-int port, vxlan0 port, and adding vlan ports to br-int bridge. +- VxLAN destination port should always be standard port. i.e., 4789. (limitation by p4 parser) +- We do not support any ofproto rules that would prevent FDB learning on OvS. +- VLAN Tagged packets are not supported. +- For VxLAN tunneled packets only IPv4-in-IPv4 is supported. +- LAG and ECMP are mutually exclusive. Both can't co-exist in the system configuration at the same time. +- LAG configuration done via bonding driver is supported and the supported mode in active-backup. +- Number of nexthop table entries cannot go beyond 8K, because nexthop table is now part of WCM block. From 934b5550efe5760c9761fcd42a19ec7fd521c6eb Mon Sep 17 00:00:00 2001 From: Derek G Foster Date: Mon, 20 Nov 2023 09:11:04 -0800 Subject: [PATCH 08/31] Update README in protobufs directory (#357) - Add "Build environment" section. - Add "Escaping the ACC build environment" section. Signed-off-by: Derek G Foster Signed-off-by: Kumar, Aashish --- protobufs/README.md | 120 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 108 insertions(+), 12 deletions(-) diff --git a/protobufs/README.md b/protobufs/README.md index 28cb34b8..57012bef 100644 --- a/protobufs/README.md +++ b/protobufs/README.md @@ -11,16 +11,37 @@ The following packages must be installed: - Stratum dependencies - Python 3.8 or above -- Python dependencies (`requirements.txt`) +- Python dependencies + +The Python wheel requires that the `build`, `setuptools`, and `wheel` +modules be installed. These are included in the `requirements.txt` file. If you wish to generate protobufs for Go, follow the instructions in the [Quick start](https://grpc.io/docs/languages/go/quickstart/) guide -to install Go and the gRPC plugins. +to install golang and the gRPC plugins. + +## Build environment + +The P4Runtime protobufs are built in HOST mode. They are are not +cross-compiled, and will not build correctly in the cross-compilation +environment. + +The build requires the Host (x86) dependencies, not the ACC (aarch64) +dependencies. + +You may use the `DEPEND_INSTALL` environment variable +or the `DEPEND_INSTALL_DIR` cmake variable +to specify the location of the host dependencies. + +If you are in the ACC build environment, see +[Escaping the ACC build environment](#escaping-the-acc-build-environment) +for a way to change the environment temporarily so you can build the +protobufs. ## Main directory To build the P4Runtime protobufs in the main directory, you must first -configure cmake. +configure cmake to build for the x86 host (not cross-compile for the ACC). If you've done a recent build, there should already be a configuration. @@ -75,16 +96,91 @@ The Go tarball will be omitted if golang is not installed. The P4Runtime protocol buffers can also be built in the `protobufs` directory. -Change to the `protobufs` directory. +1. Change to the `protobufs` directory. -Make sure the `DEPEND_INSTALL` environment variable is set. +2. Remove the `build` directory, if it exists. -Issue the following commands: + ```bash + rm -fr build + ``` -```bash -cmake -B build -cmake --build build -cmake --install build --prefix install -``` +3. Issue the following commands: + + ```bash + cmake -B build [-DDEPEND_INSTALL_DIR=] + cmake --build build + cmake --install build --prefix + ``` + + `` is the directory containing the host dependencies + (the Stratum dependencies compiled for the x86). + + `` is the directory in which you are installing + P4 Control Plane, or an alternative location (e.g. `install`). + + You may omit `DEPEND_INSTALL_DIR` if the `DEPEND_INSTALL` environment + variable is set to the location of the host dependencies. + +The tarballs and Python wheel will be installed in the `share/p4runtime` +folder under the ``. + +The Go tarball will be omitted if golang is not installed. + +## Escaping the ACC build environment + +As noted above, the P4Runtime protobufs must be generated in the host build +environment, not the environment used to cross-compile P4 Control Plane +for the ACC. + +If you're in the ACC build environment, the following procedure may be +used to escape temporarily to the host build environment. -The tarballs will be installed in the local `install` directory. +1. Change to the `protobufs` directory. + +2. Remove the `build` directory, if it exists. + + ```bash + rm -fr build + ``` + +3. Start a subshell. + + ```bash + bash + ``` + + This preserves your current environment. + +4. Neutralize the cross-compilation environment. + + ```bash + unset CMAKE_TOOLCHAIN_FILE + unset CMAKE_SYSROOT + ``` + +5. Build the P4Runtime protobufs. + + ```bash + cmake -B build -DDEPEND_INSTALL_DIR= + cmake --build build + cmake --install build --prefix + ``` + + `` is the directory containing the host dependencies + (the Stratum dependencies compiled for the x86). + + `` is the directory in which you are installing + P4 Control Plane, or an alternative location (e.g. `install`). + +6. Exit the subshell. + + ```bash + exit + ``` + + This restores your original environment. + +The tarballs and Python wheel will be installed in the `share/p4runtime` +folder under the ``. + +The Go tarball will be omitted if golang is not installed. From 6993dafd55013a6cd49f269a00a811df624dba9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 11:43:09 -0800 Subject: [PATCH 09/31] Bump actions/checkout from 3 to 4 (#358) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sabeel Ansari <35787514+5abeel@users.noreply.github.com> Signed-off-by: Kumar, Aashish --- .github/workflows/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index c72889a9..f48767f6 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -153,7 +153,7 @@ jobs: steps: - name: Clone networking-recipe - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: recursive path: recipe From 0daa0df7fbd57efb40a157a8e25179b7259c149d Mon Sep 17 00:00:00 2001 From: Derek G Foster Date: Thu, 30 Nov 2023 08:07:56 -0800 Subject: [PATCH 10/31] Add LNW with LAG to user guide (#362) Signed-off-by: Derek G Foster Signed-off-by: Kumar, Aashish --- docs/apps/lnw/lnw-index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/apps/lnw/lnw-index.rst b/docs/apps/lnw/lnw-index.rst index 993c9117..813184d8 100644 --- a/docs/apps/lnw/lnw-index.rst +++ b/docs/apps/lnw/lnw-index.rst @@ -24,4 +24,5 @@ ES2K es2k/es2k-linux-networking-ipv6 es2k/es2k-linux-networking-ecmp es2k/es2k-linux-networking-frr + es2k/es2k-linux-networking-lag \ No newline at end of file From 8acf13e7a1e3b16bb955a2c7b858b29f14c931c2 Mon Sep 17 00:00:00 2001 From: "Kumar, Aashish" Date: Thu, 23 Nov 2023 07:01:32 -0500 Subject: [PATCH 11/31] Update krnlmon & ovs submodule refs Signed-off-by: Kumar, Aashish --- krnlmon/krnlmon | 2 +- ovs/ovs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/krnlmon/krnlmon b/krnlmon/krnlmon index b25515a4..296959b8 160000 --- a/krnlmon/krnlmon +++ b/krnlmon/krnlmon @@ -1 +1 @@ -Subproject commit b25515a4b5d99e117bd41082ca061ee2b363e3eb +Subproject commit 296959b87ba37e7830460f46cf6961af9dbe5541 diff --git a/ovs/ovs b/ovs/ovs index 44102d64..742e51ee 160000 --- a/ovs/ovs +++ b/ovs/ovs @@ -1 +1 @@ -Subproject commit 44102d649ab05338613bfcedfa0c24af1a37f610 +Subproject commit 742e51ee30943eb2033b3e88163d691a5d89bc07 From e4e362f67096f74577c381ba744c5c5ac00f2aff Mon Sep 17 00:00:00 2001 From: Derek G Foster Date: Tue, 28 Nov 2023 17:44:39 -0800 Subject: [PATCH 12/31] Add README file to exclude list (#361) - Instruct Sphinx to ignore the README.md file. Signed-off-by: Derek G Foster Signed-off-by: Kumar, Aashish --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 197648e8..9f1db53f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,7 +21,7 @@ ] templates_path = ['_templates'] -exclude_patterns = ['CONTRIBUTING.rst'] +exclude_patterns = ['CONTRIBUTING.rst', 'README.md'] myst_heading_anchors = 3 From c58c965ac6cfb056f4998c8afa95999cbadc672c Mon Sep 17 00:00:00 2001 From: Derek G Foster Date: Thu, 30 Nov 2023 15:48:09 -0800 Subject: [PATCH 13/31] Update submodule references (#363) Update to latest versions of stratum and krnlmon. - Fix compiler errors and warnings. Signed-off-by: Derek G Foster Signed-off-by: Kumar, Aashish --- krnlmon/krnlmon | 2 +- stratum/stratum | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/krnlmon/krnlmon b/krnlmon/krnlmon index 296959b8..91c67674 160000 --- a/krnlmon/krnlmon +++ b/krnlmon/krnlmon @@ -1 +1 @@ -Subproject commit 296959b87ba37e7830460f46cf6961af9dbe5541 +Subproject commit 91c67674535bf245b0591d386282e75edd251174 diff --git a/stratum/stratum b/stratum/stratum index 83b35db8..92853543 160000 --- a/stratum/stratum +++ b/stratum/stratum @@ -1 +1 @@ -Subproject commit 83b35db841f432d16b8c637d80a903e0fa25ddde +Subproject commit 92853543b8d2c9b9d1789208e20aae2cda53b976 From 664af013e157fd47cb0e855695ed4d33336fc62b Mon Sep 17 00:00:00 2001 From: nupuruttarwar Date: Fri, 1 Dec 2023 11:15:16 -0800 Subject: [PATCH 14/31] Edits to the IPsec offload documentation Signed-off-by: nupuruttarwar Signed-off-by: Kumar, Aashish --- docs/apps/ipsec-offload.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/apps/ipsec-offload.md b/docs/apps/ipsec-offload.md index 4f3df7cc..ba538cb2 100644 --- a/docs/apps/ipsec-offload.md +++ b/docs/apps/ipsec-offload.md @@ -44,10 +44,10 @@ to load the hardware FXP pipeline with the IPsec package. ### Configure and run infrap4d -To be able to program Security Association Database (SAD) entries using gNMI, -enable fixed function support in infrap4d. Follow the instructions in +Follow the instructions in [Running infrap4d](/guides/es2k/running-infrap4d.md) -to prepare system with generated TDI.json and context.json file references. +and prepare the system with generated TDI.json and context.json file references. +In order to offload IPsec, fixed function support must be enabled in infrap4d. The /usr/share/stratum/es2k/es2k_skip_p4.conf file must include the fixed function configuration reference. @@ -82,7 +82,7 @@ between local and peer system. This section provides detailed information on OpenConfig model and gNMI messages with the expected format. The strongSwan plugin has the following -details encoded. +details encoded, and user interaction is not needed. ### Config SAD message @@ -130,10 +130,10 @@ at `/ipsec-offload/ipsec-spi/rx-spi`. ### Key Expiry Notification message The [gRPC Notification message](https://github.com/ipdk-io/openconfig-public/blob/master/release/models/ipsec/openconfig-ipsec-offload.yang#L308) -at `/ipsec-offload` is used as a signal to trigger the +at `/ipsec-offload/sadb-expire` is used as a signal to trigger the re-keying mechanism in IKE protocol. A gNMI subscription stream is opened from the gNMI client listening to these notification messages originating in the target. Upon receiving this -notification, clients will initiate the re-keying mechanism to refresh +notification, client will initiate the re-keying mechanism to refresh the encyrption keys. From 267a450880ea66d9f7f74d90a6af29a7777104d6 Mon Sep 17 00:00:00 2001 From: Sabeel Ansari Date: Thu, 30 Mar 2023 23:25:05 -0700 Subject: [PATCH 15/31] Fix typo Signed-off-by: Sabeel Ansari Signed-off-by: Kumar, Aashish --- docs/apps/ipsec-offload.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/apps/ipsec-offload.md b/docs/apps/ipsec-offload.md index ba538cb2..e230ca72 100644 --- a/docs/apps/ipsec-offload.md +++ b/docs/apps/ipsec-offload.md @@ -136,4 +136,4 @@ re-keying mechanism in IKE protocol. A gNMI subscription stream is opened from the gNMI client listening to these notification messages originating in the target. Upon receiving this notification, client will initiate the re-keying mechanism to refresh -the encyrption keys. +the encryption keys. From 3dc59171b0a9163f28fdd7425267799fcf88f486 Mon Sep 17 00:00:00 2001 From: aashishkuma Date: Wed, 6 Dec 2023 11:31:50 +0530 Subject: [PATCH 16/31] Update es2k-linux-networking-lag.md Addressed comments Signed-off-by: Kumar, Aashish --- .../lnw/es2k/es2k-linux-networking-lag.md | 85 +++++++------------ 1 file changed, 32 insertions(+), 53 deletions(-) diff --git a/docs/apps/lnw/es2k/es2k-linux-networking-lag.md b/docs/apps/lnw/es2k/es2k-linux-networking-lag.md index 62c89b62..9fb9ae2a 100644 --- a/docs/apps/lnw/es2k/es2k-linux-networking-lag.md +++ b/docs/apps/lnw/es2k/es2k-linux-networking-lag.md @@ -1,26 +1,6 @@ - - # Linux Networking with LAG (ES2K) -This document explains how to run the Linux networking scenario with LAG(Link Aggregation Group) on ES2K. +This document explains how to run the Linux networking scenario with LAG (Link Aggregation Group) on ES2K. ## Topology @@ -28,41 +8,39 @@ This document explains how to run the Linux networking scenario with LAG(Link Ag Notes about topology: -- Four Kernel netdevs are created by default by loading IDPF driver during ACC bring-up. You can also create more than Four netdevs. For that, we need to modify `acc_apf` parameter under `num_default_vport` in `/etc/dpcp/cfg/cp_init.cfg` on IMC before starting `run_default_init_app`. -- In `/etc/dpcp/cfg/cp_init.cfg` file also modify default `sem_num_pages` value to the value mentioned in `/opt/p4/p4sde/share/mev_reference_p4_files/linux_networking/README_P4_CP_NWS`. -- In `/etc/dpcp/cfg/cp_init.cfg` file also modify default `allow_change_mac_address` value to true. -- vlan1, vlan2, .... vlanN created using Linux commands and are on top of an IDPF Netdev. These VLAN ports should be equal to number of VM's that are spawned. -- br-int, VxLAN ports are created using ovs-vsctl command provided by the networking recipe and all the vlan ports are attached to br-int using ovs-vsctl command. +- Four Kernel netdevs are created by default by loading IDPF driver during ACC bring-up. You can also create more than four netdevs. For that, we need to modify the `acc_apf` parameter under `num_default_vport` in `/etc/dpcp/cfg/cp_init.cfg` on IMC before starting `run_default_init_app`. +- In `/etc/dpcp/cfg/cp_init.cfg`, also change the default `sem_num_pages` to the value specified in `/opt/p4/p4sde/share/mev_reference_p4_files/linux_networking/README_P4_CP_NWS`. +- In `/etc/dpcp/cfg/cp_init.cfg`, also modify the default `allow_change_mac_address` value to true. +- vlan1, vlan2, .... vlanN created using Linux commands and are on top of an IDPF Netdev. These VLAN ports should be equal to number of VMs that are spawned. +- br-int and the VxLAN ports are created using the ovs-vsctl command. The VLAN ports are attached to br-int using ovs-vsctl command. - Both physical ports P0 and P1 should be B2B connected to the Link Partner device and LAG should be configured on both the devices with the associated ports as LAG members using ip link command. -System under test will have above topology running the networking recipe. Link Partner can have the networking recipe or legacy OvS or kernel VxLAN. Note the [Limitations](#limitations) section before setting up the topology. +System under test will have the above topology running the networking recipe. Link Partner can have the networking recipe or legacy OvS or kernel VxLAN. See the [Limitations](#limitations) section before setting up the topology. ## Create P4 artifacts and start Infrap4d process -- Use Linux networking p4 program present in the directory `/opt/p4/p4sde/share/mev_reference_p4_files/linux_networking` for this scenario. -- See [Running Infrap4d on Intel IPU E2100](/guides/es2k/running-infrap4d) for compiling `P4 artifacts`, `bringing up ACC` and running `infrap4d` on ACC. +Use the Linux networking P4 program present in the `/opt/p4/p4sde/share/mev_reference_p4_files/linux_networking` directory for this scenario. +See [Running Infrap4d on Intel IPU E2100](/guides/es2k/running-infrap4d) for instructions on compiling the P4 program, bringing up the ACC, and running `infrap4d` on the ACC. -## Creating the topology +## Create the topology The p4rt-ctl and ovs-vsctl utilities can be found in $P4CP_INSTALL/bin. ### Set the forwarding pipeline -Once the application is started, set the forwarding pipeline config using -P4Runtime Client `p4rt-ctl` set-pipe command +Once the application is started, set the forwarding pipeline config using the P4Runtime Client (`p4rt-ctl`) set-pipe command: ```bash $P4CP_INSTALL/bin/p4rt-ctl set-pipe br0 $OUTPUT_DIR/linux_networking.pb.bin \ $OUTPUT_DIR/linux_networking.p4info.txt ``` -Note: Assuming `linux_networking.pb.bin` and `linux_networking.p4info.txt` -along with other P4 artifacts are created as per the steps mentioned in previous section. +`linux_networking.pb.bin` and `linux_networking.p4info.txt` were created, along with other artifacts, when the P4 program was compiled. -### Configure VSI Group and add a netdev +### Configure VSI group and add a netdev Use one of the IDPF netdevs on ACC to receive all control packets from overlay -VM's by assigning to a VSI group. VSI group 3 is dedicated for this configuration, +VMs by assigning to a VSI group. VSI group 3 is dedicated for this configuration, execute below devmem commands on IMC. ```bash @@ -81,10 +59,10 @@ Note: Here VSI 8 has been used for receiving all control packets and added to VSI group 3. This refers to HOST netdev VSIG 3 as per the topology diagram. Modify this VSI based on your configuration. -### Create Overlay network +### Create overlay network -Option 1: Create VF's on HOST and spawn VM's on top of those VF's. -Example to create 4 VF's: echo 4 > /sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.0/sriov_numvfs +Option 1: Create VFs on HOST and attach VMs to the created VFs. +Example to create 4 VFs: echo 4 > /sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.0/sriov_numvfs ```bash # VM1 configuration @@ -98,8 +76,9 @@ ip addr add 99.0.0.2/24 dev ifconfig up ``` -Option 2: If we are unable to spawn VM's on top of the VF's, for this use case we can also leverage kernel network namespaces. -Move each VF to a network namespace and assign IP addresses +Option 2: Use kernel network namespaces. + +Move each VF to a network namespace and assign IP addresses: ```bash ip netns add VM0 @@ -115,7 +94,7 @@ ip netns exec VM1 ifconfig up ### Start OvS as a separate process -Legacy OvS is used as a control plane for source MAC learning of overlay VM's. OvS should be started as a seperate process. +Legacy OvS is used as a control plane for source MAC learning of overlay VMs. OvS should be started as a seperate process. ```bash export RUN_OVS=/tmp @@ -150,8 +129,8 @@ ovs-vsctl show ### Create VLAN representers -For each VM that is spawned for overlay network we need to have a port representer. -We create VLAN netdevs on top of the IPDF netdev which is assigned to VSI group 3 in step-2 mentioned above. +We need to have a port representer for each VM that is spawned for the overlay network. +We create VLAN netdevs on top of the IPDF netdev that was assigned to VSI group 3 in the [Configure VSI Group](#configure-vsi-group-and-add-a-netdev) step. ```bash ip link add link name vlan1 type vlan id 1 @@ -160,7 +139,7 @@ ifconfig vlan1 up ifconfig vlan2 up ``` -Note: Here the assumption is, we have created 2 overlay VM's and creating 2 port representers for those VM's. +Note: Here the assumption is, we have created 2 overlay VMs and creating 2 port representers for those VMs. Port representer should always be in the format: `lowercase string 'vlan'+'vlanID'` ### Create integration bridge and add ports to the bridge @@ -180,23 +159,23 @@ ovs-vsctl add-port br-int vxlan1 -- set interface vxlan1 type=vxlan \ options:local_ip=30.1.1.1 options:remote_ip=40.1.1.1 options:dst_port=4789 ``` -Note: Here we are creating VxLAN tunnel with VNI 0, you can create any VNI for tunneling. +Note: Here we are creating VxLAN tunnel with VNI 0. You can create any VNI for tunneling. ### Configure rules for overlay control packets Configure rules to send overlay control packets from a VM to its respective port representers. -Below configuration assumes +The following configuration assumes that: - Overlay VF1 has a VSI value 14 - Overlay VF2 has a VSI value 15 -These VSI values can be checked with `/usr/bin/cli_client -q -c` command +These VSI values can be checked with the `/usr/bin/cli_client -q -c` command on IMC. This command provides VSI ID, Vport ID, and corresponding MAC addresses for all: - IDPF netdevs on ACC -- VF's on HOST +- VFs on HOST - IDPF netdevs on HOST (if IDPF driver loaded by you on HOST) - Netdevs on IMC @@ -275,7 +254,7 @@ p4rt-ctl add-entry br0 linux_networking_control.handle_tx_from_host_to_ovs_and_o Create a LAG interface and add 2 IDPF netdevs as LAG members in it. Assign IP to the LAG interface. -Below configuration assumes +The following configuration assumes that: - Underlay IDPF netdev has a VSI value 10 for first LAG member - Underlay IDPF netdev has a VSI value 11 for second LAG member @@ -314,7 +293,7 @@ ip link set bond0 up ### Test the ping scenarios - Verify the underlay ping is working fine via the active path. -- Verify the overlay ping between VM's on same host is working fine via the active path. +- Verify the overlay ping between VMs on same host is working fine via the active path. - Note the active link by using the command "cat /proc/net/bonding/bond0" on both MEV host and LP device. - Shut the active link on both MEV host and its peer Link Partner. - Verify the switchover happened from active to backup interface. @@ -327,9 +306,9 @@ Current Linux Networking support for the networking recipe has following limitat - All VLAN interfaces created on top of IDPF netdev, should always be in lowercase format "vlan+vlan_id" Ex: vlan1, vlan2, vlan3 ... vlan4094. - Set the pipeline before adding br-int port, vxlan0 port, and adding vlan ports to br-int bridge. -- VxLAN destination port should always be standard port. i.e., 4789. (limitation by p4 parser) +- VxLAN destination port should always be standard port. i.e., 4789. (limitation by P4 parser). - We do not support any ofproto rules that would prevent FDB learning on OvS. -- VLAN Tagged packets are not supported. +- VLAN-tagged packets are not supported. - For VxLAN tunneled packets only IPv4-in-IPv4 is supported. - LAG and ECMP are mutually exclusive. Both can't co-exist in the system configuration at the same time. - LAG configuration done via bonding driver is supported and the supported mode in active-backup. From aafaab6307279a20b17aa2ee008941662acb4ec9 Mon Sep 17 00:00:00 2001 From: aashishkuma Date: Wed, 6 Dec 2023 11:52:25 +0530 Subject: [PATCH 17/31] Update es2k-linux-networking-lag.md Addressing comments Signed-off-by: Kumar, Aashish --- docs/apps/lnw/es2k/es2k-linux-networking-lag.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/apps/lnw/es2k/es2k-linux-networking-lag.md b/docs/apps/lnw/es2k/es2k-linux-networking-lag.md index 9fb9ae2a..671dc31e 100644 --- a/docs/apps/lnw/es2k/es2k-linux-networking-lag.md +++ b/docs/apps/lnw/es2k/es2k-linux-networking-lag.md @@ -12,7 +12,7 @@ Notes about topology: - In `/etc/dpcp/cfg/cp_init.cfg`, also change the default `sem_num_pages` to the value specified in `/opt/p4/p4sde/share/mev_reference_p4_files/linux_networking/README_P4_CP_NWS`. - In `/etc/dpcp/cfg/cp_init.cfg`, also modify the default `allow_change_mac_address` value to true. - vlan1, vlan2, .... vlanN created using Linux commands and are on top of an IDPF Netdev. These VLAN ports should be equal to number of VMs that are spawned. -- br-int and the VxLAN ports are created using the ovs-vsctl command. The VLAN ports are attached to br-int using ovs-vsctl command. +- br-int and the VxLAN ports are created using the ovs-vsctl command. The VxLAN ports are attached to br-int using ovs-vsctl command. - Both physical ports P0 and P1 should be B2B connected to the Link Partner device and LAG should be configured on both the devices with the associated ports as LAG members using ip link command. System under test will have the above topology running the networking recipe. Link Partner can have the networking recipe or legacy OvS or kernel VxLAN. See the [Limitations](#limitations) section before setting up the topology. @@ -62,6 +62,7 @@ diagram. Modify this VSI based on your configuration. ### Create overlay network Option 1: Create VFs on HOST and attach VMs to the created VFs. + Example to create 4 VFs: echo 4 > /sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.0/sriov_numvfs ```bash @@ -130,7 +131,7 @@ ovs-vsctl show ### Create VLAN representers We need to have a port representer for each VM that is spawned for the overlay network. -We create VLAN netdevs on top of the IPDF netdev that was assigned to VSI group 3 in the [Configure VSI Group](#configure-vsi-group-and-add-a-netdev) step. +We create VLAN netdevs on top of the IDPF netdev that was assigned to VSI group 3 in the [Configure VSI Group](#configure-vsi-group-and-add-a-netdev) step. ```bash ip link add link name vlan1 type vlan id 1 From e1eed36c2b0b63e3e2d1ac47d4615fd62cffeb74 Mon Sep 17 00:00:00 2001 From: Sandeep N Date: Wed, 6 Dec 2023 15:51:50 +0530 Subject: [PATCH 18/31] Fix DPDK LNW overlay ping failure. With introduction of LNW-V2 in ES2K, DPDK LNW use case has been broken. This is due to l2_fwd_rx_with_tunnel table update is removed from ovs-p4rt. With this fix we make sure this table is populated when MAC is learnt over a tunnel port. Signed-off-by: Sandeep N --- ovs-p4rt/ovs_p4rt.cc | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/ovs-p4rt/ovs_p4rt.cc b/ovs-p4rt/ovs_p4rt.cc index 95cd94e2..8c1f7f50 100644 --- a/ovs-p4rt/ovs_p4rt.cc +++ b/ovs-p4rt/ovs_p4rt.cc @@ -226,6 +226,7 @@ void PrepareFdbTxVlanTableEntry(p4::v1::TableEntry* table_entry, return; } +#if defined(ES2K_TARGET) void PrepareFdbRxVlanTableEntry(p4::v1::TableEntry* table_entry, const struct mac_learning_info& learn_info, const ::p4::config::v1::P4Info& p4info, @@ -237,7 +238,6 @@ void PrepareFdbRxVlanTableEntry(p4::v1::TableEntry* table_entry, std::string mac_addr = CanonicalizeMac(learn_info.mac_addr); match->mutable_exact()->set_value(mac_addr); -#if defined(ES2K_TARGET) // Based on p4 program for ES2K, we need to provide a match key Bridge ID auto match1 = table_entry->add_match(); match1->set_field_id( @@ -251,7 +251,6 @@ void PrepareFdbRxVlanTableEntry(p4::v1::TableEntry* table_entry, L2_FWD_RX_TABLE_KEY_SMAC_LEARNED)); match2->mutable_exact()->set_value(EncodeByteValue(1, 1)); -#endif if (insert_entry) { auto table_action = table_entry->mutable_action(); @@ -261,13 +260,7 @@ void PrepareFdbRxVlanTableEntry(p4::v1::TableEntry* table_entry, auto param = action->add_params(); param->set_param_id(GetParamId(p4info, L2_FWD_RX_TABLE_ACTION_L2_FWD, ACTION_L2_FWD_PARAM_PORT)); -#if defined(DPDK_TARGET) - auto port_id = learn_info.vln_info.vlan_id - 1; -#elif defined(ES2K_TARGET) auto port_id = learn_info.src_port; -#else - auto port_id = 0; -#endif param->set_value(EncodeByteValue(1, port_id)); } } @@ -275,6 +268,35 @@ void PrepareFdbRxVlanTableEntry(p4::v1::TableEntry* table_entry, return; } +#elif defined(DPDK_TARGET) +void PrepareFdbRxVlanTableEntry(p4::v1::TableEntry* table_entry, + const struct mac_learning_info& learn_info, + const ::p4::config::v1::P4Info& p4info, + bool insert_entry) { + table_entry->set_table_id(GetTableId(p4info, L2_FWD_RX_WITH_TUNNEL_TABLE)); + auto match = table_entry->add_match(); + match->set_field_id(GetMatchFieldId(p4info, L2_FWD_RX_WITH_TUNNEL_TABLE, + L2_FWD_TX_TABLE_KEY_DST_MAC)); + std::string mac_addr = CanonicalizeMac(learn_info.mac_addr); + match->mutable_exact()->set_value(mac_addr); + + if (insert_entry) { + auto table_action = table_entry->mutable_action(); + auto action = table_action->mutable_action(); + action->set_action_id(GetActionId(p4info, L2_FWD_TX_TABLE_ACTION_L2_FWD)); + { + auto param = action->add_params(); + param->set_param_id(GetParamId(p4info, L2_FWD_RX_TABLE_ACTION_L2_FWD, + ACTION_L2_FWD_PARAM_PORT)); + auto port_id = learn_info.vln_info.vlan_id - 1; + param->set_value(EncodeByteValue(1, port_id)); + } + } + + return; +} +#endif + void PrepareFdbTableEntryforV4Tunnel(p4::v1::TableEntry* table_entry, const struct mac_learning_info& learn_info, const ::p4::config::v1::P4Info& p4info, From 6dc240df4e8fabf311e06f3084d7df412f0fdc18 Mon Sep 17 00:00:00 2001 From: Sabeel Ansari Date: Wed, 6 Dec 2023 16:56:53 -0800 Subject: [PATCH 19/31] Update Stratum and OVS submodules Signed-off-by: Sabeel Ansari --- ovs/ovs | 2 +- stratum/stratum | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ovs/ovs b/ovs/ovs index 742e51ee..8ae0569d 160000 --- a/ovs/ovs +++ b/ovs/ovs @@ -1 +1 @@ -Subproject commit 742e51ee30943eb2033b3e88163d691a5d89bc07 +Subproject commit 8ae0569d3f18f35d995c511391db8175fbdc3398 diff --git a/stratum/stratum b/stratum/stratum index 92853543..45f1975b 160000 --- a/stratum/stratum +++ b/stratum/stratum @@ -1 +1 @@ -Subproject commit 92853543b8d2c9b9d1789208e20aae2cda53b976 +Subproject commit 45f1975b6afea6700b584781c7933890c57dd185 From f1e9e8f69efbbfc43dc56f6978eb665e1761580e Mon Sep 17 00:00:00 2001 From: Sandeep N Date: Sun, 10 Dec 2023 12:38:04 +0530 Subject: [PATCH 20/31] Fix VLAN TAG issue in original packet. With the existing code, for a VLAN TAG port when we receive a TAG packet, we are appedning one more level of TAG and forwarding the packet. This is causing double VLAN tag on the egress packet. This causes traffic to be dropped. With this code, If a port is already configured with TAG, then we know that it can receive only TAG traffic and that means original pkt will already have a TAG and we dont need to add one more tag to the packet. Remove piece of code which adds TAG to the orig packet. Signed-off-by: Sandeep N --- ovs-p4rt/ovs_p4rt.cc | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/ovs-p4rt/ovs_p4rt.cc b/ovs-p4rt/ovs_p4rt.cc index 8c1f7f50..314c9921 100644 --- a/ovs-p4rt/ovs_p4rt.cc +++ b/ovs-p4rt/ovs_p4rt.cc @@ -177,25 +177,6 @@ void PrepareFdbTxVlanTableEntry(p4::v1::TableEntry* table_entry, ACTION_REMOVE_VLAN_AND_FWD_PARAM_VLAN_PTR)); param->set_value(EncodeByteValue(1, learn_info.vlan_info.port_vlan)); } - } else if (learn_info.vlan_info.port_vlan_mode == - P4_PORT_VLAN_NATIVE_TAGGED) { - action->set_action_id( - GetActionId(p4info, L2_FWD_TX_TABLE_ACTION_ADD_VLAN_AND_FWD)); - { - auto param = action->add_params(); - param->set_param_id(GetParamId(p4info, - L2_FWD_TX_TABLE_ACTION_ADD_VLAN_AND_FWD, - ACTION_ADD_VLAN_AND_FWD_PARAM_PORT_ID)); - auto port_id = learn_info.src_port; - param->set_value(EncodeByteValue(1, port_id)); - } - { - auto param = action->add_params(); - param->set_param_id(GetParamId(p4info, - L2_FWD_TX_TABLE_ACTION_ADD_VLAN_AND_FWD, - ACTION_ADD_VLAN_AND_FWD_PARAM_VLAN_PTR)); - param->set_value(EncodeByteValue(1, learn_info.vlan_info.port_vlan)); - } } else { action->set_action_id(GetActionId(p4info, L2_FWD_TX_TABLE_ACTION_L2_FWD)); { From 1ce1de705470a73a39492090e552456a3bd4d62e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 04:31:44 +0000 Subject: [PATCH 21/31] Bump actions/setup-go from 4.1.0 to 5.0.0 Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4.1.0 to 5.0.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v4.1.0...v5.0.0) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index f48767f6..c477ec49 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -168,7 +168,7 @@ jobs: python -m pip install setuptools build wheel - name: Set up Go environment - uses: actions/setup-go@v4.1.0 + uses: actions/setup-go@v5.0.0 with: go-version: 'stable' From 2b581b7c10fa26a7a6d33159a57445bfae96dbb3 Mon Sep 17 00:00:00 2001 From: Satish Pitchikala Date: Thu, 14 Dec 2023 02:26:58 +0530 Subject: [PATCH 22/31] packet-io documentation (#367) Signed-off-by: Satish Pitchikala Co-authored-by: Sabeel Ansari <35787514+5abeel@users.noreply.github.com> Co-authored-by: Derek G Foster --- docs/apps/apps-index.rst | 1 + docs/apps/packet-io.md | 111 ++++++++++++++++++++++++++++++++++++++ docs/clients/p4rt-ctl.rst | 17 ++++++ 3 files changed, 129 insertions(+) create mode 100644 docs/apps/packet-io.md diff --git a/docs/apps/apps-index.rst b/docs/apps/apps-index.rst index 3b9ad246..68e7adec 100644 --- a/docs/apps/apps-index.rst +++ b/docs/apps/apps-index.rst @@ -6,4 +6,5 @@ ipsec-offload lnw/lnw-index + packet-io \ No newline at end of file diff --git a/docs/apps/packet-io.md b/docs/apps/packet-io.md new file mode 100644 index 00000000..223c029d --- /dev/null +++ b/docs/apps/packet-io.md @@ -0,0 +1,111 @@ +# Packet I/O + +The Packet I/O feature facilitates the exchange of packets between control plane +applications and P4 dataplanes. +This functionality enables control plane applications to receive packets +asynchronously from the dataplane, while also allowing the injection +of packets into the dataplane. + +The Packet I/O feature is currently supported on the Intel® IPU E2100 target. + +## Feature overview + +Packet I/O consists of two essential components: Packet-In and Packet-Out. + +- **Packet-In**: Refers to a data plane packet sent by the P4Runtime server + to the control plane for further analysis. This is specified as `packetIn` + message response in the [p4runtime specification](https://github.com/ipdk-io/p4runtime-dev/blob/mirroring/proto/p4/v1/p4runtime.proto). +- **Packet-Out**: Defined as a data packet originated by the control plane + and injected into the data plane through the P4Runtime server. + This is specified as `packetOut` in p4runtime specification. + +During the set pipeline sequence, the Packet I/O configuration is extracted +from the pipeline configuration. This configuration is then utilized to +register Rx and Tx callbacks with the device driver. When a packet is +received, the device driver invokes the RX callback, and when a packet is +transmitted, the Tx callback is triggered. + +### Rx Path + +The P4 device driver invokes the registered Rx callback upon receiving a packet, +passing the packet details to the Stratum layer of `infrap4d`. The Stratum layer +parses the received packet and translates it into a PacketIn message as defined +in p4runtime.proto. The P4Runtime server sends the PacketIn message to the +connected client. + +### Tx Path + +A P4runtime client/controller can send packets to the PacketIO port as a +PacketOut message defined in p4runtime.proto. The P4CP Stratum layer translates +the PacketOut message to TDI structures and sends them to the driver. + +## Enabling Packet I/O + +To enable the Packet I/O feature, add the `pktio-args` configuration to the following files: + +- The configuration file used by the `infrap4d` process. +- The configuration file used by `tdi_pipeline_builder`. + +The Packet I/O configuration is per device and should be added under the +`p4_devices` section. + +### Packet I/O configuration + +```json + "pktio-args": { + "ports" // list of ports to receive and transmit packetIO packets + "nb_rxqs" // number of rx queues per port + "nb_txqs" // number of tx queues per port + }, +``` + +### Example + +```json + "p4_devices": [ + { + "device-id": 0, + "fixed_functions" : [], + "eal-args": "--lcores=1-2 -a af:00.6,vport=[0-1] -- -i --rxq=1 --txq=1 --hairpinq=1 --hairpin-mode=0x0", + "pktio-args": { + "ports": [0,1], + "nb_rxqs" : 4, + "nb_txqs" : 4 + }, +``` + +Follow the sequence of steps listed below to enable Packet I/O functionality. + +### Configure and run infrap4d + +The `infrap4d` process provides the gRPC server-side support for P4Runtime +packetIn and packetOut messages. + +To start `infrap4d` process with Packet I/O, the +/usr/share/stratum/es2k/es2k_skip_p4.conf file must include Packet IO +configuration. +Instructions to run infrap4d can be found at [running infrap4d](/docs/guides/es2k/running-infrap4d.md) + +Ensure you update this configuration before starting `infrap4d`. + +### Configure and set the pipeline + +The Packet IO configuration mentioned above should also be present in the +configuration file provided with the `p4c_conf_file` option for building +the pipeline. +Instructions to build and set pipeline can be found at [set pipeline](/docs/guides/setup/es2k-setup-guide.md) + +## Reference client + +The `p4rt-ctl` client can be used to exercise the Packet I/O feature. +See "Start Packet I/O" in the [p4rt-ctl guide](/docs/clients/p4rt-ctl.rst) for instructions. + +In Packet I/O mode, the following steps take place: + +- The p4rt-ctl client initializes a `pktioTap0` port designed for testing purposes. + This port facilitates the sending and receiving of packets. +- The packets sent to pktioTap0 port are forwarded to P4Runtime server as + `PacketOut` messages. +- The p4rt-ctl client establishes a connection with the P4Runtime server and awaits + incoming RX packets from the server. Subsequently, the received packets are + forwarded to the pktioTap0 port. diff --git a/docs/clients/p4rt-ctl.rst b/docs/clients/p4rt-ctl.rst index cd7e1bfe..5a871783 100644 --- a/docs/clients/p4rt-ctl.rst +++ b/docs/clients/p4rt-ctl.rst @@ -549,6 +549,23 @@ Examples: p4rt-ctl get-packet-mod-meter br0 my_control.meter1 "meter_id=2244878476,meter_index=10" +Start Packet I/O +~~~~~~~~~~~~~~~ + +.. code-block:: bash + + p4rt-ctl start-pktio SWITCH + +Arguments: + +* ``SWITCH``: Bridge name. Maps internally to device name. + +Examples: + +.. code-block:: bash + + p4rt-ctl start-pktio br0 + Known Issues ------------ From e82a77800c6887560c62a96cd5b0604eb1bb3547 Mon Sep 17 00:00:00 2001 From: Sandeep Nagapattinam Date: Thu, 14 Dec 2023 02:40:14 +0530 Subject: [PATCH 23/31] LNW v2 user guide. (#372) Signed-off-by: Sandeep N Signed-off-by: Sabeel Ansari Co-authored-by: Sabeel Ansari --- docs/apps/lnw/es2k/es2k-linux-networking.md | 659 ++++++++++-------- docs/apps/lnw/es2k/es2k-lnw-topology.png | Bin 147226 -> 119906 bytes .../lnw/es2k/linux-networking-for-es2k.md | 311 +++++++++ docs/apps/lnw/lnw-index.rst | 3 +- docs/guides/es2k/running-infrap4d.md | 56 +- 5 files changed, 710 insertions(+), 319 deletions(-) create mode 100644 docs/apps/lnw/es2k/linux-networking-for-es2k.md diff --git a/docs/apps/lnw/es2k/es2k-linux-networking.md b/docs/apps/lnw/es2k/es2k-linux-networking.md index 304cd09c..ad2fe985 100644 --- a/docs/apps/lnw/es2k/es2k-linux-networking.md +++ b/docs/apps/lnw/es2k/es2k-linux-networking.md @@ -1,292 +1,367 @@ - - -# Linux Networking for ES2K - -This document explains how to run the Linux networking scenario on ES2K. - -## Topology - -![Linux Networking Topology](es2k-lnw-topology.png) - -Notes about topology: - -- Four Kernel netdevs are created by default by loading IDPF driver during ACC bring-up. You can also create more than Four netdevs. For that, we need to modify `acc_apf` parameter under `num_default_vport` in `/etc/dpcp/cfg/cp_init.cfg` on IMC before starting `run_default_init_app`. -- In `/etc/dpcp/cfg/cp_init.cfg` file also modify default `sem_num_pages` value to the value mentioned in `/opt/p4/p4sde/share/mev_reference_p4_files/linux_networking/README_P4_CP_NWS`. -- vlan1, vlan2, .... vlanN created using Linux commands and are on top of an IDPF Netdev. These VLAN ports should be equal to number of VM's that are spawned. -- br-int, VxLAN ports are created using ovs-vsctl command provided by the networking recipe and all the vlan ports are attached to br-int using ovs-vsctl command. - -System under test will have above topology running the networking recipe. Link Partner can have the networking recipe or legacy OvS or kernel VxLAN. Note the [Limitations](#limitations) section before setting up the topology. - -## Create P4 artifacts and start Infrap4d process - -- Use Linux networking p4 program present in the directory `/opt/p4/p4sde/share/mev_reference_p4_files/linux_networking` for this scenario. -- See [Running Infrap4d on Intel IPU E2100](/guides/es2k/running-infrap4d) for compiling `P4 artifacts`, `bringing up ACC` and running `infrap4d` on ACC. - -## Creating the topology - -The p4rt-ctl and ovs-vsctl utilities can be found in $P4CP_INSTALL/bin. - -### Set the forwarding pipeline - -Once the application is started, set the forwarding pipeline config using -P4Runtime Client `p4rt-ctl` set-pipe command - -```bash -$P4CP_INSTALL/bin/p4rt-ctl set-pipe br0 $OUTPUT_DIR/linux_networking.pb.bin \ - $OUTPUT_DIR/linux_networking.p4info.txt -``` - -Note: Assuming `linux_networking.pb.bin` and `linux_networking.p4info.txt` -along with other P4 artifacts are created as per the steps mentioned in previous section. - -### Configure VSI Group and add a netdev - -Use one of the IPDF netdevs on ACC to receive all control packets from overlay -VM's by assigning to a VSI group. VSI group 3 is dedicated for this configuration, -execute below devmem commands on IMC. - -```bash -# SEM_DIRECT_MAP_PGEN_CTRL: LSB 11-bit is for vsi which need to map into vsig -devmem 0x20292002a0 64 0x8000050000000008 - -# SEM_DIRECT_MAP_PGEN_DATA_VSI_GROUP : This will set vsi -# (set in SEM_DIRECT_MAP_PGEN_CTRL register LSB) into VSIG-3. -devmem 0x2029200388 64 0x3 - -# SEM_DIRECT_MAP_PGEN_CTRL: LSB 11-bit is for vsi which need to map into vsig -devmem 0x20292002a0 64 0xA000050000000008 -``` - -Note: Here VSI 8 has been used for receiving all control packets and added to VSI group 3. This refers to HOST netdev VSIG 3 as per the topology diagram. Modify this VSI based on your configuration. - -### Create Overlay network - -Option 1: Create VF's on HOST and spawn VM's on top of those VF's. -Example to create 4 VF's: echo 4 > /sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.0/sriov_numvfs - -```bash -# VM1 configuration -telnet -ip addr add 99.0.0.1/24 dev -ifconfig up - -# VM2 configuration -telnet -ip addr add 99.0.0.2/24 dev -ifconfig up -``` - -Option 2: If we are unable to spawn VM's on top of the VF's, we can leverage kernel network namespaces. -Move each VF to a network namespace and assign IP addresses: - -```bash -ip netns add VM0 -ip link set netns VM0 -ip netns exec VM0 ip addr add 99.0.0.1/24 dev -ip netns exec VM0 ifconfig up - -ip netns add VM1 -ip link set netns VM1 -ip netns exec VM1 ip addr add 99.0.0.2/24 dev -ip netns exec VM1 ifconfig up -``` - -### Start OvS as a separate process - -Legacy OvS is used as a control plane for source MAC learning of overlay VM's. OvS should be started as a seperate process. - -```bash -export RUN_OVS=/tmp -rm -rf $RUN_OVS/etc/openvswitch -rm -rf $RUN_OVS/var/run/openvswitch -mkdir -p $RUN_OVS/etc/openvswitch/ -mkdir -p $RUN_OVS/var/run/openvswitch - -ovsdb-tool create $RUN_OVS/etc/openvswitch/conf.db \ - /opt/p4/p4-cp-nws/share/openvswitch/vswitch.ovsschema - -ovsdb-server $RUN_OVS/etc/openvswitch/conf.db \ - --remote=punix:$RUN_OVS/var/run/openvswitch/db.sock \ - --remote=db:Open_vSwitch,Open_vSwitch,manager_options \ - --pidfile=$RUN_OVS/var/run/openvswitch/ovsdb-server.pid \ - --unixctl=$RUN_OVS/var/run/openvswitch/ovsdb-server.ctl \ - --detach - -ovs-vswitchd --detach \ - --pidfile=$RUN_OVS/var/run/openvswitch/ovs-vswitchd.pid \ - --no-chdir unix:$RUN_OVS/var/run/openvswitch/db.sock \ - --unixctl=$RUN_OVS/var/run/openvswitch/ovs-vswitchd.ctl \ - --mlockall \ - --log-file=/tmp/ovs-vswitchd.log - -alias ovs-vsctl="ovs-vsctl --db unix:$RUN_OVS/var/run/openvswitch/db.sock" -ovs-vsctl set Open_vSwitch . other_config:n-revalidator-threads=1 -ovs-vsctl set Open_vSwitch . other_config:n-handler-threads=1 - -ovs-vsctl show -``` - -### Create VLAN representers - -For each VM that is spawned for overlay network we need to have a port representer. -We create VLAN netdevs on top of the IPDF netdev which is assigned to VSI group 3 in step-2 mentioned above. - -```bash -ip link add link name vlan1 type vlan id 1 -ip link add link name vlan2 type vlan id 2 -ifconfig vlan1 up -ifconfig vlan2 up -``` - -Note: Here the assumption is, we have created 2 overlay VM's and creating 2 port representers for those VM's. -Port representer should always be in the format: `lowercase string 'vlan'+'vlanID'` - -### Create integration bridge and add ports to the bridge - -Create OvS bridge, VxLAN tunnel and assign ports to the bridge. - -```bash -ovs-vsctl add-br br-int -ifconfig br-int up - -ovs-vsctl add-port br-int vlan1 -ovs-vsctl add-port br-int vlan2 -ifconfig vlan1 up -ifconfig vlan2 up - -ovs-vsctl add-port br-int vxlan1 -- set interface vxlan1 type=vxlan \ - options:local_ip=40.1.1.1 options:remote_ip=40.1.1.2 options:dst_port=4789 -``` - -Note: Here we are creating VxLAN tunnel with VNI 0, you can create any VNI for tunneling. - -### Configure rules for overlay control packets - -Configure rules to send overlay control packets from a VM to its respective port representers. - -Below configuration assumes - -- Overlay VF1 has a VSI value 14 -- Overlay VF2 has a VSI value 15 - -These VSI values can be checked with `/usr/bin/cli_client -q -c` command on IMC. This command provides VSI ID, Vport ID, and corresponding MAC addresses for all - -- IDPF netdevs on ACC -- VF's on HOST -- IDPF netdevs on HOST (if IDPF driver loaded by you on HOST) -- Netdevs on IMC - -```bash -# Rules for control packets coming from overlay VF (VSI-14). -# IPU will add a VLAN tag 1 and send to HOST1 (VSI-8). - -p4rt-ctl add-entry br0 linux_networking_control.handle_tx_from_host_to_ovs_and_ovs_to_wire_table \ - "vmeta.common.vsi=14,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.add_vlan_and_send_to_port(1,24)" -p4rt-ctl add-entry br0 linux_networking_control.handle_rx_loopback_from_host_to_ovs_table \ - "vmeta.common.vsi=14,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.set_dest(24)" -p4rt-ctl add-entry br0 linux_networking_control.vlan_push_mod_table \ - "vmeta.common.mod_blob_ptr=1,action=linux_networking_control.vlan_push(1,0,1)" - -# Rules for control packets coming from overlay VF (VSI-15). -# IPU will add a VLAN tag 2 and send to HOST1 (VSI-8). - -p4rt-ctl add-entry br0 linux_networking_control.handle_tx_from_host_to_ovs_and_ovs_to_wire_table \ - "vmeta.common.vsi=15,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.add_vlan_and_send_to_port(2,24)" -p4rt-ctl add-entry br0 linux_networking_control.handle_rx_loopback_from_host_to_ovs_table \ - "vmeta.common.vsi=15,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.set_dest(24)" -p4rt-ctl add-entry br0 linux_networking_control.vlan_push_mod_table \ - "vmeta.common.mod_blob_ptr=2,action=linux_networking_control.vlan_push(1,0,2)" - -# Rules for control packets coming from HOST1 (VSI-8). -# IPU will remove the VLAN tag 1 and send to overlay VF (VSI-14). - -p4rt-ctl add-entry br0 linux_networking_control.handle_tx_from_ovs_to_host_table \ - "vmeta.common.vsi=8,hdrs.dot1q_tag[vmeta.common.depth].hdr.vid=1,action=linux_networking_control.remove_vlan_and_send_to_port(1,30)" -p4rt-ctl add-entry br0 linux_networking_control.handle_rx_loopback_from_ovs_to_host_table \ - "vmeta.misc_internal.vm_to_vm_or_port_to_port[27:17]=14,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.set_dest(30)" -p4rt-ctl add-entry br0 linux_networking_control.vlan_pop_mod_table \ - "vmeta.common.mod_blob_ptr=1,action=linux_networking_control.vlan_pop" - -# Rules for control packets coming from HOST1 (VSI-8). -# IPU will remove the VLAN tag 2 and send to overlay VF (VSI-15). - -p4rt-ctl add-entry br0 linux_networking_control.handle_tx_from_ovs_to_host_table \ - "vmeta.common.vsi=8,hdrs.dot1q_tag[vmeta.common.depth].hdr.vid=2,action=linux_networking_control.remove_vlan_and_send_to_port(2,31)" -p4rt-ctl add-entry br0 linux_networking_control.handle_rx_loopback_from_ovs_to_host_table \ - "vmeta.misc_internal.vm_to_vm_or_port_to_port[27:17]=15,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.set_dest(31)" -p4rt-ctl add-entry br0 linux_networking_control.vlan_pop_mod_table \ - "vmeta.common.mod_blob_ptr=2,action=linux_networking_control.vlan_pop" -``` - -### Configure rules for underlay control packets - -Configure rules to send underlay control packets from IDPF netdev to physical port. - -Below configuration assumes - -- Underlay IDPF netdev has a VSI value 10 -- First physical port will have a port ID of 0 - -```bash -# Configuration for control packets between physical port 0 to underlay IDPF netdev VSI-10 -p4rt-ctl add-entry br0 linux_networking_control.handle_rx_from_wire_to_ovs_table \ - "vmeta.common.port_id=0,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.set_dest(26)" - -# Configuration for control packets between underlay IDPF netdev VSI-10 to physical port 0 -p4rt-ctl add-entry br0 linux_networking_control.handle_tx_from_host_to_ovs_and_ovs_to_wire_table \ - "vmeta.common.vsi=10,user_meta.cmeta.bit32_zeros=0,action=linux_networking_control.set_dest(0)" -``` - -### Underlay configuration - -Configure underlay IP addresses, and add static routes. - -Below configuration assumes - -- Underlay IDPF netdev has a VSI value 10 - -```bash -p4rt-ctl add-entry br0 linux_networking_control.ecmp_lpm_root_lut \ - "user_meta.cmeta.bit32_zeros=4/255.255.255.255,priority=2,action=linux_networking_control.ecmp_lpm_root_lut_action(0)" - -nmcli device set managed no -ifconfig 40.1.1.1/24 up -ip route show -ip route change 40.1.1.0/24 via 40.1.1.2 dev -``` - -### Test the ping scenarios - -- Ping between VM's on the same host -- Underlay ping -- Overlay ping: Ping between VM's on different hosts - -## Limitations - -Current Linux Networking support for the networking recipe has following limitations: - -- All VLAN interfaces created on top of IDPF netdev, should always be in lowercase format "vlan+vlan_id" -Ex: vlan1, vlan2, vlan3 ... vlan4094. -- Set the pipeline before adding br-int port, vxlan0 port, and adding vlan ports to br-int bridge. -- VxLAN destination port should always be standard port. i.e., 4789. (limitation by p4 parser) -- We do not support any ofproto rules that would prevent FDB learning on OvS. -- VLAN Tagged packets are not supported. -- For VxLAN tunneled packets only IPv4-in-IPv4 is supported. + + +# Linux Networking for ES2K + +This document explains how to run the Linux networking scenario on ES2K with 8 overlay VMs. + +## Topology + +![Linux Networking Topology](es2k-lnw-topology.png) + +Refer to [Linux Networking for E2100](linux-networking-for-es2k.md) document for more details on this feature. + +Prerequisites: + +- Follow steps mentioned in [Deploying P4 Programs for E2100](https://github.com/ipdk-io/networking-recipe/blob/main/docs/guides/es2k/running-infrap4d.md) for bringing up IPU with a particular release build. +- Download `hw-p4-programs` TAR file specific to the build and extract it to get `fxp-net_linux-networking-v2` p4 artifacts. Go through `Limitations` specified in `README` and bringup the setup accordingly. + - Modify `sem_num_pages` to 25 and `lem_num_pages` to 10 in `cp_init.cfg` present in IMC. +- For this use case, before booting ACC with a particular release build, modify `acc_apf` value to 16 under `num_default_vport` in file `cp_init.cfg` present in IMC. +- Download `IPU_Documentation` TAR file specific to the build and refer to `Getting Started Guide` on how to install compatible `IDPF driver` on host. Once an IDPF driver is installed, bring up SRIOV VF by modifying the `sriov_numvfs` file present under one of the IDPF network devices. Example as below + + ```bash + echo 16 > /sys/class/net/ens802f0/device/sriov_numvfs + ``` + +Notes about topology: + +- VMs are spawned on top of each VFs. Each VF will have a respective port representer in ACC. P4 runtime rules are configured to map VFs and its corresponding port representers. +- Each physical port will have a port representer in ACC. P4 runtime rules are configured to map VFs and its corresponding port representers. +- Each physical port will have a corresponding APF netdev on HOST. Create port representers in ACC for each HOST APF netdev. These APF netdev on HOST will receive unknown traffic for applications to act on. +- All port representers should be part of an OvS bridge. Based on topology, these OvS bridges will just perform bridging or TEP termination bridges which are used to enable underlay connectivity for VxLAN traffic. +- OvS bridges, VxLAN ports are created using ovs-vsctl command provided by the networking recipe and all the port representers are attached to OvS bridge using ovs-vsctl command. +- This config has: + - 8 Overlay VFs + - 8 Port representers in ACC for the above 8 Overlay VFs + - 2 physical ports + - 2 Port representers in ACC for the above 2 physical ports + - 2 APF netdev on HOST + - 2 Port representers in ACC for the above 2 HOST APF netdevs + +System under test will have above topology running the networking recipe. Link Partner can have the networking recipe or legacy OvS or kernel VxLAN. Refer to the limitation section in [Linux Networking for E2100](linux-networking-for-es2k.md) before setting up the topology. + +## Creating the topology + +Follow steps mentioned in [Running Infrap4d on Intel E2100](https://github.com/ipdk-io/networking-recipe/blob/main/docs/guides/es2k/running-infrap4d.md) for starting `infrap4d` process and creating protobuf binary for `fxp-net_linux-networking-v2` p4 program. + +### Port Mapping + +These VSI values can be checked with `/usr/bin/cli_client -q -c` command on IMC. This command provides VSI ID, Vport ID, and corresponding MAC addresses for all + +- IDPF netdevs on ACC +- VFs on HOST +- IDPF netdevs on HOST (if IDPF driver loaded by you on HOST) +- Netdevs on IMC + +| Overlay VFs | Overlay VFs VSI ID | ACC port representer | ACC port representer VSI ID | +| ------------| ------------------ | -------------------- | --------------------------- | +| ens802f0v0 | (0x1b) 27 | enp0s1f0d1 | (0x09) 9 | +| ens802f0v1 | (0x1c) 28 | enp0s1f0d2 | (0x0a) 10 | +| ens802f0v4 | (0x1d) 29 | enp0s1f0d3 | (0x0b) 11 | +| ens802f0v3 | (0x1e) 30 | enp0s1f0d4 | (0x0c) 12 | +| ens802f0v2 | (0x1f) 31 | enp0s1f0d5 | (0x0d) 13 | +| ens802f0v11 | (0x20) 32 | enp0s1f0d6 | (0x0e) 14 | +| ens802f0v10 | (0x21) 33 | enp0s1f0d7 | (0x0f) 15 | +| ens802f0v9 | (0x22) 34 | enp0s1f0d8 | (0x10) 16 | + +| Physical port | Physical port ID | ACC Port presenter | ACC Port presenter VSI ID | +| ------------- | ----------------- | -------------------- | ------------------------- | +| Phy port 0 | (0x0) 0 | enp0s1f0d9 | (0x11) 17 | +| Phy port 1 | (0x1) 1 | enp0s1f0d11 | (0x13) 19 | + +| APF netdev | APF netdev VSI ID | ACC Port presenter | ACC Port presenter VSI ID | +| ------------- | ----------------- | -------------------- | ------------------------- | +| ens802f0d1 | (0x18) 24 | enp0s1f0d10 | (0x12) 18 | +| ens802f0d2 | (0x19) 25 | enp0s1f0d12 | (0x14) 20 | + +(NOTE: Above port names and its VSI ID's may different from setup to setup, configure accordingly) + +### Set the forwarding pipeline + +Once the application is started, set the forwarding pipeline config using +P4Runtime Client `p4rt-ctl` set-pipe command + +```bash +$P4CP_INSTALL/bin/p4rt-ctl set-pipe br0 $OUTPUT_DIR/fxp-net_linux-networking-v2.pb.bin \ + $OUTPUT_DIR/p4info.txt +``` + +Note: Assuming `fxp-net_linux-networking-v2.pb.bin` and `p4info.txt` +along with other P4 artifacts are created as per the steps mentioned in the previous section. + +### Configure VSI Group and add a netdev + +Add all ACC port representers to VSI group 1. VSI group 1 is dedicated for this configuration, +execute below devmem commands on IMC. + +```bash +# SEM_DIRECT_MAP_PGEN_CTRL: LSB 11-bit is for vsi which need to map into vsig +devmem 0x20292002a0 64 0x8000050000000009 + +# SEM_DIRECT_MAP_PGEN_DATA_VSI_GROUP : This will set vsi +# (set in SEM_DIRECT_MAP_PGEN_CTRL register LSB) into VSIG-1. +devmem 0x2029200388 64 0x1 + +# SEM_DIRECT_MAP_PGEN_CTRL: LSB 11-bit is for vsi which need to map into vsig +devmem 0x20292002a0 64 0xA000050000000009 +``` + +Note: Here VSI 9 has been used as one of the ACC port representers and added to VSI group 1. For this use case add all 16 IDPF interfaces created on ACC. Modify this VSI based on your configuration. + +### Start OvS as a separate process + +Legacy OvS is used as a control plane for source MAC learning of overlay VM's. OvS should be started as a separate process. + +```bash +export RUN_OVS=/opt/p4/p4-cp-nws + +rm -rf $RUN_OVS/etc/openvswitch +rm -rf $RUN_OVS/var/run/openvswitch +mkdir -p $RUN_OVS/etc/openvswitch/ +mkdir -p $RUN_OVS/var/run/openvswitch + + +ovsdb-tool create $RUN_OVS/etc/openvswitch/conf.db \ + $RUN_OVS/share/openvswitch/vswitch.ovsschema + +ovsdb-server \ + --remote=punix:$RUN_OVS/var/run/openvswitch/db.sock \ + --remote=db:Open_vSwitch,Open_vSwitch,manager_options \ + --pidfile --detach + +ovs-vsctl --no-wait init + +mkdir -p /tmp/logs +ovs-vswitchd --pidfile --detach --mlockall \ + --log-file=/tmp/logs/ovs-vswitchd.log + +ovs-vsctl set Open_vSwitch . other_config:n-revalidator-threads=1 +ovs-vsctl set Open_vSwitch . other_config:n-handler-threads=1 + +ovs-vsctl show +``` + +### Create Overlay network + +Option 1: Create VFs on HOST and spawn VMs on top of those VFs. +Example: Below config is provided for one VM, and considering each VM is in one VLAN. Extend this to 8 VMs. + +```bash +# VM1 configuration +telnet +ip link add link name .10 type vlan id 10 +ip addr add 101.0.0.1/24 dev .10 +ifconfig up +ifconfig .10 up +``` + +Option 2: If we are unable to spawn VM's on top of the VF's, we can leverage kernel network namespaces. +Move each VF to a network namespace and assign IP addresses. +Example: Below config is provided for one VM, and considering each namespace is in one VLAN. Extend this to 8 namespaces. + +```bash +ip netns add VM0 +ip link set netns VM0 +ip netns exec VM0 ip link add link name .10 type vlan id 10 +ip netns exec VM0 ip addr add 101.0.0.1/24 dev .10 +ip netns exec VM0 ifconfig up +ip netns exec VM0 ifconfig .10 up +``` + +### Configure rules for mapping between Overlay VF and ACC port representer + +Configure rules to send overlay packets from a VM to its respective port representers. + +Refer above port mapping for overlay VF to ACC port representer mapping. Here sample commands are shown for a single overlay network, configure similar mapping for remaining VFs. + +Example: + +- Overlay VF1 has a VSI value 27 +- Corresponding port representer VSI value 9 +- If a VSI is used as an action, add an offset of 16 to the VSI value + +```bash +# Create a source port for an overlay VF (VSI-27). Source port action can be any value. +# For simplicity add 16 to VSI ID. + p4rt-ctl add-entry br0 linux_networking_control.tx_source_port_v4 \ + "vmeta.common.vsi=27,zero_padding=0,action=linux_networking_control.set_source_port(43)" + +# Create a mapping between overlay VF (VSI-27/source port-43) and ACC port representer (VSI-9) + p4rt-ctl add-entry br0 linux_networking_control.source_port_to_pr_map \ + "user_meta.cmeta.source_port=43,zero_padding=0,action=linux_networking_control.fwd_to_vsi(25)" + + p4rt-ctl add-entry br0 linux_networking_control.tx_acc_vsi \ + "vmeta.common.vsi=9,zero_padding=0,action=linux_networking_control.l2_fwd_and_bypass_bridge(43)" + +# Create a mapping for traffic to flow between VSIs (VSI-27/source port-43) and (VSI-9) + p4rt-ctl add-entry br0 linux_networking_control.vsi_to_vsi_loopback \ + "vmeta.common.vsi=9,target_vsi=27,action=linux_networking_control.fwd_to_vsi(43)" + + p4rt-ctl add-entry br0 linux_networking_control.vsi_to_vsi_loopback \ + "vmeta.common.vsi=27,target_vsi=9,action=linux_networking_control.fwd_to_vsi(25)" + +``` + +### Configure rules for mapping between Physical port and ACC port representer + +Configure rules to send ingress packets from a physical port to its respective port representers. + +Refer above port mapping for physical port to ACC port representer mapping. Here sample commands are shown for a single physical port, configure similar mapping for remaining physical ports. + +Example: + +- Physical port 0 port id is 0 +- Corresponding port representer VSI value 17 +- If a VSI is used as an action, add an offset of 16 to the VSI value + +```bash +# Create a source port for a physical port (Phy port-0). Source port action can be any value. +# For simplicity consider the same value as phy port id. + p4rt-ctl add-entry br0 linux_networking_control.rx_source_port \ + "vmeta.common.port_id=0,zero_padding=0,action=linux_networking_control.set_source_port(0)" + +# Create a mapping between physical port (Phy port 0/src port 0) and ACC port representer (VSI-17) + p4rt-ctl add-entry br0 linux_networking_control.rx_phy_port_to_pr_map \ + "vmeta.common.port_id=0,zero_padding=0,action=linux_networking_control.fwd_to_vsi(33)" + + p4rt-ctl add-entry br0 linux_networking_control.source_port_to_pr_map \ + "user_meta.cmeta.source_port=0,zero_padding=0,action=linux_networking_control.fwd_to_vsi(33)" + + p4rt-ctl add-entry br0 linux_networking_control.tx_acc_vsi \ + "vmeta.common.vsi=17,zero_padding=0,action=linux_networking_control.l2_fwd_and_bypass_bridge(0)" +``` + +### Configure rules for mapping between APF netdev on HOST and ACC port representer + +Configure rules to send APF netdev on HOST to its respective port representers. + +Refer above port mapping for APF netdev on HOST to ACC port representer mapping. Here sample commands are shown for APF netdev on HOST, configure similar mapping for remaining APF netdevs on HOST. + +Example: + +- APF netdev 1 on HOST has a VSI value 24 +- Corresponding port representer VSI value 18 +- If a VSI is used as an action, add an offset of 16 to the VSI value + +```bash +# Create a source port for an overlay VF (VSI-24). Source port action can be any value. +# For simplicity add 16 to VSI ID. + p4rt-ctl add-entry br0 linux_networking_control.tx_source_port_v4 \ + "vmeta.common.vsi=24,zero_padding=0,action=linux_networking_control.set_source_port(40)" + + +# Create a mapping between overlay VF (VSI-24/source port-40) and ACC port representer (VSI-18) + p4rt-ctl add-entry br0 linux_networking_control.source_port_to_pr_map \ + "user_meta.cmeta.source_port=40,zero_padding=0,action=linux_networking_control.fwd_to_vsi(34)" + + p4rt-ctl add-entry br0 linux_networking_control.tx_acc_vsi \ + "vmeta.common.vsi=17,zero_padding=0,action=linux_networking_control.l2_fwd_and_bypass_bridge(0)" + +# Create a mapping for traffic to flow between VSIs (VSI-24/source port-40) and (VSI-18) + p4rt-ctl add-entry br0 linux_networking_control.vsi_to_vsi_loopback \ + "vmeta.common.vsi=18,target_vsi=24,action=linux_networking_control.fwd_to_vsi(40)" + + p4rt-ctl add-entry br0 linux_networking_control.vsi_to_vsi_loopback \ + "vmeta.common.vsi=24,target_vsi=18,action=linux_networking_control.fwd_to_vsi(34)" +``` + +### Configure supporting p4 runtime tables + +For TCAM entry configure LPM LUT table + +```bash + p4rt-ctl add-entry br0 linux_networking_control.ipv4_lpm_root_lut \ + "user_meta.cmeta.bit32_zeros=4/255.255.255.255,priority=65535,action=linux_networking_control.ipv4_lpm_root_lut_action(0)" +``` + +Create a dummy LAG bypass table for all 8 hash indexes + +```bash + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=0,action=linux_networking_control.bypass" + + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=1,action=linux_networking_control.bypass" + + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=2,action=linux_networking_control.bypass" + + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=3,action=linux_networking_control.bypass" + + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=4,action=linux_networking_control.bypass" + + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=5,action=linux_networking_control.bypass" + + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=6,action=linux_networking_control.bypass" + + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=7,action=linux_networking_control.bypass" +``` + +### Create integration bridge and add ports to the bridge + +Create OvS bridge, VxLAN tunnel and assign overlay VFs port representer to individual bridges. +Reference provided for single overlay network, repeat similar steps for other VFs. + +Each bridge has: + +- One overlay PR which is Native-tagged to a specific VLAN +- One VxLAN port which is Native-untagged to the VLAN and with different remote TEP and VNI + +```bash +ovs-vsctl add-br br-1 +ovs-vsctl add-port br-1 enp0s1f0d1 tag=10 vlan_mode=native-tagged +ovs-vsctl add-port br-1 vxlan1 tag=10 vlan_mode=native-untagged -- set interface vxlan1 type=vxlan \ + options:local_ip=10.1.1.1 options:remote_ip=10.1.1.2 options:key=10 options:dst_port=4789 +``` + +Note: Here we are creating a VxLAN tunnel with VNI 0, you can create any VNI for tunneling. + +### Underlay configuration + +Create TEP termination bridge, add physical port's port representer and APF netdev port representer. +Reference provided for underlay network, repeat similar steps for multiple underlay networks. + +```bash +ovs-vsctl add-br br-tun-1 +ovs-vsctl add-port br-tun-1 enp0s1f0d9 +ovs-vsctl add-port br-tun-1 enp0s1f0d10 +``` + +Configure underlay IP address on the TEP termination port, route to reach remote IP is on termination bridge, and add change routes to reach remote IP. + +```bash +# Create a dummy port and add TEP local IP +ip link add dev TEP10 type dummy +ifconfig TEP10 10.1.1.1/24 up + +# On termiantion bridge, configure an IP to reach remote TEP, and modify route to include nexthop details. +ifconfig br-tun-1 1.1.1.1/24 up +ip route change 10.1.1.0/24 via 1.1.1.2 dev br-tun-1 +``` + +### Test the ping scenarios + +- Underlay ping +- Overlay ping: Ping between VM's on different hosts diff --git a/docs/apps/lnw/es2k/es2k-lnw-topology.png b/docs/apps/lnw/es2k/es2k-lnw-topology.png index 4a952241e9b10bc9aaba90f4b86df2930171a5c7..5e16a043027897b60452df12ab5ef601f890a753 100644 GIT binary patch literal 119906 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 z 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 z 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 + ovs-vsctl add-port br-int + ``` + +##### Egress traffic with VxLAN encap + +Packets coming from overlay network: + +- Determine the source port of the packet based on which overlay VSI the packet has landed on. +- Validate if the source port is part of the bridge, else drop the packet. +- If valid bridge configuration is found, find the PR associated with the bridge and forward the packet to the PR in ACC. +- OvS control plane receives the packet and forwards the packets to the destined VxLAN port if MAC is already learnt, else flood the packet in the respective bridge. +- Once the packet reaches the VxLAN port, here the kernel checks the routing table to reach `remote_ip` that is configured for the OvS VxLAN tunnel. +- Underlay network to reach `remote_ip` is configured on a TEP termination bridge. Here, the kernel resolves ARP of the underlay network. +- Once ARP is resolved, kernel encapsulates the packet and this packet will be forwarded to the destined PR of the physical port if MAC is already learnt, else flood the packet in the respective TEP termination bridge. +- Sample OvS config: + + ```bash + ovs-vsctl add-br br-int + ovs-vsctl add-port br-int + ovs-vsctl add-port br-int + ovs-vsctl add-br br-tep-termination ## this bridge has IP to reach remote TEP + ovs-vsctl add-port br-tep-termination + ``` + +#### For Rx + +##### Ingress non VxLAN packet + +If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: + +- Determine the source port of the packet based on which physical port the packet has landed on. +- Validate if the source port is part of the bridge, else drop the packet. +- If valid bridge configuration is found, find the PR associated with the bridge and forward the packet to the PR in ACC. +- OvS control plane receives the packet and forwards the packets to destined PR if MAC is already learnt, else flood the packet in the respective bridge. +- Sample OvS config: + + ```bash + ovs-vsctl add-br br-int + ovs-vsctl add-port br-int + ovs-vsctl add-port br-int + ``` + +##### Ingress VxLAN packet + +If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: + +- Determine the source port of the packet based on which physical port the packet has landed +- Validate if the source port is part of the bridge, else drop the packet. +- If valid bridge configuration is found, find the PR associated with the physical port and forward the packet to the PR in ACC. +- OvS control plane receives the packet on a TEP termination bridge, packet gets decapped and sent to VxLAN port. +- Since VxLAN port and overlay VMs PR are in the same bridge, if the overlay MAC is already learnt the packet will be forwarded to destined PR else packet will be flooded in the respective bridge. +- Sample OvS config: + + ```bash + ovs-vsctl add-br br-int + ovs-vsctl add-port br-int + ovs-vsctl add-port br-int + ovs-vsctl add-br br-tep-termination ## this bridge has IP to reach remote TEP + ovs-vsctl add-port br-tep-termination + ``` + +### Fast path (when IPU forwards the packet) + +To enable fast path mode: + +- Start the infrap4d process. +- Remove the environment variable `OVS_P4_OFFLOAD=false` before starting the `ovs-vswitchd` process. + +In this mode, we need to associate VFs on top which VMs are created and its port representers and also physical ports with its port representers. +Configure tables: + +```text +- rx_source_port +- tx_source_port_v4/tx_source_port_v6 +- tx_acc_vsi +- vsi_to_vsi_loopback +- source_port_to_pr_map +- rx_phy_port_to_pr_map +- tx_lag_table ## This is a dummy LAG entry when we have underlay as Non LAG case. +``` + +Once OvS bridge is created and PR's are added to the OvS bridge, a unique bridge ID for the OvS bridge is created and creates a mapping between ACC PR's & OvS bridge. This mapping is programed in IPU E2100 with, + +```text +- source_port_to_bridge_map +- vlan_push_mod_table ## If ACC PR is part of a VLAN +- vlan_pop_mod_table ## If ACC PR is part of a VLAN +``` + +Once a VxLAN tunnel is created on a particular OvS bridge, we program IPU E2100 with, + +```text +- rx_ipv4_tunnel_source_port/rx_ipv6_tunnel_source_port +- vxlan_encap_mod_table/vxlan_encap_v6_mod_table +- vxlan_encap_vlan_pop_mod_table/vxlan_encap_v6_vlan_pop_mod_table ## If VxLAN is part of a VLAN +- vxlan_decap_mod_table +- vxlan_decap_and_push_vlan_mod_table ## If VxLAN is part of a VLAN +- ipv4_tunnel_term_table/ipv6_tunnel_term_table +``` + +When the first packet (either Tx or Rx) reaches the IPU, since no rules are programmed, this packet will be sent to respective PR's. From PR's OvS learns the MAC address and control plane dynamically programs, + +```text +- l2_fwd_smac_table +- l2_fwd_tx_table +- l2_fwd_rx_table +- l2_to_tunnel_v4/l2_to_tunnel_v6 +``` + +When underlay network is configured and underlay neighbor is learnt we dynamically program, + +```text +- ipv4_table/ipv6_table +- nexthop_table +- neighbor_mod_table +``` + +Once these tables are configured refer to packet flow as mentioned below. + +#### For Tx + +##### Egress traffic without VxLAN encap + +Packets coming from overlay network: + +- Determine the source port of the packet based on which overlay VSI the packet has landed on. +- Validate if the source port is part of the bridge, else drop the packet. +- If valid bridge configuration is found, check if SMAC of the packet is learnt. +- Check if DMAC packet is learnt against the bridge derived above. If entry matches, forward the packet to VF corresponding to the physical port. +- Sample OvS config: + + ```bash + ovs-vsctl add-br br-int + ovs-vsctl add-port br-int + ovs-vsctl add-port br-int + ``` + +##### Egress traffic with VxLAN encap + +Packets coming from overlay network: + +- Determine the source port of the packet based on which overlay VSI the packet has landed on. +- Check if the DMAC of the packet is reachable via the VxLAN tunnel and set the remote_ip of the tunnel. +- Validate if the source port is part of the bridge, else drop the packet. +- If valid bridge configuration is found, check if SMAC of the packet is learnt. +- Check if DMAC packet is learnt against the bridge derived above. If yes, populated Src IP, Dest IP, VNI, SRC port and Dest port of outer packet. +- Based on the above derived remote_ip, retrieve what is the nexthop from ipv4_table. +- Derive from which physical port this nexthop is learnt and add the nexthop MAC address as DMAC and underlay port MAC as SMAC of the packet. +- Sample OvS config: + + ```bash + ovs-vsctl add-br br-int + ovs-vsctl add-port br-int + ovs-vsctl add-port br-int + ovs-vsctl add-br br-tep-termination ## this bridge has IP to reach remote TEP + ovs-vsctl add-port br-tep-termination + ``` + +#### For Rx + +##### Ingress non VxLAN packet + +If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: + +- Determine the source port of the packet based on which physical port the packet has landed on. +- Validate if the source port is part of the bridge, else drop the packet. +- If valid bridge configuration is found, check if the inner SMAC of the packet is learnt. +- Check if the inner DMAC packet is learnt against the bridge derived above. If entry matches, forward the packet to VF corresponding to the overlay VM. +- Sample OvS config: + + ```bash + ovs-vsctl add-br br-int + ovs-vsctl add-port br-int + ovs-vsctl add-port br-int + ``` + +##### Ingress VxLAN packet + +If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: + +- Determine the source port of the packet based on which physical port the packet has landed +- Validate if the source port is part of the bridge, else drop the packet. +- If valid bridge configuration is found, check if the inner SMAC of the packet is learnt. +- Check if the inner DMAC packet is learnt against the bridge derived above. If entry matches, decap the outer packet and forward the inner packet to the overlay VF where DMAC is learnt. +- Sample OvS config: + + ```bash + ovs-vsctl add-br br-int + ovs-vsctl add-port br-int + ovs-vsctl add-port br-int + ovs-vsctl add-br br-tep-termination ## this bridge has IP to reach remote TEP + ovs-vsctl add-port br-tep-termination + ``` + +## Summary + +- Verification of source port and Associated L2 Bridge: The P4 Control Plane (P4 CP) must ensure the validation of the source port and its corresponding L2 bridge before initiating any further regulation of datapath packet classification. +- Exception Packet Handling for All Protocols: The P4 Control Plane (P4 CP) shall incorporate exception packet handling logic, not limited to ARP but applicable to the first packet of any protocol. +- Offloading of Networking Functions: The P4 Control Plane (P4 CP) software shall provide support for the offloading of various networking functions as specified in the Linux Networking use case. These networking functions include Layer 2 (L2) and Layer 3 (L3) forwarding, Equal-Cost Multi-Path (ECMP) routing, Link Aggregation Group (LAG), as well as Virtual Extensible LAN (VXLAN) encapsulation and decapsulation. These functions shall support both single and multiple Open vSwitch (OvS) bridges. + +## Limitations + +Current Linux Networking support for the networking recipe has the following limitations: + +- VLAN configuration on OvS is supported only for NATIVE-TAG and NATIVE-UNTAG modes. +- Physical port's port representer should be added as the 1st port in Tunnel TEP bridge (br-tep-termination). +- Only OvS bridges are supported. +- Configure p4rt-ctl runtime rules before OvS configuration. +- Double vlan tag is NOT supported. +- Add all ACC PR's to VSI group 1 +- On ACC firewalld need to be disabled, this service is blocking tunnel packets. + - systemctl stop firewalld +- Refer LNW-V2 README_P4_CP_NWS which comes along with the p4 program for limitation with router_interface_id action in nexthop_table (Bug created for this) + - Manually modify context.json to remove NOP hardware action for in context.json from "set_nexthop " action in "nexthop_table". Open defect is present in p4-sde to fix this issue. + +```text +Content to be removed under hardware action is +{ + "prec": 0, + "action_code": "NOP", + "index": 0, + "value": 0, + "mask": 0 +}, +``` diff --git a/docs/apps/lnw/lnw-index.rst b/docs/apps/lnw/lnw-index.rst index 813184d8..562591e3 100644 --- a/docs/apps/lnw/lnw-index.rst +++ b/docs/apps/lnw/lnw-index.rst @@ -20,9 +20,10 @@ ES2K .. toctree:: :maxdepth: 1 + es2k/linux-networking-for-es2k es2k/es2k-linux-networking es2k/es2k-linux-networking-ipv6 es2k/es2k-linux-networking-ecmp es2k/es2k-linux-networking-frr es2k/es2k-linux-networking-lag - \ No newline at end of file + diff --git a/docs/guides/es2k/running-infrap4d.md b/docs/guides/es2k/running-infrap4d.md index f6b122f2..26818bd0 100644 --- a/docs/guides/es2k/running-infrap4d.md +++ b/docs/guides/es2k/running-infrap4d.md @@ -51,19 +51,23 @@ for step by step guide for generating and installing TLS certificates ## 4. Generate forwarding pipeline binary -### Create tofino.bin - -```bash -export OUTPUT_DIR=/opt/p4/p4sde/share/mev_reference_p4_files/simple_l3_l4_pna -cd $OUTPUT_DIR -touch tofino.bin -``` +Download `hw-p4-programs` TAR file specific to the release build and extract it to get p4 artifacts. +This document explains with `l3-fwd_sem` as a reference P4 program and the P4 artifacts are copied to `/opt/p4/l3-fwd_sem` ### Copy P4 artifacts to ACC -Copy `bfrt.json`, `context.json`, `p4info.txt` to the ACC. See +Copy `bf-rt.json`, `context.json`, `p4info.txt` to the ACC. See [Compiling P4 programs](compiling-p4-programs.md) -for instructions on generating these files. +for instructions on generating these files manually without downloading from +release build. + +### Create ipu.bin + +```bash +export OUTPUT_DIR=/opt/p4/l3-fwd_sem +cd $OUTPUT_DIR +touch ipu.bin +``` ### Prepare configuration file @@ -115,31 +119,31 @@ with the following parameters: - `program-name` - Specify the name of P4 program. For simple_l3_l4_pna example, replace - `P4-PROGRAM-NAME` with `simple_l3_l4_pna` + Specify the name of P4 program. For l3-fwd_sem example, replace + `P4-PROGRAM-NAME` with `l3-fwd_sem` - `p4_pipeline_name` - Specify the name of P4 pipeline. For simple_l3_l4_pna example, replace + Specify the name of P4 pipeline. For l3-fwd_sem example, replace `P4-PIPELINE-NAME` with `main` - `bfrt-config`, `context`, `config` and `path` - Specify the absolute paths for the files. For simple_l3_l4_pna sample program: + Specify the absolute paths for the files. For l3-fwd_sem sample program: Replace `ABSOLUTE-PATH-TO-BFRT-JSON-FILE` with - `/opt/p4/p4sde/share/mev_reference_p4_files/simple_l3_l4_pna/simple_l3_l4_pna.bf-rt.json` + `/opt/p4/l3-fwd_sem/bf-rt.json` Replace `ABSOLUTE-PATH-TO-CONTEXT-JSON-FILE` with - `/opt/p4/p4sde/share/mev_reference_p4_files/simple_l3_l4_pna/simple_l3_l4_pna.context.json` + `/opt/p4/l3-fwd_sem/context.json` Replace `ABSOLUTE-PATH-TO-TOFINO-BIN-FILE` with - `/opt/p4/p4sde/share/mev_reference_p4_files/simple_l3_l4_pna/tofino.bin` + `/opt/p4/l3-fwd_sem/ipu.bin` Replace `ABSOLUTE-PATH-FOR-JSON-FILES` with - `/opt/p4/p4sde/share/mev_reference_p4_files/simple_l3_l4_pna` + `/opt/p4/l3-fwd_sem` -The final es2k_skip_p4.conf for simple_l3_l4_pna sample program will look like: +The final es2k_skip_p4.conf for l3-fwd_sem sample program will look like: ```text { @@ -161,20 +165,20 @@ The final es2k_skip_p4.conf for simple_l3_l4_pna sample program will look like: "eal-args": "--lcores=1-2 -a 00:01.6,vport=[0-1] -- -i --rxq=1 --txq=1 --hairpinq=1 --hairpin-mode=0x0", "p4_programs": [ { - "program-name": "simple_l3_l4_pna", - "bfrt-config": "/opt/p4/p4sde/share/mev_reference_p4_files/simple_l3_l4_pna/simple_l3_l4_pna.bf-rt.json", + "program-name": "l3-fwd_sem", + "bfrt-config": "/opt/p4/l3-fwd_sem/bf-rt.json", "p4_pipelines": [ { "p4_pipeline_name": "main", - "context": "/opt/p4/p4sde/share/mev_reference_p4_files/simple_l3_l4_pna/simple_l3_l4_pna.context.json", - "config": "/opt/p4/p4sde/share/mev_reference_p4_files/simple_l3_l4_pna/tofino.bin", + "context": "/opt/p4/l3-fwd_sem/context.json", + "config": "/opt/p4/l3-fwd_sem/ipu.bin", "pipe_scope": [ 0, 1, 2, 3 ], - "path": "/opt/p4/p4sde/share/mev_reference_p4_files/simple_l3_l4_pna" + "path": "/opt/p4/l3-fwd_sem" } ] } @@ -194,7 +198,7 @@ forwarding pipeline binary. ```bash $P4CP_INSTALL/bin/tdi_pipeline_builder \ --p4c_conf_file=/usr/share/stratum/es2k/es2k_skip_p4.conf \ - --bf_pipeline_config_binary_file=$OUTPUT_DIR/simple_l3_l4_pna.pb.bin + --bf_pipeline_config_binary_file=$OUTPUT_DIR/l3-fwd_sem.pb.bin ``` ## 5. Start Infrap4d @@ -229,8 +233,8 @@ Once the application is started, set the forwarding pipeline config using P4Runtime Client `p4rt-ctl` set-pipe command ```bash -$P4CP_INSTALL/bin/p4rt-ctl set-pipe br0 $OUTPUT_DIR/simple_l3_l4_pna.pb.bin \ - $OUTPUT_DIR/simple_l3_l4_pna.p4info.txt +$P4CP_INSTALL/bin/p4rt-ctl set-pipe br0 $OUTPUT_DIR/l3-fwd_sem.pb.bin \ + $OUTPUT_DIR/l3-fwd_sem.p4info.txt ``` ## 7. Configure forwarding rule From f9c9bc487829baf010b57f901a5a5a69bd0ab5a9 Mon Sep 17 00:00:00 2001 From: Sabeel Ansari <35787514+5abeel@users.noreply.github.com> Date: Wed, 13 Dec 2023 15:11:52 -0600 Subject: [PATCH 24/31] Cleanup security docs for clarity (#376) Signed-off-by: Sabeel Ansari --- docs/guides/security/security-guide.md | 8 +++---- .../guides/security/using-tls-certificates.md | 23 ------------------- 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/docs/guides/security/security-guide.md b/docs/guides/security/security-guide.md index 1a6fc64a..12672c4e 100644 --- a/docs/guides/security/security-guide.md +++ b/docs/guides/security/security-guide.md @@ -61,7 +61,7 @@ issue requests to port 9339. To launch infrap4d in insecure mode: ```bash -$IPDK_RECIPE/install/sbin/infrap4d -grpc_open_insecure_mode=true +infrap4d -grpc_open_insecure_mode=true ``` To launch clients in insecure mode: @@ -69,13 +69,11 @@ To launch clients in insecure mode: For DPDK target: ```bash -$IPDK_RECIPE/install/bin/gnmi-ctl set \ - -grpc_use_insecure_mode=true +gnmi-ctl set -grpc_use_insecure_mode=true ``` For Intel IPU E2100 target: ```bash -$IPDK_RECIPE/install/bin/sgnmi_cli set \ - -grpc_use_insecure_mode=true +sgnmi_cli set -grpc_use_insecure_mode=true ``` diff --git a/docs/guides/security/using-tls-certificates.md b/docs/guides/security/using-tls-certificates.md index 0ec5e761..6c954a89 100644 --- a/docs/guides/security/using-tls-certificates.md +++ b/docs/guides/security/using-tls-certificates.md @@ -45,29 +45,6 @@ default location `/usr/share/stratum/certs/` to the server running infrap4d. Copy the generated `ca.crt`, `client.crt`, and `client.key` in the default location `/usr/share/stratum/certs/` to the client machine. -### Non-default location - -If you would like to use a different location for the server certificates, -copy the certifactes to the location and specify the following options on -the `infrap4d` command line. - -Option | Description ----------------------- | ------------------- --ca_cert_file=PATH | CA certificate file --server_cert_file=PATH | Server certificate file --server_key_file=PATH | Server private key file - -For example, start infrap4d with certificates in `/tmp/certs`: - -```bash -$P4CP_INSTALL/sbin/infrap4d \ - -ca_cert_file=/tmp/certs/ca.crt \ - -server_cert_file=/tmp/certs/stratum.crt \ - -server_key_file=/tmp/certs/stratum.key -``` - -Note: Client certificates must be installed in `/usr/share/stratum/certs`. - For more details about available options with respect to running infrap4d and clients in insecure mode and default behavior, see the [security_guide](security-guide.md). From a081b5a16c039d042b7b78c6f32708f7d92db1fb Mon Sep 17 00:00:00 2001 From: Sabeel Ansari <35787514+5abeel@users.noreply.github.com> Date: Wed, 13 Dec 2023 15:36:59 -0600 Subject: [PATCH 25/31] Update name to use p4cp.recipe and other minor formatting changes (#377) Signed-off-by: Sabeel Ansari --- docs/guides/es2k/building-acc-p4cp.md | 6 +++--- docs/guides/es2k/defining-acc-environment.md | 2 +- docs/guides/setup/dpdk-setup-guide.md | 7 +++---- docs/guides/setup/es2k-setup-guide.md | 9 ++++----- docs/guides/setup/tofino-setup-guide.md | 19 ++++++++++--------- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/docs/guides/es2k/building-acc-p4cp.md b/docs/guides/es2k/building-acc-p4cp.md index 1cf41b98..c29f405a 100644 --- a/docs/guides/es2k/building-acc-p4cp.md +++ b/docs/guides/es2k/building-acc-p4cp.md @@ -33,17 +33,17 @@ If you have not already done so, you will need to get a copy of the IPDK networking-recipe repository and its submodules: ```bash -git clone --recursive https://github.com/ipdk-io/networking-recipe.git ipdk.recipe +git clone --recursive https://github.com/ipdk-io/networking-recipe.git p4cp.recipe ``` -You may substitute your own local directory name for `ipdk.recipe`. +You may substitute your own local directory name for `p4cp.recipe`. ## Define the Environment First, change to the source directory: ```bash -cd ipdk.recipe +cd p4cp.recipe ``` Source the file that defines the diff --git a/docs/guides/es2k/defining-acc-environment.md b/docs/guides/es2k/defining-acc-environment.md index 859761d3..fe600d85 100644 --- a/docs/guides/es2k/defining-acc-environment.md +++ b/docs/guides/es2k/defining-acc-environment.md @@ -43,7 +43,7 @@ In the listing above, you will need to provide values for these variables: - `ACC_SDK` - install path of the ACC-RL SDK (for example, `$HOME/p4cp-dev/acc_sdk`) - `P4CPBASE` - path to the local networking-recipe directory (for example, - `$HOME/p4cp-dev/ipdk.recipe`) + `$HOME/p4cp-dev/p4cp.recipe`) From these paths, the setup script derives: diff --git a/docs/guides/setup/dpdk-setup-guide.md b/docs/guides/setup/dpdk-setup-guide.md index c54af0b6..8310dfe3 100644 --- a/docs/guides/setup/dpdk-setup-guide.md +++ b/docs/guides/setup/dpdk-setup-guide.md @@ -68,16 +68,15 @@ the build system and helper scripts. Clone the repository used to build P4 Control Plane: ```bash -git clone --recursive https://github.com/ipdk-io/networking-recipe.git ipdk.recipe -cd ipdk.recipe +git clone --recursive https://github.com/ipdk-io/networking-recipe.git p4cp.recipe +cd p4cp.recipe export P4CP_RECIPE=`pwd` ``` ### Compile the recipe ```bash -cd $P4CP_RECIPE -./make-all.sh --target=dpdk --rpath +$P4CP_RECIPE/make-all.sh --target=dpdk --rpath ``` By default, make-all.sh will create an `install` folder in the networking-recipe diff --git a/docs/guides/setup/es2k-setup-guide.md b/docs/guides/setup/es2k-setup-guide.md index 52222692..2dc9d016 100644 --- a/docs/guides/setup/es2k-setup-guide.md +++ b/docs/guides/setup/es2k-setup-guide.md @@ -84,8 +84,8 @@ the build system and helper scripts. Clone the repository used to build P4 Control Plane: ```bash -git clone --recursive https://github.com/ipdk-io/networking-recipe.git ipdk.recipe -cd ipdk.recipe +git clone --recursive https://github.com/ipdk-io/networking-recipe.git p4cp.recipe +cd p4cp.recipe export P4CP_RECIPE=`pwd` ``` @@ -157,16 +157,15 @@ the range with cfgqs-idx parameter. Total number of queues split between process ### Run the infrap4d daemon ```bash -cd $P4CP_RECIPE sudo $P4CP_INSTALL/sbin/infrap4d ``` *Note*: By default, infrap4d runs in detached mode. If you want to run in -attached mode, specify the --nodetach command-line option. +attached mode, specify the `--nodetach` command-line option. - All infrap4d logs are by default logged under `/var/log/stratum`. - All P4SDE logs are logged in `p4_driver.log` under `$P4CP_RECIPE`. -*-All OVS logs are logged under `/tmp/ovs-vswitchd.log`. +- All OVS logs are logged under `/tmp/ovs-vswitchd.log`. ### Run a sample program diff --git a/docs/guides/setup/tofino-setup-guide.md b/docs/guides/setup/tofino-setup-guide.md index 208d51c5..fa819f07 100644 --- a/docs/guides/setup/tofino-setup-guide.md +++ b/docs/guides/setup/tofino-setup-guide.md @@ -35,7 +35,9 @@ docker run --privileged --cap-add=ALL -it --name infrap4d --network host -d ubun Clone IPDK networking-recipe: ```bash -git clone --recursive git@github.com:ipdk-io/networking-recipe.git ipdk.recipe +git clone --recursive git@github.com:ipdk-io/networking-recipe.git p4cp.recipe +cd p4cp.recipe +export P4CP_RECIPE=`pwd` ``` Clone the repository used to build the Stratum dependencies: @@ -101,19 +103,18 @@ Not that `bsp-path` is not required for tofino-model. ### Build Networking Recipe ```bash -cd $IPDK_RECIPE -./make-all.sh --target=tofino --deps=/usr/local +$P4CP_RECIPE/make-all.sh --target=tofino --deps=/usr/local ``` ## Run ```bash -cd IPDK_RECIPE -cp $SDE_INSTALL/share/bf_switchd/zlog-cfg $IPDK_RECIPE/zlog-cfg-cur +cd P4CP_RECIPE +cp $SDE_INSTALL/share/bf_switchd/zlog-cfg $P4CP_RECIPE/zlog-cfg-cur mkdir -p /etc/stratum/ mkdir -p /var/log/stratum/ -LD_LIBRARY_PATH=$IPDK_RECIPE/install/lib/:$SDE_INSTALL/lib \ +LD_LIBRARY_PATH=$P4CP_RECIPE/install/lib/:$SDE_INSTALL/lib \ ./install/sbin/infrap4d \ -chassis_config_file=./stratum/stratum/stratum/hal/config/x86-64-accton-wedge100bf-32x-r0/chassis_config.pb.txt \ -tdi_switchd_cfg=$SDE_INSTALL/share/p4/targets/tofino/tofino_skip_p4.conf \ @@ -161,8 +162,8 @@ To generate the bin file for the controller. ```bash cd $SDE_INSTALL -LD_LIBRARY_PATH=$IPDK_RECIPE/install/lib/:$SDE_INSTALL/lib \ - $IPDK_RECIPE/install/bin/tdi_pipeline_builder \ +LD_LIBRARY_PATH=$P4CP_RECIPE/install/lib/:$SDE_INSTALL/lib \ + $P4CP_RECIPE/install/bin/tdi_pipeline_builder \ -p4c_conf_file=$SDE_INSTALL/share/p4/targets/tofino/tna_exact_match.conf \ - -bf_pipeline_config_binary_file=$IPDK_RECIPE/tna_exact_match.pb.bin + -bf_pipeline_config_binary_file=$P4CP_RECIPE/tna_exact_match.pb.bin ``` From 873a71a5355c8ad2404d6bf1af2eb08b892591a2 Mon Sep 17 00:00:00 2001 From: Derek G Foster Date: Wed, 13 Dec 2023 14:06:57 -0800 Subject: [PATCH 26/31] Fix errors in documents (#378) - Correct bad links and short underlines. Signed-off-by: Derek G Foster --- docs/apps/packet-io.md | 10 +++++----- docs/clients/p4rt-ctl.rst | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/apps/packet-io.md b/docs/apps/packet-io.md index 223c029d..9528436b 100644 --- a/docs/apps/packet-io.md +++ b/docs/apps/packet-io.md @@ -54,8 +54,8 @@ The Packet I/O configuration is per device and should be added under the ```json "pktio-args": { "ports" // list of ports to receive and transmit packetIO packets - "nb_rxqs" // number of rx queues per port - "nb_txqs" // number of tx queues per port + "nb_rxqs" // number of rx queues per port + "nb_txqs" // number of tx queues per port }, ``` @@ -84,7 +84,7 @@ packetIn and packetOut messages. To start `infrap4d` process with Packet I/O, the /usr/share/stratum/es2k/es2k_skip_p4.conf file must include Packet IO configuration. -Instructions to run infrap4d can be found at [running infrap4d](/docs/guides/es2k/running-infrap4d.md) +Instructions to run infrap4d can be found at [running infrap4d](/guides/es2k/running-infrap4d.md) Ensure you update this configuration before starting `infrap4d`. @@ -93,12 +93,12 @@ Ensure you update this configuration before starting `infrap4d`. The Packet IO configuration mentioned above should also be present in the configuration file provided with the `p4c_conf_file` option for building the pipeline. -Instructions to build and set pipeline can be found at [set pipeline](/docs/guides/setup/es2k-setup-guide.md) +Instructions to build and set pipeline can be found at [set pipeline](/guides/setup/es2k-setup-guide.md) ## Reference client The `p4rt-ctl` client can be used to exercise the Packet I/O feature. -See "Start Packet I/O" in the [p4rt-ctl guide](/docs/clients/p4rt-ctl.rst) for instructions. +See "Start Packet I/O" in the [p4rt-ctl guide](/clients/p4rt-ctl.rst) for instructions. In Packet I/O mode, the following steps take place: diff --git a/docs/clients/p4rt-ctl.rst b/docs/clients/p4rt-ctl.rst index 5a871783..9111cc6e 100644 --- a/docs/clients/p4rt-ctl.rst +++ b/docs/clients/p4rt-ctl.rst @@ -550,7 +550,7 @@ Examples: p4rt-ctl get-packet-mod-meter br0 my_control.meter1 "meter_id=2244878476,meter_index=10" Start Packet I/O -~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~ .. code-block:: bash From e0f878e87e16dc40ad82bc119d89bab69a9b61ae Mon Sep 17 00:00:00 2001 From: Derek G Foster Date: Wed, 13 Dec 2023 15:40:56 -0800 Subject: [PATCH 27/31] Address various issues in LNW documentation (#379) - Renamed the revised older document to "Linux Networking with Overlay VMs." - Converted line endings from MS-DOS to Linux format. - Fixed internal document links. Signed-off-by: Derek G Foster --- docs/apps/lnw/es2k/es2k-linux-networking.md | 677 ++++++++---------- docs/apps/lnw/es2k/es2k-lnw-overlay-vms.md | 366 ++++++++++ .../lnw/es2k/linux-networking-for-es2k.md | 311 -------- docs/apps/lnw/lnw-index.rst | 2 +- 4 files changed, 677 insertions(+), 679 deletions(-) create mode 100644 docs/apps/lnw/es2k/es2k-lnw-overlay-vms.md delete mode 100644 docs/apps/lnw/es2k/linux-networking-for-es2k.md diff --git a/docs/apps/lnw/es2k/es2k-linux-networking.md b/docs/apps/lnw/es2k/es2k-linux-networking.md index ad2fe985..47e1f76e 100644 --- a/docs/apps/lnw/es2k/es2k-linux-networking.md +++ b/docs/apps/lnw/es2k/es2k-linux-networking.md @@ -1,367 +1,310 @@ - - -# Linux Networking for ES2K - -This document explains how to run the Linux networking scenario on ES2K with 8 overlay VMs. - -## Topology - -![Linux Networking Topology](es2k-lnw-topology.png) - -Refer to [Linux Networking for E2100](linux-networking-for-es2k.md) document for more details on this feature. - -Prerequisites: - -- Follow steps mentioned in [Deploying P4 Programs for E2100](https://github.com/ipdk-io/networking-recipe/blob/main/docs/guides/es2k/running-infrap4d.md) for bringing up IPU with a particular release build. -- Download `hw-p4-programs` TAR file specific to the build and extract it to get `fxp-net_linux-networking-v2` p4 artifacts. Go through `Limitations` specified in `README` and bringup the setup accordingly. - - Modify `sem_num_pages` to 25 and `lem_num_pages` to 10 in `cp_init.cfg` present in IMC. -- For this use case, before booting ACC with a particular release build, modify `acc_apf` value to 16 under `num_default_vport` in file `cp_init.cfg` present in IMC. -- Download `IPU_Documentation` TAR file specific to the build and refer to `Getting Started Guide` on how to install compatible `IDPF driver` on host. Once an IDPF driver is installed, bring up SRIOV VF by modifying the `sriov_numvfs` file present under one of the IDPF network devices. Example as below - - ```bash - echo 16 > /sys/class/net/ens802f0/device/sriov_numvfs - ``` - -Notes about topology: - -- VMs are spawned on top of each VFs. Each VF will have a respective port representer in ACC. P4 runtime rules are configured to map VFs and its corresponding port representers. -- Each physical port will have a port representer in ACC. P4 runtime rules are configured to map VFs and its corresponding port representers. -- Each physical port will have a corresponding APF netdev on HOST. Create port representers in ACC for each HOST APF netdev. These APF netdev on HOST will receive unknown traffic for applications to act on. -- All port representers should be part of an OvS bridge. Based on topology, these OvS bridges will just perform bridging or TEP termination bridges which are used to enable underlay connectivity for VxLAN traffic. -- OvS bridges, VxLAN ports are created using ovs-vsctl command provided by the networking recipe and all the port representers are attached to OvS bridge using ovs-vsctl command. -- This config has: - - 8 Overlay VFs - - 8 Port representers in ACC for the above 8 Overlay VFs - - 2 physical ports - - 2 Port representers in ACC for the above 2 physical ports - - 2 APF netdev on HOST - - 2 Port representers in ACC for the above 2 HOST APF netdevs - -System under test will have above topology running the networking recipe. Link Partner can have the networking recipe or legacy OvS or kernel VxLAN. Refer to the limitation section in [Linux Networking for E2100](linux-networking-for-es2k.md) before setting up the topology. - -## Creating the topology - -Follow steps mentioned in [Running Infrap4d on Intel E2100](https://github.com/ipdk-io/networking-recipe/blob/main/docs/guides/es2k/running-infrap4d.md) for starting `infrap4d` process and creating protobuf binary for `fxp-net_linux-networking-v2` p4 program. - -### Port Mapping - -These VSI values can be checked with `/usr/bin/cli_client -q -c` command on IMC. This command provides VSI ID, Vport ID, and corresponding MAC addresses for all - -- IDPF netdevs on ACC -- VFs on HOST -- IDPF netdevs on HOST (if IDPF driver loaded by you on HOST) -- Netdevs on IMC - -| Overlay VFs | Overlay VFs VSI ID | ACC port representer | ACC port representer VSI ID | -| ------------| ------------------ | -------------------- | --------------------------- | -| ens802f0v0 | (0x1b) 27 | enp0s1f0d1 | (0x09) 9 | -| ens802f0v1 | (0x1c) 28 | enp0s1f0d2 | (0x0a) 10 | -| ens802f0v4 | (0x1d) 29 | enp0s1f0d3 | (0x0b) 11 | -| ens802f0v3 | (0x1e) 30 | enp0s1f0d4 | (0x0c) 12 | -| ens802f0v2 | (0x1f) 31 | enp0s1f0d5 | (0x0d) 13 | -| ens802f0v11 | (0x20) 32 | enp0s1f0d6 | (0x0e) 14 | -| ens802f0v10 | (0x21) 33 | enp0s1f0d7 | (0x0f) 15 | -| ens802f0v9 | (0x22) 34 | enp0s1f0d8 | (0x10) 16 | - -| Physical port | Physical port ID | ACC Port presenter | ACC Port presenter VSI ID | -| ------------- | ----------------- | -------------------- | ------------------------- | -| Phy port 0 | (0x0) 0 | enp0s1f0d9 | (0x11) 17 | -| Phy port 1 | (0x1) 1 | enp0s1f0d11 | (0x13) 19 | - -| APF netdev | APF netdev VSI ID | ACC Port presenter | ACC Port presenter VSI ID | -| ------------- | ----------------- | -------------------- | ------------------------- | -| ens802f0d1 | (0x18) 24 | enp0s1f0d10 | (0x12) 18 | -| ens802f0d2 | (0x19) 25 | enp0s1f0d12 | (0x14) 20 | - -(NOTE: Above port names and its VSI ID's may different from setup to setup, configure accordingly) - -### Set the forwarding pipeline - -Once the application is started, set the forwarding pipeline config using -P4Runtime Client `p4rt-ctl` set-pipe command - -```bash -$P4CP_INSTALL/bin/p4rt-ctl set-pipe br0 $OUTPUT_DIR/fxp-net_linux-networking-v2.pb.bin \ - $OUTPUT_DIR/p4info.txt -``` - -Note: Assuming `fxp-net_linux-networking-v2.pb.bin` and `p4info.txt` -along with other P4 artifacts are created as per the steps mentioned in the previous section. - -### Configure VSI Group and add a netdev - -Add all ACC port representers to VSI group 1. VSI group 1 is dedicated for this configuration, -execute below devmem commands on IMC. - -```bash -# SEM_DIRECT_MAP_PGEN_CTRL: LSB 11-bit is for vsi which need to map into vsig -devmem 0x20292002a0 64 0x8000050000000009 - -# SEM_DIRECT_MAP_PGEN_DATA_VSI_GROUP : This will set vsi -# (set in SEM_DIRECT_MAP_PGEN_CTRL register LSB) into VSIG-1. -devmem 0x2029200388 64 0x1 - -# SEM_DIRECT_MAP_PGEN_CTRL: LSB 11-bit is for vsi which need to map into vsig -devmem 0x20292002a0 64 0xA000050000000009 -``` - -Note: Here VSI 9 has been used as one of the ACC port representers and added to VSI group 1. For this use case add all 16 IDPF interfaces created on ACC. Modify this VSI based on your configuration. - -### Start OvS as a separate process - -Legacy OvS is used as a control plane for source MAC learning of overlay VM's. OvS should be started as a separate process. - -```bash -export RUN_OVS=/opt/p4/p4-cp-nws - -rm -rf $RUN_OVS/etc/openvswitch -rm -rf $RUN_OVS/var/run/openvswitch -mkdir -p $RUN_OVS/etc/openvswitch/ -mkdir -p $RUN_OVS/var/run/openvswitch - - -ovsdb-tool create $RUN_OVS/etc/openvswitch/conf.db \ - $RUN_OVS/share/openvswitch/vswitch.ovsschema - -ovsdb-server \ - --remote=punix:$RUN_OVS/var/run/openvswitch/db.sock \ - --remote=db:Open_vSwitch,Open_vSwitch,manager_options \ - --pidfile --detach - -ovs-vsctl --no-wait init - -mkdir -p /tmp/logs -ovs-vswitchd --pidfile --detach --mlockall \ - --log-file=/tmp/logs/ovs-vswitchd.log - -ovs-vsctl set Open_vSwitch . other_config:n-revalidator-threads=1 -ovs-vsctl set Open_vSwitch . other_config:n-handler-threads=1 - -ovs-vsctl show -``` - -### Create Overlay network - -Option 1: Create VFs on HOST and spawn VMs on top of those VFs. -Example: Below config is provided for one VM, and considering each VM is in one VLAN. Extend this to 8 VMs. - -```bash -# VM1 configuration -telnet -ip link add link name .10 type vlan id 10 -ip addr add 101.0.0.1/24 dev .10 -ifconfig up -ifconfig .10 up -``` - -Option 2: If we are unable to spawn VM's on top of the VF's, we can leverage kernel network namespaces. -Move each VF to a network namespace and assign IP addresses. -Example: Below config is provided for one VM, and considering each namespace is in one VLAN. Extend this to 8 namespaces. - -```bash -ip netns add VM0 -ip link set netns VM0 -ip netns exec VM0 ip link add link name .10 type vlan id 10 -ip netns exec VM0 ip addr add 101.0.0.1/24 dev .10 -ip netns exec VM0 ifconfig up -ip netns exec VM0 ifconfig .10 up -``` - -### Configure rules for mapping between Overlay VF and ACC port representer - -Configure rules to send overlay packets from a VM to its respective port representers. - -Refer above port mapping for overlay VF to ACC port representer mapping. Here sample commands are shown for a single overlay network, configure similar mapping for remaining VFs. - -Example: - -- Overlay VF1 has a VSI value 27 -- Corresponding port representer VSI value 9 -- If a VSI is used as an action, add an offset of 16 to the VSI value - -```bash -# Create a source port for an overlay VF (VSI-27). Source port action can be any value. -# For simplicity add 16 to VSI ID. - p4rt-ctl add-entry br0 linux_networking_control.tx_source_port_v4 \ - "vmeta.common.vsi=27,zero_padding=0,action=linux_networking_control.set_source_port(43)" - -# Create a mapping between overlay VF (VSI-27/source port-43) and ACC port representer (VSI-9) - p4rt-ctl add-entry br0 linux_networking_control.source_port_to_pr_map \ - "user_meta.cmeta.source_port=43,zero_padding=0,action=linux_networking_control.fwd_to_vsi(25)" - - p4rt-ctl add-entry br0 linux_networking_control.tx_acc_vsi \ - "vmeta.common.vsi=9,zero_padding=0,action=linux_networking_control.l2_fwd_and_bypass_bridge(43)" - -# Create a mapping for traffic to flow between VSIs (VSI-27/source port-43) and (VSI-9) - p4rt-ctl add-entry br0 linux_networking_control.vsi_to_vsi_loopback \ - "vmeta.common.vsi=9,target_vsi=27,action=linux_networking_control.fwd_to_vsi(43)" - - p4rt-ctl add-entry br0 linux_networking_control.vsi_to_vsi_loopback \ - "vmeta.common.vsi=27,target_vsi=9,action=linux_networking_control.fwd_to_vsi(25)" - -``` - -### Configure rules for mapping between Physical port and ACC port representer - -Configure rules to send ingress packets from a physical port to its respective port representers. - -Refer above port mapping for physical port to ACC port representer mapping. Here sample commands are shown for a single physical port, configure similar mapping for remaining physical ports. - -Example: - -- Physical port 0 port id is 0 -- Corresponding port representer VSI value 17 -- If a VSI is used as an action, add an offset of 16 to the VSI value - -```bash -# Create a source port for a physical port (Phy port-0). Source port action can be any value. -# For simplicity consider the same value as phy port id. - p4rt-ctl add-entry br0 linux_networking_control.rx_source_port \ - "vmeta.common.port_id=0,zero_padding=0,action=linux_networking_control.set_source_port(0)" - -# Create a mapping between physical port (Phy port 0/src port 0) and ACC port representer (VSI-17) - p4rt-ctl add-entry br0 linux_networking_control.rx_phy_port_to_pr_map \ - "vmeta.common.port_id=0,zero_padding=0,action=linux_networking_control.fwd_to_vsi(33)" - - p4rt-ctl add-entry br0 linux_networking_control.source_port_to_pr_map \ - "user_meta.cmeta.source_port=0,zero_padding=0,action=linux_networking_control.fwd_to_vsi(33)" - - p4rt-ctl add-entry br0 linux_networking_control.tx_acc_vsi \ - "vmeta.common.vsi=17,zero_padding=0,action=linux_networking_control.l2_fwd_and_bypass_bridge(0)" -``` - -### Configure rules for mapping between APF netdev on HOST and ACC port representer - -Configure rules to send APF netdev on HOST to its respective port representers. - -Refer above port mapping for APF netdev on HOST to ACC port representer mapping. Here sample commands are shown for APF netdev on HOST, configure similar mapping for remaining APF netdevs on HOST. - -Example: - -- APF netdev 1 on HOST has a VSI value 24 -- Corresponding port representer VSI value 18 -- If a VSI is used as an action, add an offset of 16 to the VSI value - -```bash -# Create a source port for an overlay VF (VSI-24). Source port action can be any value. -# For simplicity add 16 to VSI ID. - p4rt-ctl add-entry br0 linux_networking_control.tx_source_port_v4 \ - "vmeta.common.vsi=24,zero_padding=0,action=linux_networking_control.set_source_port(40)" - - -# Create a mapping between overlay VF (VSI-24/source port-40) and ACC port representer (VSI-18) - p4rt-ctl add-entry br0 linux_networking_control.source_port_to_pr_map \ - "user_meta.cmeta.source_port=40,zero_padding=0,action=linux_networking_control.fwd_to_vsi(34)" - - p4rt-ctl add-entry br0 linux_networking_control.tx_acc_vsi \ - "vmeta.common.vsi=17,zero_padding=0,action=linux_networking_control.l2_fwd_and_bypass_bridge(0)" - -# Create a mapping for traffic to flow between VSIs (VSI-24/source port-40) and (VSI-18) - p4rt-ctl add-entry br0 linux_networking_control.vsi_to_vsi_loopback \ - "vmeta.common.vsi=18,target_vsi=24,action=linux_networking_control.fwd_to_vsi(40)" - - p4rt-ctl add-entry br0 linux_networking_control.vsi_to_vsi_loopback \ - "vmeta.common.vsi=24,target_vsi=18,action=linux_networking_control.fwd_to_vsi(34)" -``` - -### Configure supporting p4 runtime tables - -For TCAM entry configure LPM LUT table - -```bash - p4rt-ctl add-entry br0 linux_networking_control.ipv4_lpm_root_lut \ - "user_meta.cmeta.bit32_zeros=4/255.255.255.255,priority=65535,action=linux_networking_control.ipv4_lpm_root_lut_action(0)" -``` - -Create a dummy LAG bypass table for all 8 hash indexes - -```bash - p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ - "user_meta.cmeta.lag_group_id=0,hash=0,action=linux_networking_control.bypass" - - p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ - "user_meta.cmeta.lag_group_id=0,hash=1,action=linux_networking_control.bypass" - - p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ - "user_meta.cmeta.lag_group_id=0,hash=2,action=linux_networking_control.bypass" - - p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ - "user_meta.cmeta.lag_group_id=0,hash=3,action=linux_networking_control.bypass" - - p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ - "user_meta.cmeta.lag_group_id=0,hash=4,action=linux_networking_control.bypass" - - p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ - "user_meta.cmeta.lag_group_id=0,hash=5,action=linux_networking_control.bypass" - - p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ - "user_meta.cmeta.lag_group_id=0,hash=6,action=linux_networking_control.bypass" - - p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ - "user_meta.cmeta.lag_group_id=0,hash=7,action=linux_networking_control.bypass" -``` - -### Create integration bridge and add ports to the bridge - -Create OvS bridge, VxLAN tunnel and assign overlay VFs port representer to individual bridges. -Reference provided for single overlay network, repeat similar steps for other VFs. - -Each bridge has: - -- One overlay PR which is Native-tagged to a specific VLAN -- One VxLAN port which is Native-untagged to the VLAN and with different remote TEP and VNI - -```bash -ovs-vsctl add-br br-1 -ovs-vsctl add-port br-1 enp0s1f0d1 tag=10 vlan_mode=native-tagged -ovs-vsctl add-port br-1 vxlan1 tag=10 vlan_mode=native-untagged -- set interface vxlan1 type=vxlan \ - options:local_ip=10.1.1.1 options:remote_ip=10.1.1.2 options:key=10 options:dst_port=4789 -``` - -Note: Here we are creating a VxLAN tunnel with VNI 0, you can create any VNI for tunneling. - -### Underlay configuration - -Create TEP termination bridge, add physical port's port representer and APF netdev port representer. -Reference provided for underlay network, repeat similar steps for multiple underlay networks. - -```bash -ovs-vsctl add-br br-tun-1 -ovs-vsctl add-port br-tun-1 enp0s1f0d9 -ovs-vsctl add-port br-tun-1 enp0s1f0d10 -``` - -Configure underlay IP address on the TEP termination port, route to reach remote IP is on termination bridge, and add change routes to reach remote IP. - -```bash -# Create a dummy port and add TEP local IP -ip link add dev TEP10 type dummy -ifconfig TEP10 10.1.1.1/24 up - -# On termiantion bridge, configure an IP to reach remote TEP, and modify route to include nexthop details. -ifconfig br-tun-1 1.1.1.1/24 up -ip route change 10.1.1.0/24 via 1.1.1.2 dev br-tun-1 -``` - -### Test the ping scenarios - -- Underlay ping -- Overlay ping: Ping between VM's on different hosts +# Linux Networking for ES2K + +Linux Networking provides support for offloading various networking functions, such as L2 forwarding, L3 forwarding, ECMP, and VxLAN encapsulation and decapsulation intelligence to the IPU. This capability empowers overlay services to establish communication with endpoints through VxLAN tunnels, thereby extending the L2 segment across the underlay network. To achieve Linux networking support, we have used legacy OvS for overlay source MAC learning and VxLAN configurations, while relying on the kernel for underlay neighbor discovery, route management, and next-hop information. + +## Feature Overview + +This feature can run in two modes: + +- Slow path: All packets must land on the control plane and only the control plane has the intelligence to forward the traffic. +- Fast path: Only first unknown traffic (both SMAC and DMAC) will be sent to the control plane and subsequent traffic should be forwarded by IPU E2100. + +To enable this feature we have, + +- `Infrap4d`: This process includes a p4runtime server. Calls TDI front end to program IPU E2100. +- `ovs-vswitchd`: This process is integrated with p4runtime intelligence and acts as a gRPC client. Programs IPU E2100 with control plane configuration and forwarding tables by communicating with gRPC server. +- `p4rt-ctl`: This python CLI includes a p4runtime client. Programs IPU E2100 with runtime rules by communicating with gRPC server. +- `Kernel stack`: All underlay related configurations are picked by `kernel monitor` thread via netlink events in `infrap4d` and these are programmed in IPU E2100 by calling TDI front end calls. + +## Topology + +This topology breakdown and configuration assumes all VMs are spawned on HOST VFs and the control plane is running on ACC. + +![Linux Networking Topology](es2k-lnw-topology.png) + +### Topology breakdown + +- Every VM spawned on top of a VF will have a corresponding port representer in ACC. +- Every physical port will have a corresponding port representer in ACC. +- Every physical port will have an uplink (APF netdev) in HOST and this uplink will have a corresponding port representer in ACC. +- All port representers are associated with an OvS bridge. +- For VxLAN egress traffic, the underlay port should be associated with a termination bridge and IP to reach the underlay network should be configured on top of this bridge. + +## Detailed Design + +### Slow path + +To enable slow path mode: + +- Start the infrap4d process with the Kernel Monitor disabled. Command: `infrap4d -disable-krnlmon` +- Set environment variable `OVS_P4_OFFLOAD=false` before starting the `ovs-vswitchd` process. + +In this mode, we need to associate VFs on top of which VMs are created and its port representers, also physical ports with its port representers. +Configure tables: + +```text +- rx_source_port +- tx_source_port_v4/tx_source_port_v6 +- tx_acc_vsi +- vsi_to_vsi_loopback +- source_port_to_pr_map +- rx_phy_port_to_pr_map +``` + +All port representers (PRs) in ACC should be associated with an OvS bridge. Mapping between PRs and bridges need to be programmed in IPU as well. +Configure table: + +```text +- source_port_to_bridge_map +``` + +For egress VxLAN traffic, an OvS VxLAN port needs to be created in ACC and associated to the integration bridge that handles overlay traffic. +Configure table: + +```text +- rx_ipv4_tunnel_source_port/rx_ipv6_tunnel_source_port +- source_port_to_bridge_map +``` + +Once these tables are configured refer to packet flow as mentioned below. + +#### For Tx + +##### Egress traffic without VxLAN encap + +Packets coming from overlay network: + +- Determine the source port of the packet based on which overlay VSI the packet has landed on. +- Validate if the source port is part of the bridge, else drop the packet. +- If valid bridge configuration is found, find the PR associated with the bridge and forward the packet to the PR in ACC. +- OvS control plane receives the packet and forwards the packets to destined PR if MAC is already learnt, else flood the packet in the respective bridge. +- Sample OvS config: + + ```bash + ovs-vsctl add-br br-int + ovs-vsctl add-port br-int + ovs-vsctl add-port br-int + ``` + +##### Egress traffic with VxLAN encap + +Packets coming from overlay network: + +- Determine the source port of the packet based on which overlay VSI the packet has landed on. +- Validate if the source port is part of the bridge, else drop the packet. +- If valid bridge configuration is found, find the PR associated with the bridge and forward the packet to the PR in ACC. +- OvS control plane receives the packet and forwards the packets to the destined VxLAN port if MAC is already learnt, else flood the packet in the respective bridge. +- Once the packet reaches the VxLAN port, here the kernel checks the routing table to reach `remote_ip` that is configured for the OvS VxLAN tunnel. +- Underlay network to reach `remote_ip` is configured on a TEP termination bridge. Here, the kernel resolves ARP of the underlay network. +- Once ARP is resolved, kernel encapsulates the packet and this packet will be forwarded to the destined PR of the physical port if MAC is already learnt, else flood the packet in the respective TEP termination bridge. +- Sample OvS config: + + ```bash + ovs-vsctl add-br br-int + ovs-vsctl add-port br-int + ovs-vsctl add-port br-int + ovs-vsctl add-br br-tep-termination ## this bridge has IP to reach remote TEP + ovs-vsctl add-port br-tep-termination + ``` + +#### For Rx + +##### Ingress non VxLAN packet + +If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: + +- Determine the source port of the packet based on which physical port the packet has landed on. +- Validate if the source port is part of the bridge, else drop the packet. +- If valid bridge configuration is found, find the PR associated with the bridge and forward the packet to the PR in ACC. +- OvS control plane receives the packet and forwards the packets to destined PR if MAC is already learnt, else flood the packet in the respective bridge. +- Sample OvS config: + + ```bash + ovs-vsctl add-br br-int + ovs-vsctl add-port br-int + ovs-vsctl add-port br-int + ``` + +##### Ingress VxLAN packet + +If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: + +- Determine the source port of the packet based on which physical port the packet has landed +- Validate if the source port is part of the bridge, else drop the packet. +- If valid bridge configuration is found, find the PR associated with the physical port and forward the packet to the PR in ACC. +- OvS control plane receives the packet on a TEP termination bridge, packet gets decapped and sent to VxLAN port. +- Since VxLAN port and overlay VMs PR are in the same bridge, if the overlay MAC is already learnt the packet will be forwarded to destined PR else packet will be flooded in the respective bridge. +- Sample OvS config: + + ```bash + ovs-vsctl add-br br-int + ovs-vsctl add-port br-int + ovs-vsctl add-port br-int + ovs-vsctl add-br br-tep-termination ## this bridge has IP to reach remote TEP + ovs-vsctl add-port br-tep-termination + ``` + +### Fast path (when IPU forwards the packet) + +To enable fast path mode: + +- Start the infrap4d process. +- Remove the environment variable `OVS_P4_OFFLOAD=false` before starting the `ovs-vswitchd` process. + +In this mode, we need to associate VFs on top which VMs are created and its port representers and also physical ports with its port representers. +Configure tables: + +```text +- rx_source_port +- tx_source_port_v4/tx_source_port_v6 +- tx_acc_vsi +- vsi_to_vsi_loopback +- source_port_to_pr_map +- rx_phy_port_to_pr_map +- tx_lag_table ## This is a dummy LAG entry when we have underlay as Non LAG case. +``` + +Once OvS bridge is created and PR's are added to the OvS bridge, a unique bridge ID for the OvS bridge is created and creates a mapping between ACC PR's & OvS bridge. This mapping is programed in IPU E2100 with, + +```text +- source_port_to_bridge_map +- vlan_push_mod_table ## If ACC PR is part of a VLAN +- vlan_pop_mod_table ## If ACC PR is part of a VLAN +``` + +Once a VxLAN tunnel is created on a particular OvS bridge, we program IPU E2100 with, + +```text +- rx_ipv4_tunnel_source_port/rx_ipv6_tunnel_source_port +- vxlan_encap_mod_table/vxlan_encap_v6_mod_table +- vxlan_encap_vlan_pop_mod_table/vxlan_encap_v6_vlan_pop_mod_table ## If VxLAN is part of a VLAN +- vxlan_decap_mod_table +- vxlan_decap_and_push_vlan_mod_table ## If VxLAN is part of a VLAN +- ipv4_tunnel_term_table/ipv6_tunnel_term_table +``` + +When the first packet (either Tx or Rx) reaches the IPU, since no rules are programmed, this packet will be sent to respective PR's. From PR's OvS learns the MAC address and control plane dynamically programs, + +```text +- l2_fwd_smac_table +- l2_fwd_tx_table +- l2_fwd_rx_table +- l2_to_tunnel_v4/l2_to_tunnel_v6 +``` + +When underlay network is configured and underlay neighbor is learnt we dynamically program, + +```text +- ipv4_table/ipv6_table +- nexthop_table +- neighbor_mod_table +``` + +Once these tables are configured refer to packet flow as mentioned below. + +#### For Tx + +##### Egress traffic without VxLAN encap + +Packets coming from overlay network: + +- Determine the source port of the packet based on which overlay VSI the packet has landed on. +- Validate if the source port is part of the bridge, else drop the packet. +- If valid bridge configuration is found, check if SMAC of the packet is learnt. +- Check if DMAC packet is learnt against the bridge derived above. If entry matches, forward the packet to VF corresponding to the physical port. +- Sample OvS config: + + ```bash + ovs-vsctl add-br br-int + ovs-vsctl add-port br-int + ovs-vsctl add-port br-int + ``` + +##### Egress traffic with VxLAN encap + +Packets coming from overlay network: + +- Determine the source port of the packet based on which overlay VSI the packet has landed on. +- Check if the DMAC of the packet is reachable via the VxLAN tunnel and set the remote_ip of the tunnel. +- Validate if the source port is part of the bridge, else drop the packet. +- If valid bridge configuration is found, check if SMAC of the packet is learnt. +- Check if DMAC packet is learnt against the bridge derived above. If yes, populated Src IP, Dest IP, VNI, SRC port and Dest port of outer packet. +- Based on the above derived remote_ip, retrieve what is the nexthop from ipv4_table. +- Derive from which physical port this nexthop is learnt and add the nexthop MAC address as DMAC and underlay port MAC as SMAC of the packet. +- Sample OvS config: + + ```bash + ovs-vsctl add-br br-int + ovs-vsctl add-port br-int + ovs-vsctl add-port br-int + ovs-vsctl add-br br-tep-termination ## this bridge has IP to reach remote TEP + ovs-vsctl add-port br-tep-termination + ``` + +#### For Rx + +##### Ingress non VxLAN packet + +If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: + +- Determine the source port of the packet based on which physical port the packet has landed on. +- Validate if the source port is part of the bridge, else drop the packet. +- If valid bridge configuration is found, check if the inner SMAC of the packet is learnt. +- Check if the inner DMAC packet is learnt against the bridge derived above. If entry matches, forward the packet to VF corresponding to the overlay VM. +- Sample OvS config: + + ```bash + ovs-vsctl add-br br-int + ovs-vsctl add-port br-int + ovs-vsctl add-port br-int + ``` + +##### Ingress VxLAN packet + +If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: + +- Determine the source port of the packet based on which physical port the packet has landed +- Validate if the source port is part of the bridge, else drop the packet. +- If valid bridge configuration is found, check if the inner SMAC of the packet is learnt. +- Check if the inner DMAC packet is learnt against the bridge derived above. If entry matches, decap the outer packet and forward the inner packet to the overlay VF where DMAC is learnt. +- Sample OvS config: + + ```bash + ovs-vsctl add-br br-int + ovs-vsctl add-port br-int + ovs-vsctl add-port br-int + ovs-vsctl add-br br-tep-termination ## this bridge has IP to reach remote TEP + ovs-vsctl add-port br-tep-termination + ``` + +## Summary + +- Verification of source port and Associated L2 Bridge: The P4 Control Plane (P4 CP) must ensure the validation of the source port and its corresponding L2 bridge before initiating any further regulation of datapath packet classification. +- Exception Packet Handling for All Protocols: The P4 Control Plane (P4 CP) shall incorporate exception packet handling logic, not limited to ARP but applicable to the first packet of any protocol. +- Offloading of Networking Functions: The P4 Control Plane (P4 CP) software shall provide support for the offloading of various networking functions as specified in the Linux Networking use case. These networking functions include Layer 2 (L2) and Layer 3 (L3) forwarding, Equal-Cost Multi-Path (ECMP) routing, Link Aggregation Group (LAG), as well as Virtual Extensible LAN (VXLAN) encapsulation and decapsulation. These functions shall support both single and multiple Open vSwitch (OvS) bridges. + +## Limitations + +Current Linux Networking support for the networking recipe has the following limitations: + +- VLAN configuration on OvS is supported only for NATIVE-TAG and NATIVE-UNTAG modes. +- Physical port's port representer should be added as the 1st port in Tunnel TEP bridge (br-tep-termination). +- Only OvS bridges are supported. +- Configure p4rt-ctl runtime rules before OvS configuration. +- Double vlan tag is NOT supported. +- Add all ACC PR's to VSI group 1 +- On ACC firewalld need to be disabled, this service is blocking tunnel packets. + - systemctl stop firewalld +- Refer LNW-V2 README_P4_CP_NWS which comes along with the p4 program for limitation with router_interface_id action in nexthop_table (Bug created for this) + - Manually modify context.json to remove NOP hardware action for in context.json from "set_nexthop " action in "nexthop_table". Open defect is present in p4-sde to fix this issue. + +```text +Content to be removed under hardware action is +{ + "prec": 0, + "action_code": "NOP", + "index": 0, + "value": 0, + "mask": 0 +}, +``` diff --git a/docs/apps/lnw/es2k/es2k-lnw-overlay-vms.md b/docs/apps/lnw/es2k/es2k-lnw-overlay-vms.md new file mode 100644 index 00000000..cccbd058 --- /dev/null +++ b/docs/apps/lnw/es2k/es2k-lnw-overlay-vms.md @@ -0,0 +1,366 @@ + + +# Linux Networking with Overlay VMs + +This document explains how to run the Linux networking scenario on ES2K with 8 overlay VMs. + +## Topology + +![Linux Networking Topology](es2k-lnw-topology.png) + +See [Linux Networking for ES2K](es2k-linux-networking.md) +for more details on this feature. + +Prerequisites: + +- Follow steps mentioned in [Deploying P4 Programs for E2100](/guides/es2k/deploying-p4-programs) for bringing up IPU with a particular release build. +- Download `hw-p4-programs` TAR file specific to the build and extract it to get `fxp-net_linux-networking-v2` p4 artifacts. Go through `Limitations` specified in `README` and bringup the setup accordingly. + - Modify `sem_num_pages` to 25 and `lem_num_pages` to 10 in `cp_init.cfg` present in IMC. +- For this use case, before booting ACC with a particular release build, modify `acc_apf` value to 16 under `num_default_vport` in file `cp_init.cfg` present in IMC. +- Download `IPU_Documentation` TAR file specific to the build and refer to `Getting Started Guide` on how to install compatible `IDPF driver` on host. Once an IDPF driver is installed, bring up SRIOV VF by modifying the `sriov_numvfs` file present under one of the IDPF network devices. Example as below + + ```bash + echo 16 > /sys/class/net/ens802f0/device/sriov_numvfs + ``` + +Notes about topology: + +- VMs are spawned on top of each VFs. Each VF will have a respective port representer in ACC. P4 runtime rules are configured to map VFs and its corresponding port representers. +- Each physical port will have a port representer in ACC. P4 runtime rules are configured to map VFs and its corresponding port representers. +- Each physical port will have a corresponding APF netdev on HOST. Create port representers in ACC for each HOST APF netdev. These APF netdev on HOST will receive unknown traffic for applications to act on. +- All port representers should be part of an OvS bridge. Based on topology, these OvS bridges will just perform bridging or TEP termination bridges which are used to enable underlay connectivity for VxLAN traffic. +- OvS bridges, VxLAN ports are created using ovs-vsctl command provided by the networking recipe and all the port representers are attached to OvS bridge using ovs-vsctl command. +- This config has: + - 8 Overlay VFs + - 8 Port representers in ACC for the above 8 Overlay VFs + - 2 physical ports + - 2 Port representers in ACC for the above 2 physical ports + - 2 APF netdev on HOST + - 2 Port representers in ACC for the above 2 HOST APF netdevs + +System under test will have above topology running the networking recipe. Link Partner can have the networking recipe or legacy OvS or kernel VxLAN. Refer to the limitation section in [Linux Networking for E2100](es2k-linux-networking.md) before setting up the topology. + +## Creating the topology + +Follow steps mentioned in [Running Infrap4d on Intel E2100](/guides/es2k/running-infrap4d.md) for starting `infrap4d` process and creating protobuf binary for `fxp-net_linux-networking-v2` p4 program. + +### Port Mapping + +These VSI values can be checked with `/usr/bin/cli_client -q -c` command on IMC. This command provides VSI ID, Vport ID, and corresponding MAC addresses for all + +- IDPF netdevs on ACC +- VFs on HOST +- IDPF netdevs on HOST (if IDPF driver loaded by you on HOST) +- Netdevs on IMC + +| Overlay VFs | Overlay VFs VSI ID | ACC port representer | ACC port representer VSI ID | +| ------------| ------------------ | -------------------- | --------------------------- | +| ens802f0v0 | (0x1b) 27 | enp0s1f0d1 | (0x09) 9 | +| ens802f0v1 | (0x1c) 28 | enp0s1f0d2 | (0x0a) 10 | +| ens802f0v4 | (0x1d) 29 | enp0s1f0d3 | (0x0b) 11 | +| ens802f0v3 | (0x1e) 30 | enp0s1f0d4 | (0x0c) 12 | +| ens802f0v2 | (0x1f) 31 | enp0s1f0d5 | (0x0d) 13 | +| ens802f0v11 | (0x20) 32 | enp0s1f0d6 | (0x0e) 14 | +| ens802f0v10 | (0x21) 33 | enp0s1f0d7 | (0x0f) 15 | +| ens802f0v9 | (0x22) 34 | enp0s1f0d8 | (0x10) 16 | + +| Physical port | Physical port ID | ACC Port presenter | ACC Port presenter VSI ID | +| ------------- | ----------------- | -------------------- | ------------------------- | +| Phy port 0 | (0x0) 0 | enp0s1f0d9 | (0x11) 17 | +| Phy port 1 | (0x1) 1 | enp0s1f0d11 | (0x13) 19 | + +| APF netdev | APF netdev VSI ID | ACC Port presenter | ACC Port presenter VSI ID | +| ------------- | ----------------- | -------------------- | ------------------------- | +| ens802f0d1 | (0x18) 24 | enp0s1f0d10 | (0x12) 18 | +| ens802f0d2 | (0x19) 25 | enp0s1f0d12 | (0x14) 20 | + +(NOTE: Above port names and its VSI ID's may different from setup to setup, configure accordingly) + +### Set the forwarding pipeline + +Once the application is started, set the forwarding pipeline config using +P4Runtime Client `p4rt-ctl` set-pipe command + +```bash +$P4CP_INSTALL/bin/p4rt-ctl set-pipe br0 $OUTPUT_DIR/fxp-net_linux-networking-v2.pb.bin \ + $OUTPUT_DIR/p4info.txt +``` + +Note: Assuming `fxp-net_linux-networking-v2.pb.bin` and `p4info.txt` +along with other P4 artifacts are created as per the steps mentioned in the previous section. + +### Configure VSI Group and add a netdev + +Add all ACC port representers to VSI group 1. VSI group 1 is dedicated for this configuration, +execute below devmem commands on IMC. + +```bash +# SEM_DIRECT_MAP_PGEN_CTRL: LSB 11-bit is for vsi which need to map into vsig +devmem 0x20292002a0 64 0x8000050000000009 + +# SEM_DIRECT_MAP_PGEN_DATA_VSI_GROUP : This will set vsi +# (set in SEM_DIRECT_MAP_PGEN_CTRL register LSB) into VSIG-1. +devmem 0x2029200388 64 0x1 + +# SEM_DIRECT_MAP_PGEN_CTRL: LSB 11-bit is for vsi which need to map into vsig +devmem 0x20292002a0 64 0xA000050000000009 +``` + +Note: Here VSI 9 has been used as one of the ACC port representers and added to VSI group 1. For this use case add all 16 IDPF interfaces created on ACC. Modify this VSI based on your configuration. + +### Start OvS as a separate process + +Legacy OvS is used as a control plane for source MAC learning of overlay VM's. OvS should be started as a separate process. + +```bash +export RUN_OVS=/opt/p4/p4-cp-nws + +rm -rf $RUN_OVS/etc/openvswitch +rm -rf $RUN_OVS/var/run/openvswitch +mkdir -p $RUN_OVS/etc/openvswitch/ +mkdir -p $RUN_OVS/var/run/openvswitch + + +ovsdb-tool create $RUN_OVS/etc/openvswitch/conf.db \ + $RUN_OVS/share/openvswitch/vswitch.ovsschema + +ovsdb-server \ + --remote=punix:$RUN_OVS/var/run/openvswitch/db.sock \ + --remote=db:Open_vSwitch,Open_vSwitch,manager_options \ + --pidfile --detach + +ovs-vsctl --no-wait init + +mkdir -p /tmp/logs +ovs-vswitchd --pidfile --detach --mlockall \ + --log-file=/tmp/logs/ovs-vswitchd.log + +ovs-vsctl set Open_vSwitch . other_config:n-revalidator-threads=1 +ovs-vsctl set Open_vSwitch . other_config:n-handler-threads=1 + +ovs-vsctl show +``` + +### Create Overlay network + +Option 1: Create VFs on HOST and spawn VMs on top of those VFs. +Example: Below config is provided for one VM, and considering each VM is in one VLAN. Extend this to 8 VMs. + +```bash +# VM1 configuration +telnet +ip link add link name .10 type vlan id 10 +ip addr add 101.0.0.1/24 dev .10 +ifconfig up +ifconfig .10 up +``` + +Option 2: If we are unable to spawn VM's on top of the VF's, we can leverage kernel network namespaces. +Move each VF to a network namespace and assign IP addresses. +Example: Below config is provided for one VM, and considering each namespace is in one VLAN. Extend this to 8 namespaces. + +```bash +ip netns add VM0 +ip link set netns VM0 +ip netns exec VM0 ip link add link name .10 type vlan id 10 +ip netns exec VM0 ip addr add 101.0.0.1/24 dev .10 +ip netns exec VM0 ifconfig up +ip netns exec VM0 ifconfig .10 up +``` + +### Configure rules for mapping between Overlay VF and ACC port representer + +Configure rules to send overlay packets from a VM to its respective port representers. + +Refer above port mapping for overlay VF to ACC port representer mapping. Here sample commands are shown for a single overlay network, configure similar mapping for remaining VFs. + +Example: + +- Overlay VF1 has a VSI value 27 +- Corresponding port representer VSI value 9 +- If a VSI is used as an action, add an offset of 16 to the VSI value + +```bash +# Create a source port for an overlay VF (VSI-27). Source port action can be any value. +# For simplicity add 16 to VSI ID. + p4rt-ctl add-entry br0 linux_networking_control.tx_source_port_v4 \ + "vmeta.common.vsi=27,zero_padding=0,action=linux_networking_control.set_source_port(43)" + +# Create a mapping between overlay VF (VSI-27/source port-43) and ACC port representer (VSI-9) + p4rt-ctl add-entry br0 linux_networking_control.source_port_to_pr_map \ + "user_meta.cmeta.source_port=43,zero_padding=0,action=linux_networking_control.fwd_to_vsi(25)" + + p4rt-ctl add-entry br0 linux_networking_control.tx_acc_vsi \ + "vmeta.common.vsi=9,zero_padding=0,action=linux_networking_control.l2_fwd_and_bypass_bridge(43)" + +# Create a mapping for traffic to flow between VSIs (VSI-27/source port-43) and (VSI-9) + p4rt-ctl add-entry br0 linux_networking_control.vsi_to_vsi_loopback \ + "vmeta.common.vsi=9,target_vsi=27,action=linux_networking_control.fwd_to_vsi(43)" + + p4rt-ctl add-entry br0 linux_networking_control.vsi_to_vsi_loopback \ + "vmeta.common.vsi=27,target_vsi=9,action=linux_networking_control.fwd_to_vsi(25)" + +``` + +### Configure rules for mapping between Physical port and ACC port representer + +Configure rules to send ingress packets from a physical port to its respective port representers. + +Refer above port mapping for physical port to ACC port representer mapping. Here sample commands are shown for a single physical port, configure similar mapping for remaining physical ports. + +Example: + +- Physical port 0 port id is 0 +- Corresponding port representer VSI value 17 +- If a VSI is used as an action, add an offset of 16 to the VSI value + +```bash +# Create a source port for a physical port (Phy port-0). Source port action can be any value. +# For simplicity consider the same value as phy port id. + p4rt-ctl add-entry br0 linux_networking_control.rx_source_port \ + "vmeta.common.port_id=0,zero_padding=0,action=linux_networking_control.set_source_port(0)" + +# Create a mapping between physical port (Phy port 0/src port 0) and ACC port representer (VSI-17) + p4rt-ctl add-entry br0 linux_networking_control.rx_phy_port_to_pr_map \ + "vmeta.common.port_id=0,zero_padding=0,action=linux_networking_control.fwd_to_vsi(33)" + + p4rt-ctl add-entry br0 linux_networking_control.source_port_to_pr_map \ + "user_meta.cmeta.source_port=0,zero_padding=0,action=linux_networking_control.fwd_to_vsi(33)" + + p4rt-ctl add-entry br0 linux_networking_control.tx_acc_vsi \ + "vmeta.common.vsi=17,zero_padding=0,action=linux_networking_control.l2_fwd_and_bypass_bridge(0)" +``` + +### Configure rules for mapping between APF netdev on HOST and ACC port representer + +Configure rules to send APF netdev on HOST to its respective port representers. + +Refer above port mapping for APF netdev on HOST to ACC port representer mapping. Here sample commands are shown for APF netdev on HOST, configure similar mapping for remaining APF netdevs on HOST. + +Example: + +- APF netdev 1 on HOST has a VSI value 24 +- Corresponding port representer VSI value 18 +- If a VSI is used as an action, add an offset of 16 to the VSI value + +```bash +# Create a source port for an overlay VF (VSI-24). Source port action can be any value. +# For simplicity add 16 to VSI ID. + p4rt-ctl add-entry br0 linux_networking_control.tx_source_port_v4 \ + "vmeta.common.vsi=24,zero_padding=0,action=linux_networking_control.set_source_port(40)" + + +# Create a mapping between overlay VF (VSI-24/source port-40) and ACC port representer (VSI-18) + p4rt-ctl add-entry br0 linux_networking_control.source_port_to_pr_map \ + "user_meta.cmeta.source_port=40,zero_padding=0,action=linux_networking_control.fwd_to_vsi(34)" + + p4rt-ctl add-entry br0 linux_networking_control.tx_acc_vsi \ + "vmeta.common.vsi=17,zero_padding=0,action=linux_networking_control.l2_fwd_and_bypass_bridge(0)" + +# Create a mapping for traffic to flow between VSIs (VSI-24/source port-40) and (VSI-18) + p4rt-ctl add-entry br0 linux_networking_control.vsi_to_vsi_loopback \ + "vmeta.common.vsi=18,target_vsi=24,action=linux_networking_control.fwd_to_vsi(40)" + + p4rt-ctl add-entry br0 linux_networking_control.vsi_to_vsi_loopback \ + "vmeta.common.vsi=24,target_vsi=18,action=linux_networking_control.fwd_to_vsi(34)" +``` + +### Configure supporting p4 runtime tables + +For TCAM entry configure LPM LUT table + +```bash + p4rt-ctl add-entry br0 linux_networking_control.ipv4_lpm_root_lut \ + "user_meta.cmeta.bit32_zeros=4/255.255.255.255,priority=65535,action=linux_networking_control.ipv4_lpm_root_lut_action(0)" +``` + +Create a dummy LAG bypass table for all 8 hash indexes + +```bash + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=0,action=linux_networking_control.bypass" + + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=1,action=linux_networking_control.bypass" + + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=2,action=linux_networking_control.bypass" + + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=3,action=linux_networking_control.bypass" + + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=4,action=linux_networking_control.bypass" + + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=5,action=linux_networking_control.bypass" + + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=6,action=linux_networking_control.bypass" + + p4rt-ctl add-entry br0 linux_networking_control.tx_lag_table \ + "user_meta.cmeta.lag_group_id=0,hash=7,action=linux_networking_control.bypass" +``` + +### Create integration bridge and add ports to the bridge + +Create OvS bridge, VxLAN tunnel and assign overlay VFs port representer to individual bridges. +Reference provided for single overlay network, repeat similar steps for other VFs. + +Each bridge has: + +- One overlay PR which is Native-tagged to a specific VLAN +- One VxLAN port which is Native-untagged to the VLAN and with different remote TEP and VNI + +```bash +ovs-vsctl add-br br-1 +ovs-vsctl add-port br-1 enp0s1f0d1 tag=10 vlan_mode=native-tagged +ovs-vsctl add-port br-1 vxlan1 tag=10 vlan_mode=native-untagged -- set interface vxlan1 type=vxlan \ + options:local_ip=10.1.1.1 options:remote_ip=10.1.1.2 options:key=10 options:dst_port=4789 +``` + +Note: Here we are creating a VxLAN tunnel with VNI 0, you can create any VNI for tunneling. + +### Underlay configuration + +Create TEP termination bridge, add physical port's port representer and APF netdev port representer. +Reference provided for underlay network, repeat similar steps for multiple underlay networks. + +```bash +ovs-vsctl add-br br-tun-1 +ovs-vsctl add-port br-tun-1 enp0s1f0d9 +ovs-vsctl add-port br-tun-1 enp0s1f0d10 +``` + +Configure underlay IP address on the TEP termination port, route to reach remote IP is on termination bridge, and add change routes to reach remote IP. + +```bash +# Create a dummy port and add TEP local IP +ip link add dev TEP10 type dummy +ifconfig TEP10 10.1.1.1/24 up + +# On termiantion bridge, configure an IP to reach remote TEP, and modify route to include nexthop details. +ifconfig br-tun-1 1.1.1.1/24 up +ip route change 10.1.1.0/24 via 1.1.1.2 dev br-tun-1 +``` + +### Test the ping scenarios + +- Underlay ping +- Overlay ping: Ping between VMs on different hosts diff --git a/docs/apps/lnw/es2k/linux-networking-for-es2k.md b/docs/apps/lnw/es2k/linux-networking-for-es2k.md deleted file mode 100644 index 3e9b2242..00000000 --- a/docs/apps/lnw/es2k/linux-networking-for-es2k.md +++ /dev/null @@ -1,311 +0,0 @@ - -# Linux Networking for ES2K - -Linux Networking provides support for offloading various networking functions, such as L2 forwarding, L3 forwarding, ECMP, and VxLAN encapsulation and decapsulation intelligence to the IPU. This capability empowers overlay services to establish communication with endpoints through VxLAN tunnels, thereby extending the L2 segment across the underlay network. To achieve Linux networking support, we have used legacy OvS for overlay source MAC learning and VxLAN configurations, while relying on the kernel for underlay neighbor discovery, route management, and next-hop information. - -## Feature Overview - -This feature can run in two modes: - -- Slow path: All packets must land on the control plane and only the control plane has the intelligence to forward the traffic. -- Fast path: Only first unknown traffic (both SMAC and DMAC) will be sent to the control plane and subsequent traffic should be forwarded by IPU E2100. - -To enable this feature we have, - -- `Infrap4d`: This process includes a p4runtime server. Calls TDI front end to program IPU E2100. -- `ovs-vswitchd`: This process is integrated with p4runtime intelligence and acts as a gRPC client. Programs IPU E2100 with control plane configuration and forwarding tables by communicating with gRPC server. -- `p4rt-ctl`: This python CLI includes a p4runtime client. Programs IPU E2100 with runtime rules by communicating with gRPC server. -- `Kernel stack`: All underlay related configurations are picked by `kernel monitor` thread via netlink events in `infrap4d` and these are programmed in IPU E2100 by calling TDI front end calls. - -## Topology - -This topology breakdown and configuration assumes all VMs are spawned on HOST VFs and the control plane is running on ACC. - -![Linux Networking Topology](es2k-lnw-topology.png) - -### Topology breakdown - -- Every VM spawned on top of a VF will have a corresponding port representer in ACC. -- Every physical port will have a corresponding port representer in ACC. -- Every physical port will have an uplink (APF netdev) in HOST and this uplink will have a corresponding port representer in ACC. -- All port representers are associated with an OvS bridge. -- For VxLAN egress traffic, the underlay port should be associated with a termination bridge and IP to reach the underlay network should be configured on top of this bridge. - -## Detailed Design - -### Slow path - -To enable slow path mode: - -- Start the infrap4d process with the Kernel Monitor disabled. Command: `infrap4d -disable-krnlmon` -- Set environment variable `OVS_P4_OFFLOAD=false` before starting the `ovs-vswitchd` process. - -In this mode, we need to associate VFs on top of which VMs are created and its port representers, also physical ports with its port representers. -Configure tables: - -```text -- rx_source_port -- tx_source_port_v4/tx_source_port_v6 -- tx_acc_vsi -- vsi_to_vsi_loopback -- source_port_to_pr_map -- rx_phy_port_to_pr_map -``` - -All port representers (PRs) in ACC should be associated with an OvS bridge. Mapping between PRs and bridges need to be programmed in IPU as well. -Configure table: - -```text -- source_port_to_bridge_map -``` - -For egress VxLAN traffic, an OvS VxLAN port needs to be created in ACC and associated to the integration bridge that handles overlay traffic. -Configure table: - -```text -- rx_ipv4_tunnel_source_port/rx_ipv6_tunnel_source_port -- source_port_to_bridge_map -``` - -Once these tables are configured refer to packet flow as mentioned below. - -#### For Tx - -##### Egress traffic without VxLAN encap - -Packets coming from overlay network: - -- Determine the source port of the packet based on which overlay VSI the packet has landed on. -- Validate if the source port is part of the bridge, else drop the packet. -- If valid bridge configuration is found, find the PR associated with the bridge and forward the packet to the PR in ACC. -- OvS control plane receives the packet and forwards the packets to destined PR if MAC is already learnt, else flood the packet in the respective bridge. -- Sample OvS config: - - ```bash - ovs-vsctl add-br br-int - ovs-vsctl add-port br-int - ovs-vsctl add-port br-int - ``` - -##### Egress traffic with VxLAN encap - -Packets coming from overlay network: - -- Determine the source port of the packet based on which overlay VSI the packet has landed on. -- Validate if the source port is part of the bridge, else drop the packet. -- If valid bridge configuration is found, find the PR associated with the bridge and forward the packet to the PR in ACC. -- OvS control plane receives the packet and forwards the packets to the destined VxLAN port if MAC is already learnt, else flood the packet in the respective bridge. -- Once the packet reaches the VxLAN port, here the kernel checks the routing table to reach `remote_ip` that is configured for the OvS VxLAN tunnel. -- Underlay network to reach `remote_ip` is configured on a TEP termination bridge. Here, the kernel resolves ARP of the underlay network. -- Once ARP is resolved, kernel encapsulates the packet and this packet will be forwarded to the destined PR of the physical port if MAC is already learnt, else flood the packet in the respective TEP termination bridge. -- Sample OvS config: - - ```bash - ovs-vsctl add-br br-int - ovs-vsctl add-port br-int - ovs-vsctl add-port br-int - ovs-vsctl add-br br-tep-termination ## this bridge has IP to reach remote TEP - ovs-vsctl add-port br-tep-termination - ``` - -#### For Rx - -##### Ingress non VxLAN packet - -If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: - -- Determine the source port of the packet based on which physical port the packet has landed on. -- Validate if the source port is part of the bridge, else drop the packet. -- If valid bridge configuration is found, find the PR associated with the bridge and forward the packet to the PR in ACC. -- OvS control plane receives the packet and forwards the packets to destined PR if MAC is already learnt, else flood the packet in the respective bridge. -- Sample OvS config: - - ```bash - ovs-vsctl add-br br-int - ovs-vsctl add-port br-int - ovs-vsctl add-port br-int - ``` - -##### Ingress VxLAN packet - -If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: - -- Determine the source port of the packet based on which physical port the packet has landed -- Validate if the source port is part of the bridge, else drop the packet. -- If valid bridge configuration is found, find the PR associated with the physical port and forward the packet to the PR in ACC. -- OvS control plane receives the packet on a TEP termination bridge, packet gets decapped and sent to VxLAN port. -- Since VxLAN port and overlay VMs PR are in the same bridge, if the overlay MAC is already learnt the packet will be forwarded to destined PR else packet will be flooded in the respective bridge. -- Sample OvS config: - - ```bash - ovs-vsctl add-br br-int - ovs-vsctl add-port br-int - ovs-vsctl add-port br-int - ovs-vsctl add-br br-tep-termination ## this bridge has IP to reach remote TEP - ovs-vsctl add-port br-tep-termination - ``` - -### Fast path (when IPU forwards the packet) - -To enable fast path mode: - -- Start the infrap4d process. -- Remove the environment variable `OVS_P4_OFFLOAD=false` before starting the `ovs-vswitchd` process. - -In this mode, we need to associate VFs on top which VMs are created and its port representers and also physical ports with its port representers. -Configure tables: - -```text -- rx_source_port -- tx_source_port_v4/tx_source_port_v6 -- tx_acc_vsi -- vsi_to_vsi_loopback -- source_port_to_pr_map -- rx_phy_port_to_pr_map -- tx_lag_table ## This is a dummy LAG entry when we have underlay as Non LAG case. -``` - -Once OvS bridge is created and PR's are added to the OvS bridge, a unique bridge ID for the OvS bridge is created and creates a mapping between ACC PR's & OvS bridge. This mapping is programed in IPU E2100 with, - -```text -- source_port_to_bridge_map -- vlan_push_mod_table ## If ACC PR is part of a VLAN -- vlan_pop_mod_table ## If ACC PR is part of a VLAN -``` - -Once a VxLAN tunnel is created on a particular OvS bridge, we program IPU E2100 with, - -```text -- rx_ipv4_tunnel_source_port/rx_ipv6_tunnel_source_port -- vxlan_encap_mod_table/vxlan_encap_v6_mod_table -- vxlan_encap_vlan_pop_mod_table/vxlan_encap_v6_vlan_pop_mod_table ## If VxLAN is part of a VLAN -- vxlan_decap_mod_table -- vxlan_decap_and_push_vlan_mod_table ## If VxLAN is part of a VLAN -- ipv4_tunnel_term_table/ipv6_tunnel_term_table -``` - -When the first packet (either Tx or Rx) reaches the IPU, since no rules are programmed, this packet will be sent to respective PR's. From PR's OvS learns the MAC address and control plane dynamically programs, - -```text -- l2_fwd_smac_table -- l2_fwd_tx_table -- l2_fwd_rx_table -- l2_to_tunnel_v4/l2_to_tunnel_v6 -``` - -When underlay network is configured and underlay neighbor is learnt we dynamically program, - -```text -- ipv4_table/ipv6_table -- nexthop_table -- neighbor_mod_table -``` - -Once these tables are configured refer to packet flow as mentioned below. - -#### For Tx - -##### Egress traffic without VxLAN encap - -Packets coming from overlay network: - -- Determine the source port of the packet based on which overlay VSI the packet has landed on. -- Validate if the source port is part of the bridge, else drop the packet. -- If valid bridge configuration is found, check if SMAC of the packet is learnt. -- Check if DMAC packet is learnt against the bridge derived above. If entry matches, forward the packet to VF corresponding to the physical port. -- Sample OvS config: - - ```bash - ovs-vsctl add-br br-int - ovs-vsctl add-port br-int - ovs-vsctl add-port br-int - ``` - -##### Egress traffic with VxLAN encap - -Packets coming from overlay network: - -- Determine the source port of the packet based on which overlay VSI the packet has landed on. -- Check if the DMAC of the packet is reachable via the VxLAN tunnel and set the remote_ip of the tunnel. -- Validate if the source port is part of the bridge, else drop the packet. -- If valid bridge configuration is found, check if SMAC of the packet is learnt. -- Check if DMAC packet is learnt against the bridge derived above. If yes, populated Src IP, Dest IP, VNI, SRC port and Dest port of outer packet. -- Based on the above derived remote_ip, retrieve what is the nexthop from ipv4_table. -- Derive from which physical port this nexthop is learnt and add the nexthop MAC address as DMAC and underlay port MAC as SMAC of the packet. -- Sample OvS config: - - ```bash - ovs-vsctl add-br br-int - ovs-vsctl add-port br-int - ovs-vsctl add-port br-int - ovs-vsctl add-br br-tep-termination ## this bridge has IP to reach remote TEP - ovs-vsctl add-port br-tep-termination - ``` - -#### For Rx - -##### Ingress non VxLAN packet - -If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: - -- Determine the source port of the packet based on which physical port the packet has landed on. -- Validate if the source port is part of the bridge, else drop the packet. -- If valid bridge configuration is found, check if the inner SMAC of the packet is learnt. -- Check if the inner DMAC packet is learnt against the bridge derived above. If entry matches, forward the packet to VF corresponding to the overlay VM. -- Sample OvS config: - - ```bash - ovs-vsctl add-br br-int - ovs-vsctl add-port br-int - ovs-vsctl add-port br-int - ``` - -##### Ingress VxLAN packet - -If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: - -- Determine the source port of the packet based on which physical port the packet has landed -- Validate if the source port is part of the bridge, else drop the packet. -- If valid bridge configuration is found, check if the inner SMAC of the packet is learnt. -- Check if the inner DMAC packet is learnt against the bridge derived above. If entry matches, decap the outer packet and forward the inner packet to the overlay VF where DMAC is learnt. -- Sample OvS config: - - ```bash - ovs-vsctl add-br br-int - ovs-vsctl add-port br-int - ovs-vsctl add-port br-int - ovs-vsctl add-br br-tep-termination ## this bridge has IP to reach remote TEP - ovs-vsctl add-port br-tep-termination - ``` - -## Summary - -- Verification of source port and Associated L2 Bridge: The P4 Control Plane (P4 CP) must ensure the validation of the source port and its corresponding L2 bridge before initiating any further regulation of datapath packet classification. -- Exception Packet Handling for All Protocols: The P4 Control Plane (P4 CP) shall incorporate exception packet handling logic, not limited to ARP but applicable to the first packet of any protocol. -- Offloading of Networking Functions: The P4 Control Plane (P4 CP) software shall provide support for the offloading of various networking functions as specified in the Linux Networking use case. These networking functions include Layer 2 (L2) and Layer 3 (L3) forwarding, Equal-Cost Multi-Path (ECMP) routing, Link Aggregation Group (LAG), as well as Virtual Extensible LAN (VXLAN) encapsulation and decapsulation. These functions shall support both single and multiple Open vSwitch (OvS) bridges. - -## Limitations - -Current Linux Networking support for the networking recipe has the following limitations: - -- VLAN configuration on OvS is supported only for NATIVE-TAG and NATIVE-UNTAG modes. -- Physical port's port representer should be added as the 1st port in Tunnel TEP bridge (br-tep-termination). -- Only OvS bridges are supported. -- Configure p4rt-ctl runtime rules before OvS configuration. -- Double vlan tag is NOT supported. -- Add all ACC PR's to VSI group 1 -- On ACC firewalld need to be disabled, this service is blocking tunnel packets. - - systemctl stop firewalld -- Refer LNW-V2 README_P4_CP_NWS which comes along with the p4 program for limitation with router_interface_id action in nexthop_table (Bug created for this) - - Manually modify context.json to remove NOP hardware action for in context.json from "set_nexthop " action in "nexthop_table". Open defect is present in p4-sde to fix this issue. - -```text -Content to be removed under hardware action is -{ - "prec": 0, - "action_code": "NOP", - "index": 0, - "value": 0, - "mask": 0 -}, -``` diff --git a/docs/apps/lnw/lnw-index.rst b/docs/apps/lnw/lnw-index.rst index 562591e3..68392f8a 100644 --- a/docs/apps/lnw/lnw-index.rst +++ b/docs/apps/lnw/lnw-index.rst @@ -20,8 +20,8 @@ ES2K .. toctree:: :maxdepth: 1 - es2k/linux-networking-for-es2k es2k/es2k-linux-networking + es2k/es2k-lnw-overlay-vms es2k/es2k-linux-networking-ipv6 es2k/es2k-linux-networking-ecmp es2k/es2k-linux-networking-frr From cf40b065b0e8ec085a8ea8b277f696d72e417cbb Mon Sep 17 00:00:00 2001 From: bharticemk Date: Wed, 13 Dec 2023 22:11:38 -0500 Subject: [PATCH 28/31] Added support for delete meter configuration Signed-off-by: bharticemk --- clients/p4rt-ctl/p4rt-ctl.in | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/clients/p4rt-ctl/p4rt-ctl.in b/clients/p4rt-ctl/p4rt-ctl.in index d2979b9f..2646b1e2 100644 --- a/clients/p4rt-ctl/p4rt-ctl.in +++ b/clients/p4rt-ctl/p4rt-ctl.in @@ -78,6 +78,7 @@ for P4Runtime switches: add-meter-config SWITCH MTR_TBL MTR_FLOW add packet mod meter config table entry get-packet-mod-meter SWITCH MTR_TBL MTR_FLOW gets packet mod meter table entry get-direct-pkt-mod-meter SWITCH MTR_TBL MTR_FLOW gets direct packet mod meter table entry + del-meter-config SWITCH MTR_TBL MTR_FLOW delete packet mod meter config table entry """ def usage(): @@ -1909,6 +1910,34 @@ def p4ctl_get_direct_pkt_mod_meter_entry(client, bridge, tbl_name, flow): if entity.direct_meter_entry.table_entry.table_id == ce.table_entry.table_id: print(_format_dme(entry.direct_meter_entry)) +@with_client +def p4ctl_del_meter_config(client, bridge, tbl_name, flow): + """ + del-meter-config SWITCH MTR_TBL MTR_FLOW + Example: + p4rt-ctl del-meter-config br0 my_control.meter1 "meter_id=2244878476,meter_index=10" + """ + p4info = client.get_p4info() + if not p4info: + raise Exception("cannot retrieve P4Info from device {}".format(bridge)) + + helper = P4InfoHelper(p4info) + entity = p4runtime_pb2.Entity() + ce = entity.meter_entry + + if ce is None: + raise Exception("Cannot find meter_entry field in entity") + + meter_id, index = parse_get_meter_flow(flow) + ce.index.index = int(index) + ce.meter_id = int(meter_id) + + update = p4runtime_pb2.Update() + update.type = p4runtime_pb2.Update.DELETE + update.entity.meter_entry.CopyFrom(ce) + + client.write_update(update) + all_commands = { "show": (p4ctl_show, 1), "set-pipe": (p4ctl_set_pipe, 3), @@ -1933,6 +1962,7 @@ all_commands = { "add-meter-config" : (p4ctl_add_meter_config, 3), "get-packet-mod-meter" : (p4ctl_get_packet_mod_meter_entry, 2), "get-direct-pkt-mod-meter" : (p4ctl_get_direct_pkt_mod_meter_entry, 2) + "del-meter-config" : (p4ctl_del_meter_config, 2) } From c042655df5e527f4f17a8a02ff9a33f1c76fc90e Mon Sep 17 00:00:00 2001 From: bharticemk Date: Thu, 14 Dec 2023 08:40:01 -0500 Subject: [PATCH 29/31] Updating Stratum Submodule reference for network-receipe Signed-off-by: bharticemk --- stratum/stratum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stratum/stratum b/stratum/stratum index 45f1975b..b987441a 160000 --- a/stratum/stratum +++ b/stratum/stratum @@ -1 +1 @@ -Subproject commit 45f1975b6afea6700b584781c7933890c57dd185 +Subproject commit b987441afd34b740685aedc8164fd07a7aee0d99 From d28037e67ceb74390f7e91d9e65b2358e2fc100e Mon Sep 17 00:00:00 2001 From: nupuruttarwar Date: Fri, 15 Dec 2023 10:42:57 -0800 Subject: [PATCH 30/31] Fix documentation Fix linux networking documentation and update few guides according to IPU SDK procedure Signed-off-by: nupuruttarwar --- docs/apps/lnw/es2k/es2k-linux-networking.md | 83 ++++++++++---------- docs/apps/lnw/es2k/es2k-lnw-overlay-vms.md | 85 +++++++++------------ docs/guides/es2k/deploying-p4-programs.md | 50 ++++++------ docs/guides/es2k/enabling-comm-channel.md | 62 ++++++--------- 4 files changed, 126 insertions(+), 154 deletions(-) diff --git a/docs/apps/lnw/es2k/es2k-linux-networking.md b/docs/apps/lnw/es2k/es2k-linux-networking.md index 47e1f76e..9f2393f7 100644 --- a/docs/apps/lnw/es2k/es2k-linux-networking.md +++ b/docs/apps/lnw/es2k/es2k-linux-networking.md @@ -1,6 +1,6 @@ # Linux Networking for ES2K -Linux Networking provides support for offloading various networking functions, such as L2 forwarding, L3 forwarding, ECMP, and VxLAN encapsulation and decapsulation intelligence to the IPU. This capability empowers overlay services to establish communication with endpoints through VxLAN tunnels, thereby extending the L2 segment across the underlay network. To achieve Linux networking support, we have used legacy OvS for overlay source MAC learning and VxLAN configurations, while relying on the kernel for underlay neighbor discovery, route management, and next-hop information. +Linux Networking provides support for offloading various networking functions, such as L2 forwarding, L3 forwarding, ECMP, and VxLAN encapsulation and decapsulation intelligence to the IPU. This capability empowers overlay services to establish communication with endpoints through VxLAN tunnels, thereby extending the L2 segment across the underlay network. To achieve Linux networking support, we have enhanced OvS for overlay source MAC learning and VxLAN configurations, while relying on the kernel for underlay neighbor discovery, route management, and next-hop information. ## Feature Overview @@ -14,7 +14,7 @@ To enable this feature we have, - `Infrap4d`: This process includes a p4runtime server. Calls TDI front end to program IPU E2100. - `ovs-vswitchd`: This process is integrated with p4runtime intelligence and acts as a gRPC client. Programs IPU E2100 with control plane configuration and forwarding tables by communicating with gRPC server. - `p4rt-ctl`: This python CLI includes a p4runtime client. Programs IPU E2100 with runtime rules by communicating with gRPC server. -- `Kernel stack`: All underlay related configurations are picked by `kernel monitor` thread via netlink events in `infrap4d` and these are programmed in IPU E2100 by calling TDI front end calls. +- `Kernel stack`: All underlay related configurations are picked by `kernel monitor` thread via netlink events in `infrap4d` and these are programmed in IPU E2100 by calling TDI front end APIs. ## Topology @@ -24,11 +24,11 @@ This topology breakdown and configuration assumes all VMs are spawned on HOST VF ### Topology breakdown -- Every VM spawned on top of a VF will have a corresponding port representer in ACC. -- Every physical port will have a corresponding port representer in ACC. -- Every physical port will have an uplink (APF netdev) in HOST and this uplink will have a corresponding port representer in ACC. -- All port representers are associated with an OvS bridge. -- For VxLAN egress traffic, the underlay port should be associated with a termination bridge and IP to reach the underlay network should be configured on top of this bridge. +- Every VM spawned on top of a VF will have a corresponding port representor in ACC. +- Every physical port will have a corresponding port representor in ACC. +- Every physical port will have an uplink (APF netdev) in HOST and this uplink will have a corresponding port representor in ACC. +- All port representors are associated with an OvS bridge. +- For VxLAN egress traffic, the underlay port should be associated with a termination bridge and the IP to reach the underlay network should be configured on this bridge. ## Detailed Design @@ -39,8 +39,7 @@ To enable slow path mode: - Start the infrap4d process with the Kernel Monitor disabled. Command: `infrap4d -disable-krnlmon` - Set environment variable `OVS_P4_OFFLOAD=false` before starting the `ovs-vswitchd` process. -In this mode, we need to associate VFs on top of which VMs are created and its port representers, also physical ports with its port representers. -Configure tables: +In this mode, we need to associate VFs with VMs and its port representors along with physical ports and its port representors. Configure following tables to map these in IPU: ```text - rx_source_port @@ -51,15 +50,13 @@ Configure tables: - rx_phy_port_to_pr_map ``` -All port representers (PRs) in ACC should be associated with an OvS bridge. Mapping between PRs and bridges need to be programmed in IPU as well. -Configure table: +All port representors (PRs) in ACC should be associated with an OvS bridge. Configure table below to program the mapping between PRs and bridges in IPU: ```text - source_port_to_bridge_map ``` -For egress VxLAN traffic, an OvS VxLAN port needs to be created in ACC and associated to the integration bridge that handles overlay traffic. -Configure table: +For egress VxLAN traffic, an OvS VxLAN port needs to be created in ACC with associated integration bridge that handles overlay traffic. Configure following tables to map these in IPU: ```text - rx_ipv4_tunnel_source_port/rx_ipv6_tunnel_source_port @@ -70,7 +67,7 @@ Once these tables are configured refer to packet flow as mentioned below. #### For Tx -##### Egress traffic without VxLAN encap +##### Egress traffic without VxLAN encapsulation Packets coming from overlay network: @@ -86,37 +83,37 @@ Packets coming from overlay network: ovs-vsctl add-port br-int ``` -##### Egress traffic with VxLAN encap +##### Egress traffic with VxLAN encapsulation Packets coming from overlay network: - Determine the source port of the packet based on which overlay VSI the packet has landed on. - Validate if the source port is part of the bridge, else drop the packet. -- If valid bridge configuration is found, find the PR associated with the bridge and forward the packet to the PR in ACC. +- If valid bridge configuration is found, find the PR associated with the bridge and forward it to the PR in ACC. - OvS control plane receives the packet and forwards the packets to the destined VxLAN port if MAC is already learnt, else flood the packet in the respective bridge. - Once the packet reaches the VxLAN port, here the kernel checks the routing table to reach `remote_ip` that is configured for the OvS VxLAN tunnel. -- Underlay network to reach `remote_ip` is configured on a TEP termination bridge. Here, the kernel resolves ARP of the underlay network. -- Once ARP is resolved, kernel encapsulates the packet and this packet will be forwarded to the destined PR of the physical port if MAC is already learnt, else flood the packet in the respective TEP termination bridge. +- Underlay network to reach `remote_ip` is configured on a TEP termination bridge and kernel resolves the ARP for underlay network. +- Once ARP is resolved, kernel encapsulates the packet and it is forwarded to the destined PR of the physical port if MAC is already learnt, else flooded in the respective TEP termination bridge. - Sample OvS config: ```bash ovs-vsctl add-br br-int ovs-vsctl add-port br-int ovs-vsctl add-port br-int - ovs-vsctl add-br br-tep-termination ## this bridge has IP to reach remote TEP + ovs-vsctl add-br br-tep-termination ## this bridge should be configured with IP to reach remote TEP ovs-vsctl add-port br-tep-termination ``` #### For Rx -##### Ingress non VxLAN packet +##### Ingress traffic without VxLAN encapsulation -If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: +If the packets coming from a remote machine to the physical port are not VxLAN encapped packets: - Determine the source port of the packet based on which physical port the packet has landed on. - Validate if the source port is part of the bridge, else drop the packet. -- If valid bridge configuration is found, find the PR associated with the bridge and forward the packet to the PR in ACC. -- OvS control plane receives the packet and forwards the packets to destined PR if MAC is already learnt, else flood the packet in the respective bridge. +- If valid bridge configuration is found, find the PR associated with the bridge and forward it to the PR in ACC. +- OvS control plane receives the packet and it is forwarded to destined PR if MAC is already learnt, else flooded in the respective bridge. - Sample OvS config: ```bash @@ -125,13 +122,13 @@ If the packets coming from a remote machine to the physical port are not VxLAN t ovs-vsctl add-port br-int ``` -##### Ingress VxLAN packet +##### Ingress traffic with VxLAN encapsulation -If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: +If the packets coming from a remote machine to the physical port are VxLAN encapped packets: -- Determine the source port of the packet based on which physical port the packet has landed +- Determine the source port of the packet based on which physical port the packet has landed on. - Validate if the source port is part of the bridge, else drop the packet. -- If valid bridge configuration is found, find the PR associated with the physical port and forward the packet to the PR in ACC. +- If valid bridge configuration is found, find the PR associated with the physical port and forward it to the PR in ACC. - OvS control plane receives the packet on a TEP termination bridge, packet gets decapped and sent to VxLAN port. - Since VxLAN port and overlay VMs PR are in the same bridge, if the overlay MAC is already learnt the packet will be forwarded to destined PR else packet will be flooded in the respective bridge. - Sample OvS config: @@ -148,10 +145,10 @@ If the packets coming from a remote machine to the physical port are not VxLAN t To enable fast path mode: -- Start the infrap4d process. +- Start the infrap4d process. Command: `infrap4d` - Remove the environment variable `OVS_P4_OFFLOAD=false` before starting the `ovs-vswitchd` process. -In this mode, we need to associate VFs on top which VMs are created and its port representers and also physical ports with its port representers. +In this mode, we need to associate VFs with the VMs and its port representors along with physical ports and its port representors. Configure tables: ```text @@ -204,7 +201,7 @@ Once these tables are configured refer to packet flow as mentioned below. #### For Tx -##### Egress traffic without VxLAN encap +##### Egress traffic without VxLAN encapsulation Packets coming from overlay network: @@ -220,7 +217,7 @@ Packets coming from overlay network: ovs-vsctl add-port br-int ``` -##### Egress traffic with VxLAN encap +##### Egress traffic with VxLAN encapsulation Packets coming from overlay network: @@ -243,9 +240,9 @@ Packets coming from overlay network: #### For Rx -##### Ingress non VxLAN packet +##### Ingress traffic without VxLAN encap -If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: +If the packets coming from a remote machine to the physical port are not VxLAN encapped packets: - Determine the source port of the packet based on which physical port the packet has landed on. - Validate if the source port is part of the bridge, else drop the packet. @@ -259,9 +256,9 @@ If the packets coming from a remote machine to the physical port are not VxLAN t ovs-vsctl add-port br-int ``` -##### Ingress VxLAN packet +##### Ingress traffic with VxLAN encapsulation -If the packets coming from a remote machine to the physical port are not VxLAN tunnel packets: +If the packets coming from a remote machine to the physical port are VxLAN encapped packets: - Determine the source port of the packet based on which physical port the packet has landed - Validate if the source port is part of the bridge, else drop the packet. @@ -279,27 +276,27 @@ If the packets coming from a remote machine to the physical port are not VxLAN t ## Summary -- Verification of source port and Associated L2 Bridge: The P4 Control Plane (P4 CP) must ensure the validation of the source port and its corresponding L2 bridge before initiating any further regulation of datapath packet classification. -- Exception Packet Handling for All Protocols: The P4 Control Plane (P4 CP) shall incorporate exception packet handling logic, not limited to ARP but applicable to the first packet of any protocol. -- Offloading of Networking Functions: The P4 Control Plane (P4 CP) software shall provide support for the offloading of various networking functions as specified in the Linux Networking use case. These networking functions include Layer 2 (L2) and Layer 3 (L3) forwarding, Equal-Cost Multi-Path (ECMP) routing, Link Aggregation Group (LAG), as well as Virtual Extensible LAN (VXLAN) encapsulation and decapsulation. These functions shall support both single and multiple Open vSwitch (OvS) bridges. +- Verification of source port and associated L2 Bridge: The P4 Control Plane (P4 CP) must ensure the validation of the source port and its corresponding L2 bridge before initiating any further regulation of datapath packet classification. +- Exception packet handling for all protocols: The P4 Control Plane (P4 CP) shall incorporate exception packet handling logic, not limited to ARP but applicable to the first packet of any protocol. +- Offloading of networking functions: The P4 Control Plane (P4 CP) software shall provide support for the offloading of various networking functions as specified in the Linux Networking use case. These networking functions include Layer 2 (L2) and Layer 3 (L3) forwarding, Equal-Cost Multi-Path (ECMP) routing, Link Aggregation Group (LAG), as well as Virtual Extensible LAN (VXLAN) encapsulation and decapsulation. These functions shall support both single and multiple Open vSwitch (OvS) bridges. ## Limitations Current Linux Networking support for the networking recipe has the following limitations: - VLAN configuration on OvS is supported only for NATIVE-TAG and NATIVE-UNTAG modes. -- Physical port's port representer should be added as the 1st port in Tunnel TEP bridge (br-tep-termination). +- Physical port's port representor should be added as the 1st port in tunnel TEP bridge (br-tep-termination). - Only OvS bridges are supported. - Configure p4rt-ctl runtime rules before OvS configuration. - Double vlan tag is NOT supported. -- Add all ACC PR's to VSI group 1 -- On ACC firewalld need to be disabled, this service is blocking tunnel packets. +- Add all ACC PR's to VSI group 1. +- On ACC, firewall need to be disabled. Otherwise, this service will block tunneled packets. - systemctl stop firewalld -- Refer LNW-V2 README_P4_CP_NWS which comes along with the p4 program for limitation with router_interface_id action in nexthop_table (Bug created for this) +- Refer LNW-V2 README_P4_CP_NWS which comes along with the P4 program for limitation with router_interface_id action in nexthop_table (Defect filed) - Manually modify context.json to remove NOP hardware action for in context.json from "set_nexthop " action in "nexthop_table". Open defect is present in p4-sde to fix this issue. ```text -Content to be removed under hardware action is +Content to be removed under hardware action in context.json is { "prec": 0, "action_code": "NOP", diff --git a/docs/apps/lnw/es2k/es2k-lnw-overlay-vms.md b/docs/apps/lnw/es2k/es2k-lnw-overlay-vms.md index cccbd058..95b3f7e3 100644 --- a/docs/apps/lnw/es2k/es2k-lnw-overlay-vms.md +++ b/docs/apps/lnw/es2k/es2k-lnw-overlay-vms.md @@ -1,20 +1,3 @@ - # Linux Networking with Overlay VMs @@ -29,10 +12,14 @@ for more details on this feature. Prerequisites: -- Follow steps mentioned in [Deploying P4 Programs for E2100](/guides/es2k/deploying-p4-programs) for bringing up IPU with a particular release build. - Download `hw-p4-programs` TAR file specific to the build and extract it to get `fxp-net_linux-networking-v2` p4 artifacts. Go through `Limitations` specified in `README` and bringup the setup accordingly. - - Modify `sem_num_pages` to 25 and `lem_num_pages` to 10 in `cp_init.cfg` present in IMC. -- For this use case, before booting ACC with a particular release build, modify `acc_apf` value to 16 under `num_default_vport` in file `cp_init.cfg` present in IMC. +- Follow steps mentioned in [Deploying P4 Programs for E2100](/guides/es2k/deploying-p4-programs) for bringing up IPU with a custom P4 package. + - Modify `load_custom_pkg.sh` with following parameters for linux_networking package. +```text + sed -i 's/sem_num_pages = 1;/sem_num_pages = 25;/g' $CP_INIT_CFG + sed -i 's/lem_num_pages = 1;/lem_num_pages = 10;/g' $CP_INIT_CFG + sed -i 's/acc_apf = 4;/acc_apf = 16;/g' $CP_INIT_CFG +``` - Download `IPU_Documentation` TAR file specific to the build and refer to `Getting Started Guide` on how to install compatible `IDPF driver` on host. Once an IDPF driver is installed, bring up SRIOV VF by modifying the `sriov_numvfs` file present under one of the IDPF network devices. Example as below ```bash @@ -41,18 +28,18 @@ Prerequisites: Notes about topology: -- VMs are spawned on top of each VFs. Each VF will have a respective port representer in ACC. P4 runtime rules are configured to map VFs and its corresponding port representers. -- Each physical port will have a port representer in ACC. P4 runtime rules are configured to map VFs and its corresponding port representers. -- Each physical port will have a corresponding APF netdev on HOST. Create port representers in ACC for each HOST APF netdev. These APF netdev on HOST will receive unknown traffic for applications to act on. -- All port representers should be part of an OvS bridge. Based on topology, these OvS bridges will just perform bridging or TEP termination bridges which are used to enable underlay connectivity for VxLAN traffic. -- OvS bridges, VxLAN ports are created using ovs-vsctl command provided by the networking recipe and all the port representers are attached to OvS bridge using ovs-vsctl command. +- VMs are spawned on top of each VFs. Each VF will have a respective port representor in ACC. P4 runtime rules are configured to map VFs and its corresponding port representors. +- Each physical port will have a port representor in ACC. P4 runtime rules are configured to map VFs and its corresponding port representors. +- Each physical port will have a corresponding APF netdev on HOST. Create port representors in ACC for each HOST APF netdev. These APF netdev on HOST will receive unknown traffic for applications to act on. +- All port representors should be part of an OvS bridge. Based on topology, these OvS bridges will just perform bridging or TEP termination bridges which are used to enable underlay connectivity for VxLAN traffic. +- OvS bridges, VxLAN ports are created using ovs-vsctl command provided by the networking recipe and all the port representors are attached to OvS bridge using ovs-vsctl command. - This config has: - 8 Overlay VFs - - 8 Port representers in ACC for the above 8 Overlay VFs + - 8 Port representors in ACC for the above 8 Overlay VFs - 2 physical ports - - 2 Port representers in ACC for the above 2 physical ports + - 2 Port representors in ACC for the above 2 physical ports - 2 APF netdev on HOST - - 2 Port representers in ACC for the above 2 HOST APF netdevs + - 2 Port representors in ACC for the above 2 HOST APF netdevs System under test will have above topology running the networking recipe. Link Partner can have the networking recipe or legacy OvS or kernel VxLAN. Refer to the limitation section in [Linux Networking for E2100](es2k-linux-networking.md) before setting up the topology. @@ -69,7 +56,7 @@ These VSI values can be checked with `/usr/bin/cli_client -q -c` command on IMC. - IDPF netdevs on HOST (if IDPF driver loaded by you on HOST) - Netdevs on IMC -| Overlay VFs | Overlay VFs VSI ID | ACC port representer | ACC port representer VSI ID | +| Overlay VFs | Overlay VFs VSI ID | ACC port representor | ACC port representor VSI ID | | ------------| ------------------ | -------------------- | --------------------------- | | ens802f0v0 | (0x1b) 27 | enp0s1f0d1 | (0x09) 9 | | ens802f0v1 | (0x1c) 28 | enp0s1f0d2 | (0x0a) 10 | @@ -107,7 +94,7 @@ along with other P4 artifacts are created as per the steps mentioned in the prev ### Configure VSI Group and add a netdev -Add all ACC port representers to VSI group 1. VSI group 1 is dedicated for this configuration, +Add all ACC port representors to VSI group 1. VSI group 1 is dedicated for this configuration, execute below devmem commands on IMC. ```bash @@ -122,11 +109,11 @@ devmem 0x2029200388 64 0x1 devmem 0x20292002a0 64 0xA000050000000009 ``` -Note: Here VSI 9 has been used as one of the ACC port representers and added to VSI group 1. For this use case add all 16 IDPF interfaces created on ACC. Modify this VSI based on your configuration. +Note: Here VSI 9 has been used as one of the ACC port representors and added to VSI group 1. For this use case add all 16 IDPF interfaces created on ACC. Modify this VSI based on your configuration. ### Start OvS as a separate process -Legacy OvS is used as a control plane for source MAC learning of overlay VM's. OvS should be started as a separate process. +Enhanced OvS is used as a control plane for source MAC learning of overlay VM's. This OvS binary is available as part of ACC build and should be started as a separate process. ```bash export RUN_OVS=/opt/p4/p4-cp-nws @@ -184,16 +171,16 @@ ip netns exec VM0 ifconfig up ip netns exec VM0 ifconfig .10 up ``` -### Configure rules for mapping between Overlay VF and ACC port representer +### Configure rules for mapping between Overlay VF and ACC port representor -Configure rules to send overlay packets from a VM to its respective port representers. +Configure rules to send overlay packets from a VM to its respective port representors. -Refer above port mapping for overlay VF to ACC port representer mapping. Here sample commands are shown for a single overlay network, configure similar mapping for remaining VFs. +Refer above port mapping for overlay VF to ACC port representor mapping. Here sample commands are shown for a single overlay network, configure similar mapping for remaining VFs. Example: - Overlay VF1 has a VSI value 27 -- Corresponding port representer VSI value 9 +- Corresponding port representor VSI value 9 - If a VSI is used as an action, add an offset of 16 to the VSI value ```bash @@ -202,7 +189,7 @@ Example: p4rt-ctl add-entry br0 linux_networking_control.tx_source_port_v4 \ "vmeta.common.vsi=27,zero_padding=0,action=linux_networking_control.set_source_port(43)" -# Create a mapping between overlay VF (VSI-27/source port-43) and ACC port representer (VSI-9) +# Create a mapping between overlay VF (VSI-27/source port-43) and ACC port representor (VSI-9) p4rt-ctl add-entry br0 linux_networking_control.source_port_to_pr_map \ "user_meta.cmeta.source_port=43,zero_padding=0,action=linux_networking_control.fwd_to_vsi(25)" @@ -218,16 +205,16 @@ Example: ``` -### Configure rules for mapping between Physical port and ACC port representer +### Configure rules for mapping between Physical port and ACC port representor -Configure rules to send ingress packets from a physical port to its respective port representers. +Configure rules to send ingress packets from a physical port to its respective port representors. -Refer above port mapping for physical port to ACC port representer mapping. Here sample commands are shown for a single physical port, configure similar mapping for remaining physical ports. +Refer above port mapping for physical port to ACC port representor mapping. Here sample commands are shown for a single physical port, configure similar mapping for remaining physical ports. Example: - Physical port 0 port id is 0 -- Corresponding port representer VSI value 17 +- Corresponding port representor VSI value 17 - If a VSI is used as an action, add an offset of 16 to the VSI value ```bash @@ -236,7 +223,7 @@ Example: p4rt-ctl add-entry br0 linux_networking_control.rx_source_port \ "vmeta.common.port_id=0,zero_padding=0,action=linux_networking_control.set_source_port(0)" -# Create a mapping between physical port (Phy port 0/src port 0) and ACC port representer (VSI-17) +# Create a mapping between physical port (Phy port 0/src port 0) and ACC port representor (VSI-17) p4rt-ctl add-entry br0 linux_networking_control.rx_phy_port_to_pr_map \ "vmeta.common.port_id=0,zero_padding=0,action=linux_networking_control.fwd_to_vsi(33)" @@ -247,16 +234,16 @@ Example: "vmeta.common.vsi=17,zero_padding=0,action=linux_networking_control.l2_fwd_and_bypass_bridge(0)" ``` -### Configure rules for mapping between APF netdev on HOST and ACC port representer +### Configure rules for mapping between APF netdev on HOST and ACC port representor -Configure rules to send APF netdev on HOST to its respective port representers. +Configure rules to send APF netdev on HOST to its respective port representors. -Refer above port mapping for APF netdev on HOST to ACC port representer mapping. Here sample commands are shown for APF netdev on HOST, configure similar mapping for remaining APF netdevs on HOST. +Refer above port mapping for APF netdev on HOST to ACC port representor mapping. Here sample commands are shown for APF netdev on HOST, configure similar mapping for remaining APF netdevs on HOST. Example: - APF netdev 1 on HOST has a VSI value 24 -- Corresponding port representer VSI value 18 +- Corresponding port representor VSI value 18 - If a VSI is used as an action, add an offset of 16 to the VSI value ```bash @@ -266,7 +253,7 @@ Example: "vmeta.common.vsi=24,zero_padding=0,action=linux_networking_control.set_source_port(40)" -# Create a mapping between overlay VF (VSI-24/source port-40) and ACC port representer (VSI-18) +# Create a mapping between overlay VF (VSI-24/source port-40) and ACC port representor (VSI-18) p4rt-ctl add-entry br0 linux_networking_control.source_port_to_pr_map \ "user_meta.cmeta.source_port=40,zero_padding=0,action=linux_networking_control.fwd_to_vsi(34)" @@ -320,7 +307,7 @@ Create a dummy LAG bypass table for all 8 hash indexes ### Create integration bridge and add ports to the bridge -Create OvS bridge, VxLAN tunnel and assign overlay VFs port representer to individual bridges. +Create OvS bridge, VxLAN tunnel and assign overlay VFs port representor to individual bridges. Reference provided for single overlay network, repeat similar steps for other VFs. Each bridge has: @@ -339,7 +326,7 @@ Note: Here we are creating a VxLAN tunnel with VNI 0, you can create any VNI for ### Underlay configuration -Create TEP termination bridge, add physical port's port representer and APF netdev port representer. +Create TEP termination bridge, add physical port's port representor and APF netdev port representor. Reference provided for underlay network, repeat similar steps for multiple underlay networks. ```bash diff --git a/docs/guides/es2k/deploying-p4-programs.md b/docs/guides/es2k/deploying-p4-programs.md index 373b88d0..d4bf97d7 100644 --- a/docs/guides/es2k/deploying-p4-programs.md +++ b/docs/guides/es2k/deploying-p4-programs.md @@ -14,47 +14,47 @@ to generate the P4 artifacts required for deployment. Data Path Control Plane (DPCP) starts with a default P4 package. To load a custom P4 package follow below steps: -### 2.1 Interrupt default startup routine +### 2.1 Copy the custom P4 package -Reboot IMC and type ``N`` when the following message is shown on IMC console:: +Copy the custom P4 package (p4_custom.pkg) in `/work/scripts` directory to IMC. -```text -start ipumgmtd and auxiliary script [Y/N] \ -(default start both automatically after 10 seconds)? -``` - -### 2.2 Copy the custom P4 package +### 2.2 Modify the script responsible for loading custom package -Copy the custom P4 package (.pkg) in `/etc/dpcp/package` directory and -overwrite the `default_pkg.pkg`. +Replace the `p4_custom.pkg` with custom package name in `load_custom_pkg.sh` script. -For example, replace `default_pkg.pkg` with `simple_l3_l4_pna.pkg` +Any modifications intended in node policy `cp_init.cfg` should be provided as part of +the same script. ```bash -root@mev-imc:/etc/dpcp/package# ls -lrt /etc/dpcp/package/ -total 2364 --rw-r--r-- 1 root root 963032 Jan 1 04:56 simple_l3_l4_pna.pkg --rw-r--r-- 1 root root 1450456 Jun 8 2023 e2100-default-1.0.3.0.pkg -drwxr-xr-x 2 root root 0 Jun 8 2023 runtime_files -drwxr-xr-x 3 root root 0 Jun 8 2023 ref_pkg -lrwxrwxrwx 1 root root 25 Jun 8 2023 default_pkg.pkg -> e2100-default-1.0.3.0.pkg -root@mev-imc:/etc/dpcp/package# cp simple_l3_l4_pna.pkg default_pkg.pkg +[root@ipu-imc /]# cd /work/scripts +[root@ipu-imc scripts]# cat load_custom_pkg.sh +#!/bin/sh +CP_INIT_CFG=/etc/dpcp/cfg/cp_init.cfg +echo "Checking for custom package..." +if [ -e p4_custom.pkg ]; then + echo "Custom package p4_custom.pkg found. Overriding default package" + cp p4_custom.pkg /etc/dpcp/package/ + rm -rf /etc/dpcp/package/default_pkg.pkg + ln -s /etc/dpcp/package/ p4_custom.pkg /etc/dpcp/package/default_pkg.pkg + sed -i 's/sem_num_pages = 1;/sem_num_pages = 25;/g' $CP_INIT_CFG +else + echo "No custom package found. Continuing with default package" +fi ``` If Communication Channel support is required, [enable the communication channel](enabling-comm-channel.md) before proceeding to the next step. -### 2.3 Start the IMC - -Run the IMC start-up script. +### 2.3 Reboot the IMC ```bash -root@mev-imc:~# /etc/init.d/run_default_init_app +root@mev-imc:~# reboot ``` +Once the IMC reboots successfully, IPU is loaded with the custom P4 package. -By default, `cpf_host` parameter in `/etc/dpcp/cfg/cp_init.cfg` is set to 4 which -enables ACC. If the start-up script is executed successfully, ACC comes up with a +By default, `cpf_host` parameter in node_policy is set to 4 which +enables ACC. If the IMC reboots successfully, ACC comes up with a statically assigned IP address `192.168.0.2` to the eth0 network interface. You can access ACC from IMC over an SSH session using this IP address. diff --git a/docs/guides/es2k/enabling-comm-channel.md b/docs/guides/es2k/enabling-comm-channel.md index d1220aa1..18c4d003 100644 --- a/docs/guides/es2k/enabling-comm-channel.md +++ b/docs/guides/es2k/enabling-comm-channel.md @@ -7,52 +7,40 @@ running on the Host to communicate with infrap4d running on the ACC. Ports used for communication channels are defined by the node policy on IMC. -## 1. Interrupt default start-up routine +## 1 Modify the custom package config script on IMC -Reboot IMC and type ``N`` when the following message is shown on IMC console:: +Modify the `load_custom_pkg.sh` script to specify comm_vports. -```text -start ipumgmtd and auxiliary script [Y/N] \ -(default start both automatically after 10 seconds)? -``` - -## 2. Specify communication channel ports - -The config file uses the function numbers that are defined as below: - -| Function number | Definition | -|------------------------|-------------------| -| 0 | Xeon Host | -| 4 | ACC | -| 5 | IMC | - -Format used to indicate communication channels: -`(([function number, vport_index],[pf_num, vport_index]),...)` - -Modify `/etc/dpcp/cfg/cp_init.cfg` to change the value of `comm_vports`. - -```text -/* IMC_LAN_APF_VPORT_0 ([5,0]) <--> ACC_APF_VPORT_0 ([4,0]) */ -/* HOST0_LAN_APF_VPORT_3 ([0, 3]) <--> ACC_LAN_APF_VPORT_3 [(4,2)]*/ -comm_vports = (([5,0],[4,0]),([0,3],[4,2])); +```bash +[root@ipu-imc /]# cd /work/scripts +[root@ipu-imc scripts]# cat load_custom_pkg.sh +#!/bin/sh +CP_INIT_CFG=/etc/dpcp/cfg/cp_init.cfg +echo "Checking for custom package..." +if [ -e p4_custom.pkg ]; then + echo "Custom package p4_custom.pkg found. Overriding default package" + cp p4_custom.pkg /etc/dpcp/package/ + rm -rf /etc/dpcp/package/default_pkg.pkg + ln -s /etc/dpcp/package/ p4_custom.pkg /etc/dpcp/package/default_pkg.pkg + sed -i 's/sem_num_pages = 1;/sem_num_pages = 25;/g' $CP_INIT_CFG + sed -i "s/comm_vports = ((\[5,0\],\[4,0\]))\;/comm_vports = ((\[5,0\],\[4,0\]),(\[0,3\],\[4,2\]))\;/g" $CP_INIT_CFG +else + echo "No custom package found. Continuing with default package" + sed -i "s/comm_vports = ((\[5,0\],\[4,0\]))\;/comm_vports = ((\[5,0\],\[4,0\]),(\[0,3\],\[4,2\]))\;/g" $CP_INIT_CFG + +fi ``` - This will enable communication between IMC-ACC and Host-ACC. -Note: Changes made to `cp_init.cfg` are not persistent across IMC reboots. - -## 3. Start the IMC - -Run the IMC start-up script. +## 2. Reboot the IMC ```bash -root@mev-imc:~# /etc/init.d/run_default_init_app +root@mev-imc:~# reboot ``` -By default, `cpf_host` parameter in `/etc/dpcp/cfg/cp_init.cfg` is set to 4 which -enables ACC. If the start-up script is executed successfully, ACC comes up with a -statically assigned IP address `192.168.0.2` to the eth0 network interface. -You can access ACC from IMC over an SSH session using this IP address. +If IMC is rebooted successfully, ACC comes up with a statically assigned IP address + `192.168.0.2` to the eth0 network interface. You can access ACC from IMC over an +SSH session using this IP address. ## 3. Load the IDPF driver on Host From 45ded6541958487bbb58382f91c7b4c3ea5c37b8 Mon Sep 17 00:00:00 2001 From: nupuruttarwar Date: Mon, 18 Dec 2023 11:38:09 -0800 Subject: [PATCH 31/31] Address review comments Signed-off-by: nupuruttarwar --- docs/apps/lnw/es2k/es2k-linux-networking.md | 45 ++++++++++----------- docs/apps/lnw/es2k/es2k-lnw-overlay-vms.md | 6 +-- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/docs/apps/lnw/es2k/es2k-linux-networking.md b/docs/apps/lnw/es2k/es2k-linux-networking.md index 9f2393f7..d7f80e78 100644 --- a/docs/apps/lnw/es2k/es2k-linux-networking.md +++ b/docs/apps/lnw/es2k/es2k-linux-networking.md @@ -28,7 +28,7 @@ This topology breakdown and configuration assumes all VMs are spawned on HOST VF - Every physical port will have a corresponding port representor in ACC. - Every physical port will have an uplink (APF netdev) in HOST and this uplink will have a corresponding port representor in ACC. - All port representors are associated with an OvS bridge. -- For VxLAN egress traffic, the underlay port should be associated with a termination bridge and the IP to reach the underlay network should be configured on this bridge. +- For VxLAN egress traffic, the underlay port should be associated with a termination bridge. The IP address to reach the underlay network should be configured on this bridge. ## Detailed Design @@ -39,7 +39,7 @@ To enable slow path mode: - Start the infrap4d process with the Kernel Monitor disabled. Command: `infrap4d -disable-krnlmon` - Set environment variable `OVS_P4_OFFLOAD=false` before starting the `ovs-vswitchd` process. -In this mode, we need to associate VFs with VMs and its port representors along with physical ports and its port representors. Configure following tables to map these in IPU: +In this mode, VMs are spawned on top of VFs and associated with their port representors. Also, physical ports are associated with their port representors. Configure the following tables to map these in IPU: ```text - rx_source_port @@ -74,7 +74,7 @@ Packets coming from overlay network: - Determine the source port of the packet based on which overlay VSI the packet has landed on. - Validate if the source port is part of the bridge, else drop the packet. - If valid bridge configuration is found, find the PR associated with the bridge and forward the packet to the PR in ACC. -- OvS control plane receives the packet and forwards the packets to destined PR if MAC is already learnt, else flood the packet in the respective bridge. +- OvS control plane receives the packet and forwards the packet to destined PR if MAC is already learnt, else floods the packet in the valid bridge found. - Sample OvS config: ```bash @@ -89,18 +89,19 @@ Packets coming from overlay network: - Determine the source port of the packet based on which overlay VSI the packet has landed on. - Validate if the source port is part of the bridge, else drop the packet. -- If valid bridge configuration is found, find the PR associated with the bridge and forward it to the PR in ACC. -- OvS control plane receives the packet and forwards the packets to the destined VxLAN port if MAC is already learnt, else flood the packet in the respective bridge. +- If valid bridge configuration is found, find the PR associated with the bridge and forward the packet to the PR in ACC. +- OvS control plane receives the packet and forwards the packet to the destined VxLAN port if MAC is already learnt, else flood the packet in the valid bridge found. - Once the packet reaches the VxLAN port, here the kernel checks the routing table to reach `remote_ip` that is configured for the OvS VxLAN tunnel. -- Underlay network to reach `remote_ip` is configured on a TEP termination bridge and kernel resolves the ARP for underlay network. -- Once ARP is resolved, kernel encapsulates the packet and it is forwarded to the destined PR of the physical port if MAC is already learnt, else flooded in the respective TEP termination bridge. +- Underlay network to reach `remote_ip` is configured on a TEP termination bridge. The kernel resolves the ARP for underlay network. +- Once ARP is resolved, the kernel encapsulates the packet. It then forwards the packet to the PR of the physical port if the MAC is already learnt, or floods it to the TEP termination bridge if not. - Sample OvS config: ```bash ovs-vsctl add-br br-int ovs-vsctl add-port br-int ovs-vsctl add-port br-int - ovs-vsctl add-br br-tep-termination ## this bridge should be configured with IP to reach remote TEP + ovs-vsctl add-br br-tep-termination + # Configure bridge with IP address to reach remote TEP ovs-vsctl add-port br-tep-termination ``` @@ -108,12 +109,12 @@ Packets coming from overlay network: ##### Ingress traffic without VxLAN encapsulation -If the packets coming from a remote machine to the physical port are not VxLAN encapped packets: +If the packet coming from a remote machine to the physical port is not VxLAN encapsulated packet: - Determine the source port of the packet based on which physical port the packet has landed on. - Validate if the source port is part of the bridge, else drop the packet. -- If valid bridge configuration is found, find the PR associated with the bridge and forward it to the PR in ACC. -- OvS control plane receives the packet and it is forwarded to destined PR if MAC is already learnt, else flooded in the respective bridge. +- If valid bridge configuration is found, find the PR associated with the bridge and forward the packet to the PR in ACC. +- OvS control plane receives the packet and forwards it to destined PR if MAC is already learnt, else floods the packet in the valid bridge found. - Sample OvS config: ```bash @@ -124,13 +125,13 @@ If the packets coming from a remote machine to the physical port are not VxLAN e ##### Ingress traffic with VxLAN encapsulation -If the packets coming from a remote machine to the physical port are VxLAN encapped packets: +If the packet coming from a remote machine to the physical port is VxLAN encapsulated packet: - Determine the source port of the packet based on which physical port the packet has landed on. - Validate if the source port is part of the bridge, else drop the packet. -- If valid bridge configuration is found, find the PR associated with the physical port and forward it to the PR in ACC. +- If valid bridge configuration is found, find the PR associated with the physical port and forward the packet to the PR in ACC. - OvS control plane receives the packet on a TEP termination bridge, packet gets decapped and sent to VxLAN port. -- Since VxLAN port and overlay VMs PR are in the same bridge, if the overlay MAC is already learnt the packet will be forwarded to destined PR else packet will be flooded in the respective bridge. +- Since VxLAN port and overlay VMs PR are in the same bridge, if the overlay MAC is already learnt the packet will be forwarded to destined PR else packet will be flooded in the valid bridge found. - Sample OvS config: ```bash @@ -240,9 +241,9 @@ Packets coming from overlay network: #### For Rx -##### Ingress traffic without VxLAN encap +##### Ingress traffic without VxLAN encapsulation -If the packets coming from a remote machine to the physical port are not VxLAN encapped packets: +If the packet coming from a remote machine to the physical port is not VxLAN encapsulated packet: - Determine the source port of the packet based on which physical port the packet has landed on. - Validate if the source port is part of the bridge, else drop the packet. @@ -258,7 +259,7 @@ If the packets coming from a remote machine to the physical port are not VxLAN e ##### Ingress traffic with VxLAN encapsulation -If the packets coming from a remote machine to the physical port are VxLAN encapped packets: +If the packet coming from a remote machine to the physical port are VxLAN encapsulated packet: - Determine the source port of the packet based on which physical port the packet has landed - Validate if the source port is part of the bridge, else drop the packet. @@ -285,18 +286,16 @@ If the packets coming from a remote machine to the physical port are VxLAN encap Current Linux Networking support for the networking recipe has the following limitations: - VLAN configuration on OvS is supported only for NATIVE-TAG and NATIVE-UNTAG modes. -- Physical port's port representor should be added as the 1st port in tunnel TEP bridge (br-tep-termination). +- Physical port's port representor should be added as the first port in tunnel TEP bridge (br-tep-termination). - Only OvS bridges are supported. - Configure p4rt-ctl runtime rules before OvS configuration. - Double vlan tag is NOT supported. - Add all ACC PR's to VSI group 1. -- On ACC, firewall need to be disabled. Otherwise, this service will block tunneled packets. +- On ACC, firewall needs to be disabled. Otherwise, this service will block encapsulated packets. - systemctl stop firewalld -- Refer LNW-V2 README_P4_CP_NWS which comes along with the P4 program for limitation with router_interface_id action in nexthop_table (Defect filed) - - Manually modify context.json to remove NOP hardware action for in context.json from "set_nexthop " action in "nexthop_table". Open defect is present in p4-sde to fix this issue. - +- See LNW-V2 README_P4_CP_NWS, which comes with the P4 program for more information about limitations in router_interface_id action in nexthop_table(Defect filed). + - Manually modify context.json to remove NOP hardware action for in context.json from "set_nexthop " action in "nexthop_table". Open defect is present in p4-sde to fix this issue. Content to be removed under hardware action in context.json is ```text -Content to be removed under hardware action in context.json is { "prec": 0, "action_code": "NOP", diff --git a/docs/apps/lnw/es2k/es2k-lnw-overlay-vms.md b/docs/apps/lnw/es2k/es2k-lnw-overlay-vms.md index 95b3f7e3..2c9bd2ca 100644 --- a/docs/apps/lnw/es2k/es2k-lnw-overlay-vms.md +++ b/docs/apps/lnw/es2k/es2k-lnw-overlay-vms.md @@ -1,4 +1,3 @@ - # Linux Networking with Overlay VMs This document explains how to run the Linux networking scenario on ES2K with 8 overlay VMs. @@ -14,11 +13,12 @@ Prerequisites: - Download `hw-p4-programs` TAR file specific to the build and extract it to get `fxp-net_linux-networking-v2` p4 artifacts. Go through `Limitations` specified in `README` and bringup the setup accordingly. - Follow steps mentioned in [Deploying P4 Programs for E2100](/guides/es2k/deploying-p4-programs) for bringing up IPU with a custom P4 package. - - Modify `load_custom_pkg.sh` with following parameters for linux_networking package. +Modify `load_custom_pkg.sh` with following parameters for linux_networking package: ```text sed -i 's/sem_num_pages = 1;/sem_num_pages = 25;/g' $CP_INIT_CFG sed -i 's/lem_num_pages = 1;/lem_num_pages = 10;/g' $CP_INIT_CFG sed -i 's/acc_apf = 4;/acc_apf = 16;/g' $CP_INIT_CFG + ``` - Download `IPU_Documentation` TAR file specific to the build and refer to `Getting Started Guide` on how to install compatible `IDPF driver` on host. Once an IDPF driver is installed, bring up SRIOV VF by modifying the `sriov_numvfs` file present under one of the IDPF network devices. Example as below @@ -28,7 +28,7 @@ Prerequisites: Notes about topology: -- VMs are spawned on top of each VFs. Each VF will have a respective port representor in ACC. P4 runtime rules are configured to map VFs and its corresponding port representors. +- VMs are spawned on top of each VF. Each VF will have a port representor in ACC. P4 runtime rules are configured to map VFs and their corresponding port representors. - Each physical port will have a port representor in ACC. P4 runtime rules are configured to map VFs and its corresponding port representors. - Each physical port will have a corresponding APF netdev on HOST. Create port representors in ACC for each HOST APF netdev. These APF netdev on HOST will receive unknown traffic for applications to act on. - All port representors should be part of an OvS bridge. Based on topology, these OvS bridges will just perform bridging or TEP termination bridges which are used to enable underlay connectivity for VxLAN traffic.