Merge pull request #159 from rtbrick/icmpv6-ra

add ICMPv6 RA support for network interfaces
This commit is contained in:
Hannes Gredler
2023-02-25 10:15:54 +01:00
committed by GitHub
7 changed files with 61 additions and 2 deletions
+7
View File
@@ -584,6 +584,13 @@ json_parse_network_interface(json_t *network_interface, bbl_network_config_s *ne
return false;
}
}
value = json_object_get(network_interface, "ipv6-router-advertisement");
if(json_is_boolean(value)) {
network_config->ipv6_ra = json_boolean_value(value);
} else {
network_config->ipv6_ra = true;
}
if(json_unpack(network_interface, "{s:s}", "gateway-mac", &s) == 0) {
if(sscanf(s, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
&network_config->gateway_mac[0],
+1
View File
@@ -100,6 +100,7 @@ typedef struct bbl_network_config_
ipv4_prefix ip;
ipv4addr_t gateway;
bool ipv6_ra;
ipv6_prefix ip6;
ipv6addr_t gateway6;
+3 -2
View File
@@ -89,8 +89,9 @@
/* Network Interface Send Mask */
#define BBL_IF_SEND_ARP_REQUEST 0x00000001
#define BBL_IF_SEND_ICMPV6_NS 0x00000002
#define BBL_IF_SEND_ISIS_P2P_HELLO 0x00000004
#define BBL_IF_SEND_LDP_HELLO 0x00000008
#define BBL_IF_SEND_ICMPV6_RA 0x00000004
#define BBL_IF_SEND_ISIS_P2P_HELLO 0x00000008
#define BBL_IF_SEND_LDP_HELLO 0x00000010
#define BBL_AVG_SAMPLES 5
#define BBL_MAX_STREAM_OVERHEAD 128
+6
View File
@@ -118,6 +118,10 @@ bbl_network_interfaces_add()
network_interface->ip6_ll[13] = network_interface->mac[3];
network_interface->ip6_ll[14] = network_interface->mac[4];
network_interface->ip6_ll[15] = network_interface->mac[5];
if(network_config->ipv6_ra) {
network_interface->ipv6_ra = true;
network_interface->send_requests |= BBL_IF_SEND_ICMPV6_RA;
}
/* Init IPv6 */
if(ipv6_prefix_not_zero(&network_config->ip6) &&
@@ -366,6 +370,8 @@ bbl_network_rx_icmpv6(bbl_network_interface_s *interface,
secondary_ip6 = secondary_ip6->next;
}
}
} else if(icmpv6->type == IPV6_ICMPV6_ROUTER_SOLICITATION && interface->ipv6_ra) {
interface->send_requests |= BBL_IF_SEND_ICMPV6_RA;
} else if(icmpv6->type == IPV6_ICMPV6_ECHO_REQUEST) {
bbl_network_icmpv6_echo_reply(interface, eth, ipv6, icmpv6);
}
+3
View File
@@ -34,6 +34,9 @@ typedef struct bbl_network_interface_
ipv4_prefix ip;
ipv4addr_t gateway;
bool ipv6_enabled;
bool ipv6_ra;
ipv6_prefix ip6; /* global IPv6 address */
ipv6addr_t ip6_ll; /* link-local IPv6 address */
ipv6addr_t gateway6;
+18
View File
@@ -713,6 +713,24 @@ encode_icmpv6(uint8_t *buf, uint16_t *len,
*(uint32_t*)buf = 0;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t));
break;
case IPV6_ICMPV6_ROUTER_ADVERTISEMENT:
*buf = 64; /* Hop Limit */
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
*buf = 0; /* Flags */
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
*(uint16_t*)buf = htobe16(30); /* Router lifetime */
BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t));
*(uint32_t*)buf = 0; /* Reachable time */
BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t));
*(uint32_t*)buf = 0; /* Retrans time */
BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t));
*buf = 1; /* Source link-layer address */
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
*buf = 1; /* Length (1 = 8 byte) */
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
memcpy(buf, icmp->mac, ETH_ADDR_LEN);
BUMP_WRITE_BUFFER(buf, len, ETH_ADDR_LEN);
break;
case IPV6_ICMPV6_NEIGHBOR_SOLICITATION:
*(uint32_t*)buf = 0; /* Reserved */
BUMP_WRITE_BUFFER(buf, len, sizeof(uint32_t));
+23
View File
@@ -1373,6 +1373,13 @@ bbl_tx_network_nd_timeout(timer_s *timer)
interface->send_requests |= BBL_IF_SEND_ICMPV6_NS;
}
void
bbl_tx_network_ra_timeout(timer_s *timer)
{
bbl_network_interface_s *interface = timer->data;
interface->send_requests |= BBL_IF_SEND_ICMPV6_RA;
}
static protocol_error_t
bbl_tx_encode_network_packet(bbl_network_interface_s *interface, uint8_t *buf, uint16_t *len)
{
@@ -1426,6 +1433,22 @@ bbl_tx_encode_network_packet(bbl_network_interface_s *interface, uint8_t *buf, u
1, 0, interface, &bbl_tx_network_nd_timeout);
}
result = encode_ethernet(buf, len, &eth);
} else if(interface->send_requests & BBL_IF_SEND_ICMPV6_RA) {
interface->send_requests &= ~BBL_IF_SEND_ICMPV6_RA;
ipv6_multicast_mac(ipv6_multicast_all_nodes, mac);
eth.dst = mac;
eth.type = ETH_TYPE_IPV6;
eth.next = &ipv6;
ipv6.src = interface->ip6_ll;
ipv6.dst = (void*)ipv6_multicast_all_nodes;
ipv6.protocol = IPV6_NEXT_HEADER_ICMPV6;
ipv6.next = &icmpv6;
ipv6.ttl = 255;
icmpv6.type = IPV6_ICMPV6_ROUTER_ADVERTISEMENT;
icmpv6.mac = interface->mac;
timer_add(&g_ctx->timer_root, &interface->timer_nd, "RA timer",
10, 0, interface, &bbl_tx_network_ra_timeout);
result = encode_ethernet(buf, len, &eth);
} else if(interface->send_requests & BBL_IF_SEND_ISIS_P2P_HELLO) {
interface->send_requests &= ~BBL_IF_SEND_ISIS_P2P_HELLO;
result = isis_p2p_hello_encode(interface, buf, len, &eth);