try 42: ndp in the switch. this episode is with checksums...
This commit is contained in:
parent
492888fd2f
commit
c89441001b
3 changed files with 53 additions and 35 deletions
27
doc/plan.org
27
doc/plan.org
|
@ -754,6 +754,7 @@ DEBUG:main:cpu = <CpuHeader task=ICMP6_GENERAL ingress_port=1 type=0x86dd |<Raw
|
||||||
DEBUG:main:reassambled=<Ether dst=00:00:0a:00:00:42 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=32 nh=ICMPv6 hlim=255 src=fe80::200:aff:fe00:1 dst=2001:db8::42 |<ICMPv6ND_NS type=Neighbor Solicitation code=0 cksum=0x82b res=0 tgt=2001:db8::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>>
|
DEBUG:main:reassambled=<Ether dst=00:00:0a:00:00:42 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=32 nh=ICMPv6 hlim=255 src=fe80::200:aff:fe00:1 dst=2001:db8::42 |<ICMPv6ND_NS type=Neighbor Solicitation code=0 cksum=0x82b res=0 tgt=2001:db8::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>>
|
||||||
|
|
||||||
***** TODO Debug why neighbor discover does not work anymore
|
***** TODO Debug why neighbor discover does not work anymore
|
||||||
|
****** log
|
||||||
p4@ubuntu:~$ mx h1 tcpdump -lni any
|
p4@ubuntu:~$ mx h1 tcpdump -lni any
|
||||||
sudo: unable to resolve host ubuntu
|
sudo: unable to resolve host ubuntu
|
||||||
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
|
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
|
||||||
|
@ -767,10 +768,28 @@ DEBUG:main:cpu = <CpuHeader task=ICMP6_NS ingress_port=1 type=0x86dd |<Raw loa
|
||||||
DEBUG:main:reassambled=<Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=32 nh=ICMPv6 hlim=255 src=fe80::200:aff:fe00:1 dst=ff02::1:ff00:42 |<ICMPv6ND_NS type=Neighbor Solicitation code=0 cksum=0x37df res=0 tgt=2001:db8::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>>
|
DEBUG:main:reassambled=<Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=32 nh=ICMPv6 hlim=255 src=fe80::200:aff:fe00:1 dst=ff02::1:ff00:42 |<ICMPv6ND_NS type=Neighbor Solicitation code=0 cksum=0x37df res=0 tgt=2001:db8::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>>
|
||||||
INFO:main:Doing neighbor solicitation
|
INFO:main:Doing neighbor solicitation
|
||||||
DEBUG:main:OUTGOING: <Ether dst=00:00:0a:00:00:01 src=00:00:0a:00:00:42 type=0x86dd |<IPv6 nh=ICMPv6 hlim=255 src=2001:db8::42 dst=fe80::200:aff:fe00:1 |<ICMPv6ND_NA cksum=None R=0 S=1 tgt=2001:db8::42 |<ICMPv6NDOptDstLLAddr lladdr=00:00:0a:00:00:42 |>>>>
|
DEBUG:main:OUTGOING: <Ether dst=00:00:0a:00:00:01 src=00:00:0a:00:00:42 type=0x86dd |<IPv6 nh=ICMPv6 hlim=255 src=2001:db8::42 dst=fe80::200:aff:fe00:1 |<ICMPv6ND_NA cksum=None R=0 S=1 tgt=2001:db8::42 |<ICMPv6NDOptDstLLAddr lladdr=00:00:0a:00:00:42 |>>>>
|
||||||
DEBUG:main:INCOMING: <Ether dst=00:00:0a:00:00:01 src=00:00:0a:00:00:42 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=32 nh=ICMPv6 hlim=255 src=2001:db8::42 dst=fe80::200:aff:fe00:1 |<ICMPv6ND_NA type=Neighbor Advertisement code=0 cksum=0xa5e9 R=0 S=1 O=1 res=0x0 tgt=2001:db8::42 |<ICMPv6NDOptDstLLAddr type=2 len=1 lladdr=00:00:0a:00:00:42 |>>>>
|
DEBUG:main:INCOMING: <Ether dst=00:00:0a:00:00:01
|
||||||
****** Do we have a routing for fe80::/10? Probably not. Shouldn't we see it in the controller then?
|
src=00:00:0a:00:00:42 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=32
|
||||||
****** TODO Implement address learning?
|
nh=ICMPv6 hlim=255 src=2001:db8::42
|
||||||
****** TODO Not sure whether we should react on router solicitation
|
dst=fe80::200:aff:fe00:1 |<ICMPv6ND_NA type=Neighbor Advertisement
|
||||||
|
code=0 cksum=0xa5e9 R=0 S=1 O=1 res=0x0
|
||||||
|
tgt=2001:db8::42 |<ICMPv6NDOptDstLLAddr type=2 len=1
|
||||||
|
lladdr=00:00:0a:00:00:42 |>>>>
|
||||||
|
|
||||||
|
|
||||||
|
After removing noise:
|
||||||
|
|
||||||
|
DEBUG:main:reassambled=<Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=32 nh=ICMPv6 hlim=255 src=fe80::200:aff:fe00:1 dst=ff02::1:ff00:42 |<ICMPv6ND_NS type=Neighbor Solicitation code=0 cksum=0x37df res=0 tgt=2001:db8::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>>
|
||||||
|
DEBUG:main:reassambled=<Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=32 nh=ICMPv6 hlim=255 src=fe80::200:aff:fe00:1 dst=ff02::1:ff00:42 |<ICMPv6ND_NS type=Neighbor Solicitation code=0 cksum=0x37df res=0 tgt=2001:db8::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>>
|
||||||
|
DEBUG:main:reassambled=<Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=32 nh=ICMPv6 hlim=255 src=2001:db8::1 dst=ff02::1:ff00:42 |<ICMPv6ND_NS type=Neighbor Solicitation code=0 cksum=0x13a7 res=0 tgt=2001:db8::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>>
|
||||||
|
DEBUG:main:reassambled=<Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=32 nh=ICMPv6 hlim=255 src=2001:db8::1 dst=ff02::1:ff00:42 |<ICMPv6ND_NS type=Neighbor Solicitation code=0 cksum=0x13a7 res=0 tgt=2001:db8::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>>
|
||||||
|
DEBUG:main:reassambled=<Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=32 nh=ICMPv6 hlim=255 src=2001:db8::1 dst=ff02::1:ff00:42 |<ICMPv6ND_NS type=Neighbor Solicitation code=0 cksum=0x13a7 res=0 tgt=2001:db8::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>>
|
||||||
|
|
||||||
|
****** Do we have routing for fe80::/10? Probably not. Shouldn't we see it in the controller then?
|
||||||
|
****** NDP is controller only!
|
||||||
|
***** TODO Maybe merge v6_address and v6_networks - /128 is the same
|
||||||
|
***** TODO Implement address learning?
|
||||||
|
***** TODO Not sure whether we should react on router solicitation
|
||||||
- Using static routes -> should do the job
|
- Using static routes -> should do the job
|
||||||
***** TODO Implement the calculation
|
***** TODO Implement the calculation
|
||||||
***** TODO Sketch the flow for session handling for icmp6 w/o packet loss
|
***** TODO Sketch the flow for session handling for icmp6 w/o packet loss
|
||||||
|
|
|
@ -47,6 +47,8 @@ class L2Controller(object):
|
||||||
self.task = dict(reversed(item) for item in cpu_fields.items())
|
self.task = dict(reversed(item) for item in cpu_fields.items())
|
||||||
|
|
||||||
self.info={}
|
self.info={}
|
||||||
|
|
||||||
|
# https://en.wikipedia.org/wiki/Solicited-node_multicast_address
|
||||||
self.info['ndp_multicast'] = ipaddress.ip_network("ff02::1:ff00:0/104")
|
self.info['ndp_multicast'] = ipaddress.ip_network("ff02::1:ff00:0/104")
|
||||||
self.info['mac_address'] = "00:00:0a:00:00:42"
|
self.info['mac_address'] = "00:00:0a:00:00:42"
|
||||||
self.info['ipv6_link_local'] = ipaddress.ip_address("fe80::200:aff:fe00:42")
|
self.info['ipv6_link_local'] = ipaddress.ip_address("fe80::200:aff:fe00:42")
|
||||||
|
@ -136,7 +138,6 @@ class L2Controller(object):
|
||||||
|
|
||||||
return addr
|
return addr
|
||||||
|
|
||||||
|
|
||||||
def init_other_port_multicast_groups(self):
|
def init_other_port_multicast_groups(self):
|
||||||
""" map multicast group x to send to
|
""" map multicast group x to send to
|
||||||
all ports but x - basically broadcasting without sending back to ourselves
|
all ports but x - basically broadcasting without sending back to ourselves
|
||||||
|
@ -153,21 +154,6 @@ class L2Controller(object):
|
||||||
|
|
||||||
self.controller.mc_node_associate(g_handle, n_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"
|
|
||||||
|
|
||||||
self.controller.table_clear("ndp")
|
|
||||||
for port in self.ports:
|
|
||||||
self.controller.table_add("ndp", "multicast_pkg", [ndp_prefix, str(port)], [str(port)])
|
|
||||||
|
|
||||||
|
|
||||||
# Special rule for switch entries
|
|
||||||
self.controller.table_add("ndp_answer", "icmp6_neighbor_solicitation", ["ff02::1:ff00:42", "135"], ["2001:db8:61::42"])
|
|
||||||
|
|
||||||
def init_boilerplate(self, sw_name):
|
def init_boilerplate(self, sw_name):
|
||||||
self.topo = Topology(db="topology.db")
|
self.topo = Topology(db="topology.db")
|
||||||
self.sw_name = sw_name
|
self.sw_name = sw_name
|
||||||
|
@ -180,8 +166,6 @@ class L2Controller(object):
|
||||||
if self.cpu_port:
|
if self.cpu_port:
|
||||||
self.controller.mirroring_add(100, self.cpu_port)
|
self.controller.mirroring_add(100, self.cpu_port)
|
||||||
|
|
||||||
# self.init_ndp()
|
|
||||||
|
|
||||||
def config(self):
|
def config(self):
|
||||||
self.fill_tables()
|
self.fill_tables()
|
||||||
self.config_hosts()
|
self.config_hosts()
|
||||||
|
@ -192,6 +176,14 @@ class L2Controller(object):
|
||||||
net = self.info['ndp_multicast']
|
net = self.info['ndp_multicast']
|
||||||
self.controller.table_add("v6_networks", "controller_debug", [str(net)])
|
self.controller.table_add("v6_networks", "controller_debug", [str(net)])
|
||||||
|
|
||||||
|
def init_ndp_in_switch(self, addr):
|
||||||
|
icmp6_addr = self.gen_ndp_multicast_addr(addr)
|
||||||
|
icmp6_net = "{}/128".format(icmp6_addr)
|
||||||
|
|
||||||
|
self.controller.table_add("v6_networks",
|
||||||
|
"icmp6_neighbor_solicitation",
|
||||||
|
[str(icmp6_net)], [str(addr)])
|
||||||
|
|
||||||
def fill_tables(self):
|
def fill_tables(self):
|
||||||
self.controller.table_clear("v6_networks")
|
self.controller.table_clear("v6_networks")
|
||||||
for v6route in self.v6_routes[self.mode]:
|
for v6route in self.v6_routes[self.mode]:
|
||||||
|
@ -200,6 +192,9 @@ class L2Controller(object):
|
||||||
if self.args.multicast_to_controller:
|
if self.args.multicast_to_controller:
|
||||||
self.listen_to_icmp6_multicast()
|
self.listen_to_icmp6_multicast()
|
||||||
|
|
||||||
|
for v6addr in self.v6_addresses[self.mode]:
|
||||||
|
self.init_ndp_in_switch(v6addr)
|
||||||
|
|
||||||
self.controller.table_clear("v4_networks")
|
self.controller.table_clear("v4_networks")
|
||||||
for v4route in self.v4_routes[self.mode]:
|
for v4route in self.v4_routes[self.mode]:
|
||||||
self.controller.table_add("v4_networks", "set_egress_port", [str(v4route['net'])], [str(v4route['port'])])
|
self.controller.table_add("v4_networks", "set_egress_port", [str(v4route['net'])], [str(v4route['port'])])
|
||||||
|
@ -401,7 +396,7 @@ class L2Controller(object):
|
||||||
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':
|
elif ICMPv6MLReport2 in orig_packet and orig_packet['IPv6'].dst == 'ff02::16':
|
||||||
mc_group = orig_packet['ICMPv6MLDMultAddrRec'].dst
|
mc_group = orig_packet['ICMPv6MLDMultAddrRec'].dst
|
||||||
log.debug("Multicast registration for {} from {} -- should probably handle this".format(mc_group, cpu_header.ingress_port))
|
log.debug("Multicast registration for {} port {} -- should probably handle this".format(mc_group, cpu_header.ingress_port))
|
||||||
elif ICMPv6ND_RS in orig_packet and orig_packet['IPv6'].dst == 'ff02::2':
|
elif ICMPv6ND_RS in orig_packet and orig_packet['IPv6'].dst == 'ff02::2':
|
||||||
src = orig_packet['IPv6'].src
|
src = orig_packet['IPv6'].src
|
||||||
log.debug("Router solicitation from {} -- should probably handle this?".format(src))
|
log.debug("Router solicitation from {} -- should probably handle this?".format(src))
|
||||||
|
|
|
@ -49,6 +49,10 @@ control MyIngress(inout headers hdr,
|
||||||
hdr.ipv6.dst_addr = hdr.ipv6.src_addr;
|
hdr.ipv6.dst_addr = hdr.ipv6.src_addr;
|
||||||
hdr.ipv6.src_addr = addr;
|
hdr.ipv6.src_addr = addr;
|
||||||
hdr.icmp6.type = ICMP6_NA;
|
hdr.icmp6.type = ICMP6_NA;
|
||||||
|
|
||||||
|
/* checksum trigger / content */
|
||||||
|
meta.do_cksum = 1;
|
||||||
|
meta.cast_length = (bit<32>) hdr.ipv6.payload_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
action icmp6_echo_reply() {
|
action icmp6_echo_reply() {
|
||||||
|
|
Loading…
Reference in a new issue