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 |                                                                            |       |
 | 
			
		||||
|            | ARP egress support                                                         |       |
 | 
			
		||||
|            |                                                                            |       |
 | 
			
		||||
| 2019-04-03 |                                                                            |       |
 | 
			
		||||
|            | ARP corrections -- ARP working for the switch!                             |       |
 | 
			
		||||
|            |                                                                            |       |
 | 
			
		||||
|            |                                                                            |       |
 | 
			
		||||
| 2019-04-04 | NAT64 1:1 table ICMP, ICMPv6 working                                       |       |
 | 
			
		||||
|            | 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 protocol 58 is wrong -> should be 1
 | 
			
		||||
***** 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 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.
 | 
			
		||||
****** TODO Calculate ICMP checksum
 | 
			
		||||
****** TODO Check field lengths
 | 
			
		||||
****** DONE Calculate ICMP checksum
 | 
			
		||||
****** DONE Check field lengths
 | 
			
		||||
***** 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 Update p4c to avoid compiler bug
 | 
			
		||||
***** TODO Updating p4c
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,7 +37,8 @@ table_id_fields = {
 | 
			
		|||
    4: 'TABLE_NAT46',
 | 
			
		||||
    5: 'TABLE_V4_NETWORKS',
 | 
			
		||||
    6: 'TABLE_ARP',
 | 
			
		||||
    7: 'TABLE_ARP_EGRESS'
 | 
			
		||||
    7: 'TABLE_ARP_EGRESS',
 | 
			
		||||
    8: 'TABLE_ICMP'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table_proto = {
 | 
			
		||||
| 
						 | 
				
			
			@ -224,7 +225,7 @@ class L2Controller(object):
 | 
			
		|||
    def init_ndp_in_switch(self, addr):
 | 
			
		||||
        icmp6_addr = self.gen_ndp_multicast_addr(addr)
 | 
			
		||||
        icmp6_net = "{}/128".format(icmp6_addr)
 | 
			
		||||
        icmp6_type = 135
 | 
			
		||||
        icmp6_type = table_proto['ICMP_NS']
 | 
			
		||||
        mac_addr =  self.info['mac_addr']
 | 
			
		||||
 | 
			
		||||
        self.controller.table_add("icmp6",
 | 
			
		||||
| 
						 | 
				
			
			@ -233,13 +234,21 @@ class L2Controller(object):
 | 
			
		|||
 | 
			
		||||
    def init_icmp6_echo_in_switch(self, addr):
 | 
			
		||||
        icmp6_addr = addr
 | 
			
		||||
        icmp6_type = 128
 | 
			
		||||
        icmp6_type = table_proto['ICMP6_ECHO_REQUEST']
 | 
			
		||||
        icmp6_net = "{}/128".format(icmp6_addr)
 | 
			
		||||
 | 
			
		||||
        self.controller.table_add("icmp6",
 | 
			
		||||
                                  "icmp6_echo_reply",
 | 
			
		||||
                                  [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):
 | 
			
		||||
        return net[self.info['switch_suffix']]
 | 
			
		||||
| 
						 | 
				
			
			@ -251,6 +260,7 @@ class L2Controller(object):
 | 
			
		|||
 | 
			
		||||
        self.controller.table_clear("v4_networks")
 | 
			
		||||
        self.controller.table_clear("v4_arp")
 | 
			
		||||
        self.controller.table_clear("v4_arp_egress")
 | 
			
		||||
        for v4route in self.v4_routes[self.mode]:
 | 
			
		||||
            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:
 | 
			
		||||
            self.listen_to_icmp6_multicast()
 | 
			
		||||
 | 
			
		||||
        # icmp6 echo request + NDP
 | 
			
		||||
        self.controller.table_clear("icmp6")
 | 
			
		||||
        for v6addr in self.v6_addresses[self.mode]:
 | 
			
		||||
            self.init_ndp_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("nat46")
 | 
			
		||||
        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_ARP         = 6;
 | 
			
		||||
const bit<16> TABLE_ARP_EGRESS  = 7;
 | 
			
		||||
const bit<16> TABLE_ICMP        = 8;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const bit<16> TYPE_IPV4  = 0x0800;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@
 | 
			
		|||
#define ADDRESS_TABLE_SIZE 64                               /* maximum number of addresses per protocol */
 | 
			
		||||
#define NDP_TABLE_SIZE 64                                   /* maximum number of multicast groups */
 | 
			
		||||
#define ICMP6_TABLE_SIZE 64                                 /* icmp6 handlers */
 | 
			
		||||
#define ICMP_TABLE_SIZE 64                                 /* icmp6 handlers */
 | 
			
		||||
#define NAT64_TABLE_SIZE 64                                 /* nat64 and nat46 entries */
 | 
			
		||||
 | 
			
		||||
#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() {
 | 
			
		||||
        if(hdr.icmp6.isValid()) {
 | 
			
		||||
            if(hdr.icmp6.code == ICMP6_ECHO_REQUEST) {
 | 
			
		||||
| 
						 | 
				
			
			@ -299,7 +299,28 @@ Echo or Echo Reply Message
 | 
			
		|||
        }
 | 
			
		||||
        size = ICMP6_TABLE_SIZE;
 | 
			
		||||
        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 ***********************************/
 | 
			
		||||
| 
						 | 
				
			
			@ -440,7 +461,10 @@ Echo or Echo Reply Message
 | 
			
		|||
 | 
			
		||||
            v6_networks.apply(); /* regular egress / routing */
 | 
			
		||||
        } 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()) {
 | 
			
		||||
                    nat46_icmp_generic();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue