141 KiB
- Time table / log
- Thesis implementation
- Setup test VM for P4: 2a0a:e5c0:2:12:400:f0ff:fea9:c3e3
- Get feature list of jool
- Get feature list of tayga
- Setup P4 base / structure
- Create minimal controller for populating tables
- Checkout / review egress settings
- Create Basis to translate ipv6 –> ipv4 with a (freely programmable) prefix; test ping6_switch
- Insert prefix into switch: v6_networks
- Support multiple ipv6 source networks: need new table w/ 2 keys! -> not at the moment
- Write test.py to generate correct destination packets
- Using test.py, new NDP packets been seen, bur zero icmp on the outgoing side
- Debug why neighbor discover does not work anymore
- Finish NDP in switch
- Maybe merge v6_address and v6_networks - /128 is the same
- Implement address learning? -> not at the moment
- Not sure whether we should react on router solicitation -> not at the moment
- Implement the calculation
- Sketch the flow for session handling for icmp6 w/o packet loss
- Create table entry for mapping v4->v6 [net]
- Create table entry for mapping v6->v4 [net]
- Implement ICMP <-> ICMP6 translation
- 2019-02-28 / icmp testing / first NDP steps
- Parse icmp
- Parse icmpv6
- Add (static) egress configuration
- Calculate ICMP6 checksums in controller
- Implement minimal neighbor discovery in controller
- For the switch
- Register IPv6 address in table
- Parse ICMPv6 up to neighbor solicitation -> no: checksum problem
- Use NDP (Neighbor Solicitation (NDP) , Neighbor Advertisement (NDP)) -> no: controller
- Approach 2: use cpu header, forward information to controller
- Fix the ip address match/mapping: 42 -> 2a -> use hex originally
- Find out why wrong type is used -> overlapping with NDP
- Disable debug by default -> gives correct packets
- For other nodes -> multicast
- Maybe implement link local addresses (missing at the moment)
- If destination is within ff02::1:ff00:0/104, multicast
- For the switch
- Make switch answer icmp6 echo request for
- Introduce mixed mode: switch: icmp6 echo reply, controller: NDP
- Add default route for v6 hosts
- TEST ping6ing an emulated ipv6 host / Translate icmp <-> icmp6: test v6_static_mapping
- try1: only packets on h1 + controller -> wrong checksum 2019-03-25
- try2: checksum ok, but no packets on h3
- try3: re-rewrite: no packets on h3 again (2019-03-30)
- try4: h3 receives packet, but length seems to be off
- try5: packet is good, but routing is "strange": default route == 10.0.0.66
- try6: host sees packet, but does not react on it, manually tring gateway ping
- try7: checkout dump from ping4_gw-2019-03-31-0916-h3.pcap: regular arp
- Get a real world arp trace
- Implement default route handling, maybe implement ARP?
- Add table name support in debug messages
- Why getting IPv6 packets in
- Solve logic problem: Valid headers
- Check translated fields
- source correctly translated to 10.1.1.1
- destination correctly translated to 10.0.0.1 -> pings h3
- egress is correct, comes out at h3
- protocol 58 is wrong -> should be 1
- figure out switch() syntax
- transform protocol specific: icmp6 -> icmp
- Implement double table, as there are no if's in actions
- Debug Ethernet frame check sequence error -> need to compute checksum
- Calculate ICMP checksum
- Check field lengths
- Fix resolve / mac addresses -> ethernet is wrong!
- Fix IPv4 header checksum // wrong according to wireshark
- check packets static_nat64-2019-04-03-0957-h1.pcap: answer not outputted/natted!
- transform protocol specific: icmp -> icmp6
- Test result (2019-04-03)
- Add / check default route for v4 hosts
- Check IPv4 -> IPv6 translation
- Implement ipv6<->ipv4 udp translation
- Implement ipv6<->ipv4 tcp translation
- Update p4c to avoid compiler bug
- Get p4 VM / vagrant running
- Get p4c & co. running on the notebook
- mininet via packages
- p4c
- install behavioral-model
- Debug / reread the virtualbox script from the lecture
- Get p4c installed / running
- Get p4utils running (?)
- log of python, p4app, p4c installation
- log Try2: using virtualenv that uses site packages for using mininet
- Trying local vagrant VM
- Creating network
- Adding hosts:
- Adding switches:
- Setup test VM [dual stack] for Jool:
- Setup test VM [dual stack] for tayga:
- NAT64/NAT46 Features in jool and tayga
- Additional features queue (to be discussed)
- Thesis documentation
- Introduction
- Motivation
- Translation mechanisms
- Current state of the art tayga/jool
- P4 based implementation
- Comparison with existing tools (Performance, Features)
- P4 Possible Improvements / Current Challenges / Limitations
- cannot read key from table
- ICMP6: checksum over payload
- Synchronisation with the controller
- p4c expression bug 2019-03-30
- Only one LPM key supported in tables (2019-03-23)
- No table meta information for default actions (asked 2019-03-25)
- No switch in actions, No conditional execution in actions
- Modules, OS
- Code sharing (controller, switch)
- Implementation description and limitations
- References / Follow up
- RFC 791 IPv4 https://tools.ietf.org/html/rfc791
- RFC 792 ICMP https://tools.ietf.org/html/rfc792
- RFC 826 ARP https://tools.ietf.org/html/rfc826
- RFC 1017 ICMP checksum https://tools.ietf.org/html/rfc1071
- RFC 2373 IP Version 6 Addressing Architecture
- RFC 2460 IPv6 (Checksum https://tools.ietf.org/html/rfc2460#section-8.1)
- RFC 2464 Transmission of IPv6 Packets over Ethernet Networks https://tools.ietf.org/html/rfc2464
- RFC 3810 MLD2 https://tools.ietf.org/html/rfc3810
- RFC 4038 Application Aspects of IPv6 Transition https://tools.ietf.org/html/rfc4038
- RFC 4291 IP Version 6 Addressing Architecture https://tools.ietf.org/html/rfc4291
- RFC 4443 ICMPv6 https://tools.ietf.org/html/rfc4443
- RFC 4861: https://tools.ietf.org/html/rfc4861 Neighbor discovery
- RFC 6052: https://tools.ietf.org/html/rfc6052 IPv6 Addressing of IPv4/IPv6 Translators - first NAT64??
- RFC 6145 IP/ICMP Translation Algorithm
- RFC 6146 Stateful nat http://tools.ietf.org/html/rfc6146
- RFC 6147 DNS64 https://tools.ietf.org/html/rfc6147
- RFC 6586 for deployment experiences using Stateful NAT64.
- RFC 7757 Explicit Address Mappings for Stateless IP/ICMP Translation - https://tools.ietf.org/html/rfc7757
- RFC 7915 IP/ICMP Translation Algorithm https://tools.ietf.org/html/rfc7915
- EAMT/Jool: https://www.jool.mx/en/eamt.html
- Solicited node multicast address https://en.wikipedia.org/wiki/Solicited-node_multicast_address
- Scapy / IPv6: https://www.idsv6.de/Downloads/IPv6PacketCreationWithScapy.pdf
- V1 model: https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4
- Cisco NAT64 https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/ipaddr_nat/configuration/xe-3s/nat-xe-3s-book/iadnat-stateful-nat64.pdf
- Wiki_mac: https://en.wikipedia.org/wiki/MAC_address
- Initial administration
- Clarify PDF / form with Denise Spicher: free form description
- Create task description to be handed in mystudies
- Create list of tasks / initial brainstorming
- Get OK from Ueli Maurer that thesis is valid in Information Security Area
- Find out how-when-whom-where to meet / define schedule
- Latex and/or org-mode for the thesis? org for starting
- Add initial milestones
- Proposal / task description
Time table / log
When? | What? | Notes |
2019-02-21 | Kick-Off | x |
Finish all admin points | x | |
Know when/how to coordinate | x | |
2019-02-21 | Clarifications Ueli Maurer (Mentor) | x |
Write mail / phone | x | |
2019-02-22 | Have all papers handed in | |
2019-02-22 | Have rough definition of tasks | x |
2019-02-23 | python2 / ipaddress is buggy | x |
p4utils is python2 only support | ||
bmpy_utils is not installable with pip | ||
python2 / latest ipaddress==1.0.22 still has the bug | ||
ipaddress.ip_network("2001:db8:61::/64") | ||
IPv6Network(u'3230:3031:3a64:6238:3a36:313a:3a2f:3634/128') | ||
egress routing | x | |
2019-02-24 | non reliable neighbor entries / flushing addresses puts into failed | |
2019-02-28 | Meet Laurent #2 | |
- Status | ||
* Setup base code | ||
* Parser for all protocols (udp,tcp,icmp,icmp6) | ||
* Started with icmp translation | ||
* Investigating into IPv6 based checksums | ||
* Reading into various RFCs, NDP, MLD | ||
* Reading about multicast / trying to figure out dynamic membership | ||
- Challenges | ||
* Some issues with python2 (ipaddr) - slowing down | x | |
https://github.com/phihag/ipaddress/issues/46 | ||
* Forwarded and received icmp6 packets are not "accepted" | ||
- Questions | ||
* Multicast: in controller | x | |
* Re-using code (lee howard) -> ok & mention | x | |
* A lot of redundant code / different tables / repeating: use if's | x | |
* 65k parsing is insane | x | |
- Next steps: | ||
* Supporting MLD | ||
* Save stuff in the controller | ||
* checkout ipaddr bug / status | ||
* Variable length / icmp6 in the controller | ||
* Go simple… | ||
* Meeting Edgar & Alexander week after | ||
* Summary on Slack | ||
* 1130 meeting now | ||
2019-03-01 | Feature list / priority list / roadmap clear | x |
Joining P4 Slack | ||
2019-03-03 | icmp6 revised: | |
- add address to table for forwarding to controller | x | |
- select correct format for forwarding | ||
- decode in controller | ||
- send back to switch | ||
- test with host | ||
2019-03-06 | Meet Laurent #3 | |
- Checksum's in scapy | x | |
- Python2 ipaddress fix (import future) | x | |
- Added custom package format / additional information in packet | x | |
- (partial) NDP working in controller | x | |
- P4 checksum_with_payload | x | |
- Reading scapy / inet6 | x | |
- Further checksum tests -> required everywhere in IPv6 | x | |
- icmp6 echo request working in controller | x | |
- Hosts can ping6 the switch | x | |
- Ran into P4 casting bug: https://github.com/p4lang/p4c/issues/1765 | x | |
-> seems to be more than just casting bug | x | |
- Default route for ipv6 hosts | x | |
Next target: | ||
- Focus on enabling the "Internet" with ICMP6 translation | x | |
Next steps: | ||
- Investigate again into checksumming with payload in P4 | x | |
- Answering icmp6 echo request in in the switch | x | |
- Translate icmp6 to icmp | x | |
- Translate icmp to icmp6 | ||
- Multiple branches: | x | |
* Work on checksumming / p4 | x | |
* Work on metadata passing / p4 | x | |
* Work on static mapping (w/ incorrect checksum) 1:1 | ||
* v1model/ | ||
Notes: | ||
* Edgar back on Friday // check tofino checksumming | ||
* Bugs mentioning in thesis | ||
* Maybe run static mapping on tofino / p4_14 | ||
* Tofino p4_16: alpha compiler | ||
* Send recap / mail next week | ||
* week after 1130 Thursday | ||
2019-03-07 | ICMP6 checksumming works!!! | x |
-> more fields needed to be included! | ||
2019-03-13 | Tried/trying to get vagrant VM or P4* running on the notebook | |
2019-03-14 | NAT64 static rewrite | x |
- table support | ||
- checksum not yet ported for translations | ||
- how to get mask from lpm table match? | ||
- how to get network from lpm match? | ||
- Create p4lang/p4-spec bug | ||
https://github.com/p4lang/p4-spec/issues/745 | ||
2019-03-21 | Meet Laurent #4 - post poned - sick | x |
https://github.com/p4lang/p4-spec/issues/660 sizeof() missing | ||
- Need to introduce new headers | ||
- Might need deeper parsing for icmp6_ns | ||
- Need hwaddr in icmp6_na | ||
- Need to find out how to handle imcp6 options after target address | ||
2019-03-23 | Parsing down to link layer option | x |
Parsing on wrong field detected by unset fields in wireshark | ||
Correcting parser->leads to incorrect checksum | ||
- NDP is answered to, but icmp6 echo request isn't -> extend table | ||
Problem with multiple LPM keys in table | ||
- logical problem, overlapping length matches | ||
- priority / ordering would be helpful | ||
2019-03-25 | x | |
Writing down double LPM problem | ||
Removing source network support, documenting limitation | ||
Rewriting code to use multiple NAT64 destinations | ||
New test.py v6_static_mapping tests | ||
Again checksum errors in NDP answer | ||
Added debug code to send table ID towards controller | ||
2019-03-26 | x | |
Find out where packet is stuck | ||
2019-03-27 | ||
switch cannot be used in actions! | ||
Refactor program to use multiple tables instead of switch | ||
Ethernet frame check sequence error | ||
2019-03-28 | Meet Laurent #4 | |
- Router solicitation for finding router on startup | ||
- test.py for TDD | ||
- Parsing icmp6 is not enough - one layer deeper | ||
- No LPM priorities | ||
- if/switch action logic | ||
- partial translation working to IPv4 | ||
- Focus on checksumming work (again) | ||
Notes: | ||
- Later using ternary matching | ||
- Document (nested) if's in action (in thesis) | ||
- SW and HW Targets Tofino [Albert, Thomas] | ||
- P414/P416 for Tofino? | ||
- Barefoot support/question: Ticket/Support System | ||
- Can try P416 compiler | ||
- Next week Laurent not around: send email + Albert/Thomas/Edgar meeting | ||
2019-03-30 | ||
Refactoring code | ||
Hitting expression bug | ||
Translating TO icmp4 works! | ||
2019-04-02 | ||
ARP egress support | ||
2019-04-03 | ||
ARP corrections – ARP working for the switch! | x | |
ICMP w/ incorrect checksum | x | |
ICMP w/ correct checksum - PING REPLIES!!! | x | |
Next: check / verify / translate nat46 | ||
2019-04-04 | ||
Report [no meeting w/ Laurent] | ||
Added arp handling | ||
Added icmp handling | ||
Need to setup hardware addresses -> in theor resolution -> hardcoded atm | ||
2019-04-04 | NAT64 1:1 table ICMP, ICMPv6 working | x |
Will need some switch local ip addresses | x | |
2019-04-11 | PLAN: NAT64 1:1 table UDP working | |
checksums in both directions | ||
2019-04-11 | ||
Meeting Laurent | ||
Status: | ||
- Minimal ARP working (for the switch address) | ||
- echo ping/request icmp<->icmp6 working | ||
- udp_v6->udp_v4 working | ||
- tcp_v6->tcp_v4 working | ||
- udp_v4->udp_v6 working | ||
- tcp_v4->udp_v6 working | ||
Next steps: | ||
- Hardware | ||
- icmp++ | ||
- pmtu | ||
- sessions main step | ||
Notes: | ||
- broadcast link only | ||
- About 2w delivery time | ||
- Get in touch with Tobias | ||
- Scalability analysis -> how many connections/connections/s | ||
- Forwarding information in tables | ||
- Hendrik: semester thesis / NetPFGA | ||
- Tobias: advising Hendrik / Netpfga | ||
2019-04-18 | PLAN: NAT64 1:1 table TCP/UDP working | x |
2019-04-23 | ||
Meet Laurent | ||
General | ||
- Get a better understanding of what others did | ||
Review docs / specs | ||
- Jool EAMT/SIIT fully | ||
- IPv4 embedding | ||
* Motivation/objective: working with real world DNS64 | ||
* RFC6052 suffix support | ||
* RFC4291 IPv4-Compatible IPv6 Address (16 0s) | ||
* RFC4291 IPv4-Mapped IPv6 Address (16 1s) | ||
- Session handling | ||
* RFC6145: Translation ip/icmp, obsoleted by RFC 7915 | ||
* RFC6146: NAT64 definition, only TCP, UDP, and ICMP traffic | ||
* RFC6052: embedding support | ||
* Mode: IPv6 outgoing -> "masquarading" | ||
* Mode: IPv4 | ||
- Translation details | ||
* How to handle ICMP4->icmp6 correctly (RFC7915) | ||
- Hardware | ||
* NetFPGA | ||
* Hardware machine for software comparison? | ||
New todos: | ||
- Translate fragment header | ||
- Support MTU / packet too big | ||
- Support PMTU, tcp mss | ||
Meeting notes | ||
- difference based | ||
- first physical access | ||
- tofino: if it compiles -> line rate | ||
- chaining switches / OS -> single port rate | ||
- netpfga | ||
- reason about what in hardware and what in software -> reason tradeoff | !!! | |
- table gets full | ||
Follow up: | ||
- what's the MTU of an interface? have a table | ||
- have port/mtu | ||
- total packeth length -> from IP | ||
- tables not in data plane | ||
- Meeting Hendrik | ||
- Meeting Kamila | ||
- 768k | ||
2019-05-02 | Jool SIIT / range / offset support https://www.jool.mx/en/run-vanilla.html | x |
Jool EAMT support https://www.jool.mx/en/run-eam.html | ||
Bidirectional support | ||
Will need IPv6 embedding suport https://tools.ietf.org/html/rfc6052 | ||
2019-04-18 | NAT64 prefix based IPv6->IPv4 conversion [tayga] | |
Use case: IPv6 hosts send to specific /96 | ||
2019-05-23 | NAT64 dynamic pool implementation: n:1 ipv6 to ipv4 mapping | |
And n:1 stateful mappings https://www.jool.mx/en/run-nat64.html | ||
Needs active controller | ||
Needs timeout / leases | ||
Might work w/ registers | ||
2018-06-27 | ||
Target Hardware: code running | ||
2019-07-11 | ||
Integrated org-documentation into latex / export working | ||
https://bastibe.de/2014-09-23-org-cite.html | ||
http://viveks.info/org-mode-academic-writing-bibliographies-org-ref/ | ||
https://github.com/jkitchin/org-ref | ||
2019-07-25 | Benmarking results between P4, Jool, Tayga | |
Real hardware of advantage | ||
2019-08-01 | Latest start writing documentation | |
2019-08-21 | hand in thesis |
Thesis implementation
DONE Setup test VM for P4: 2a0a:e5c0:2:12:400:f0ff:fea9:c3e3
DONE Get feature list of jool
DONE Get feature list of tayga
DONE Setup P4 base / structure
DONE Create minimal controller for populating tables
DONE Checkout / review egress settings
DONE Create Basis to translate ipv6 –> ipv4 with a (freely programmable) prefix; test ping6_switch
DONE Insert prefix into switch: v6_networks
DONE Support multiple ipv6 source networks: need new table w/ 2 keys! -> not at the moment
DONE Write test.py to generate correct destination packets
>>> a = ipaddress.ip_network("2001:db8::/32") >>> b = ipaddress.ip_address("10.0.0.1") >>> a[int(b)] IPv6Address('2001:db8::a00:1')
DONE Using test.py, new NDP packets been seen, bur zero icmp on the outgoing side
p4@ubuntu:~/master-thesis/p4app$ python test.py –method v6_static_mapping –debug INFO:main:Trying to reach 10.0.0.1 (64:ff9b::a00:1) from h1 sudo: unable to resolve host ubuntu PING 64:ff9b::a00:1(64:ff9b::a00:1) 56 data bytes
— 64:ff9b::a00:1 ping statistics — 1 packets transmitted, 0 received, 100% packet loss, time 0ms
p4@ubuntu:~/master-thesis/p4app$ \x00\x00\x00 :\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x00\n\xff\xfe\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x87\x00\x08+\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:cpu = <CpuHeader task=ICMP6_GENERAL ingress_port=1 type=0x86dd |<Raw load='`\x00\x00\x00\x00 :\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x00\n\xff\xfe\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x87\x00\x08+\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> 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:INCOMING: <Ether dst=00:00:0a:00:00:42 src=00:00:0a:00:00:01 type=0x4242 |<Raw load='\x00\x02\x00\x01\x86\xdd`\x00\x00\x00\x00 :\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x00\n\xff\xfe\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x87\x00\x08+\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:cpu = <CpuHeader task=ICMP6_GENERAL ingress_port=1 type=0x86dd |<Raw load='`\x00\x00\x00\x00 :\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x00\n\xff\xfe\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x87\x00\x08+\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> 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:INCOMING: <Ether dst=00:00:0a:00:00:42 src=00:00:0a:00:00:01 type=0x4242 |<Raw load='\x00\x02\x00\x01\x86\xdd`\x00\x00\x00\x00 :\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x00\n\xff\xfe\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x87\x00\x08+\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:cpu = <CpuHeader task=ICMP6_GENERAL ingress_port=1 type=0x86dd |<Raw load='`\x00\x00\x00\x00 :\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x00\n\xff\xfe\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x87\x00\x08+\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> 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 |>>>>
DONE Debug why neighbor discover does not work anymore
log
p4@ubuntu:~$ mx h1 tcpdump -lni any sudo: unable to resolve host ubuntu tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
19:57:53.258805 IP6 fe80::200:aff:fe00:1 > ff02::1:ff00:42: ICMP6, neighbor solicitation, who has 2001:db8::42, length 32 19:57:54.256924 IP6 2001:db8::1 > 2001:db8::1: ICMP6, destination unreachable, unreachable address 64:ff9b::a00:1, length 112
EBUG:main:INCOMING: <Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x4242 |<Raw load='\x00\x01\x00\x01\x86\xdd`\x00\x00\x00\x00 :\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x00\n\xff\xfe\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x007\xdf\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:cpu = <CpuHeader task=ICMP6_NS ingress_port=1 type=0x86dd |<Raw load='`\x00\x00\x00\x00 :\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x00\n\xff\xfe\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x007\xdf\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> 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 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 |>>>>
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!
DONE Finish NDP in switch
DONE Need to set R/S/O bits
DONE Need to parse R/S/O bits
DONE Maybe merge v6_address and v6_networks - /128 is the same
DONE Implement address learning? -> not at the moment
DONE Not sure whether we should react on router solicitation -> not at the moment
- Using static routes -> should do the job
DONE Implement the calculation
Currently offset + ip address
DONE Sketch the flow for session handling for icmp6 w/o packet loss
- switch receives icmp6 packet for known prefix
- controller needs to create session entry (?)
Not sure what I meant to do here - closing.
DONE Create table entry for mapping v4->v6 [net]
DONE Create table entry for mapping v6->v4 [net]
DONE Implement ICMP <-> ICMP6 translation
DONE 2019-02-28 / icmp testing / first NDP steps
DONE pinging in router mode: nothing shown in the controller, multicast forwarded -> "ok"
root@ubuntu:~/master-thesis/p4app# ping6 -c1 2001:db8:61::42 PING 2001:db8:61::42(2001:db8:61::42) 56 data bytes From 2001:db8:61::1 icmp_seq=1 Destination unreachable: Address unreachable
— 2001:db8:61::42 ping statistics — 1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
root@ubuntu:~/master-thesis/p4app#
sudo: unable to resolve host ubuntu tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on h1-eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 09:47:07.191569 IP6 2001:db8:61::1 > ff02::1:ff00:42: ICMP6, neighbor solicitation, who has 2001:db8:61::42, length 32 09:47:08.190331 IP6 2001:db8:61::1 > ff02::1:ff00:42: ICMP6, neighbor solicitation, who has 2001:db8:61::42, length 32 09:47:09.190279 IP6 2001:db8:61::1 > ff02::1:ff00:42: ICMP6, neighbor solicitation, who has 2001:db8:61::42, length 32
DONE special rule for ff02::1:ff00:42
Semi works, replies are there, but host still retries:
p4@ubuntu:~/master-thesis$ h=1; mx h$h tcpdump -lni h$h-eth0 sudo: unable to resolve host ubuntu tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on h1-eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 09:58:04.786979 IP6 2001:db8:61::1 > ff02::1:ff00:42: ICMP6, neighbor solicitation, who has 2001:db8:61::42, length 32 09:58:04.793560 IP6 2001:db8:61::42 > 2001:db8:61::1: ICMP6, neighbor advertisement, tgt is 2001:db8:61::42, length 32 09:58:05.786311 IP6 2001:db8:61::1 > ff02::1:ff00:42: ICMP6, neighbor solicitation, who has 2001:db8:61::42, length 32 09:58:05.790506 IP6 2001:db8:61::42 > 2001:db8:61::1: ICMP6, neighbor advertisement, tgt is 2001:db8:61::42, length 32 09:58:06.786254 IP6 2001:db8:61::1 > ff02::1:ff00:42: ICMP6, neighbor solicitation, who has 2001:db8:61::42, length 32 09:58:06.792325 IP6 2001:db8:61::42 > 2001:db8:61::1: ICMP6, neighbor advertisement, tgt is 2001:db8:61::42, length 32
Maybe checksums?
DONE Parse icmp
DONE Parse icmpv6
DONE Add (static) egress configuration
DONE Calculate ICMP6 checksums in controller
Need to include the payload!?!!
DONE Implement minimal neighbor discovery in controller
DONE For the switch
DONE Register IPv6 address in table
DONE Parse ICMPv6 up to neighbor solicitation -> no: checksum problem
DONE Use NDP (Neighbor Solicitation (NDP) , Neighbor Advertisement (NDP)) -> no: controller
Approach 2: use cpu header, forward information to controller
DONE Fix the ip address match/mapping: 42 -> 2a -> use hex originally
DONE Find out why wrong type is used -> overlapping with NDP
DEBUG:main:INCOMING: <Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x4242 |<Raw load='\x00\x03\x00\x01\x86\xdd`\x00\x00\x00\x00 :\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x00\xd3\xa4\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> p=<Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x4242 |<Raw load='\x00\x03\x00\x01\x86\xdd`\x00\x00\x00\x00 :\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x00\xd3\xa4\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:cpu = <CpuHeader task=DEBUG ingress_port=1 type=0x86dd |<Raw load='`\x00\x00\x00\x00 :\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x00\xd3\xa4\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:o=<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=0xd3a4 res=0 tgt=2001:db8::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>> DEBUG:main:Debug purpose only DEBUG:main:INCOMING: <Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x4242 |<Raw load='\x00\x03\x00\x01\x86\xdd`\x00\x00\x00\x00 :\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x00\xd3\xa4\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> p=<Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x4242 |<Raw load='\x00\x03\x00\x01\x86\xdd`\x00\x00\x00\x00 :\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x00\xd3\xa4\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:cpu = <CpuHeader task=DEBUG ingress_port=1 type=0x86dd |<Raw load='`\x00\x00\x00\x00 :\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x00\xd3\xa4\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:o=<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=0xd3a4 res=0 tgt=2001:db8::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>> DEBUG:main:Debug purpose only DEBUG:main:INCOMING: <Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x4242 |<Raw load='\x00\x03\x00\x01\x86\xdd`\x00\x00\x00\x00 :\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x00\xd3\xa4\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> p=<Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x4242 |<Raw load='\x00\x03\x00\x01\x86\xdd`\x00\x00\x00\x00 :\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x00\xd3\xa4\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:cpu = <CpuHeader task=DEBUG ingress_port=1 type=0x86dd |<Raw load='`\x00\x00\x00\x00 :\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x00\xd3\xa4\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:o=<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=0xd3a4 res=0 tgt=2001:db8::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>> DEBUG:main:Debug purpose only
Disable debug by default -> gives correct packets
DEBUG:main:INCOMING: <Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x4242 |<Raw load='\x00\x01\x00\x01\x86\xdd`\x00\x00\x00\x00 :\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x00\xd3\xa4\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:cpu = <CpuHeader task=ICMP6_NS ingress_port=1 type=0x86dd |<Raw load='`\x00\x00\x00\x00 :\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x00\xd3\xa4\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:o=<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=0xd3a4 res=0 tgt=2001:db8::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>> DEBUG:main:Doing neighbor solicitation DEBUG:main:INCOMING: <Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x4242 |<Raw load='\x00\x01\x00\x01\x86\xdd`\x00\x00\x00\x00 :\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x00\xd3\xa4\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:cpu = <CpuHeader task=ICMP6_NS ingress_port=1 type=0x86dd |<Raw load='`\x00\x00\x00\x00 :\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x00\xd3\xa4\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:o=<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=0xd3a4 res=0 tgt=2001:db8::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>> DEBUG:main:Doing neighbor solicitation DEBUG:main:INCOMING: <Ether dst=33:33:ff:00:00:42 src=00:00:0a:00:00:01 type=0x4242 |<Raw load='\x00\x01\x00\x01\x86\xdd`\x00\x00\x00\x00 :\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x00\xd3\xa4\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:cpu = <CpuHeader task=ICMP6_NS ingress_port=1 type=0x86dd |<Raw load='`\x00\x00\x00\x00 :\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00B\x87\x00\xd3\xa4\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x01\x01\x00\x00\n\x00\x00\x01' |>> DEBUG:main:o=<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=0xd3a4 res=0 tgt=2001:db8::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>> DEBUG:main:Doing neighbor solicitation
DONE For other nodes -> multicast
TODO Maybe implement link local addresses (missing at the moment)
ff02::/??
rfc4861
"Neighbor Solicitation messages are multicast to the solicited-node multicast address of the target address."
DONE multicasting / groups
If destination is within ff02::1:ff00:0/104, multicast
DONE Make switch answer icmp6 echo request for
DONE Introduce mixed mode: switch: icmp6 echo reply, controller: NDP
DONE try 1: reply seen, but checksum is incorrect
DONE try 2: analysing tagya checksumming code
static uint16_t ip6_checksum(struct ip6 *ip6, uint32_t data_len, uint8_t proto) { uint32_t sum = 0; uint16_t *p; int i;
for (i = 0, p = ip6->src.s6_addr16; i < 16; ;
sum += htonl(data_len) >> 16;
sum += htonl(data_len) & 0xffff;
sum += htons(proto);i)
sum += *p
while (sum > 0xffff) sum = (sum & 0xffff) + (sum >> 16);
return ~sum; }
static uint16_t convert_cksum(struct ip6 *ip6, struct ip4 *ip4) { uint32_t sum = 0; uint16_t *p; int i;
sum += ~ip4->src.s_addr >> 16; sum += ~ip4->src.s_addr & 0xffff; sum += ~ip4->dest.s_addr >> 16; sum += ~ip4->dest.s_addr & 0xffff;
for (i = 0, p = ip6->src.s6_addr16; i < 16; ;i)
sum += *p
while (sum > 0xffff) sum = (sum & 0xffff) + (sum >> 16);
return sum; } … static int xlate_payload_4to6(struct pkt *p, struct ip6 *ip6) { uint16_t *tck; uint16_t cksum;
if (p->ip4->flags_offset & htons(IP4_F_MASK)) return 0;
switch (p->data_proto) { case 1: cksum = ip6_checksum(ip6, htons(p->ip4->length) - p->header_len, 58); cksum = ones_add(p->icmp->cksum, cksum); if (p->icmp->type == 8) { p->icmp->type = 128; p->icmp->cksum = ones_add(cksum, ~(128 - 8)); } else { p->icmp->type = 129; p->icmp->cksum = ones_add(cksum, ~(129 - 0)); } return 0;
DONE Add default route for v6 hosts
p4@ubuntu:~/master-thesis$ mx h1 ip -6 r sudo: unable to resolve host ubuntu 2001:db8::/64 dev h1-eth0 proto kernel metric 256 pref medium fe80::/64 dev h1-eth0 proto kernel metric 256 pref medium default via 2001:db8::42 dev h1-eth0 metric 1024 pref medium p4@ubuntu:~/master-thesis$
DONE TEST ping6ing an emulated ipv6 host / Translate icmp <-> icmp6: test v6_static_mapping
DONE try1: only packets on h1 + controller -> wrong checksum 2019-03-25
- filename=static_nat64-2019-03-25-1121-h1.pcap
- intf=h1-eth0
- mx h1 tcpdump -ni h1-eth0 -w static_nat64-2019-03-25-1121-h1.pcap
tcpdump: listening on h1-eth0, link-type EN10MB (Ethernet), capture size 262144 bytes ^C10 packets captured 10 packets received by filter 0 packets dropped by kernel 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 |>>>>
That looks like NDP is not working again. Why: checksum seems to be incorrect according to wireshark. Why? Checksum is the SAME as in the request -> probably not updated. After inserting marker: it's clear that the checksum code DOES NOT work on the task field!
Problem: task field might be overriden for controller use in different table -> need different task field!
DONE try2: checksum ok, but no packets on h3
DONE Setup a default rule for the IPv4 world to debug on controller
Still not seeing the converted packet, however seeing icmp6_ns packets which should not be there:
table entry for ns:
ff:02:00:00:00:00:00:00:00:00:00:01:ff:00:00:42/128
debug packet seen in controller:
DEBUG:main:v6 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:v6 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:v6 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:v6 reassambled=<Ether dst=00:00:0a:00:00:42 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=920946 plen=64 nh=ICMPv6 hlim=64 src=2001:db8::1 dst=2001:db8:1::a00:1 |<ICMPv6EchoRequest type=Echo Request code=0 cksum=0xf981 id=0x5f7c seq=0x1 data='N\xc6\x98\\\x00\x00\x00\x00\x12\x1b\t\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567' |>>>
debugging MIGHT come from nat64 table!
DONE try3: re-rewrite: no packets on h3 again (2019-03-30)
p4@ubuntu:~$ ~/master-thesis/p4app/sniff-host.sh h1 static_nat64
- cd /home/p4/master-thesis/pcap
- host=h1
- name=static_nat64
- date +%F-%H%M
- now=2019-03-30-1608
- filename=static_nat64-2019-03-30-1608-h1.pcap
- intf=h1-eth0
- mx h1 tcpdump -ni h1-eth0 -w static_nat64-2019-03-30-1608-h1.pcap
tcpdump: listening on h1-eth0, link-type EN10MB (Ethernet), capture size 262144 bytes ^C10 packets captured 10 packets received by filter 0 packets dropped by kernel
p4@ubuntu:~$ p4@ubuntu:~/master-thesis/pcap$ ../p4app/sniff-host.sh h3 static_nat64
- cd /home/p4/master-thesis/pcap
- host=h3
- name=static_nat64
- date +%F-%H%M
- now=2019-03-30-1608
- filename=static_nat64-2019-03-30-1608-h3.pcap
- intf=h3-eth0
- mx h3 tcpdump -ni h3-eth0 -w static_nat64-2019-03-30-1608-h3.pcap
tcpdump: listening on h3-eth0, link-type EN10MB (Ethernet), capture size 262144 bytes ^C0 packets captured 0 packets received by filter 0 packets dropped by kernel
p4@ubuntu:~/master-thesis/pcap$
-> NDP is going to the controller instead of being handled by the switch INFO:main:unhandled 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 |>>>> from table TABLE_V6_NETWORKS
-> checksums likely broken again due to checksum changes -> solved, test case for verification is
p4@ubuntu:~$ python ~/master-thesis/p4app/test.py -m v6_static_mapping --debug
INFO:main:Trying to reach 10.0.0.1 (2001:db8:1::a00:1) from h1
PING 2001:db8:1::a00:1(2001:db8:1::a00:1) 56 data bytes
From 2001:db8::1 icmp_seq=1 Destination unreachable: Address unreachable
--- 2001:db8:1::a00:1 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
p4@ubuntu:~$ python ~/master-thesis/p4app/test.py -m ping6_switch --debug
INFO:main:Trying to reach 2001:db8::42 from h1
PING 2001:db8::42(2001:db8::42) 56 data bytes
64 bytes from 2001:db8::42: icmp_seq=1 ttl=64 time=6.30 ms
--- 2001:db8::42 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 6.304/6.304/6.304/0.000 ms
DONE try4: h3 receives packet, but length seems to be off
- Seeing frame check sequence error
- total length ipv4 = 69 (h3)
- ipv6 payload length = 64 (h1)
- comes from hdr.ipv4.totalLen = (bit<16>) hdr.ipv6.payload_length + 5;
- https://tools.ietf.org/html/rfc791:
Total Length is the length of the datagram, measured in octets, including internet header and data.
- checksum = 0 -> offset incorrect???
- ipv4 checksum is 0
- nat64 frame length = 98 bytes
- theory: ethernet: 48+48+16 = 112 bit -> 12 bytes
- nat64: 76 bytes inside ethernet frame
- nat64: 69 bytes according to total_len
- nat64: -5 bytes = icmp4 = 64 bytes
- icmp6 == 64 bytes
- diff of 7 bytes :-)
- icmp should be:
- type+code+checksum = 4 bytes
- seq + identifier = 4 bytes
- data = variable, source is 56 bytes
- real world ping: total_length = 84, 48 bytes icmp data
- header length in both cases = 5
- identification 0 in nat64, 0x2cad in real
- flags 0 in nat64, 0x4000 (DF) in real
- ttl = 64 both
- proto = icmp both cases
- header checksum = 0 in nat64, set in real
- data is shorter in nat64, due to total_len error
- real world icmp contains time stamp data ???
- wireshark EXPECTS timestamp data in echo request! + 8 bytes and then data
- almost fits diff 7 vs. 8
- 8 bytes in one block in wireshark
- after ipv4: 6 + 8 + 3*(16) + 2 = 64 – wtf??
- icmp6: data == 56 bytes
- nat64 and realping4 frame == 98 bytes
TODO Correct IPv4 header checksum
TODO Correct ICMP header checksum
TODO Fix length issue
- Seems like total_len is too short - but why?
DONE try5: packet is good, but routing is "strange": default route == 10.0.0.66
root@ubuntu:~# ip r default via 10.0.0.66 dev h3-eth0 10.0.0.0/24 dev h3-eth0 proto kernel scope link src 10.0.0.1 root@ubuntu:~#
DONE try6: host sees packet, but does not react on it, manually tring gateway ping
p4@ubuntu:~$ mx h3 tcpdump -lni h3-eth0 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on h3-eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 09:06:02.636669 IP 10.1.1.1 > 10.0.0.1: ICMP echo request, id 31058, seq 1, length 64
in h3:
root@ubuntu:~# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: h3-eth0@if38: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9500 qdisc netem state UP group default qlen 1000 link/ether 00:00:0a:00:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.0.0.1/24 scope global h3-eth0 valid_lft forever preferred_lft forever root@ubuntu:~#
no arp entries:
root@ubuntu:~# arp -an root@ubuntu:~#
root@ubuntu:~# ping -c1 10.0.0.66 PING 10.0.0.66 (10.0.0.66) 56(84) bytes of data. From 10.0.0.1 icmp_seq=1 Destination Host Unreachable
— 10.0.0.66 ping statistics — 1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
root@ubuntu:~#
DONE try7: checkout dump from ping4_gw-2019-03-31-0916-h3.pcap: regular arp
DONE Get a real world arp trace
root@line:/home/nico/vcs/master-thesis/pcap# tcpdump -ni wlan0 -w ping4_realworld_p7 icmp or arp or host 192.168.4.1 tcpdump: listening on wlan0, link-type EN10MB (Ethernet), capture size 262144 bytes root@line:~# arp -an ? (192.168.4.188) at 00:0d:b9:46:3b:d4 [ether] on wlan0 root@line:~# ping -c1 192.168.4.1 PING 192.168.4.1 (192.168.4.1) 56(84) bytes of data. 64 bytes from 192.168.4.1: icmp_seq=1 ttl=64 time=15.5 ms
— 192.168.4.1 ping statistics — 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 15.533/15.533/15.533/0.000 ms root@line:~#
TODO Implement default route handling, maybe implement ARP?
DONE create arp table
TODO Multiple tables not supported
p4c –target bmv2 –arch v1model –std p4-16 "../p4src/static-mapping.p4" -o "/home/p4/master-thesis/p4src" ../p4src/static-mapping.p4(366): error: Program is not supported by this target, because table MyIngress.v6_networks has multiple successors table v6_networks { ^^^^^^^^^^^ Compilation Error
Entry in v4_networks?
DONE Add table name support in debug messages
DONE Why getting IPv6 packets in
INFO:main:unhandled 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 |>>>> from table TABLE_V6_NETWORKS INFO:main:unhandled 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 |>>>> from table TABLE_V6_NETWORKS INFO:main:unhandled 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 |>>>> from table TABLE_NAT64 INFO:main:unhandled reassambled=<Ether dst=00:00:0a:00:00:42 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=920946 plen=64 nh=ICMPv6 hlim=64 src=2001:db8::1 dst=2001:db8:1::a00:1 |<ICMPv6EchoRequest type=Echo Request code=0 cksum=0x3d1a id=0xade seq=0x1 data='\x1f\x92\x9a\\\x00\x00\x00\x00WU\x02\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567' |>>> from table TABLE_V4_NETWORKS
DONE Solve logic problem: Valid headers
- If ipv6 header is valid && nat64 will be made and afterwards v4 egress needs to be applied
- If ipv4 header is valid && nat46 will be made and afterwards v6 egress needs to be applied
DONE Check translated fields
DONE source correctly translated to 10.1.1.1
DONE destination correctly translated to 10.0.0.1 -> pings h3
DONE egress is correct, comes out at h3
DONE protocol 58 is wrong -> should be 1
DONE figure out switch() syntax
DONE transform protocol specific: icmp6 -> icmp
DONE Implement double table, as there are no if's in actions
DONE Debug Ethernet frame check sequence error -> need to compute checksum
https://en.wikipedia.org/wiki/Frame_check_sequence
According to Edgar this should not be seen anyway.
DONE Calculate ICMP checksum
DONE Check field lengths
DONE Fix resolve / mac addresses -> ethernet is wrong!
INFO:main:unhandled 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 |>>>> from table TABLE_V6_NETWORKS INFO:main:unhandled 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 |>>>> from table TABLE_V6_NETWORKS INFO:main:unhandled 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 |>>>> from table TABLE_V6_NETWORKS
According to pcap/static_nat64-2019-04-03-0932-h3.pcap ethernet frame looks good. Still no reply / reaction from host h3.
DONE Fix IPv4 header checksum // wrong according to wireshark
When & how to update?
DONE check packets static_nat64-2019-04-03-0957-h1.pcap: answer not outputted/natted!
INFO:main:unhandled 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 |>>>> from table TABLE_V6_NETWORKS INFO:main:unhandled 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 |>>>> from table TABLE_V6_NETWORKS INFO:main:unhandled 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 |>>>> from table TABLE_V6_NETWORKS INFO:main:unhandled reassambled=<Ether dst=00:00:0a:00:00:42 src=00:00:0a:00:00:03 type=0x800 |<IP version=4 ihl=5 tos=0x0 len=84 id=60628 flags= frag=0 ttl=64 proto=icmp chksum=0x78d2 src=10.0.0.1 dst=10.1.1.1 options=[] |<ICMP type=echo-reply code=0 chksum=0x9138 id=0x26e9 seq=0x1 |<Raw load='\x8b\x83\xa4\\\x00\x00\x00\x00S*\x06\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567' |>>>> from table TABLE_V6_NETWORKS
Adding entry to lpm match table nat46 match key: LPM-0a:01:01:00/24 action: nat46_static runtime data: 20:01:0d:b8:00:00:00:00:00:00:00:00:00:00:00:00 0a:01:01:00 20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:00 Entry has been added with handle 0
[09:57:31.415] [bmv2] [T] [thread 9332] [105.0] [cxt 0] Applying table 'MyIngress.v6_networks' [09:57:31.415] [bmv2] [D] [thread 9332] [105.0] [cxt 0] Looking up key:
- hdr.ipv6.dst_addr : 20010db8000000000000000000000001
[09:57:31.415] [bmv2] [D] [thread 9332] [105.0] [cxt 0] Table 'MyIngress.v6_networks': miss
DONE transform protocol specific: icmp -> icmp6
DONE Make switch answer IPv4 icmp echo request for
DONE Test result (2019-04-03)
p4@ubuntu:~$ python ~/master-thesis/p4app/test.py -m v6_static_mapping PING 2001:db8:1::a00:1(2001:db8:1::a00:1) 56 data bytes 64 bytes from 2001:db8:1::a00:1: icmp_seq=1 ttl=64 time=14.7 ms
— 2001:db8:1::a00:1 ping statistics — 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 14.750/14.750/14.750/0.000 ms p4@ubuntu:~$
DONE Add / check default route for v4 hosts
DONE Check IPv4 -> IPv6 translation
p4@ubuntu:~$ python ~/master-thesis/p4app/test.py -m v4_static_mapping PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data. 64 bytes from 10.1.1.1: icmp_seq=1 ttl=64 time=12.5 ms
— 10.1.1.1 ping statistics — 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 12.593/12.593/12.593/0.000 ms p4@ubuntu:~$
TODO Implement ipv6<->ipv4 udp translation
DONE udp: ipv6->ipv4
p4@ubuntu:~$ mx h3 "echo V4-OK | socat - UDP-LISTEN:2342" /usr/bin/mx: line 25: [: too many arguments V6-OK p4@ubuntu:~$
p4@ubuntu:~$ mx h1 "echo V6-OK | socat - UDP6:[2001:db8:1::a00:1]:2342" /usr/bin/mx: line 25: [: too many arguments V4-OK p4@ubuntu:~$
pcap/v6_udp-2019-04-11-0840-h1.pcap
pcap/v6_udp-2019-04-11-0840-h3.pcap
TODO udp: ipv4->ipv6
p4@ubuntu:~$ mx h3 "echo V4-OK | socat - UDP:10.1.1.1:2342" /usr/bin/mx: line 25: [: too many arguments V6-OK p4@ubuntu:~$ p4@ubuntu:~$ mx h1 "echo V6-OK | socat - UDP6-LISTEN:2342" /usr/bin/mx: line 25: [: too many arguments V4-OK
proof
create mode 100644 pcap/v4_udp-2019-04-11-0855-h1.pcap create mode 100644 pcap/v4_udp-2019-04-11-0855-h3.pcap
DONE Implement ipv6<->ipv4 tcp translation
DONE tcp: v6 -> v4
p4@ubuntu:~$ mx h1 "echo V6-OK | socat - TCP6:[2001:db8:1::a00:1]:2342" /usr/bin/mx: line 25: [: too many arguments V4-OK p4@ubuntu:~$ p4@ubuntu:~$ mx h3 "echo V4-OK | socat - TCP-LISTEN:2342" /usr/bin/mx: line 25: [: too many arguments V6-OK p4@ubuntu:~$
Proof
create mode 100644 pcap/v6_tcp-2019-04-11-0846-h1.pcap create mode 100644 pcap/v6_tcp-2019-04-11-0846-h3.pcap
DONE tcp: v4 -> v6
p4@ubuntu:~$ mx h3 "echo V4-OK | socat - TCP:10.1.1.1:2342" /usr/bin/mx: line 25: [: too many arguments V6-OK p4@ubuntu:~$ p4@ubuntu:~$ mx h1 "echo V6-OK | socat - TCP6-LISTEN:2342" /usr/bin/mx: line 25: [: too many arguments V4-OK p4@ubuntu:~$
Proof
pcap/v4_tcp-2019-04-11-0853-h1.pcap | Bin 0 -> 1174 bytes pcap/v4_tcp-2019-04-11-0853-h3.pcap | Bin 0 -> 1070 bytes
TODO Update p4c to avoid compiler bug
TODO Updating p4c
DONE Try1
p4@ubuntu:~/p4-learning/vm/bin$ sh update-p4c.sh update-p4c.sh: 34: update-p4c.sh: Syntax error: "(" unexpected p4@ubuntu:~/p4-learning/vm/bin$ git pull Already up-to-date. p4@ubuntu:~/p4-learning/vm/bin$ git describe --always fb9d0ea p4@ubuntu:~/p4-learning/vm/bin$
p4@ubuntu:~/p4-tools/p4c$ git checkout 1ab1c796677a3a2349df9619d82831a39a6e4437 p4@ubuntu:~/p4-tools/p4c/build$ cmake .. p4@ubuntu:~/p4-tools/p4c/build$ make -j8
DONE Need to upgrade RAM / c++ errors / killed
DONE Compile error from 1ab1c79
[ 33%] Building CXX object frontends/CMakeFiles/frontend.dir/unified_frontend_sources_4.cpp.o [ 37%] Building CXX object frontends/CMakeFiles/frontend.dir/__/ir/ir-generated.cpp.o [ 35%] Building CXX object frontends/CMakeFiles/frontend.dir/unified_frontend_sources_2.cpp.o [ 43%] Built target midend [ 45%] Linking CXX static library libfrontend.a [ 56%] Built target frontend Scanning dependencies of target bmv2backend make[2]: * No rule to make target '../control-plane/p4runtime/proto/p4/v1/p4data.proto', needed by 'control-plane/google/rpc/status.pb.cc'. Stop. CMakeFiles/Makefile2:1197: recipe for target 'control-plane/CMakeFiles/controlplane.dir/all' failed make[1]: * [control-plane/CMakeFiles/controlplane.dir/all] Error 2 make[1]: * Waiting for unfinished jobs…. [ 58%] Building CXX object backends/bmv2/CMakeFiles/bmv2backend.dir/unified_bmv2_backend_common_srcs_1.cpp.o [ 59%] Building CXX object backends/bmv2/CMakeFiles/bmv2backend.dir/unified_bmv2_backend_common_srcs_2.cpp.o [ 61%] Linking CXX static library libbmv2backend.a [ 61%] Built target bmv2backend Makefile:138: recipe for target 'all' failed make: * [all] Error 2 p4@ubuntu:~/p4-tools/p4c/build$ cd .. p4@ubuntu:~/p4-tools/p4c$ git describe –always 1ab1c79 p4@ubuntu:~/p4-tools/p4c$
DONE Upgrading to latest master: 46609cd -> fails
p4@ubuntu:~/p4-tools/p4c$ git describe –always 46609cd
p4@ubuntu:~/p4-tools/p4c$ cd build/ p4@ubuntu:~/p4-tools/p4c/build$ make clean frontends/CMakeFiles/frontend.dir/build.make:93: warning: overriding recipe for target 'frontends/parsers/v1/v1parser.output' frontends/CMakeFiles/frontend.dir/build.make:74: warning: ignoring old recipe for target 'frontends/parsers/v1/v1parser.output' p4@ubuntu:~/p4-tools/p4c/build$ cmake .. && make -j8 [ 50%] Building CXX object frontends/CMakeFiles/frontend.dir/unified_frontend_sources_5.cpp.o [ 51%] Building CXX object frontends/CMakeFiles/frontend.dir/unified_frontend_sources_6.cpp.o [ 53%] Linking CXX static library libir.a [ 53%] Built target ir [ 54%] Building CXX object frontends/CMakeFiles/frontend.dir/unified_frontend_sources_7.cpp.o [ 56%] Linking CXX static library libfrontend.a [ 56%] Built target frontend make[2]: *** No rule to make target '../control-plane/p4runtime/proto/p4/v1/p4data.proto', needed by 'control-plane/google/rpc/status.pb.cc'. Stop. CMakeFiles/Makefile2:1197: recipe for target 'control-plane/CMakeFiles/controlplane.dir/all' failed make[1]: *** [control-plane/CMakeFiles/controlplane.dir/all] Error 2 make[1]: *** Waiting for unfinished jobs.... Scanning dependencies of target bmv2backend [ 58%] Building CXX object backends/bmv2/CMakeFiles/bmv2backend.dir/unified_bmv2_backend_common_srcs_2.cpp.o [ 59%] Building CXX object backends/bmv2/CMakeFiles/bmv2backend.dir/unified_bmv2_backend_common_srcs_1.cpp.o [ 61%] Linking CXX static library libbmv2backend.a [ 61%] Built target bmv2backend Makefile:138: recipe for target 'all' failed make: *** [all] Error 2 p4@ubuntu:~/p4-tools/p4c/build$
DONE Build on notebook succeeds 900557c5
[16:37] line:p4c% git describe –always 900557c5
TODO Build on VM with 900557c5 after removing build/
TODO Get p4 VM / vagrant running
DONE install libvirtd-daemon
DONE install ebtables
DONE install dnsmasq
TODO Get p4c & co. running on the notebook
DONE mininet via packages
DONE p4c
(virtualenv-with-site) [17:43] line:build% make install
[ 0%] Built target update_includes
[ 0%] Built target linkgraphs
[ 0%] Built target linkbmv2
[ 0%] Built target linkp4cebpf
[ 0%] Built target linkp4test
[ 1%] Built target p4c_driver
[ 4%] Built target p4ctoolkit
[ 12%] Built target irgenerator
[ 14%] Generating IR class files
[ 14%] Built target genIR
[ 18%] Built target ir
[ 18%] Built target mkv1dirs
[ 18%] Built target mkp4dirs
[ 45%] Built target frontend
[ 51%] Built target midend
[ 51%] Built target mkP4configdir
[ 64%] Built target controlplane
[ 68%] Built target bmv2backend
[ 75%] Built target p4c-bm2-psa
[ 81%] Built target p4c-bm2-ss
[ 84%] Built target p4c-ebpf
[ 87%] Built target p4test
[ 90%] Built target p4c-graphs
[ 93%] Built target gtest
[100%]
Built target gtestp4c
Install the project…
– Install configuration: "RELEASE"
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/share/p4c/p4include
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/share/p4c/p4include/p4d2model.p4
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/share/p4c/p4include/v1model.p4
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/share/p4c/p4include/core.p4
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/share/p4c/p4include/psa.p4
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/bin/p4c
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/share/p4c/p4c_src
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/share/p4c/p4c_src/driver.py
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/share/p4c/p4c_src/util.py
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/share/p4c/p4c_src/config.py
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/share/p4c/p4c_src/__init__.py
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/share/p4c/p4c_src/main.py
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/share/p4c/p4c_src/p4c.bmv2.cfg
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/share/p4c/p4c_src/p4c.ebpf.cfg
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/bin/p4c-bm2-ss
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/bin/p4c-bm2-psa
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/bin/p4c-ebpf
– Up-to-date: /home/nico/vcs/master-thesis/support/p4c-installation/share/p4c/p4include
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/share/p4c/p4include/ebpf_model.p4
– Installing: /home/nico/vcs/master-thesis/support/p4c-installation/bin/p4test
– Installing: home/nico/vcs/master-thesis/support/p4c-installation/bin/p4c-graphs
(virtualenv-with-site) [0:42] line:build% ls /home/nico/vcs/master-thesis/support/p4c-installation/bin
p4c p4c-bm2-psa p4c-bm2-ss p4c-ebpf p4c-graphs p4test
(virtualenv-with-site) [0:42] line:build%
TODO install behavioral-model
TODO Debug / reread the virtualbox script from the lecture
TODO Get p4c installed / running
log
[16:31] line:p4c% git submodule update –init –recursive
root@line:~# apt install bison \ > build-essential \ > cmake \ > flex \ > g++ \ > libboost-dev \ > libboost-graph-dev \ > libboost-iostreams1.58-dev \ > libfl-dev \ > libgc-dev \ > libgmp-dev \ > pkg-config \ > python-ipaddr \ > python-pip \ > python-setuptools \ > tcpdump Reading package lists… Done Building dependency tree Reading state information… Done Package libboost-iostreams1.58-dev is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source
E: Package 'libboost-iostreams1.58-dev' has no installation candidate root@line:~# apt install libpcap-dev libelf-dev llvm clang iproute2 net-tools
[16:33] line:p4c% . ~/vcs/master-thesis/support/virtualenv2/bin/activate (virtualenv2) [16:35] line:p4c% pip install tenjin \ pyroute2 \ ply==3.8 \ scapy==2.4.0
Using newer version of libboost-iostreams1.58-dev
buidling
(virtualenv2) [16:36] line:p4c% mkdir build && \ cd build && \ cmake .. '-DCMAKE_CXX_FLAGS:STRING=-O3'
missing protobuf
(virtualenv2) [16:36] line:p4c% mkdir build && \ cd build && \ cmake .. '-DCMAKE_CXX_FLAGS:STRING=-O3'
cd build && \ cmake .. '-DCMAKE_CXX_FLAGS:STRING=-O3'– The C compiler identification is GNU 8.3.0 – The CXX compiler identification is GNU 8.3.0 – Check for working C compiler: /usr/bin/cc – Check for working C compiler: /usr/bin/cc – works – Detecting C compiler ABI info – Detecting C compiler ABI info - done – Detecting C compile features – Detecting C compile features - done – Check for working CXX compiler: /usr/bin/c++ – Check for working CXX compiler: /usr/bin/c++ – works – Detecting CXX compiler ABI info – Detecting CXX compiler ABI info - done – Detecting CXX compile features – Detecting CXX compile features - done – Found PythonInterp: /home/nico/vcs/master-thesis/support/virtualenv2/bin/python (found version "2.7.16") – Found FLEX: /usr/bin/flex (found version "2.6.4") – Found BISON: /usr/bin/bison (found suitable version "3.3.2", minimum required is "3.0.2") CMake Error at /usr/share/cmake-3.13/Modules/FindPackageHandleStandardArgs.cmake:137 (message): Could NOT find Protobuf (missing: Protobuf_INCLUDE_DIR) (Required is at least version "3.0.0") Call Stack (most recent call first): /usr/share/cmake-3.13/Modules/FindPackageHandleStandardArgs.cmake:378 (_FPHSA_FAILURE_MESSAGE) /usr/share/cmake-3.13/Modules/FindProtobuf.cmake:595 (FIND_PACKAGE_HANDLE_STANDARD_ARGS) CMakeLists.txt:81 (find_package)
– Configuring incomplete, errors occurred! See also "/home/nico/vcs/master-thesis/support/p4c/build/CMakeFiles/CMakeOutput.log". See also "/home/nico/vcs/master-thesis/support/p4c/build/CMakeFiles/CMakeError.log". (virtualenv2) [16:36] line:build% apt search protobuf
(virtualenv2) [16:38] line:build% sudo apt install python-protobuf protobuf-compiler
(virtualenv2) [16:38] line:build% cmake .. '-DCMAKE_CXX_FLAGS:STRING=-O3' – Found Protobuf: /usr/lib/x86_64-linux-gnu/libprotobuf.a;-lpthread (found suitable version "3.6.1", minimum required is "3.0.0") – Boost version: 1.67.0 – Found the following Boost libraries: – iostreams – regex – Found LibGc: /usr/lib/x86_64-linux-gnu/libgccpp.so (found suitable version "7.6.4", minimum required is "7.2.0") – Found Threads: TRUE – Found LibGmp: /usr/lib/x86_64-linux-gnu/libgmpxx.so – Looking for clock_gettime in rt – Looking for clock_gettime in rt - found – Looking for execinfo.h – Looking for execinfo.h - found – Looking for ucontext.h – Looking for ucontext.h - found – Looking for C++ include cxxabi.h – Looking for C++ include cxxabi.h - found – Looking for memchr – Looking for memchr - found – Looking for pipe2 – Looking for pipe2 - found – Looking for GC_print_stats – Looking for GC_print_stats - found – Found PY_difflib: /usr/lib/python2.7/difflib.pyc – Found PY_shutil: /usr/lib/python2.7/shutil.pyc – Found PY_tempfile: /usr/lib/python2.7/tempfile.pyc – Found PY_subprocess: /usr/lib/python2.7/subprocess.pyc – Found PY_re: /home/nico/vcs/master-thesis/support/virtualenv2/lib/python2.7/re.pyc – Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE) – Program 'simple_switch_CLI' (https://github.com/p4lang/behavioral-model.git) not found; Searched . Will not run BMv2 tests. (missing: SIMPLE_SWITCH SIMPLE_SWITCH_CLI) – Program 'psa_switch_CLI' (https://github.com/p4lang/behavioral-model.git) not found; Searched . Will not run PSA BMv2 tests. (missing: PSA_SWITCH PSA_SWITCH_CLI) – Performing Test HAVE_OPTION_Wall – Performing Test HAVE_OPTION_Wall - Success – Performing Test HAVE_OPTION_Wextra – Performing Test HAVE_OPTION_Wextra - Success – Performing Test HAVE_OPTION_Wnooverloadedvirtual – Performing Test HAVE_OPTION_Wnooverloadedvirtual - Success – Performing Test HAVE_OPTION_Wnodeprecated – Performing Test HAVE_OPTION_Wnodeprecated - Success – Using the GNU gold linker. – Available extensions CMake Warning at backends/bmv2/CMakeLists.txt:193 (MESSAGE): BMv2 simple switch is not available, not adding v1model BMv2 tests
CMake Warning at backends/bmv2/CMakeLists.txt:199 (MESSAGE): BMv2 PSA switch is not available, not adding PSA BMv2 tests
– Found LLVM 7.0.1 – Added 14 tests to 'ebpf-kernel' (0 xfails) – Added 14 tests to 'ebpf-bcc' (0 xfails) – Added 14 tests to 'ebpf' (0 xfails) – Added 161 tests to 'p4' (0 xfails) – Added 506 tests to 'p4' (4 xfails) – Added 204 tests to 'p14_to_16' (0 xfails) – CTest parallel: -j 8 – Configuring done – Generating done – Build files have been written to: /home/nico/vcs/master-thesis/support/p4c/build
testing in build directory: works
/home/nico/vcs/master-thesis/support/p4c/build
Changing install path
CMAKE_INSTALL_PREFIX cmake .. '-DCMAKE_CXX_FLAGS:STRING=-O3' -DCMAKE_INSTALL_PREFIX=/home/nico/vcs/master-thesis/support/p4c-installation
TODO Get p4utils running (?)
log of python, p4app, p4c installation
[16:16] line:support% virtualenv virtualenv2 Running virtualenv with interpreter /usr/bin/python2 New python executable in /home/nico/vcs/master-thesis/support/virtualenv2/bin/python2 Also creating executable in /home/nico/vcs/master-thesis/support/virtualenv2/bin/python Installing setuptools, pkg_resources, pip, wheel…done. [16:16] line:support%
[16:18] line:p4-utils-nsg% . ~/vcs/master-thesis/support/virtualenv2/bin/activate (virtualenv2) [16:19] line:p4-utils-nsg% which pip /home/nico/vcs/master-thesis/support/virtualenv2/bin/pip (virtualenv2) [16:19] line:p4-utils-nsg%
pip install -e .
Missing python development headers
copying psutil/tests/test_memory_leaks.py -> build/lib.linux-x86_64-2.7/psutil/tests running build_ext building 'psutil._psutil_linux' extension creating build/temp.linux-x86_64-2.7 creating build/temp.linux-x86_64-2.7/psutil x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fdebug-prefix-map=/build/python2.7-UboFgi/python2.7-2.7.16~rc1=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -DPSUTIL_POSIX=1 -DPSUTIL_VERSION=561 -DPSUTIL_LINUX=1 -I/usr/include/python2.7 -c psutil/_psutil_common.c -o build/temp.linux-x86_64-2.7/psutil/_psutil_common.o psutil/_psutil_common.c:9:10: fatal error: Python.h: No such file or directory #include <Python.h> ^~~~~~~~~~ compilation terminated. error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
root@line:~# apt install python2-dev
installing, but missing mininet.net
(virtualenv2) [16:21] line:p4-utils-nsg% pip install -e "." DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7. Obtaining /home/nico/vcs/master-thesis/support/p4-utils-nsg Requirement already satisfied: setuptools in /home/nico/vcs/master-thesis/support/virtualenv2/lib/python2.7/site-packages (from p4utils==0.2) (40.8.0) Requirement already satisfied: networkx in /home/nico/vcs/master-thesis/support/virtualenv2/lib/python2.7/site-packages (from p4utils==0.2) (2.2) Requirement already satisfied: ipaddress in /home/nico/vcs/master-thesis/support/virtualenv2/lib/python2.7/site-packages (from p4utils==0.2) (1.0.22) Requirement already satisfied: scapy in /home/nico/vcs/master-thesis/support/virtualenv2/lib/python2.7/site-packages (from p4utils==0.2) (2.4.2) Requirement already satisfied: psutil in /home/nico/vcs/master-thesis/support/virtualenv2/lib/python2.7/site-packages (from p4utils==0.2) (5.6.1) Requirement already satisfied: decorator>=4.3.0 in /home/nico/vcs/master-thesis/support/virtualenv2/lib/python2.7/site-packages (from networkx->p4utils==0.2) (4.3.2) Installing collected packages: p4utils Found existing installation: p4utils 0.2 Not uninstalling p4utils at /home/nico/vcs/master-thesis/support/p4-utils-nsg, outside environment /home/nico/vcs/master-thesis/support/virtualenv2 Can't uninstall 'p4utils'. No files were found to uninstall. Running setup.py develop for p4utils Successfully installed p4utils (virtualenv2) [16:21] line:p4-utils-nsg%
log Try2: using virtualenv that uses site packages for using mininet
[17:13] line:support% virtualenv –system-site-packages virtualenv-with-site Running virtualenv with interpreter /usr/bin/python2 New python executable in /home/nico/vcs/master-thesis/support/virtualenv-with-site/bin/python2 Also creating executable in /home/nico/vcs/master-thesis/support/virtualenv-with-site/bin/python Installing setuptools, pkg_resources, pip, wheel…done. [17:23] line:support% . ./virtualenv-with-site/bin/activate (virtualenv-with-site) [17:23] line:support% (virtualenv-with-site) [17:23] line:p4-utils-nsg% pip install -e . (virtualenv-with-site) [17:23] line:p4-utils-nsg% pip install -e . DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7. Obtaining /home/nico/vcs/master-thesis/support/p4-utils-nsg Requirement already satisfied: setuptools in /home/nico/vcs/master-thesis/support/virtualenv-with-site/lib/python2.7/site-packages (from p4utils==0.2) (40.8.0) Collecting networkx (from p4utils==0.2) Requirement already satisfied: ipaddress in /usr/lib/python2.7/dist-packages (from p4utils==0.2) (1.0.17) Requirement already satisfied: scapy in /usr/lib/python2.7/dist-packages (from p4utils==0.2) (2.4.0) Collecting psutil (from p4utils==0.2) Collecting decorator>=4.3.0 (from networkx->p4utils==0.2) Using cached https://files.pythonhosted.org/packages/f1/cd/7c8240007e9716b14679bc217a1baefa4432aa30394f7e2ec40a52b1a708/decorator-4.3.2-py2.py3-none-any.whl Installing collected packages: decorator, networkx, psutil, p4utils Running setup.py develop for p4utils Successfully installed decorator-4.3.2 networkx-2.2 p4utils psutil-5.6.1 (virtualenv-with-site) [17:23] line:p4-utils-nsg% which p4run /home/nico/vcs/master-thesis/support/virtualenv-with-site/bin/p4run (virtualenv-with-site) [17:24] line:p4-utils-nsg%
p4c –target bmv2 –arch v1model –std p4-16 "../p4src/static-mapping.p4" -o "/home/nico/vcs/master-thesis/p4src" ../p4src/static-mapping.p4(80): [–Wwarn=unused] warning: Table ndp_answer is not used; removing table ndp_answer { ^^^^^^^^^^ ../p4src/static-mapping.p4(96): [–Wwarn=unused] warning: Table port2mcast is not used; removing table port2mcast { ^^^^^^^^^^ ../p4src/static-mapping.p4(111): [–Wwarn=unused] warning: Table addr2mcast is not used; removing table addr2mcast { ^^^^^^^^^^ ../p4src/static-mapping.p4(128): [–Wwarn=unused] warning: Table ndp is not used; removing table ndp { ^^^ Switch port mapping: s1: 1:h1 2:h2 3:h3 4:h4 5:sw-cpu
Trying local vagrant VM
libvirtd missing user
root@line:~# libvirtd 2019-03-12 16:39:14.556+0000: 20235: info : libvirt version: 5.0.0, package: 1 (Guido Günther <agx@sigxcpu.org> Wed, 16 Jan 2019 10:31:33 +0100) 2019-03-12 16:39:14.556+0000: 20235: info : hostname: line 2019-03-12 16:39:14.556+0000: 20235: error : virGetUserID:1038 : invalid argument: Failed to parse user 'libvirt-qemu' 2019-03-12 16:39:14.556+0000: 20235: error : virStateInitialize:662 : Initialization of QEMU state driver failed: invalid argument: Failed to parse user 'libvirt-qemu' 2019-03-12 16:39:14.556+0000: 20235: error : daemonRunStateInit:799 : Driver state initialization failed root@line:~# useradd -m libvirt-qemu root@line:~#
root@line:~# strace -fF -e open libvirtd
strace: deprecated option -F ignored
strace: Process 20602 attached
strace: Process 20603 attached
strace: Process 20604 attached
strace: Process 20605 attached
strace: Process 20606 attached
strace: Process 20607 attached
strace: Process 20608 attached
strace: Process 20609 attached
strace: Process 20610 attached
strace: Process 20611 attached
strace: Process 20612 attached
strace: Process 20613 attached
strace: Process 20614 attached
strace: Process 20615 attached
strace: Process 20616 attached
strace: Process 20617 attached
strace: Process 20618 attached
[pid 20618] + exited with 0 +
[pid 20601] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20618, si_uid=0, si_status=0, si_utime=0, si_stime=0} —
strace: Process 20619 attached
[pid 20619] + exited with 0 +
[pid 20601] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20619, si_uid=0, si_status=0, si_utime=0, si_stime=0} —
strace: Process 20620 attached
strace: Process 20621 attached
strace: Process 20622 attached
[pid 20622] + exited with 0 +
[pid 20601] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20622, si_uid=0, si_status=0, si_utime=0, si_stime=0} —
strace: Process 20623 attached
[pid 20623] + exited with 0 +
[pid 20621] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20623, si_uid=0, si_status=0, si_utime=0, si_stime=0} —
strace: Process 20624 attached
[pid 20624] + exited with 0 +
[pid 20601] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20624, si_uid=0, si_status=0, si_utime=0, si_stime=0} —
strace: Process 20625 attached
[pid 20625] + exited with 0 +
[pid 20617] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20625, si_uid=0, si_status=0, si_utime=0, si_stime=0} —
strace: Process 20626 attached
[pid 20626] + exited with 0 +
[pid 20601] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20626, si_uid=0, si_status=0, si_utime=0, si_stime=0} —
strace: Process 20627 attached
[pid 20627] + exited with 0 +
[pid 20617] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20627, si_uid=0, si_status=0, si_utime=0, si_stime=0} —
strace: Process 20628 attached
[pid 20621] + exited with 0 +
strace: Process 20629 attached
strace: Process 20630 attached
strace: Process 20631 attached
strace: Process 20632 attached
strace: Process 20633 attached
[pid 20631] + exited with 0 +
[pid 20633] + exited with 1 +
[pid 20630] + exited with 0 +
[pid 20628] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20630, si_uid=1001, si_status=0, si_utime=0, si_stime=0} —
[pid 20632] + exited with 1 +
[pid 20629] + exited with 1 +
[pid 20628] + exited with 1 +
[pid 20601] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20628, si_uid=1001, si_status=1, si_utime=1, si_stime=0} —
2019-03-12 16:40:53.098+0000: 20617: info : libvirt version: 5.0.0, package: 1 (Guido Günther <agx@sigxcpu.org> Wed, 16 Jan 2019 10:31:33 +0100)
2019-03-12 16:40:53.098+0000: 20617: info : hostname: line
2019-03-12 16:40:53.098+0000: 20617: error : virQEMUCapsNewForBinaryInternal:4681 : internal error: Failed to probe QEMU binary with QMP: qemu-system-i386: cannot create PID file: Cannot open pid file: Permission denied
2019-03-12 16:40:53.098+0000: 20617: warning : virQEMUCapsLogProbeFailure:4628 : Failed to probe capabilities for /usr/bin/qemu-system-i386: internal error: Failed to probe QEMU binary with QMP: qemu-system-i386: cannot create PID file: Cannot open pid file: Permission denied
strace: Process 20634 attached
strace: Process 20635 attached
strace: Process 20636 attached
strace: Process 20637 attached
strace: Process 20638 attached
strace: Process 20639 attached
[pid 20637] + exited with 0 +
[pid 20639] + exited with 1 +
[pid 20636] + exited with 0 +
[pid 20634] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20636, si_uid=1001, si_status=0, si_utime=0, si_stime=0} —
[pid 20638] + exited with 1 +
[pid 20635] + exited with 1 +
[pid 20634] + exited with 1 +
[pid 20617] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20634, si_uid=1001, si_status=1, si_utime=1, si_stime=0} —
2019-03-12 16:40:53.145+0000: 20617: error : virQEMUCapsNewForBinaryInternal:4681 : internal error: Failed to probe QEMU binary with QMP: qemu-system-x86_64: cannot create PID file: Cannot open pid file: Permission denied
2019-03-12 16:40:53.145+0000: 20617: warning : virQEMUCapsLogProbeFailure:4628 : Failed to probe capabilities for /usr/bin/qemu-system-x86_64: internal error: Failed to probe QEMU binary with QMP: qemu-system-x86_64: cannot create PID file: Cannot open pid file: Permission denied
strace: Process 20640 attached
[pid 20640] + exited with 0 +
[pid 20617] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20640, si_uid=0, si_status=0, si_utime=0, si_stime=0} —
strace: Process 20641 attached
[pid 20641] + exited with 0 +
[pid 20617] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20641, si_uid=0, si_status=0, si_utime=0, si_stime=0} —
strace: Process 20642 attached
[pid 20642] + exited with 2 +
[pid 20601] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20642, si_uid=0, si_status=2, si_utime=0, si_stime=0} —
strace: Process 20643 attached
[pid 20643] + exited with 0 +
[pid 20617] — SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20643, si_uid=0, si_status=0, si_utime=0, si_stime=0} —
[pid 20617] + exited with 0 +
[pid 20601] — SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} —
^Cstrace: Process 20601 detached
strace: Process 20602 detached
strace: Process 20603 detached
strace: Process 20604 detached
strace: Process 20605 detached
strace: Process 20606 detached
strace: Process 20607 detached
strace: Process 20608 detached
strace: Process 20609 detached
strace: Process 20610 detached
strace: Process 20611 detached
strace: Process 20612 detached
strace: Process 20613 detached
strace: Process 20614 detached
strace: Process 20615 detached
strace: Process 20616 detached
strace: Process 20620 detached
Creating network
Adding hosts:
h1 h2 h3 h4
Adding switches:
Cannot find required executable simple_switch. Please make sure that it is installed and available in your $PATH: (home/nico/vcs/master-thesis/support/virtualenv-with-site/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/nico/vcs/master-thesis/support/p4c/build) (virtualenv-with-site) root@line:/home/nico/vcs/master-thesis/p4app#
TODO Setup test VM [dual stack] for Jool:
TODO Setup test VM [dual stack] for tayga:
NAT64/NAT46 Features in jool and tayga
TODO Static 1:1 NAT46: translate from IPv4 to IPv6 with a table
TODO TCP
TODO UDP
TODO ICMP <-> ICMPv6
TODO Stateless Prefix based NAT64: IPv6 to IPv4 translation prefix based
Allows IPv6 hosts to reach the IPv4 Internet
See time table above
Additional features queue (to be discussed)
TODO Offset based translation (v4->v6) -> same as range (?)
TODO IP address learning (v6/v4) for real life switch? How do hosts find it?
Thesis documentation
Introduction
Related work
RFC6052
- Defining well known prefix 64:ff9b::/96
- Defining embedding depending on prefix: /32../104 in 8 bit steps
- Longer than /96: suffix support
Motivation
TBD
Translation mechanisms
- v4 to v6 / vice versa
- Stateful / stateless
- static / dynamic
Explicit Address Mappings Table (EAMT)
Range based mapping tables See https://www.jool.mx/en/eamt.html, https://tools.ietf.org/html/rfc7757
Stateful NAT46
- Not needed
- IP address based translation is enough
Current state of the art tayga/jool
TBD
Tayga
- Single threaded
- Multi threaded work started due to initiative of ungleich / Chrisrock [IPv6.chat]
Jool
- EAMT bidirectional only (!)
IPtables interaction
```
user@T:~# # Create a Jool iptables instance named "example." user@T:~# # Also, establish that the IPv6 representation of any IPv4 address should be user@T:~# # `2001:db8::<IPv4 address>`. (See sections below for examples.) user@T:~# jool_siit instance add "example" –iptables –pool6 2001:db8::/96 user@T:~# user@T:~# # Tell iptables which traffic should be handled by our newly-created instance: user@T:~# user@T:~# # IPv6: only packets from 2001:db8::198.51.100.8/125 to 2001:db8::192.0.2 user@T:~# ip6tables -t mangle -A PREROUTING \ > -s 2001:db8::198.51.100.8/125 -d 2001:db8::192.0.2.0/120 \ > -j JOOL_SIIT –instance "example" user@T:~# # IPv4: Only packets from 192.0.2 to 198.51.100.8/29 user@T:~# iptables -t mangle -A PREROUTING \ > -s 192.0.2.0/24 -d 198.51.100.8/29 \ > -j JOOL_SIIT –instance "example" ``` 5656
Cisco (?)
TODO P4 based implementation
General
- IPv6 subnet 2001:db8::/32
- IPv6 hosts are in 2001:db8:6::/64
- IPv6 default router (::/0) is 2001:db8:6::42/64
- IPv4 mapped Internet "NAT64 prefix" 2001:db8:4444::/96 (should go into a table)
- 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
TODO IPv4 embedding
RFC6052
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|PL| 0-------------32--40--48--56--64--72--80--88--96--104---------|
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|32| prefix |v4(32) | u | suffix |
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|40| prefix |v4(24) | u |(8)| suffix |
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|48| prefix |v4(16) | u | (16) | suffix |
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|56| prefix |(8)| u | v4(24) | suffix |
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|64| prefix | u | v4(32) | suffix |
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|96| prefix | v4(32) |
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Bits 64..71 have to be 0 – ref rfc4291 - host identifier - why? Section 2.5.1 of rfc4291 "required to be unique within a subnet prefix" Modified EUI-64 format. Compare EUI-64: first 8 bits of mac address
inverting u bit from rfc 4291
the "u" bit is set to one (1) to indicate universal scope, and it is set to zero (0) to indicate local scope.
0 0 0 1 1 2
|0 7 8 5 6 3|
+----+----+----+----+----+----+
|cccc|ccug|cccc|cccc|cccc|cccc|
+----+----+----+----+----+----+
Neighbor discover protocol
Initial log
- Matching on prefix & ingress port, setting multicast
Being forwarded:
p4@ubuntu:~/master-thesis$ mx h1 tcpdump -ni h1-eth0 sudo: unable to resolve host ubuntu tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on h1-eth0, link-type EN10MB (Ethernet), capture size 262144 bytes ^C14:59:22.871803 IP6 2001:db8:62::1 > ff02::1:ff00:2: ICMP6, neighbor solicitation, who has 2001:db8:62::2, length 32 14:59:23.863913 IP6 2001:db8:62::1 > ff02::1:ff00:2: ICMP6, neighbor solicitation, who has 2001:db8:62::2, length 32 14:59:24.864033 IP6 2001:db8:62::1 > ff02::1:ff00:2: ICMP6, neighbor solicitation, who has 2001:db8:62::2, length 32
3 packets captured 3 packets received by filter 0 packets dropped by kernel
But no answer yet!
root@ubuntu:~/master-thesis/p4app# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: h1-eth0@if123: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9500 qdisc netem state UP group default qlen 1000 link/ether 00:00:0a:00:00:01 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 2001:db8:62::2/64 scope global valid_lft forever preferred_lft forever inet6 2001:db8:61::1/64 scope global valid_lft forever preferred_lft forever inet6 fe80::200:aff:fe00:1/64 scope link valid_lft forever preferred_lft forever root@ubuntu:~/master-thesis/p4app#
Link local communication does not work:
root@ubuntu:~/master-thesis/p4app# ping6 -c1 fe80::200:aff:fe00:2%h1-eth0 PING fe80::200:aff:fe00:2%h1-eth0(fe80::200:aff:fe00:2) 56 data bytes From fe80::200:aff:fe00:1 icmp_seq=1 Destination unreachable: Address unreachable
— fe80::200:aff:fe00:2%h1-eth0 ping statistics — 1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms
root@ubuntu:~/master-thesis/p4app#
Packet is received on the other host, but not answered. Why?
Real trace from my network:
18:48:17.008524 IP6 2a0a:e5c1:111:111:eb7:ffdb:e245:f712 > ff02::1:ffb7:e225: ICMP6, neighbor solicitation, who has 2a0a:e5c1:111:111:1016:3c5a:38b7:e225, length 32 18:48:18.015016 IP6 2a0a:e5c1:111:111:eb7:ffdb:e245:f712 > ff02::1:ffb7:e225: ICMP6, neighbor solicitation, who has 2a0a:e5c1:111:111:1016:3c5a:38b7:e225, length 32 18:48:18.031165 IP6 2a0a:e5c1:111:111:1016:3c5a:38b7:e225 > 2a0a:e5c1:111:111:eb7:ffdb:e245:f712: ICMP6, neighbor advertisement, tgt is 2a0a:e5c1:111:111:1016:3c5a:38b7:e225, length 32 18:48:18.031236 IP6 2a0a:e5c1:111:111:eb7:ffdb:e245:f712 > 2a0a:e5c1:111:111:1016:3c5a:38b7:e225: ICMP6, echo request, seq 1, length 64 18:48:18.031267 IP6 2a0a:e5c1:111:111:eb7:ffdb:e245:f712 > 2a0a:e5c1:111:111:1016:3c5a:38b7:e225: ICMP6, echo request, seq 2, length 64 18:48:18.131709 IP6 2a0a:e5c1:111:111:1016:3c5a:38b7:e225 > 2a0a:e5c1:111:111:eb7:ffdb:e245:f712: ICMP6, echo reply, seq 1, length 64 18:48:18.131732 IP6 2a0a:e5c1:111:111:1016:3c5a:38b7:e225 > 2a0a:e5c1:111:111:eb7:ffdb:e245:f712: ICMP6, echo reply, seq 2, length 64
root@ubuntu:~/master-thesis/p4app# cat /proc/sys/net/ipv6/conf/*/disable_ipv6 1 1 0 0 root@ubuntu:~/master-thesis/p4app# root@ubuntu:~/master-thesis/p4app# ls -1 /proc/sys/net/ipv6/conf/*/disable_ipv6 /proc/sys/net/ipv6/conf/all/disable_ipv6 /proc/sys/net/ipv6/conf/default/disable_ipv6 /proc/sys/net/ipv6/conf/h1-eth0/disable_ipv6 /proc/sys/net/ipv6/conf/lo/disable_ipv6 root@ubuntu:~/master-thesis/p4app#
Works on mininet
mininet> h2 bash root@line:~# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: h2-eth0@if93: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 32:0e:1e:bf:3c:4b brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.0.0.2/8 brd 10.255.255.255 scope global h2-eth0 valid_lft forever preferred_lft forever inet6 fe80::300e:1eff:febf:3c4b/64 scope link valid_lft forever preferred_lft forever root@line:~# ip addr add 2001:db8:61::42/64 dev h2-eth0 root@line:~# ^Dexit mininet> h1 bash root@line:~# ip addr add 2001:db8:61::42/64^[[D^[[D^?^?^?^?^?^?^?^?^?^?^?^C^C root@line:~# ^Dexit mininet> h1 ip addr add 2001:db8:61::2/64 dev h1-eth0 mininet> h2 ping6 -c2 2001:db8:61::2 PING 2001:db8:61::2(2001:db8:61::2) 56 data bytes 64 bytes from 2001:db8:61::2: icmp_seq=1 ttl=64 time=0.230 ms 64 bytes from 2001:db8:61::2: icmp_seq=2 ttl=64 time=0.138 ms
— 2001:db8:61::2 ping statistics — 2 packets transmitted, 2 received, 0% packet loss, time 1018ms rtt min/avg/max/mdev = 0.138/0.184/0.230/0.046 ms mininet>
mininet on VM also works
mininet> h1 ip addr add 2001:db8:61::1/64 dev h1-eth0 mininet> h2 ip addr add 2001:db8:61::2/64 dev h2-eth0 mininet> h2 ping6 -c2 2001:db8:61::2 PING 2001:db8:61::2(2001:db8:61::2) 56 data bytes 64 bytes from 2001:db8:61::2: icmp_seq=1 ttl=64 time=0.053 ms 64 bytes from 2001:db8:61::2: icmp_seq=2 ttl=64 time=0.082 ms
— 2001:db8:61::2 ping statistics — 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 0.053/0.067/0.082/0.016 ms mininet>
WORKING trace on mininet on the VM
19:38:49.852088 IP6 2001:db8:61::2 > ff02::1:ff00:1: ICMP6, neighbor solicitation, who has 2001:db8:61::1, length 32 19:38:49.852144 IP6 2001:db8:61::1 > 2001:db8:61::2: ICMP6, neighbor advertisement, tgt is 2001:db8:61::1, length 32 19:38:49.852163 IP6 2001:db8:61::2 > 2001:db8:61::1: ICMP6, echo request, seq 1, length 64 19:38:49.852176 IP6 2001:db8:61::1 > 2001:db8:61::2: ICMP6, echo reply, seq 1, length 64
checking ipv6 in p4-utils
p4@ubuntu:~/p4-utils$ grep -ri ipv6 . ./p4utils/mininetlib/p4_mininet.py: # disable IPv6 ./p4utils/mininetlib/p4_mininet.py: self.cmd("sysctl -w net.ipv6.conf.all.disable_ipv6=1") ./p4utils/mininetlib/p4_mininet.py: self.cmd("sysctl -w net.ipv6.conf.default.disable_ipv6=1") ./p4utils/mininetlib/p4_mininet.py: self.cmd("sysctl -w net.ipv6.conf.lo.disable_ipv6=1") ./p4utils/mininetlib/p4net.py: #remove Ipv6 for all the interfaces ./p4utils/mininetlib/p4net.py: cmd2 = "sysctl net.ipv6.conf.{0}.disable_ipv6=1" ./p4utils/mininetlib/p4net.py: #remove ipv6 Binary file ./p4utils/mininetlib/p4_mininet.pyc matches Binary file ./p4utils/mininetlib/p4net.pyc matches Binary file ./p4utils/utils/runtime_API.pyc matches ./p4utils/utils/runtime_API.py:class UIn_BadIPv6Error(UIn_Error): ./p4utils/utils/runtime_API.py:def ipv6Addr_to_bytes(addr): ./p4utils/utils/runtime_API.py: from ipaddr import IPv6Address ./p4utils/utils/runtime_API.py: ip = IPv6Address(addr) ./p4utils/utils/runtime_API.py: raise UIn_BadIPv6Error() ./p4utils/utils/runtime_API.py: raise UIn_BadIPv6Error() ./p4utils/utils/runtime_API.py: return ipv6Addr_to_bytes(input_str) ./p4utils/utils/runtime_API.py: except UIn_BadIPv6Error: ./p4utils/utils/runtime_API.py: raise UIn_BadParamError("Invalid IPv6 address") p4@ubuntu:~/p4-utils$
Messages we see in the controller on startup
DEBUG:main:INCOMING: <Ether dst=33:33:00:00:00:16 src=00:00:0a:00:00:02 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=56 nh=Hop-by-Hop Option Header hlim=1 src=:: dst=ff02::16 |<IPv6ExtHdrHopByHop nh=ICMPv6 len=0 autopad=On options=[<RouterAlert otype=Router Alert [00: skip, 0: Don't change en-route] optlen=2 value=Datagram contains a MLD message |>, <PadN otype=PadN [00: skip, 0: Don't change en-route] optlen=0 |>] |<ICMPv6MLReport2 type=MLD Report Version 2 res=0 cksum=0x6d6d reserved=0 records_number=2 records=[<ICMPv6MLDMultAddrRec rtype=4 auxdata_len=0 sources_number=0 dst=ff02::1:ff00:1 sources=[ ] auxdata='' |<ICMPv6MLDMultAddrRec rtype=4 auxdata_len=0 sources_number=0 dst=ff02::1:ff00:2 |>>] |>>>> DEBUG:main:INCOMING: <Ether dst=33:33:00:00:00:16 src=00:01:0a:00:00:02 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=36 nh=Hop-by-Hop Option Header hlim=1 src=fe80::201:aff:fe00:2 dst=ff02::16 |<IPv6ExtHdrHopByHop nh=ICMPv6 len=0 autopad=On options=[<RouterAlert otype=Router Alert [00: skip, 0: Don't change en-route] optlen=2 value=Datagram contains a MLD message |>, <PadN otype=PadN [00: skip, 0: Don't change en-route] optlen=0 |>] |<ICMPv6MLReport2 type=MLD Report Version 2 res=0 cksum=0x6604 reserved=0 records_number=1 records=[<ICMPv6MLDMultAddrRec rtype=4 auxdata_len=0 sources_number=0 dst=ff02::1:ff00:2 |>] |>>>> DEBUG:main:INCOMING: <Ether dst=33:33:00:00:00:16 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=36 nh=Hop-by-Hop Option Header hlim=1 src=fe80::200:aff:fe00:1 dst=ff02::16 |<IPv6ExtHdrHopByHop nh=ICMPv6 len=0 autopad=On options=[<RouterAlert otype=Router Alert [00: skip, 0: Don't change en-route] optlen=2 value=Datagram contains a MLD message |>, <PadN otype=PadN [00: skip, 0: Don't change en-route] optlen=0 |>] |<ICMPv6MLReport2 type=MLD Report Version 2 res=0 cksum=0x6607 reserved=0 records_number=1 records=[<ICMPv6MLDMultAddrRec rtype=4 auxdata_len=0 sources_number=0 dst=ff02::1:ff00:1 |>] |>>>> DEBUG:main:INCOMING: <Ether dst=33:33:00:00:00:02 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=16 nh=ICMPv6 hlim=255 src=fe80::200:aff:fe00:1 dst=ff02::2 |<ICMPv6ND_RS type=Router Solicitation code=0 cksum=0xf72e res=0 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>> DEBUG:main:INCOMING: <Ether dst=33:33:00:00:00:16 src=00:00:0a:00:00:02 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=56 nh=Hop-by-Hop Option Header hlim=1 src=:: dst=ff02::16 |<IPv6ExtHdrHopByHop nh=ICMPv6 len=0 autopad=On options=[<RouterAlert otype=Router Alert [00: skip, 0: Don't change en-route] optlen=2 value=Datagram contains a MLD message |>, <PadN otype=PadN [00: skip, 0: Don't change en-route] optlen=0 |>] |<ICMPv6MLReport2 type=MLD Report Version 2 res=0 cksum=0x6d6d reserved=0 records_number=2 records=[<ICMPv6MLDMultAddrRec rtype=4 auxdata_len=0 sources_number=0 dst=ff02::1:ff00:1 sources=[ ] auxdata='' |<ICMPv6MLDMultAddrRec rtype=4 auxdata_len=0 sources_number=0 dst=ff02::1:ff00:2 |>>] |>>>> DEBUG:main:INCOMING: <Ether dst=33:33:00:00:00:16 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=36 nh=Hop-by-Hop Option Header hlim=1 src=fe80::200:aff:fe00:1 dst=ff02::16 |<IPv6ExtHdrHopByHop nh=ICMPv6 len=0 autopad=On options=[<RouterAlert otype=Router Alert [00: skip, 0: Don't change en-route] optlen=2 value=Datagram contains a MLD message |>, <PadN otype=PadN [00: skip, 0: Don't change en-route] optlen=0 |>] |<ICMPv6MLReport2 type=MLD Report Version 2 res=0 cksum=0x6607 reserved=0 records_number=1 records=[<ICMPv6MLDMultAddrRec rtype=4 auxdata_len=0 sources_number=0 dst=ff02::1:ff00:1 |>] |>>>> DEBUG:main:INCOMING: <Ether dst=33:33:00:00:00:16 src=00:00:0a:00:00:02 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=56 nh=Hop-by-Hop Option Header hlim=1 src=fe80::200:aff:fe00:2 dst=ff02::16 |<IPv6ExtHdrHopByHop nh=ICMPv6 len=0 autopad=On options=[<RouterAlert otype=Router Alert [00: skip, 0: Don't change en-route] optlen=2 value=Datagram contains a MLD message |>, <PadN otype=PadN [00: skip, 0: Don't change en-route] optlen=0 |>] |<ICMPv6MLReport2 type=MLD Report Version 2 res=0 cksum=0x63ea reserved=0 records_number=2 records=[<ICMPv6MLDMultAddrRec rtype=4 auxdata_len=0 sources_number=0 dst=ff02::1:ff00:1 sources=[ ] auxdata='' |<ICMPv6MLDMultAddrRec rtype=4 auxdata_len=0 sources_number=0 dst=ff02::1:ff00:2 |>>] |>>>> DEBUG:main:INCOMING: <Ether dst=33:33:00:00:00:02 src=00:00:0a:00:00:02 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=16 nh=ICMPv6 hlim=255 src=fe80::200:aff:fe00:2 dst=ff02::2 |<ICMPv6ND_RS type=Router Solicitation code=0 cksum=0xf72d res=0 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:02 |>>>> DEBUG:main:INCOMING: <Ether dst=33:33:00:00:00:16 src=00:00:0a:00:00:02 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=56 nh=Hop-by-Hop Option Header hlim=1 src=fe80::200:aff:fe00:2 dst=ff02::16 |<IPv6ExtHdrHopByHop nh=ICMPv6 len=0 autopad=On options=[<RouterAlert otype=Router Alert [00: skip, 0: Don't change en-route] optlen=2 value=Datagram contains a MLD message |>, <PadN otype=PadN [00: skip, 0: Don't change en-route] optlen=0 |>] |<ICMPv6MLReport2 type=MLD Report Version 2 res=0 cksum=0x63ea reserved=0 records_number=2 records=[<ICMPv6MLDMultAddrRec rtype=4 auxdata_len=0 sources_number=0 dst=ff02::1:ff00:1 sources=[ ] auxdata='' |<ICMPv6MLDMultAddrRec rtype=4 auxdata_len=0 sources_number=0 dst=ff02::1:ff00:2 |>>] |>>>> DEBUG:main:INCOMING: <Ether dst=33:33:00:00:00:02 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=16 nh=ICMPv6 hlim=255 src=fe80::200:aff:fe00:1 dst=ff02::2 |<ICMPv6ND_RS type=Router Solicitation code=0 cksum=0xf72e res=0 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>> DEBUG:main:INCOMING: <Ether dst=33:33:00:00:00:02 src=00:00:0a:00:00:02 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=16 nh=ICMPv6 hlim=255 src=fe80::200:aff:fe00:2 dst=ff02::2 |<ICMPv6ND_RS type=Router Solicitation code=0 cksum=0xf72d res=0 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:02 |>>>> DEBUG:main:INCOMING: <Ether dst=33:33:00:00:00:02 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=16 nh=ICMPv6 hlim=255 src=fe80::200:aff:fe00:1 dst=ff02::2 |<ICMPv6ND_RS type=Router Solicitation code=0 cksum=0xf72e res=0 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>> DEBUG:main:INCOMING: <Ether dst=33:33:00:00:00:02 src=00:00:0a:00:00:02 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=16 nh=ICMPv6 hlim=255 src=fe80::200:aff:fe00:2 dst=ff02::2 |<ICMPv6ND_RS type=Router Solicitation code=0 cksum=0xf72d res=0 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:02 |>>>>
Ignored ICMPv6 packets
We are not using router advertisements, so we ignore RS packets DEBUG:main:INCOMING: <Ether dst=33:33:00:00:00:02 src=00:00:0a:00:00:01 type=0x86dd |<IPv6 version=6 tc=0 fl=0 plen=16 nh=ICMPv6 hlim=255 src=fe80::200:aff:fe00:1 dst=ff02::2 |<ICMPv6ND_RS type=Router Solicitation code=0 cksum=0xf72e res=0 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>>
Double table entries due to collision
- NDP: last 24 bit
- Switch has same ending address in different networks -> equal last 24 bit
- results in trying to add multicast address multiple times
Adding entry to exact match table v6_addresses match key: EXACT-ff:02:00:00:00:00:00:00:00:00:00:01:ff:00:00:42 action: controller_reply runtime data: 00:01 Invalid table operation (DUPLICATE_ENTRY) Adding entry to exact match table v6_addresses match key: EXACT-ff:02:00:00:00:00:00:00:00:00:00:01:ff:00:00:43 action: controller_reply runtime data: 00:01 Invalid table operation (DUPLICATE_ENTRY) Adding entry to exact match table v6_addresses match key: EXACT-20:01:0d:b8:00:00:00:01:00:00:00:00:00:00:00:43 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
ICMPv6
General / Intro
Different lengths possible
[20:35] line:~% ping -6 -s 20 ::1 PING ::1(::1) 20 data bytes 28 bytes from ::1: icmp_seq=1 ttl=64 time=0.045 ms 28 bytes from ::1: icmp_seq=2 ttl=64 time=0.064 ms ^C — ::1 ping statistics — 2 packets transmitted, 2 received, 0% packet loss, time 1018ms rtt min/avg/max/mdev = 0.045/0.054/0.064/0.012 ms [20:36] line:~% ping -6 -s 80 ::1 PING ::1(::1) 80 data bytes 88 bytes from ::1: icmp_seq=1 ttl=64 time=0.053 ms 88 bytes from ::1: icmp_seq=2 ttl=64 time=0.095 ms ^C — ::1 ping statistics — 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 0.053/0.074/0.095/0.021 ms [20:36] line:~%
Different checksum in most packets.
root@ubuntu:~/master-thesis# ip -6 neigh show root@ubuntu:~/master-thesis# ip -6 neigh add 2001:db8:61::42 dev h1-eth0 lladdr 00:00:0a:00:00:42 root@ubuntu:~/master-thesis# ip -6 neigh show 2001:db8:61::42 dev h1-eth0 lladdr 00:00:0a:00:00:42 PERMANENT root@ubuntu:~/master-thesis#
root@ubuntu:~/master-thesis# tcpdump -ni h1-eth0 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on h1-eth0, link-type EN10MB (Ethernet), capture size 262144 bytes ^C20:22:43.944152 IP6 2001:db8:61::1 > 2001:db8:61::42: ICMP6, echo request, seq 1, length 64 20:22:43.945992 IP6 2001:db8:61::1 > 2001:db8:61::42: ICMP6, echo request, seq 1, length 64 20:22:44.952453 IP6 2001:db8:61::1 > 2001:db8:61::42: ICMP6, echo request, seq 2, length 64 20:22:44.953995 IP6 2001:db8:61::1 > 2001:db8:61::42: ICMP6, echo request, seq 2, length 64
4 packets captured 4 packets received by filter 0 packets dropped by kernel root@ubuntu:~/master-thesis#
When pinging we see
DEBUG:main:INCOMING: <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:61::1 dst=ff02::1:ff00:42 |<ICMPv6ND_NS type=Neighbor Solicitation code=0 cksum=0xd343 res=0 tgt=2001:db8:61::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>> DEBUG:main:INCOMING: <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:61::1 dst=ff02::1:ff00:42 |<ICMPv6ND_NS type=Neighbor Solicitation code=0 cksum=0xd343 res=0 tgt=2001:db8:61::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>> DEBUG:main:INCOMING: <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:61::1 dst=ff02::1:ff00:42 |<ICMPv6ND_NS type=Neighbor Solicitation code=0 cksum=0xd343 res=0 tgt=2001:db8:61::42 |<ICMPv6NDOptSrcLLAddr type=1 len=1 lladdr=00:00:0a:00:00:01 |>>>>
Hosts
Left side: IPv6
Right side: IPv4
Included in the header
DONE Supported feature: NDP NA/NS
- For resolving mac address
- Initially controller
- Ported into switch
DONE Supported feature: icmp6 echo reply
p4@ubuntu:~/master-thesis/p4app$ python test.py –method ping6_switch PING 2001:db8::42(2001:db8::42) 56 data bytes 64 bytes from 2001:db8::42: icmp_seq=1 ttl=64 time=3.05 ms
— 2001:db8::42 ping statistics — 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 3.055/3.055/3.055/0.000 ms p4@ubuntu:~/master-thesis/p4app$
Requirements
Static NAT64
Asymmetric maps: v6->v4 can match whole IPv4 Internet (/96) But v4->v6 can only map sub range! Using /24s (for convience) in IPv4
Development mode/loop
Code - commit - push - pull - restart switch - check whether all tables are present (missing .apply()) restart controller - check whether tables are applied correctly (type conversion problems) - start tcpdump - start test program - stop tcpdump - add pcap to git repo - git add-commit-push - git pull - start wireshark - debug packets - analyse code - goto 1
Setting up a system for working on P4 on devuan
Scripts in the wild
mininet
bmv2
[21:24] line:~% sudo apt install libthrift-dev [21:26] line:~% sudo apt install thrift-compiler libnanomsg-dev libjudy-dev
TODO Session / dynamice mappings
General
- Have 1..n session IPv4 addresses
- Handle outgoing IPv6: create new session
- Handle in
TODO Case IPv6 initiator
- Mapping whole IPv4 Internet in /96 prefix
- Session information for mapping reply
- Timeout handling in controller
- Got 4-5 tuple ([proto], src ip, src port, dst ip, dst port)
- Does not / never signal end
- Needs timeout for cleaning up
- Similar to udp
- react on FIN/RST (?) – could be an addition
- usual protocol specific changes
- Session??
- src ip, dst ip, code ?
TODO Case IPv4 initiator
- Needs upper level protol
TODO General network matching
DONE Create table(s)
DONE Fill it up from the controller: general network
TODO Create controller session handler
- controller selects "outgoing" IPv4 address range => base for sessions
- IPv4 addresses can be "random" (in our test case), but need to be unique
- switch does not need to know about the "range", only about sessions
- on session create, controller selects "random" ip (ring?)
- on session create, controller selects "random port" (next in range?)
- on session create controller adds choice into 2 tables: incoming, outgoing
DONE Feed back to controller: implemented in switch
DONE Create ipv6 session in the controller
Create ipv4 session in the controller
TODO Ensure translation code works
TODO tcp session
TODO udp session
TODO tcp session
TODO Comparison with existing tools (Performance, Features)
Features
What? | Description | State in P4 | References |
---|---|---|---|
Jool EAMT | Mapping with tables, multiple entries | Supported | https://www.jool.mx/en/eamt.html, https://www.jool.mx/en/run-eam.html, RFC 7757 |
Jool SIIT | Mapping IPv6 to range of IPv4, one entry | Supported by EAMT | |
Jool Stateful NAT64 | https://www.jool.mx/en/intro-xlat.html#stateful-nat64 | ||
https://www.jool.mx/en/run-nat64.html |
P4 Possible Improvements / Current Challenges / Limitations
DONE cannot read key from table
log
Key and mask for matching destination is in table. We need this information in the action. However this information is not exposed, so we need to specify another parameter with the same information as in the key(s).
Log from slack: (2019-03-14)
nico [1:55 PM] If I use LPM for matching, can I easily get the network address from P4 or do I have to use a bitmask myself? In the latter case it is not exactly clear how to get the mask from the table
Nate Foster [1:58 PM] You want to retrieve the address in the packet? In a table? And do you want to do the retrieving from the data plane or the control plane? (edited)
nico [2:00 PM] If I have a match in a table that matches on LPM, it can be any IP address in a network For calculating the NAT64/NAT46 translation, I will need the base address, i.e. network address to do subtractions/additions So it is fully data plane, what I would like to do I'll commit sample code to show the use case more clearly https://gitlab.ethz.ch/nicosc/master-thesis/blob/master/p4src/static-mapping.p4#L73 GitLab p4src/static-mapping.p4 · master · nicosc / master-thesis gitlab.ethz.ch So the action nat64_static() is used in the table v6_networks. In v6_networks I use a match on `hdr.ipv6.dst_addr: lpm;` What I would like to be able is to get the network address ; I can do that manually, if I have the mask I can also re-inject this parameter by another action argument, but I'd assume that I can somewhere read this out from the table / match
Nate Foster [2:15 PM] To make sure I understand, in the data plane, you want to retrieve the address in the lpm pattern? (edited)
nico [2:16 PM] I want to retrieve the key
Nate Foster [2:16 PM] Wait. The value `hdr.ipv6.dst_addr` is the thing used in the match. So you have that. What you don’t have is the IPv6 address and mask put into the table by the control plane. I assume you want the latter, right?
nico [2:17 PM] For example, if my matching key is 2001:db8::/32 and the real address is 2001:db8::f00, then I would like to retrieve 2001:db8:: and 32 from the table exactly 🙂 I can "fix" this by adding another argument, but it feels somewhat wrong to do that Because the table already knows this information
Nate Foster [2:26 PM] I can’t think of a way other than the action parameter hack.
nico [2:26 PM] Oh, ok Is it because the information is "lost in hardware"?
Nate Foster [2:31 PM] No you’re right that most implementations have the value in memory. And one can imagine a different table API that allowed one to retrieve it in the data plane. But unless I am missing something obvious, P4 hides it…
Result
Need to duplicate information
DONE ICMP6: checksum over payload
- variable length, up to 65k
Exists!
DONE Synchronisation with the controller
- Double data type definition -> might differ
- TYPE_CPU for ethernet
- Port ingress offset (9 vs. 16 bit)
p4c expression bug 2019-03-30
Hit in master-thesis 0.4-28-g881643e
Warning: you requested the nanomsg event logger, but bmv2 was compiled without -DBMELOG, and the event logger cannot be activated
Calling target program-options parser
[14:01:44.334] [bmv2] [D] [thread 23356] Set default default entry for table 'MyIngress.icmp6': MyIngress.controller_debug_table_id - 2,
[14:01:44.341] [bmv2] [D] [thread 23356] Set default default entry for table 'MyIngress.nat64': MyIngress.controller_debug_table_id - 1,
[14:01:44.344] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_act': act -
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_act_0': act_0 -
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_nat64_icmp6_generic': MyIngress.nat64_icmp6_generic -
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_act_1': act_1 -
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_act_2': act_2 -
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'MyIngress.v4_networks': MyIngress.controller_debug_table_id - 5,
[14:01:44.345] [bmv2] [D] [thread 23356] Set default default entry for table 'MyIngress.v6_networks': MyIngress.controller_debug_table_id - 3,
[14:01:44.346] [bmv2] [D] [thread 23356] Set default default entry for table 'tbl_act_3': act_3 -
Invalid entry type 'expression' in field list
bad json:
{
"type" : "expression",
"value" : {
"type" : "expression",
"value" : {
"left" : null,
"op" : "d2b",
"right" : {
"type" : "field",
"value" : [ "scalars", "metadata.chk_icmp6_na_ns" ]
}
}
}
}
DONE Only one LPM key supported in tables (2019-03-23)
Priority support in ternary possible. Means rewriting for developers. Could possibly be supported by switching to ternary mode internally.
../p4src/static-mapping.p4(121): error: MyIngress.nat64, Multiple LPM keys in table
table nat64 {
^^^^^
Compilation Error
Code:
table nat64 {
key = {
hdr.ipv6.src_addr: lpm;
hdr.ipv6.dst_addr: lpm;
}
actions = {
controller_debug;
nat64_static;
NoAction;
}
size = NAT64_TABLE_SIZE;
default_action = controller_debug;
}
No table meta information for default actions (asked 2019-03-25)
Is there any meta information for "from which table was the action called" available? My use case is having a debug action that sends packets to the controller and I use it as a default_action in various tables; however know I don't know anymore from which table the action was called. Is there any kind of meta information which table called me available?
I could work around this by using if(! .. .hit) { my_action(table_id) }, but it would not work with using default_action = …
DONE No switch in actions, No conditional execution in actions
3 possible solutions
- multi table (state as of 2019-03-28)
- switch/if in actions: with shadow tables
- switch/if in apply block
log
Imho, compiler should be able to unroll these to some degree.
../p4src/static-mapping.p4(60): error: SwitchStatement: switch statements not allowed in actions
switch(hdr.icmp6.type) {
^^^^^^
../p4src/static-mapping.p4(57): error: MethodCallStatement: Conditional execution in actions is not supported on this target
hdr.icmp.setValid();
^^^^^^^^^^^^^^^^^^^
../p4src/static-mapping.p4(70): error: MethodCallStatement: Conditional execution in actions is not supported on this target
hdr.icmp6.setInvalid();
^^^^^^^^^^^^^^^^^^^^^^
../p4src/static-mapping.p4(73): error: MethodCallStatement: Conditional execution in actions is not supported on this target
hdr.icmp6_na_ns.setInvalid();
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
../p4src/static-mapping.p4(74): error: MethodCallStatement: Conditional execution in actions is not supported on this target
hdr.icmp6_option_link_layer_addr.setInvalid();
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Compilation Error
p4@ubuntu:~/master-thesis/p4app$
Code:
if(hdr.ipv6.next_header == PROTO_ICMP6) {
nat64_icmp6();
}
TODO Modules, OS
Not addressed so far: how to create re-usable code fragments that can be plugged in easily. There could be a hypothetical "P4OS" that manages code fragments. This might include, but not limited to downloading (signed?) source code, managing dependencies similar to Linux package management, handling updates, etc.
TODO Code sharing (controller, switch)
Many constants double defined. Easy to make errors.
Implementation description and limitations
Implementation description [move todos here]
TODO Support (non-) fragmentation
- if DF bit is not set in ipv4
TODO Supporting [different] MTUs
- sizes of headers are different
- packet might not fit into same mtu anymore
- send back "ICMP Packet Too Big messages to the sender." RFC7915
TODO pmtud support
- mss change
translator MUST send a Packet Too Big error message or fragment the packet when the packet size exceeds the MTU of the next-hop interface.
Limitations
IPv4 embedding (RFC6052, RFC4291)
Supported is similar to the "IPv4-Compatible IPv6 Address" as defined by rfc4291 section 2.5.5.1. Longer prefixes can be specified, but effectively last part used. Not ensuring 16 0 bits. Deprecated according to RFC4291.
Also section 2.5.5.2 "IPv4-Mapped IPv6 Address"
- Only correctly support /96 prefix
- Other modes also embed in last 32 bits
- However supports any prefix length >= 96
Mac addresses: bit 0 = unicast (0)/multicast(1), bit 1 = local (1)/global (0) - site wiki/mac
U/L bit is universal/local, bit 2; inverting: local = 0, global = 1
No fragmentation support (yet)
In line with RFC7915
Fragmented ICMP/ICMPv6 packets will not be translated by IP/ICMP translators.
No session handling (yet)
1:1 mappings. No (automatic) session.
IPv4 / IPv6 embedding
Currently offset based - probably not following the RFC!
No DNS64
has already been solved in a different domain - could even do transparent / in network modification
Incomplete NDP
Very limited option support
NAT64 mappings not source network dependent
Only the destination network is matched for deciding on NAT64, as priority based double LPM is not supported. This limits a prefix to be used only in one network.
TODO No resolution of hardware addresses
- hardcoded ip –> mac addresses
Correct version: Resolve mac address in controller, buffer packet, replay packet / handle packet. Only has to be set, when packets originate from the switch/controller.
TODO No support of IPv4 options
- header is assumed to be always 20 octets
TODO Security issue: not checking checksums before
- Could be implemented
References / Follow up
RFC 791 IPv4 https://tools.ietf.org/html/rfc791
RFC 792 ICMP https://tools.ietf.org/html/rfc792
RFC 826 ARP https://tools.ietf.org/html/rfc826
RFC 1017 ICMP checksum https://tools.ietf.org/html/rfc1071
- Related to RFC 6052, Host identifier
RFC 2373 IP Version 6 Addressing Architecture
- Referenced by RFC2464
- Obsoleted by RFC3513
RFC 2460 IPv6 (Checksum https://tools.ietf.org/html/rfc2460#section-8.1)
RFC 2464 Transmission of IPv6 Packets over Ethernet Networks https://tools.ietf.org/html/rfc2464
- embedding of Mac addresses
RFC 3810 MLD2 https://tools.ietf.org/html/rfc3810
RFC 4038 Application Aspects of IPv6 Transition https://tools.ietf.org/html/rfc4038
- Ref by RFC4291 / mapped ipv4
RFC 4291 IP Version 6 Addressing Architecture https://tools.ietf.org/html/rfc4291
-!
RFC 4443 ICMPv6 https://tools.ietf.org/html/rfc4443
RFC 4861: https://tools.ietf.org/html/rfc4861 Neighbor discovery
RFC 6052: https://tools.ietf.org/html/rfc6052 IPv6 Addressing of IPv4/IPv6 Translators - first NAT64??
RFC 6145 IP/ICMP Translation Algorithm
- Obsoleted by 7915
RFC 6146 Stateful nat http://tools.ietf.org/html/rfc6146
- Referenced from Jool
RFC 6147 DNS64 https://tools.ietf.org/html/rfc6147
RFC 6586 for deployment experiences using Stateful NAT64.
RFC 7757 Explicit Address Mappings for Stateless IP/ICMP Translation - https://tools.ietf.org/html/rfc7757
RFC 7915 IP/ICMP Translation Algorithm https://tools.ietf.org/html/rfc7915
- Requires RFC 6144
- MUST support one or more address mapping algorithms, which are defined in Section 6.
- does not translate IPv6 extension headers except the Fragment Header.
EAMT/Jool: https://www.jool.mx/en/eamt.html
Solicited node multicast address https://en.wikipedia.org/wiki/Solicited-node_multicast_address
DONE Initial administration
DONE Clarify PDF / form with Denise Spicher: free form description
DONE Create task description to be handed in mystudies
DONE Create list of tasks / initial brainstorming
DONE Get OK from Ueli Maurer that thesis is valid in Information Security Area
DONE Find out how-when-whom-where to meet / define schedule
DONE Latex and/or org-mode for the thesis? org for starting
DONE Add initial milestones
180d plan
25w
DONE Proposal / task description
Task description for mystudies
High speed NAT64 with P4
Currently there are two main open source NAT64 solution available: tayga and jool. The former is a single threaded, cpu bound user space solution, the latter a custom Linux kernel module.
This thesis challenges this status quo by developing a P4 based solution supporting all features of jool/tayga and comparing the performance, security and adaptivity of the solutions.
- Milestone 1: Stateless NAT64/NAT46 translations in P4
- Milestone 2: Stateful (dynamic) NAT64/NAT46 translations
- Milestone 3: Hardware adaption
Original ideas
Proposal 1: Automating NAT64 with P4
In IPv6 only data centers IPv4 connectivity is still a business requirement. Current state of the art methods include layer 7 proxying or static assignments. both featuring static assignments.
A flexible, dynamic assignment of IPv4 addresses to IPv6 hosts, similar to lease times in DHCPv4 and prefix delegations in DHCPv6 could reduce the pressure on IPv4 addresses.
I would suggest the develop of a new protocol (likely UDP embedded) that allows hosts to request on-network support for IPv4 addresses. As IPv4 addresses have to be treated as "expensive", an accounting metric has to be introduced. While in the business world this is usually related to money, in the network world IPv4 users could be paying the network by (reduced) bandwidth.
If such a metric existed, devices attached to the network could also try to negotiate and wait for using IPv4, when the price / penality for IPv4 is low (this might be very suitable for mail exchangers for instance).
Proposal 2: High speed NAT64 with P4
Currently there are two main open source NAT64 solution available: tayga[0] and jool[1]. The former is a single threaded, cpu bound user space solution, the latter a custom Linux kernel module.
I would like to challenge this status quo and develop a P4 based solution supporting all features of jool/tayga and comparing the performance and adaptivity of the solutions.
[0] http://www.litech.org/tayga/ [1] https://www.jool.mx/en/index.html
Proposal 3: Challenging the status quo with IPv10
The de facto standard in networking is to treat IPv4 and IPv6 as "impossible to combine". This proposal is to challenge this notion with three different methods:
- Extensions to IPv4 to request remote IPv6 transport
- Extensions to IPv6 to request remote IPv4 transport
- Support in network equipment to handle the extensions
As the IPv4 header does not allow embedding IPv6 addresses due to size limitations, embedding the destination address in a secondary header might be necessary (possibly encapsulated in UDP).