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:
Fri Jun 16 06:45:17 2017 +0100
Revision:
20:918e62713e63
Parent:
4:0a9d1eeaa905
Child:
21:3754f30e7b69
Enable MLD proxying to upstream (#44)

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