From 880db528e71f61e6d646bd4f0d56100355ae173e Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Tue, 19 Mar 2019 23:01:55 +0100 Subject: [PATCH] Mute multicast registrations (MLDv2) --- doc/plan.org | 6 ++++-- p4app/controller.py | 41 +++++++++++++++++++++++++++-------------- p4src/static-mapping.p4 | 3 --- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/doc/plan.org b/doc/plan.org index 1074833..112aa4f 100644 --- a/doc/plan.org +++ b/doc/plan.org @@ -1042,8 +1042,10 @@ action: icmp6_echo_reply runtime data: Entry has been added with handle 5 - - +***** General approach + - Need to react on our multicast group + - But also need to forward to other ports that subscribed to + that multicast group! **** Static mappings - likely need table(s) - need tcp & udp translation diff --git a/p4app/controller.py b/p4app/controller.py index 5ac524a..13d3d36 100644 --- a/p4app/controller.py +++ b/p4app/controller.py @@ -73,12 +73,15 @@ class L2Controller(object): self.v6_routes[None] = [] self.v6_routes['base'] = [] + self.ports = [] + for port in range(1,3): net = self.info['v6_gen'].next() self.v6_routes['base'].append({ "net": net, "port": port} ) + self.ports.append(port) self.v6_routes['router'] = self.v6_routes['base'] @@ -94,6 +97,8 @@ class L2Controller(object): "net": net, "port": port} ) + self.ports.append(port) + self.v4_routes['router'] = self.v4_routes['base'] self.v4_routes['range_router'] = self.v4_routes['base'] @@ -125,6 +130,7 @@ class L2Controller(object): }) self.init_boilerplate(sw_name) + self.init_other_port_multicast_groups() def gen_ndp_multicast_addr(self, addr): """ append the 24 bit of the address to the multicast address""" @@ -134,27 +140,32 @@ class L2Controller(object): return addr + + def init_other_port_multicast_groups(self): + """ map multicast group x to send to + all ports but x - basically broadcasting without sending back to ourselves + """ + + # create multicast nodes + for rid in self.ports: + ports = [ x for x in self.ports if not x == rid ] + n_handle = self.controller.mc_node_create(rid, ports) + log.debug("Creating MC node rid={} ports={} handle={}".format(rid, ports, n_handle)) + + g_handle = self.controller.mc_mgrp_create(rid) + log.debug("Created MC group mgrp={} handle={} && associating afterwards".format(rid, g_handle)) + + self.controller.mc_node_associate(g_handle, n_handle) + + 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): - ports = [ x for x in all_ports if not x == rid ] - n_handle = self.controller.mc_node_create(rid, ports) - log.debug("Creating MC node rid={} ports={} handle={}".format(rid, ports, n_handle)) - - g_handle = self.controller.mc_mgrp_create(rid) - log.debug("Creating MC group mgrp={} handle={} && associating afterwards".format(rid, g_handle)) - - self.controller.mc_node_associate(g_handle, n_handle) - - self.controller.table_clear("ndp") - for port in all_ports: + for port in self.ports: self.controller.table_add("ndp", "multicast_pkg", [ndp_prefix, str(port)], [str(port)]) @@ -392,6 +403,8 @@ class L2Controller(object): if ICMPv6ND_NS in orig_packet and orig_packet['IPv6'].src == '::': log.debug("Neighbor solicitation for checking her own IP address") + elif ICMPv6MLReport2 in orig_packet and orig_packet['IPv6'].dst == 'ff02::16': + log.debug("Multicast registration -- should probably handle this") elif cpu_header.task == self.task['DEBUG']: log.debug("reassambled={}".format(orig_packet.__repr__())) elif cpu_header.task == self.task['ICMP6_NS']: diff --git a/p4src/static-mapping.p4 b/p4src/static-mapping.p4 index d3556ef..cda8f27 100644 --- a/p4src/static-mapping.p4 +++ b/p4src/static-mapping.p4 @@ -184,7 +184,6 @@ control MyIngress(inout headers hdr, /********************** NDP support ***********************************/ - table ndp { key = { hdr.ipv6.dst_addr: lpm; @@ -196,14 +195,12 @@ control MyIngress(inout headers hdr, NoAction; } size = NDP_TABLE_SIZE; -// default_action = NoAction; default_action = controller_debug; } /********************** ADDRESS TABLES ***********************************/ action icmp6_answer() { - if(hdr.icmp6.isValid()) { if(hdr.icmp6.code == ICMP6_ECHO_REQUEST) { ipv6_addr_t tmp = hdr.ipv6.src_addr;