From 72c600d8dadee438e341461dddf1c1b121ac2f79 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Tue, 26 Feb 2019 15:30:47 +0100 Subject: [PATCH] [NDP] Begin to add multicast / NDP support --- doc/plan.org | 6 ++++-- p4app/controller.py | 9 +++++++++ p4src/headers.p4 | 1 + p4src/settings.p4 | 1 + p4src/static-mapping.p4 | 20 ++++++++++++++++++++ 5 files changed, 35 insertions(+), 2 deletions(-) diff --git a/doc/plan.org b/doc/plan.org index 7f339d2..d13ca94 100644 --- a/doc/plan.org +++ b/doc/plan.org @@ -77,10 +77,11 @@ ****** rfc4861 "Neighbor Solicitation messages are multicast to the solicited-node multicast address of the target address." -****** multicasting / groups +****** DONE multicasting / groups ******* create a group ("node") that contains "all other" ports ******* create a multicast group with an ID ******* associate the "node" with the multicast group ID +***** If destination is within ff02::1:ff00:0/104, multicast **** TODO Make switch answer icmp6 echo request for **** TODO Make switch answer icmp echo request for @@ -156,7 +157,8 @@ user@T:~# iptables -t mangle -A PREROUTING \ - IPv4 hosts are in 10.0.4.0/24 - IPv6 in IPv4 mapped hosts are in 10.0.6.0/24 - IPv4 default router = 10.0.0.42 - +**** Neighbor discover protocol + - Matching on prefix & ingress port, setting multicast **** Static mappings - likely need table(s) - need tcp & udp translation diff --git a/p4app/controller.py b/p4app/controller.py index 2bfb9c0..4c027b5 100644 --- a/p4app/controller.py +++ b/p4app/controller.py @@ -89,6 +89,9 @@ class L2Controller(object): def init_ndp(self): """ initialise neighbor discovery protocol""" + # https://en.wikipedia.org/wiki/Solicited-node_multicast_address + ndp_prefix = "ff02::1:ff00:0/104" + all_ports = range(1,5) # create multicast nodes for rid in range(1,5): @@ -101,6 +104,12 @@ class L2Controller(object): self.controller.mc_node_associate(g_handle, n_handle) + + self.controller.table_clear("ndp") + for port in all_ports: + self.controller.table_add("ndp", "multicast_pkg", [ndp_prefix, port], [str(port)]) + + def init_boilerplate(self, sw_name): self.topo = Topology(db="topology.db") self.sw_name = sw_name diff --git a/p4src/headers.p4 b/p4src/headers.p4 index 5c28e1a..c8f232b 100644 --- a/p4src/headers.p4 +++ b/p4src/headers.p4 @@ -9,6 +9,7 @@ typedef bit<48> mac_addr_t; typedef bit<32> ipv4_addr_t; typedef bit<128> ipv6_addr_t; typedef bit<9> port_t; +typedef bit<16> mcast_t; const bit<16> TYPE_IPV4 = 0x0800; diff --git a/p4src/settings.p4 b/p4src/settings.p4 index ca15a0c..7610ce6 100644 --- a/p4src/settings.p4 +++ b/p4src/settings.p4 @@ -9,5 +9,6 @@ #define THE_ANSWER_TO_LIFE_THE_UNIVERSE_AND_EVERYTHING 42 /* Important constant */ #define ROUTING_TABLE_SIZE 64 /* maximum routes per protocol */ #define ADDRESS_TABLE_SIZE 64 /* maximum number of addresses per protocol */ +#define NDP_TABLE_SIZE 64 /* maximum number of multicast groups */ #endif diff --git a/p4src/static-mapping.p4 b/p4src/static-mapping.p4 index 9add5e2..8d0624a 100644 --- a/p4src/static-mapping.p4 +++ b/p4src/static-mapping.p4 @@ -21,6 +21,26 @@ control MyIngress(inout headers hdr, clone3(CloneType.I2E, 100, meta); } + /********************** NDP support ***********************************/ + + /* map port to group */ + action multicast_pkg(mcast_t mcast_grp) { + standard_metadata.mcast_grp = mcast_grp; + } + + table ndp { + key = { + hdr.ipv6.dst_addr: lpm; + standard_metadata.ingress_port : exact; + } + actions = { + multicast_pkg; + NoAction; + } + size = NDP_TABLE_SIZE; + default_action = NoAction; + } + /********************** ADDRESS TABLES ***********************************/ action icmp6_answer() {