Begin to introduce arp support

This commit is contained in:
Nico Schottelius 2019-03-31 15:48:00 +02:00
parent e1e56184c9
commit 07f0867175
4 changed files with 100 additions and 7 deletions

View file

@ -603,7 +603,7 @@ 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:~#
***** TODO try6: host sees packet, but does not react on it
***** 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
@ -630,9 +630,31 @@ 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
***** TODO Implement default route handling, maybe implement ARP
******
--- 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
***** TODO 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?
****** Entry in v4_networks?
**** DONE Add table name support in debug messages
**** DONE Why getting IPv6 packets in
@ -1726,6 +1748,7 @@ used only in one network.
*** 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 2460 IPv6 (Checksum https://tools.ietf.org/html/rfc2460#section-8.1)
**** RFC 3810 MLD2 https://tools.ietf.org/html/rfc3810

View file

@ -35,7 +35,8 @@ table_id_fields = {
2: 'TABLE_ICMP6',
3: 'TABLE_V6_NETWORKS',
4: 'TABLE_NAT46',
5: 'TABLE_V4_NETWORKS'
5: 'TABLE_V4_NETWORKS',
6: 'TABLE_ARP'
}
table_proto = {
@ -47,6 +48,10 @@ table_proto = {
'ICMP_ECHO_REQUEST' : 8
}
table_arp = {
'ARP_REQUEST': 1,
'ARP_REPLY': 2
}
class CpuHeader(Packet):
@ -72,6 +77,7 @@ class L2Controller(object):
# https://en.wikipedia.org/wiki/Solicited-node_multicast_address
self.info['ndp_multicast'] = ipaddress.ip_network("ff02::1:ff00:0/104")
self.info['mac_addr'] = "00:00:0a:00:00:42"
self.info['mac_broadcast'] = "ff:ff:ff:ff:ff:ff:ff"
self.info['ipv6_link_local'] = ipaddress.ip_address("fe80::200:aff:fe00:42")
self.info['v6_mask'] = 64
@ -234,6 +240,9 @@ class L2Controller(object):
[str(icmp6_net), str(icmp6_type)], [])
def ipv4_router(self, net):
return net[self.info['switch_suffix']]
def fill_tables(self):
self.controller.table_clear("v6_networks")
for v6route in self.v6_routes[self.mode]:
@ -243,6 +252,14 @@ class L2Controller(object):
for v4route in self.v4_routes[self.mode]:
self.controller.table_add("v4_networks", "set_egress_port", [str(v4route['net'])], [str(v4route['port'])])
# ARP support
router = "{}/32".format(self.ipv4_router(v4route['net']))
self.controller.table_add("v4_arp", "arp_reply",
[str(self.info['mac_broadcast']),
str(table_arp['ARP_REQUEST']),
router],
[str(self.info['mac_addr'])]
if self.args.multicast_to_controller:
self.listen_to_icmp6_multicast()
@ -304,7 +321,7 @@ class L2Controller(object):
dev = "{}-eth0".format(host)
net = v4route['net']
ipaddr = "{}/{}".format(net[1],net.prefixlen)
router = str(net[self.info['switch_suffix']])
router = self.ipv4_router(net)
self.config_v4_host(host, str(net), str(ipaddr), dev, router)

View file

@ -5,6 +5,8 @@
#include <core.p4>
#include <v1model.p4>
/**************************************** types ****************************************/
typedef bit<48> mac_addr_t;
typedef bit<32> ipv4_addr_t;
typedef bit<128> ipv6_addr_t;
@ -13,11 +15,14 @@ typedef bit<16> mcast_t;
typedef bit<16> task_t;
typedef bit<16> table_t; /* to map debug messages - 16 bit to match shortenumfield */
/**************************************** constants ****************************************/
const bit<16> TABLE_NAT64 = 1;
const bit<16> TABLE_ICMP6 = 2;
const bit<16> TABLE_V6_NETWORKS = 3;
const bit<16> TABLE_NAT46 = 4;
const bit<16> TABLE_V4_NETWORKS = 5;
const bit<16> TABLE_ARP = 6;
const bit<16> TYPE_IPV4 = 0x0800;
@ -41,6 +46,8 @@ const bit<8> ICMP6_NA = 136;
const bit<8> ICMP_ECHO_REPLY = 0;
const bit<8> ICMP_ECHO_REQUEST = 8;
const bit<16> ARP_REQUEST = 1;
const bit<16> ARP_REPLY = 2;
/* RFC4861, Section 4.6 */
const bit<8> ICMP6_NDP_OPT_SOURCE_LL = 1;
@ -58,6 +65,8 @@ const task_t TASK_CHECKSUM_ICMP6 = 5; /* data plane */
const task_t TASK_CHECKSUM_ICMP6_NA = 6; /* data plane */
const task_t TASK_CHECKSUM_ICMP = 7; /* data plane */
/**************************************** header ****************************************/
/* 48+48+16 = 112 */
header ethernet_t {
@ -154,6 +163,17 @@ header icmp_t {
bit<16> checksum;
}
header arp_t {
bit<16> hw_type;
bit<16> protocol;
bit<8> hw_size;
bit<8> protocol_size;
bit<16> opcode;
mac_addr_t src_mac_addr;
ipv4_addr_t src_ipv4_addr;
mac_addr_t dst_mac_addr;
ipv4_addr_t dst_ipv4_addr;
}
header cpu_t {
task_t task;
@ -162,6 +182,8 @@ header cpu_t {
table_t table_id;
}
/**************************************** struct ****************************************/
struct headers {
ethernet_t ethernet;
ipv4_t ipv4;
@ -175,6 +197,7 @@ struct headers {
icmp6_option_link_layer_addr_t icmp6_option_link_layer_addr;
}
struct metadata {
port_t ingress_port;
task_t task;

View file

@ -225,7 +225,7 @@ Echo or Echo Reply Message
}
/********************** ICMP6 ***********************************/
/********************** ICMP6 + NDP ***********************************/
/* old/unused action */
action icmp6_answer() {
@ -329,7 +329,36 @@ Echo or Echo Reply Message
// }
// size = NDP_TABLE_SIZE;
// default_action = NoAction;
// }
// }
/********************** ARP ***********************************/
action arp_reply(mac_addr_t mac_addr) {
ipv4_addr_t tmp = hdr.arp.src_ipv4_addr;
hdr.arp.src_mac_addr = mac_addr;
hdr.arp.src_ipv4_addr = hdr.arp.dst_ipv4_addr;
hdr.arp.dst_mac_addr = hdr.arp.src_mac_addr;
hdr.arp.dst_ipv4_addr = tmp;
hdr.arp.opcode = ARP_REPLY;
}
table v4_arp {
key = {
hdr.ethernet.dst_addr: exact;
hdr.arp.opcode: exact;
hdr.arp.dst_ipv4_addr: lpm;
}
actions = {
controller_debug_table_id;
NoAction;
}
size = ICMP6_TABLE_SIZE;
default_action = controller_debug_table_id(TABLE_ARP);
}
/********************** ROUTING (egress definiton) TABLES ***********************************/
@ -400,6 +429,7 @@ Echo or Echo Reply Message
v6_networks.apply();
exit;
}
v4_arp.apply();
v4_networks.apply(); /* regular routing, egress */
}
}