Nanostack Border Router is a generic mbed border router implementation that provides the 6LoWPAN ND or Thread border router initialization logic.

Committer:
mbed_official
Date:
Mon Jun 19 08:00:19 2017 +0100
Revision:
21:3754f30e7b69
Parent:
20:918e62713e63
Child:
22:8740285d8f09
Revert "Enable MLD proxying to upstream (#44)" (#45)

This reverts commit 8cb0b7bea3280a9d3eeea7a5da4b908d5b5fee75.
.
Commit copied from https://github.com/ARMmbed/nanostack-border-router

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 0:85f4174a8e29 1 /*
mbed_official 0:85f4174a8e29 2 * Copyright (c) 2016 ARM Limited. All rights reserved.
mbed_official 0:85f4174a8e29 3 */
mbed_official 0:85f4174a8e29 4
mbed_official 0:85f4174a8e29 5 #include <string.h>
mbed_official 0:85f4174a8e29 6 #include "net_interface.h"
mbed_official 0:85f4174a8e29 7 #include "mbed-trace/mbed_trace.h"
mbed_official 0:85f4174a8e29 8 #include "thread_border_router_api.h"
mbed_official 0:85f4174a8e29 9 #include "thread_br_conn_handler.h"
mbed_official 0:85f4174a8e29 10 #include "thread_dhcpv6_server.h"
mbed_official 0:85f4174a8e29 11 #include "borderrouter_helpers.h"
mbed_official 0:85f4174a8e29 12 #include "common_functions.h"
mbed_official 0:85f4174a8e29 13 #include "eventOS_event_timer.h"
mbed_official 0:85f4174a8e29 14 #include "thread_bbr_ext.h"
mbed_official 0:85f4174a8e29 15
mbed_official 0:85f4174a8e29 16 #define TRACE_GROUP "TBRH"
mbed_official 0:85f4174a8e29 17 #define DHCP_SERVER_SHUTDOWN_TIMEOUT (100)
mbed_official 0:85f4174a8e29 18
mbed_official 0:85f4174a8e29 19 typedef struct {
mbed_official 0:85f4174a8e29 20
mbed_official 0:85f4174a8e29 21 uint8_t dhcp_prefix[16];
mbed_official 0:85f4174a8e29 22 timeout_t *thread_dhcp_shutdown_timer;
mbed_official 0:85f4174a8e29 23 uint8_t dhcp_prefix_len;
mbed_official 0:85f4174a8e29 24 int8_t thread_interface_id;
mbed_official 0:85f4174a8e29 25 int8_t eth_interface_id;
mbed_official 0:85f4174a8e29 26 bool eth_connection_ready;
mbed_official 0:85f4174a8e29 27 bool thread_connection_ready;
mbed_official 0:85f4174a8e29 28 bool dhcp_server_running;
mbed_official 0:85f4174a8e29 29 } thread_br_handler_t;
mbed_official 0:85f4174a8e29 30
mbed_official 0:85f4174a8e29 31 static thread_br_handler_t thread_br_handler;
mbed_official 0:85f4174a8e29 32 static void thread_br_conn_handler_border_router_startup_attempt(void);
mbed_official 0:85f4174a8e29 33 static bool thread_br_conn_handler_default_route_enable(void);
mbed_official 0:85f4174a8e29 34 static void thread_br_conn_handler_dhcp_server_stop_cb(void *arg);
mbed_official 0:85f4174a8e29 35 static void thread_br_conn_handler_border_router_shutdown_request(void);
mbed_official 0:85f4174a8e29 36
mbed_official 0:85f4174a8e29 37
mbed_official 0:85f4174a8e29 38 void thread_br_conn_handler_init(void)
mbed_official 0:85f4174a8e29 39 {
mbed_official 0:85f4174a8e29 40 thread_br_handler.eth_connection_ready = false;
mbed_official 0:85f4174a8e29 41 thread_br_handler.thread_connection_ready = false;
mbed_official 0:85f4174a8e29 42 thread_br_handler.dhcp_server_running = false;
mbed_official 0:85f4174a8e29 43 thread_br_handler.dhcp_prefix_len = 0;
mbed_official 0:85f4174a8e29 44 thread_br_handler.thread_interface_id = -1;
mbed_official 0:85f4174a8e29 45 thread_br_handler.eth_interface_id = -1;
mbed_official 0:85f4174a8e29 46 thread_br_handler.thread_dhcp_shutdown_timer = NULL;
mbed_official 0:85f4174a8e29 47 memset(thread_br_handler.dhcp_prefix, 0, 16);
mbed_official 0:85f4174a8e29 48 }
mbed_official 0:85f4174a8e29 49
mbed_official 0:85f4174a8e29 50 static void thread_br_conn_handler_border_router_startup_attempt(void)
mbed_official 0:85f4174a8e29 51 {
mbed_official 0:85f4174a8e29 52 if (thread_br_handler.thread_dhcp_shutdown_timer != NULL) {
mbed_official 0:85f4174a8e29 53 tr_debug("DHCP server already running, enable default_route");
mbed_official 0:85f4174a8e29 54 eventOS_timeout_cancel(thread_br_handler.thread_dhcp_shutdown_timer);
mbed_official 0:85f4174a8e29 55 thread_br_handler.thread_dhcp_shutdown_timer = NULL;
mbed_official 0:85f4174a8e29 56 }
mbed_official 0:85f4174a8e29 57
mbed_official 0:85f4174a8e29 58 if (!thread_br_handler.eth_connection_ready) {
mbed_official 0:85f4174a8e29 59 tr_debug("eth0 is down");
mbed_official 0:85f4174a8e29 60 return;
mbed_official 0:85f4174a8e29 61 } else if (!thread_br_handler.thread_connection_ready) {
mbed_official 0:85f4174a8e29 62 tr_debug("mesh0 is down");
mbed_official 0:85f4174a8e29 63 return;
mbed_official 0:85f4174a8e29 64 }
mbed_official 0:85f4174a8e29 65
mbed_official 0:85f4174a8e29 66 if (thread_br_handler.dhcp_prefix_len == 0) {
mbed_official 0:85f4174a8e29 67 //No prefix/prefix_len to start DHCP server
mbed_official 0:85f4174a8e29 68 tr_error("DHCP server prefix length = 0");
mbed_official 0:85f4174a8e29 69 return;
mbed_official 0:85f4174a8e29 70 }
mbed_official 0:85f4174a8e29 71
mbed_official 0:85f4174a8e29 72 if (thread_br_handler.thread_interface_id == -1) {
mbed_official 0:85f4174a8e29 73 tr_error("Thread interface ID not set");
mbed_official 0:85f4174a8e29 74 return;
mbed_official 0:85f4174a8e29 75 }
mbed_official 0:85f4174a8e29 76
mbed_official 0:85f4174a8e29 77 if (thread_br_handler.dhcp_server_running == true) {
mbed_official 0:85f4174a8e29 78 // DHCP server is already running, enable default route
mbed_official 0:85f4174a8e29 79 tr_debug("DHCP server already running, enable default_route");
mbed_official 0:85f4174a8e29 80 thread_br_conn_handler_default_route_enable();
mbed_official 0:85f4174a8e29 81 return;
mbed_official 0:85f4174a8e29 82 }
mbed_official 0:85f4174a8e29 83
mbed_official 0:85f4174a8e29 84 int retcode = thread_dhcpv6_server_add(thread_br_handler.thread_interface_id, thread_br_handler.dhcp_prefix, 200, true);
mbed_official 0:85f4174a8e29 85 if (retcode == 0) {
mbed_official 0:85f4174a8e29 86 tr_debug("DHCP server started ");
mbed_official 0:85f4174a8e29 87 if (thread_br_conn_handler_default_route_enable()) {
mbed_official 0:85f4174a8e29 88 thread_br_handler.dhcp_server_running = true;
mbed_official 0:85f4174a8e29 89 thread_bbr_extension_start(thread_br_handler.thread_interface_id, thread_br_handler.eth_interface_id);
mbed_official 0:85f4174a8e29 90 } else {
mbed_official 0:85f4174a8e29 91 tr_error("Failed to update DHCP default route");
mbed_official 0:85f4174a8e29 92 }
mbed_official 0:85f4174a8e29 93 } else {
mbed_official 0:85f4174a8e29 94 tr_error("DHCP server start failed");
mbed_official 0:85f4174a8e29 95 }
mbed_official 0:85f4174a8e29 96 }
mbed_official 0:85f4174a8e29 97
mbed_official 0:85f4174a8e29 98 void thread_br_conn_handler_thread_connection_update(bool status)
mbed_official 0:85f4174a8e29 99 {
mbed_official 0:85f4174a8e29 100 thread_br_handler.thread_connection_ready = status;
mbed_official 4:0a9d1eeaa905 101 tr_debug("mesh0 connection status: %d", status);
mbed_official 4:0a9d1eeaa905 102
mbed_official 0:85f4174a8e29 103 if (status) {
mbed_official 0:85f4174a8e29 104 thread_br_conn_handler_border_router_startup_attempt();
mbed_official 0:85f4174a8e29 105 } else {
mbed_official 0:85f4174a8e29 106 // Thread network down. Reset DHCP server back to original state
mbed_official 0:85f4174a8e29 107 thread_br_handler.dhcp_server_running = false;
mbed_official 4:0a9d1eeaa905 108 // stop mDNS responder as no thread network
mbed_official 4:0a9d1eeaa905 109 thread_border_router_mdns_responder_stop();
mbed_official 0:85f4174a8e29 110 if (thread_br_handler.thread_dhcp_shutdown_timer != NULL) {
mbed_official 0:85f4174a8e29 111 // cancel active shutdown timer
mbed_official 0:85f4174a8e29 112 eventOS_timeout_cancel(thread_br_handler.thread_dhcp_shutdown_timer);
mbed_official 0:85f4174a8e29 113 thread_br_handler.thread_dhcp_shutdown_timer = NULL;
mbed_official 0:85f4174a8e29 114 }
mbed_official 0:85f4174a8e29 115 }
mbed_official 0:85f4174a8e29 116 }
mbed_official 0:85f4174a8e29 117
mbed_official 0:85f4174a8e29 118 void thread_br_conn_handler_ethernet_connection_update(bool status)
mbed_official 0:85f4174a8e29 119 {
mbed_official 0:85f4174a8e29 120 thread_br_handler.eth_connection_ready = status;
mbed_official 4:0a9d1eeaa905 121 tr_debug("Eth0 connection status: %d", status);
mbed_official 4:0a9d1eeaa905 122
mbed_official 0:85f4174a8e29 123 if (status) {
mbed_official 0:85f4174a8e29 124 thread_br_conn_handler_border_router_startup_attempt();
mbed_official 0:85f4174a8e29 125 } else {
mbed_official 0:85f4174a8e29 126 // Ethernet connection down, request DHCP server shutdown
mbed_official 0:85f4174a8e29 127 thread_br_conn_handler_border_router_shutdown_request();
mbed_official 4:0a9d1eeaa905 128 thread_border_router_mdns_responder_stop();
mbed_official 0:85f4174a8e29 129 }
mbed_official 0:85f4174a8e29 130 }
mbed_official 0:85f4174a8e29 131
mbed_official 0:85f4174a8e29 132 void thread_br_conn_handler_eth_ready()
mbed_official 0:85f4174a8e29 133 {
mbed_official 0:85f4174a8e29 134 uint8_t prefix_len = 64;
mbed_official 0:85f4174a8e29 135 uint8_t global_address[16];
mbed_official 0:85f4174a8e29 136
mbed_official 0:85f4174a8e29 137 if (0 == arm_net_address_get(thread_br_conn_handler_eth_interface_id_get(), ADDR_IPV6_GP, global_address)) {
mbed_official 0:85f4174a8e29 138 tr_info("Ethernet (eth0) bootstrap ready. IP: %s", print_ipv6(global_address));
mbed_official 0:85f4174a8e29 139 } else {
mbed_official 0:85f4174a8e29 140 tr_warn("arm_net_address_get fail");
mbed_official 0:85f4174a8e29 141 }
mbed_official 0:85f4174a8e29 142 thread_br_handler.dhcp_prefix_len = prefix_len;
mbed_official 0:85f4174a8e29 143 memset(thread_br_handler.dhcp_prefix, 0, 16);
mbed_official 0:85f4174a8e29 144 memcpy(thread_br_handler.dhcp_prefix, global_address, prefix_len / 8);
mbed_official 0:85f4174a8e29 145 }
mbed_official 0:85f4174a8e29 146
mbed_official 0:85f4174a8e29 147 static bool thread_br_conn_handler_default_route_enable(void)
mbed_official 0:85f4174a8e29 148 {
mbed_official 0:85f4174a8e29 149 thread_border_router_info_t thread_border_router_info;
mbed_official 0:85f4174a8e29 150 thread_border_router_info.Prf = 1;
mbed_official 0:85f4174a8e29 151 thread_border_router_info.P_preferred = false;
mbed_official 0:85f4174a8e29 152 thread_border_router_info.P_slaac = false;
mbed_official 0:85f4174a8e29 153 thread_border_router_info.P_dhcp = true;
mbed_official 0:85f4174a8e29 154 thread_border_router_info.P_configure = false;
mbed_official 0:85f4174a8e29 155 thread_border_router_info.P_default_route = true;
mbed_official 0:85f4174a8e29 156 thread_border_router_info.P_on_mesh = false;
mbed_official 0:85f4174a8e29 157 thread_border_router_info.P_nd_dns = false;
mbed_official 0:85f4174a8e29 158 thread_border_router_info.stableData = true;
mbed_official 0:85f4174a8e29 159
mbed_official 0:85f4174a8e29 160 if (thread_border_router_prefix_add(thread_br_handler.thread_interface_id, thread_br_handler.dhcp_prefix, thread_br_handler.dhcp_prefix_len, &thread_border_router_info) == 0) {
mbed_official 0:85f4174a8e29 161 thread_border_router_publish(thread_br_handler.thread_interface_id);
mbed_official 0:85f4174a8e29 162 tr_debug("Updated %s prefix", print_ipv6_prefix(thread_br_handler.dhcp_prefix, thread_br_handler.dhcp_prefix_len));
mbed_official 4:0a9d1eeaa905 163 thread_border_router_mdns_responder_start(thread_br_handler.thread_interface_id, thread_br_handler.eth_interface_id, "ARM-BR");
mbed_official 0:85f4174a8e29 164 return true;
mbed_official 0:85f4174a8e29 165 } else {
mbed_official 0:85f4174a8e29 166 tr_error("Failed to enable default_route flag to prefix");
mbed_official 0:85f4174a8e29 167 return false;
mbed_official 0:85f4174a8e29 168 }
mbed_official 0:85f4174a8e29 169 }
mbed_official 0:85f4174a8e29 170
mbed_official 0:85f4174a8e29 171 static void thread_br_conn_handler_dhcp_server_stop_cb(void *arg)
mbed_official 0:85f4174a8e29 172 {
mbed_official 0:85f4174a8e29 173 (void)arg;
mbed_official 4:0a9d1eeaa905 174
mbed_official 4:0a9d1eeaa905 175 tr_debug("DHCP server stop cb");
mbed_official 0:85f4174a8e29 176 thread_br_handler.thread_dhcp_shutdown_timer = NULL;
mbed_official 0:85f4174a8e29 177 thread_br_handler.dhcp_server_running = false;
mbed_official 0:85f4174a8e29 178 thread_dhcpv6_server_delete(thread_br_handler.thread_interface_id, thread_br_handler.dhcp_prefix);
mbed_official 0:85f4174a8e29 179 thread_border_router_publish(thread_br_handler.thread_interface_id);
mbed_official 0:85f4174a8e29 180 thread_br_handler.dhcp_prefix_len = 0;
mbed_official 0:85f4174a8e29 181 memset(thread_br_handler.dhcp_prefix, 0, 16);
mbed_official 0:85f4174a8e29 182 }
mbed_official 0:85f4174a8e29 183
mbed_official 0:85f4174a8e29 184 static void thread_br_conn_handler_border_router_shutdown_request(void)
mbed_official 0:85f4174a8e29 185 {
mbed_official 0:85f4174a8e29 186 if (thread_br_handler.dhcp_server_running && thread_br_handler.thread_dhcp_shutdown_timer == NULL) {
mbed_official 0:85f4174a8e29 187 tr_debug("DHCP server shutdown timer started");
mbed_official 0:85f4174a8e29 188 thread_br_handler.thread_dhcp_shutdown_timer = eventOS_timeout_ms(thread_br_conn_handler_dhcp_server_stop_cb, DHCP_SERVER_SHUTDOWN_TIMEOUT, NULL);
mbed_official 0:85f4174a8e29 189 }
mbed_official 0:85f4174a8e29 190 }
mbed_official 0:85f4174a8e29 191
mbed_official 0:85f4174a8e29 192 void thread_br_conn_handler_thread_interface_id_set(int8_t interfaceId)
mbed_official 0:85f4174a8e29 193 {
mbed_official 0:85f4174a8e29 194 thread_br_handler.thread_interface_id = interfaceId;
mbed_official 0:85f4174a8e29 195 thread_bbr_extension_mesh_interface_updated_ntf(thread_br_handler.thread_interface_id);
mbed_official 0:85f4174a8e29 196 }
mbed_official 0:85f4174a8e29 197
mbed_official 0:85f4174a8e29 198 int8_t thread_br_conn_handler_thread_interface_id_get(void)
mbed_official 0:85f4174a8e29 199 {
mbed_official 0:85f4174a8e29 200 return thread_br_handler.thread_interface_id;
mbed_official 0:85f4174a8e29 201 }
mbed_official 0:85f4174a8e29 202
mbed_official 0:85f4174a8e29 203 bool thread_br_conn_handler_eth_connection_status_get(void)
mbed_official 0:85f4174a8e29 204 {
mbed_official 0:85f4174a8e29 205 return thread_br_handler.eth_connection_ready;
mbed_official 0:85f4174a8e29 206 }
mbed_official 0:85f4174a8e29 207
mbed_official 0:85f4174a8e29 208 bool thread_br_conn_handler_thread_connection_status_get(void)
mbed_official 0:85f4174a8e29 209 {
mbed_official 0:85f4174a8e29 210 return thread_br_handler.thread_connection_ready;
mbed_official 0:85f4174a8e29 211 }
mbed_official 0:85f4174a8e29 212
mbed_official 0:85f4174a8e29 213 void thread_br_conn_handler_eth_interface_id_set(int8_t interfaceId)
mbed_official 0:85f4174a8e29 214 {
mbed_official 0:85f4174a8e29 215 thread_br_handler.eth_interface_id = interfaceId;
mbed_official 0:85f4174a8e29 216 thread_bbr_extension_bb_interface_updated_ntf(thread_br_handler.eth_interface_id);
mbed_official 0:85f4174a8e29 217 }
mbed_official 0:85f4174a8e29 218
mbed_official 0:85f4174a8e29 219 int8_t thread_br_conn_handler_eth_interface_id_get(void)
mbed_official 0:85f4174a8e29 220 {
mbed_official 0:85f4174a8e29 221 return thread_br_handler.eth_interface_id;
mbed_official 0:85f4174a8e29 222 }