Transport table debug information to controller
This commit is contained in:
parent
e1146070c4
commit
9ca4d4c8de
4 changed files with 88 additions and 26 deletions
52
doc/plan.org
52
doc/plan.org
|
@ -422,7 +422,24 @@ Problem: task field might be overriden for controller use in different
|
||||||
table -> need different task field!
|
table -> need different task field!
|
||||||
|
|
||||||
***** try2: checksum ok, but no packets on h3
|
***** try2: checksum ok, but no packets on h3
|
||||||
****** Setup a default rule for the IPv4 world to debug on controller
|
****** 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!
|
||||||
|
|
||||||
|
|
||||||
*** TODO Get p4 VM / vagrant running
|
*** TODO Get p4 VM / vagrant running
|
||||||
**** DONE install libvirtd-daemon
|
**** DONE install libvirtd-daemon
|
||||||
|
@ -1219,8 +1236,8 @@ debug packets - analyse code - goto 1
|
||||||
[21:26] line:~% sudo apt install thrift-compiler
|
[21:26] line:~% sudo apt install thrift-compiler
|
||||||
libnanomsg-dev libjudy-dev
|
libnanomsg-dev libjudy-dev
|
||||||
*** Performance comparison
|
*** Performance comparison
|
||||||
*** Feature/Functionality difference / overview / CHALLENGES / LIMITATIONS in P4
|
*** Challenges / Limitations in P4
|
||||||
**** P4: cannot read key from table
|
**** DONE cannot read key from table
|
||||||
***** log
|
***** log
|
||||||
Key and mask for matching destination is in table. We need this
|
Key and mask for matching destination is in table. We need this
|
||||||
information in the action. However this information is not exposed, so
|
information in the action. However this information is not exposed, so
|
||||||
|
@ -1285,7 +1302,7 @@ Need to duplicate information
|
||||||
**** DONE ICMP6: checksum over payload
|
**** DONE ICMP6: checksum over payload
|
||||||
- variable length, up to 65k
|
- variable length, up to 65k
|
||||||
Exists!
|
Exists!
|
||||||
**** Synchronisation with the controller
|
**** DONE Synchronisation with the controller
|
||||||
- Double data type definition -> might differ
|
- Double data type definition -> might differ
|
||||||
- TYPE_CPU for ethernet
|
- TYPE_CPU for ethernet
|
||||||
- Port ingress offset (9 vs. 16 bit)
|
- Port ingress offset (9 vs. 16 bit)
|
||||||
|
@ -1315,18 +1332,29 @@ Code:
|
||||||
}
|
}
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
**** (current) Implementation limitations
|
**** No table meta information for default actions (asked 2019-03-25)
|
||||||
***** No fragmentation support (yet)
|
Is there any meta information for "from which table was the action
|
||||||
***** No session handling (yet)
|
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 = ...
|
||||||
|
|
||||||
|
*** Implementation limitations
|
||||||
|
**** No fragmentation support (yet)
|
||||||
|
**** No session handling (yet)
|
||||||
1:1 mappings. No (automatic) session.
|
1:1 mappings. No (automatic) session.
|
||||||
***** IPv4 / IPv6 embedding
|
**** IPv4 / IPv6 embedding
|
||||||
Currently offset based - probably not following the RFC!
|
Currently offset based - probably not following the RFC!
|
||||||
***** No DNS64
|
**** No DNS64
|
||||||
has already been solved in a different domain - could even do
|
has already been solved in a different domain - could even do
|
||||||
transparent / in network modification
|
transparent / in network modification
|
||||||
***** Incomplete NDP
|
**** Incomplete NDP
|
||||||
Very limited option support
|
Very limited option support
|
||||||
***** NAT64 mappings not source network dependent
|
**** NAT64 mappings not source network dependent
|
||||||
Only the destination network is matched for deciding on NAT64, as
|
Only the destination network is matched for deciding on NAT64, as
|
||||||
priority based double LPM is not supported. This limits a prefix to be
|
priority based double LPM is not supported. This limits a prefix to be
|
||||||
used only in one network.
|
used only in one network.
|
||||||
|
|
|
@ -23,11 +23,20 @@ log = logging.getLogger("main")
|
||||||
|
|
||||||
|
|
||||||
cpu_fields = {
|
cpu_fields = {
|
||||||
|
0: 'UNSET',
|
||||||
1: 'ICMP6_NS',
|
1: 'ICMP6_NS',
|
||||||
2: 'ICMP6_GENERAL',
|
2: 'ICMP6_GENERAL',
|
||||||
3: 'DEBUG'
|
3: 'DEBUG'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table_id_fields = {
|
||||||
|
0: 'UNSET_TABLE',
|
||||||
|
1: 'TABLE_NAT64',
|
||||||
|
2: 'TABLE_ICMP6,
|
||||||
|
3: 'TABLE_V6_NETWORKS,
|
||||||
|
4: 'TABLE_NAT46',
|
||||||
|
5: 'TABLE_V4_NETWORKS'
|
||||||
|
}
|
||||||
|
|
||||||
class CpuHeader(Packet):
|
class CpuHeader(Packet):
|
||||||
name = 'CpuPacket'
|
name = 'CpuPacket'
|
||||||
|
@ -35,6 +44,7 @@ class CpuHeader(Packet):
|
||||||
ShortEnumField('task', 1, cpu_fields ),
|
ShortEnumField('task', 1, cpu_fields ),
|
||||||
ShortField('ingress_port', 0),
|
ShortField('ingress_port', 0),
|
||||||
XShortEnumField("type", 0x9000, ETHER_TYPES)
|
XShortEnumField("type", 0x9000, ETHER_TYPES)
|
||||||
|
ShortEnumField('table_id', 1, table_id_fields ),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -421,8 +431,6 @@ class L2Controller(object):
|
||||||
def recv_msg_cpu(self, pkg):
|
def recv_msg_cpu(self, pkg):
|
||||||
packet = Ether(str(pkg))
|
packet = Ether(str(pkg))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if packet.type == 0x0800:
|
if packet.type == 0x0800:
|
||||||
log.debug("Received raw (untagged) packet - BUG")
|
log.debug("Received raw (untagged) packet - BUG")
|
||||||
self.debug_print_pkg(pkg)
|
self.debug_print_pkg(pkg)
|
||||||
|
@ -432,13 +440,14 @@ class L2Controller(object):
|
||||||
cpu_header = CpuHeader(packet.payload)
|
cpu_header = CpuHeader(packet.payload)
|
||||||
ether_orig = Ether(src=packet.src, dst=packet.dst, type=cpu_header.type)
|
ether_orig = Ether(src=packet.src, dst=packet.dst, type=cpu_header.type)
|
||||||
orig_packet = ether_orig / IP(cpu_header.load)
|
orig_packet = ether_orig / IP(cpu_header.load)
|
||||||
|
log.debug("cpu = {}".format(cpu_header.__repr__()))
|
||||||
log.debug("v4 reassambled={}".format(orig_packet.__repr__()))
|
log.debug("v4 reassambled={}".format(orig_packet.__repr__()))
|
||||||
|
|
||||||
elif packet.type == 0x4242:
|
elif packet.type == 0x4242:
|
||||||
cpu_header = CpuHeader(packet.payload)
|
cpu_header = CpuHeader(packet.payload)
|
||||||
|
|
||||||
# Not necessary anymore - cpu decoding works
|
# Not necessary anymore - cpu decoding works
|
||||||
# log.debug("cpu = {}".format(cpu_header.__repr__()))
|
log.debug("cpu = {}".format(cpu_header.__repr__()))
|
||||||
|
|
||||||
ether_orig = Ether(src=packet.src, dst=packet.dst, type=cpu_header.type)
|
ether_orig = Ether(src=packet.src, dst=packet.dst, type=cpu_header.type)
|
||||||
|
|
||||||
|
@ -454,7 +463,7 @@ class L2Controller(object):
|
||||||
src = orig_packet['IPv6'].src
|
src = orig_packet['IPv6'].src
|
||||||
log.debug("Router solicitation from {} -- should probably handle this?".format(src))
|
log.debug("Router solicitation from {} -- should probably handle this?".format(src))
|
||||||
elif cpu_header.task == self.task['DEBUG']:
|
elif cpu_header.task == self.task['DEBUG']:
|
||||||
log.debug("v6 reassambled={}".format(orig_packet.__repr__()))
|
log.debug("[debug] v6 reassambled={}".format(orig_packet.__repr__()))
|
||||||
elif cpu_header.task == self.task['ICMP6_NS']:
|
elif cpu_header.task == self.task['ICMP6_NS']:
|
||||||
log.info("Doing neighbor solicitation for the switch in the controller")
|
log.info("Doing neighbor solicitation for the switch in the controller")
|
||||||
self.handle_icmp6_ns(orig_packet)
|
self.handle_icmp6_ns(orig_packet)
|
||||||
|
|
|
@ -12,6 +12,14 @@ typedef bit<9> port_t;
|
||||||
typedef bit<16> mcast_t;
|
typedef bit<16> mcast_t;
|
||||||
typedef bit<16> task_t;
|
typedef bit<16> task_t;
|
||||||
|
|
||||||
|
typedef bit<8> table_t; /* to map debug messages */
|
||||||
|
|
||||||
|
const bit<8> TABLE_NAT64 = 1;
|
||||||
|
const bit<8> TABLE_ICMP6 = 2;
|
||||||
|
const bit<8> TABLE_V6_NETWORKS = 3;
|
||||||
|
const bit<8> TABLE_NAT46 = 4;
|
||||||
|
const bit<8> TABLE_V4_NETWORKS = 5;
|
||||||
|
|
||||||
|
|
||||||
const bit<16> TYPE_IPV4 = 0x0800;
|
const bit<16> TYPE_IPV4 = 0x0800;
|
||||||
const bit<16> TYPE_IPV6 = 0x86DD;
|
const bit<16> TYPE_IPV6 = 0x86DD;
|
||||||
|
@ -148,6 +156,7 @@ header cpu_t {
|
||||||
task_t task;
|
task_t task;
|
||||||
bit<16> ingress_port;
|
bit<16> ingress_port;
|
||||||
bit<16> ethertype;
|
bit<16> ethertype;
|
||||||
|
table_t table_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct headers {
|
struct headers {
|
||||||
|
@ -169,6 +178,7 @@ struct metadata {
|
||||||
task_t switch_task;
|
task_t switch_task;
|
||||||
bit<16> tcp_length;
|
bit<16> tcp_length;
|
||||||
bit<32> cast_length;
|
bit<32> cast_length;
|
||||||
|
table_t table_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -32,6 +32,11 @@ control MyIngress(inout headers hdr,
|
||||||
clone3(CloneType.I2E, 100, meta);
|
clone3(CloneType.I2E, 100, meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
action controller_debug_table_id(table_t table_id) {
|
||||||
|
hdr.cpu.table_id = table_id;
|
||||||
|
controller_reply(TASK_DEBUG);
|
||||||
|
}
|
||||||
|
|
||||||
action controller_debug() {
|
action controller_debug() {
|
||||||
controller_reply(TASK_DEBUG);
|
controller_reply(TASK_DEBUG);
|
||||||
}
|
}
|
||||||
|
@ -242,7 +247,6 @@ control MyIngress(inout headers hdr,
|
||||||
}
|
}
|
||||||
size = NDP_TABLE_SIZE;
|
size = NDP_TABLE_SIZE;
|
||||||
default_action = NoAction;
|
default_action = NoAction;
|
||||||
// default_action = controller_debug;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle multicast registration of NDP */
|
/* Handle multicast registration of NDP */
|
||||||
|
@ -257,7 +261,6 @@ control MyIngress(inout headers hdr,
|
||||||
}
|
}
|
||||||
size = NDP_TABLE_SIZE;
|
size = NDP_TABLE_SIZE;
|
||||||
default_action = NoAction;
|
default_action = NoAction;
|
||||||
// default_action = controller_debug;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************** NDP support for OTHERS (unused ATM) ***********************************/
|
/********************** NDP support for OTHERS (unused ATM) ***********************************/
|
||||||
|
@ -273,7 +276,7 @@ control MyIngress(inout headers hdr,
|
||||||
NoAction;
|
NoAction;
|
||||||
}
|
}
|
||||||
size = NDP_TABLE_SIZE;
|
size = NDP_TABLE_SIZE;
|
||||||
default_action = controller_debug;
|
default_action = NoAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -306,7 +309,7 @@ control MyIngress(inout headers hdr,
|
||||||
NoAction;
|
NoAction;
|
||||||
}
|
}
|
||||||
size = ROUTING_TABLE_SIZE;
|
size = ROUTING_TABLE_SIZE;
|
||||||
default_action = controller_debug;
|
default_action = NoAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
table v4_networks {
|
table v4_networks {
|
||||||
|
@ -319,19 +322,30 @@ control MyIngress(inout headers hdr,
|
||||||
NoAction;
|
NoAction;
|
||||||
}
|
}
|
||||||
size = ROUTING_TABLE_SIZE;
|
size = ROUTING_TABLE_SIZE;
|
||||||
default_action = controller_debug;
|
default_action = NoAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************** APPLYING TABLES ***********************************/
|
/********************** APPLYING TABLES ***********************************/
|
||||||
apply {
|
apply {
|
||||||
if(hdr.ipv6.isValid()) {
|
if(hdr.ipv6.isValid()) {
|
||||||
icmp6.apply(); /* icmp6 echo, icmp6 ndp */
|
if(!icmp6.apply().hit) { /* icmp6 echo, icmp6 ndp */
|
||||||
nat64.apply(); /* v6 -> v4 */
|
controller_debug_table_id(TABLE_ICMP6);
|
||||||
v6_networks.apply(); /* routing, egress */
|
}
|
||||||
|
|
||||||
|
if(!nat64.apply().hit) { /* v6 -> v4 */
|
||||||
|
controller_debug_table_id(TABLE_NAT64);
|
||||||
|
}
|
||||||
|
if(!v6_networks.apply().hit) {
|
||||||
|
controller_debug_table_id(TABLE_V6_NETWORKS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(hdr.ipv4.isValid()) {
|
if(hdr.ipv4.isValid()) {
|
||||||
nat46.apply(); /* v4->v6 */
|
if(!nat46.apply().hit) { /* v4->v6 */
|
||||||
v4_networks.apply(); /* routing, egress */
|
controller_debug_table_id(TABLE_NAT46);
|
||||||
|
}
|
||||||
|
if(!v4_networks.apply().hit) { /* routing, egress */
|
||||||
|
controller_debug_table_id(TABLE_V4_NETWORKS)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -351,6 +365,7 @@ control MyEgress(inout headers hdr,
|
||||||
hdr.cpu.ethertype = hdr.ethernet.ethertype;
|
hdr.cpu.ethertype = hdr.ethernet.ethertype;
|
||||||
hdr.cpu.ingress_port = (bit<16>) meta.ingress_port;
|
hdr.cpu.ingress_port = (bit<16>) meta.ingress_port;
|
||||||
|
|
||||||
|
|
||||||
hdr.ethernet.ethertype = TYPE_CPU;
|
hdr.ethernet.ethertype = TYPE_CPU;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue