Mute multicast registrations (MLDv2)

This commit is contained in:
Nico Schottelius 2019-03-19 23:01:55 +01:00
parent 4d90fd46a8
commit 880db528e7
3 changed files with 31 additions and 19 deletions

View file

@ -1042,8 +1042,10 @@ action: icmp6_echo_reply
runtime data: runtime data:
Entry has been added with handle 5 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 **** Static mappings
- likely need table(s) - likely need table(s)
- need tcp & udp translation - need tcp & udp translation

View file

@ -73,12 +73,15 @@ class L2Controller(object):
self.v6_routes[None] = [] self.v6_routes[None] = []
self.v6_routes['base'] = [] self.v6_routes['base'] = []
self.ports = []
for port in range(1,3): for port in range(1,3):
net = self.info['v6_gen'].next() net = self.info['v6_gen'].next()
self.v6_routes['base'].append({ self.v6_routes['base'].append({
"net": net, "net": net,
"port": port} "port": port}
) )
self.ports.append(port)
self.v6_routes['router'] = self.v6_routes['base'] self.v6_routes['router'] = self.v6_routes['base']
@ -94,6 +97,8 @@ class L2Controller(object):
"net": net, "net": net,
"port": port} "port": port}
) )
self.ports.append(port)
self.v4_routes['router'] = self.v4_routes['base'] self.v4_routes['router'] = self.v4_routes['base']
self.v4_routes['range_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_boilerplate(sw_name)
self.init_other_port_multicast_groups()
def gen_ndp_multicast_addr(self, addr): def gen_ndp_multicast_addr(self, addr):
""" append the 24 bit of the address to the multicast address""" """ append the 24 bit of the address to the multicast address"""
@ -134,27 +140,32 @@ class L2Controller(object):
return addr 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): def init_ndp(self):
""" initialise neighbor discovery protocol""" """ initialise neighbor discovery protocol"""
# https://en.wikipedia.org/wiki/Solicited-node_multicast_address # https://en.wikipedia.org/wiki/Solicited-node_multicast_address
ndp_prefix = "ff02::1:ff00:0/104" 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") 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)]) 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 == '::': if ICMPv6ND_NS in orig_packet and orig_packet['IPv6'].src == '::':
log.debug("Neighbor solicitation for checking her own IP address") 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']: elif cpu_header.task == self.task['DEBUG']:
log.debug("reassambled={}".format(orig_packet.__repr__())) log.debug("reassambled={}".format(orig_packet.__repr__()))
elif cpu_header.task == self.task['ICMP6_NS']: elif cpu_header.task == self.task['ICMP6_NS']:

View file

@ -184,7 +184,6 @@ control MyIngress(inout headers hdr,
/********************** NDP support ***********************************/ /********************** NDP support ***********************************/
table ndp { table ndp {
key = { key = {
hdr.ipv6.dst_addr: lpm; hdr.ipv6.dst_addr: lpm;
@ -196,14 +195,12 @@ control MyIngress(inout headers hdr,
NoAction; NoAction;
} }
size = NDP_TABLE_SIZE; size = NDP_TABLE_SIZE;
// default_action = NoAction;
default_action = controller_debug; default_action = controller_debug;
} }
/********************** ADDRESS TABLES ***********************************/ /********************** ADDRESS TABLES ***********************************/
action icmp6_answer() { action icmp6_answer() {
if(hdr.icmp6.isValid()) { if(hdr.icmp6.isValid()) {
if(hdr.icmp6.code == ICMP6_ECHO_REQUEST) { if(hdr.icmp6.code == ICMP6_ECHO_REQUEST) {
ipv6_addr_t tmp = hdr.ipv6.src_addr; ipv6_addr_t tmp = hdr.ipv6.src_addr;