Add icmp handling / replying
This commit is contained in:
parent
79a46f42c2
commit
d87b897069
5 changed files with 58 additions and 11 deletions
13
doc/plan.org
13
doc/plan.org
|
@ -173,6 +173,10 @@
|
||||||
| 2019-04-02 | | |
|
| 2019-04-02 | | |
|
||||||
| | ARP egress support | |
|
| | ARP egress support | |
|
||||||
| | | |
|
| | | |
|
||||||
|
| 2019-04-03 | | |
|
||||||
|
| | ARP corrections -- ARP working for the switch! | |
|
||||||
|
| | | |
|
||||||
|
| | | |
|
||||||
| 2019-04-04 | NAT64 1:1 table ICMP, ICMPv6 working | |
|
| 2019-04-04 | NAT64 1:1 table ICMP, ICMPv6 working | |
|
||||||
| | Will need some switch local ip addresses | |
|
| | Will need some switch local ip addresses | |
|
||||||
| | | |
|
| | | |
|
||||||
|
@ -681,16 +685,17 @@ INFO:main:unhandled reassambled=<Ether dst=00:00:0a:00:00:42 src=00:00:0a:00:00
|
||||||
***** DONE egress is correct, comes out at h3
|
***** DONE egress is correct, comes out at h3
|
||||||
***** DONE protocol 58 is wrong -> should be 1
|
***** DONE protocol 58 is wrong -> should be 1
|
||||||
***** DONE figure out switch() syntax
|
***** DONE figure out switch() syntax
|
||||||
***** TODO transform protocol specific: icmp6 -> icmp
|
***** DONE transform protocol specific: icmp6 -> icmp
|
||||||
****** DONE Implement double table, as there are no if's in actions
|
****** DONE Implement double table, as there are no if's in actions
|
||||||
****** DONE Debug Ethernet frame check sequence error -> need to compute checksum
|
****** DONE Debug Ethernet frame check sequence error -> need to compute checksum
|
||||||
https://en.wikipedia.org/wiki/Frame_check_sequence
|
https://en.wikipedia.org/wiki/Frame_check_sequence
|
||||||
|
|
||||||
According to Edgar this should not be seen anyway.
|
According to Edgar this should not be seen anyway.
|
||||||
****** TODO Calculate ICMP checksum
|
****** DONE Calculate ICMP checksum
|
||||||
****** TODO Check field lengths
|
****** DONE Check field lengths
|
||||||
***** TODO transform protocol specific: icmp -> icmp6
|
***** TODO transform protocol specific: icmp -> icmp6
|
||||||
**** TODO Make switch answer IPv4 icmp echo request for
|
****** TODO Make switch answer IPv4 icmp echo request for
|
||||||
|
******* DONE Make switch respond to ARP
|
||||||
**** TODO Add / check default route for v4 hosts
|
**** TODO Add / check default route for v4 hosts
|
||||||
**** TODO Update p4c to avoid compiler bug
|
**** TODO Update p4c to avoid compiler bug
|
||||||
***** TODO Updating p4c
|
***** TODO Updating p4c
|
||||||
|
|
|
@ -37,7 +37,8 @@ table_id_fields = {
|
||||||
4: 'TABLE_NAT46',
|
4: 'TABLE_NAT46',
|
||||||
5: 'TABLE_V4_NETWORKS',
|
5: 'TABLE_V4_NETWORKS',
|
||||||
6: 'TABLE_ARP',
|
6: 'TABLE_ARP',
|
||||||
7: 'TABLE_ARP_EGRESS'
|
7: 'TABLE_ARP_EGRESS',
|
||||||
|
8: 'TABLE_ICMP'
|
||||||
}
|
}
|
||||||
|
|
||||||
table_proto = {
|
table_proto = {
|
||||||
|
@ -224,7 +225,7 @@ class L2Controller(object):
|
||||||
def init_ndp_in_switch(self, addr):
|
def init_ndp_in_switch(self, addr):
|
||||||
icmp6_addr = self.gen_ndp_multicast_addr(addr)
|
icmp6_addr = self.gen_ndp_multicast_addr(addr)
|
||||||
icmp6_net = "{}/128".format(icmp6_addr)
|
icmp6_net = "{}/128".format(icmp6_addr)
|
||||||
icmp6_type = 135
|
icmp6_type = table_proto['ICMP_NS']
|
||||||
mac_addr = self.info['mac_addr']
|
mac_addr = self.info['mac_addr']
|
||||||
|
|
||||||
self.controller.table_add("icmp6",
|
self.controller.table_add("icmp6",
|
||||||
|
@ -233,13 +234,21 @@ class L2Controller(object):
|
||||||
|
|
||||||
def init_icmp6_echo_in_switch(self, addr):
|
def init_icmp6_echo_in_switch(self, addr):
|
||||||
icmp6_addr = addr
|
icmp6_addr = addr
|
||||||
icmp6_type = 128
|
icmp6_type = table_proto['ICMP6_ECHO_REQUEST']
|
||||||
icmp6_net = "{}/128".format(icmp6_addr)
|
icmp6_net = "{}/128".format(icmp6_addr)
|
||||||
|
|
||||||
self.controller.table_add("icmp6",
|
self.controller.table_add("icmp6",
|
||||||
"icmp6_echo_reply",
|
"icmp6_echo_reply",
|
||||||
[str(icmp6_net), str(icmp6_type)], [])
|
[str(icmp6_net), str(icmp6_type)], [])
|
||||||
|
|
||||||
|
def init_icmp_echo_in_switch(self, addr):
|
||||||
|
icmp_addr = addr
|
||||||
|
icmp_type = table_proto['ICMP_ECHO_REQUEST']
|
||||||
|
icmp_net = "{}/32".format(icmp_addr)
|
||||||
|
|
||||||
|
self.controller.table_add("icmp",
|
||||||
|
"icmp_echo_reply",
|
||||||
|
[str(icmp_net), str(icmp_type)], [])
|
||||||
|
|
||||||
def ipv4_router(self, net):
|
def ipv4_router(self, net):
|
||||||
return net[self.info['switch_suffix']]
|
return net[self.info['switch_suffix']]
|
||||||
|
@ -251,6 +260,7 @@ class L2Controller(object):
|
||||||
|
|
||||||
self.controller.table_clear("v4_networks")
|
self.controller.table_clear("v4_networks")
|
||||||
self.controller.table_clear("v4_arp")
|
self.controller.table_clear("v4_arp")
|
||||||
|
self.controller.table_clear("v4_arp_egress")
|
||||||
for v4route in self.v4_routes[self.mode]:
|
for v4route in self.v4_routes[self.mode]:
|
||||||
self.controller.table_add("v4_networks", "set_egress_port", [str(v4route['net'])], [str(v4route['port'])])
|
self.controller.table_add("v4_networks", "set_egress_port", [str(v4route['net'])], [str(v4route['port'])])
|
||||||
|
|
||||||
|
@ -267,11 +277,17 @@ class L2Controller(object):
|
||||||
if self.args.multicast_to_controller:
|
if self.args.multicast_to_controller:
|
||||||
self.listen_to_icmp6_multicast()
|
self.listen_to_icmp6_multicast()
|
||||||
|
|
||||||
|
# icmp6 echo request + NDP
|
||||||
self.controller.table_clear("icmp6")
|
self.controller.table_clear("icmp6")
|
||||||
for v6addr in self.v6_addresses[self.mode]:
|
for v6addr in self.v6_addresses[self.mode]:
|
||||||
self.init_ndp_in_switch(v6addr)
|
self.init_ndp_in_switch(v6addr)
|
||||||
self.init_icmp6_echo_in_switch(v6addr)
|
self.init_icmp6_echo_in_switch(v6addr)
|
||||||
|
|
||||||
|
# icmp echo request
|
||||||
|
self.controller.table_clear("icmp")
|
||||||
|
for addr in self.v4_addresses[self.mode]:
|
||||||
|
self.init_icmp_echo_in_switch(addr)
|
||||||
|
|
||||||
self.controller.table_clear("nat64")
|
self.controller.table_clear("nat64")
|
||||||
self.controller.table_clear("nat46")
|
self.controller.table_clear("nat46")
|
||||||
for nat64map in self.nat64_map[self.mode]:
|
for nat64map in self.nat64_map[self.mode]:
|
||||||
|
|
|
@ -24,6 +24,7 @@ const bit<16> TABLE_NAT46 = 4;
|
||||||
const bit<16> TABLE_V4_NETWORKS = 5;
|
const bit<16> TABLE_V4_NETWORKS = 5;
|
||||||
const bit<16> TABLE_ARP = 6;
|
const bit<16> TABLE_ARP = 6;
|
||||||
const bit<16> TABLE_ARP_EGRESS = 7;
|
const bit<16> TABLE_ARP_EGRESS = 7;
|
||||||
|
const bit<16> TABLE_ICMP = 8;
|
||||||
|
|
||||||
|
|
||||||
const bit<16> TYPE_IPV4 = 0x0800;
|
const bit<16> TYPE_IPV4 = 0x0800;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#define ADDRESS_TABLE_SIZE 64 /* maximum number of addresses per protocol */
|
#define ADDRESS_TABLE_SIZE 64 /* maximum number of addresses per protocol */
|
||||||
#define NDP_TABLE_SIZE 64 /* maximum number of multicast groups */
|
#define NDP_TABLE_SIZE 64 /* maximum number of multicast groups */
|
||||||
#define ICMP6_TABLE_SIZE 64 /* icmp6 handlers */
|
#define ICMP6_TABLE_SIZE 64 /* icmp6 handlers */
|
||||||
|
#define ICMP_TABLE_SIZE 64 /* icmp6 handlers */
|
||||||
#define NAT64_TABLE_SIZE 64 /* nat64 and nat46 entries */
|
#define NAT64_TABLE_SIZE 64 /* nat64 and nat46 entries */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -225,9 +225,9 @@ Echo or Echo Reply Message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/********************** ICMP6 + NDP ***********************************/
|
/********************** ICMP6 + NDP + ICMP ***********************************/
|
||||||
|
|
||||||
/* old/unused action */
|
/* old/unused action -- is it??*/
|
||||||
action icmp6_answer() {
|
action icmp6_answer() {
|
||||||
if(hdr.icmp6.isValid()) {
|
if(hdr.icmp6.isValid()) {
|
||||||
if(hdr.icmp6.code == ICMP6_ECHO_REQUEST) {
|
if(hdr.icmp6.code == ICMP6_ECHO_REQUEST) {
|
||||||
|
@ -299,7 +299,28 @@ Echo or Echo Reply Message
|
||||||
}
|
}
|
||||||
size = ICMP6_TABLE_SIZE;
|
size = ICMP6_TABLE_SIZE;
|
||||||
default_action = controller_debug_table_id(TABLE_ICMP6);
|
default_action = controller_debug_table_id(TABLE_ICMP6);
|
||||||
// default_action = NoAction;
|
}
|
||||||
|
|
||||||
|
action icmp_echo_reply() {
|
||||||
|
ipv4_addr_t tmp = hdr.ipv4.src_addr;
|
||||||
|
|
||||||
|
hdr.icmp.type = ICMP_ECHO_REPLY;
|
||||||
|
hdr.ipv4.src_addr = hdr.ipv4.dst_addr;
|
||||||
|
hdr.ipv4.dst_addr = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
table icmp {
|
||||||
|
key = {
|
||||||
|
hdr.ipv4.dst_addr: lpm;
|
||||||
|
hdr.icmp.type: exact;
|
||||||
|
}
|
||||||
|
actions = {
|
||||||
|
icmp_echo_reply;
|
||||||
|
controller_debug_table_id;
|
||||||
|
NoAction;
|
||||||
|
}
|
||||||
|
size = ICMP_TABLE_SIZE;
|
||||||
|
default_action = controller_debug_table_id(TABLE_ICMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************** debugging / general support ***********************************/
|
/********************** debugging / general support ***********************************/
|
||||||
|
@ -440,7 +461,10 @@ Echo or Echo Reply Message
|
||||||
|
|
||||||
v6_networks.apply(); /* regular egress / routing */
|
v6_networks.apply(); /* regular egress / routing */
|
||||||
} else if(hdr.ipv4.isValid()) {
|
} else if(hdr.ipv4.isValid()) {
|
||||||
if(nat46.apply().hit) {
|
if(icmp.apply().hit()) {
|
||||||
|
v4_networks.apply();
|
||||||
|
exit;
|
||||||
|
} else if(nat46.apply().hit) {
|
||||||
if(hdr.icmp.isValid()) {
|
if(hdr.icmp.isValid()) {
|
||||||
nat46_icmp_generic();
|
nat46_icmp_generic();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue