1 /* 2 * Copyright (c) 2020, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * This file includes definitions for Backbone Router management. 32 */ 33 34 #ifndef BACKBONE_ROUTER_MANAGER_HPP_ 35 #define BACKBONE_ROUTER_MANAGER_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE 40 41 #include <openthread/backbone_router.h> 42 #include <openthread/backbone_router_ftd.h> 43 44 #include "backbone_router/backbone_tmf.hpp" 45 #include "backbone_router/bbr_leader.hpp" 46 #include "backbone_router/multicast_listeners_table.hpp" 47 #include "backbone_router/ndproxy_table.hpp" 48 #include "common/locator.hpp" 49 #include "common/non_copyable.hpp" 50 #include "net/netif.hpp" 51 #include "thread/network_data.hpp" 52 #include "thread/tmf.hpp" 53 54 namespace ot { 55 56 namespace BackboneRouter { 57 58 /** 59 * Implements the definitions for Backbone Router management. 60 */ 61 class Manager : public InstanceLocator, private NonCopyable 62 { 63 friend class ot::Notifier; 64 friend class Tmf::Agent; 65 friend class BackboneTmfAgent; 66 67 public: 68 /** 69 * Initializes the Backbone Router manager. 70 * 71 * @param[in] aInstance A reference to the OpenThread instance. 72 */ 73 explicit Manager(Instance &aInstance); 74 75 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE 76 /** 77 * Returns the NdProxy Table. 78 * 79 * @returns The NdProxy Table. 80 */ 81 NdProxyTable &GetNdProxyTable(void); 82 #endif 83 84 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 85 /** 86 * Configures response status for next DUA registration. 87 * 88 * Note: available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled. 89 * Only used for test and certification. 90 * 91 * @param[in] aMlIid A pointer to the Mesh Local IID. If `nullptr`, respond with @p aStatus for any 92 * coming DUA.req, otherwise only respond the one with matching @p aMlIid. 93 * @param[in] aStatus The status to respond. 94 */ 95 void ConfigNextDuaRegistrationResponse(const Ip6::InterfaceIdentifier *aMlIid, uint8_t aStatus); 96 97 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE 98 /** 99 * Configures response status for next Multicast Listener Registration. 100 * 101 * Note: available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled. 102 * Only used for test and certification. 103 * 104 * @param[in] aStatus The status to respond. 105 */ 106 void ConfigNextMulticastListenerRegistrationResponse(ThreadStatusTlv::MlrStatus aStatus); 107 #endif 108 #endif 109 110 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE 111 /** 112 * Gets the Multicast Listeners Table. 113 * 114 * @returns The Multicast Listeners Table. 115 */ GetMulticastListenersTable(void)116 MulticastListenersTable &GetMulticastListenersTable(void) { return mMulticastListenersTable; } 117 #endif 118 119 /** 120 * Returns if messages destined to a given Domain Unicast Address should be forwarded to the Backbone 121 * link. 122 * 123 * @param aAddress The Domain Unicast Address. 124 * 125 * @retval TRUE If messages destined to the Domain Unicast Address should be forwarded to the Backbone link. 126 * @retval FALSE If messages destined to the Domain Unicast Address should not be forwarded to the Backbone link. 127 */ 128 bool ShouldForwardDuaToBackbone(const Ip6::Address &aAddress); 129 130 /** 131 * Returns a reference to the Backbone TMF agent. 132 * 133 * @returns A reference to the Backbone TMF agent. 134 */ GetBackboneTmfAgent(void)135 BackboneTmfAgent &GetBackboneTmfAgent(void) { return mBackboneTmfAgent; } 136 137 /** 138 * Sends BB.qry on the Backbone link. 139 * 140 * @param[in] aDua The Domain Unicast Address to query. 141 * @param[in] aRloc16 The short address of the address resolution initiator or `Mle::kInvalidRloc16` for 142 * DUA DAD. 143 * 144 * @retval kErrorNone Successfully sent BB.qry on backbone link. 145 * @retval kErrorInvalidState If the Backbone Router is not primary, or not enabled. 146 * @retval kErrorNoBufs If insufficient message buffers available. 147 */ 148 Error SendBackboneQuery(const Ip6::Address &aDua, uint16_t aRloc16 = Mle::kInvalidRloc16); 149 150 /** 151 * Send a Proactive Backbone Notification (PRO_BB.ntf) on the Backbone link. 152 * 153 * @param[in] aDua The Domain Unicast Address to notify. 154 * @param[in] aMeshLocalIid The Mesh-Local IID to notify. 155 * @param[in] aTimeSinceLastTransaction Time since last transaction (in seconds). 156 * 157 * @retval kErrorNone Successfully sent PRO_BB.ntf on backbone link. 158 * @retval kErrorNoBufs If insufficient message buffers available. 159 */ 160 Error SendProactiveBackboneNotification(const Ip6::Address &aDua, 161 const Ip6::InterfaceIdentifier &aMeshLocalIid, 162 uint32_t aTimeSinceLastTransaction); 163 164 private: 165 static constexpr uint8_t kDefaultHoplimit = 1; 166 static constexpr uint32_t kTimerInterval = 1000; 167 168 template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 169 170 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE 171 void HandleMulticastListenerRegistration(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 172 173 void SendMulticastListenerRegistrationResponse(const Coap::Message &aMessage, 174 const Ip6::MessageInfo &aMessageInfo, 175 ThreadStatusTlv::MlrStatus aStatus, 176 Ip6::Address *aFailedAddresses, 177 uint8_t aFailedAddressNum); 178 void SendBackboneMulticastListenerRegistration(const Ip6::Address *aAddresses, 179 uint8_t aAddressNum, 180 uint32_t aTimeout); 181 #endif 182 183 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE 184 void HandleDuaRegistration(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 185 Error SendBackboneAnswer(const Ip6::MessageInfo &aQueryMessageInfo, 186 const Ip6::Address &aDua, 187 uint16_t aSrcRloc16, 188 const NdProxyTable::NdProxy &aNdProxy); 189 Error SendBackboneAnswer(const Ip6::Address &aDstAddr, 190 const Ip6::Address &aDua, 191 const Ip6::InterfaceIdentifier &aMeshLocalIid, 192 uint32_t aTimeSinceLastTransaction, 193 uint16_t aSrcRloc16); 194 void HandleDadBackboneAnswer(const Ip6::Address &aDua, const Ip6::InterfaceIdentifier &aMeshLocalIid); 195 void HandleExtendedBackboneAnswer(const Ip6::Address &aDua, 196 const Ip6::InterfaceIdentifier &aMeshLocalIid, 197 uint32_t aTimeSinceLastTransaction, 198 uint16_t aSrcRloc16); 199 void HandleProactiveBackboneNotification(const Ip6::Address &aDua, 200 const Ip6::InterfaceIdentifier &aMeshLocalIid, 201 uint32_t aTimeSinceLastTransaction); 202 void SendDuaRegistrationResponse(const Coap::Message &aMessage, 203 const Ip6::MessageInfo &aMessageInfo, 204 const Ip6::Address &aTarget, 205 ThreadStatusTlv::DuaStatus aStatus); 206 #endif 207 void HandleNotifierEvents(Events aEvents); 208 209 void HandleTimer(void); 210 211 void LogError(const char *aText, Error aError) const; 212 213 using BbrTimer = TimerMilliIn<Manager, &Manager::HandleTimer>; 214 215 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE 216 NdProxyTable mNdProxyTable; 217 #endif 218 219 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE 220 MulticastListenersTable mMulticastListenersTable; 221 #endif 222 BbrTimer mTimer; 223 224 BackboneTmfAgent mBackboneTmfAgent; 225 226 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 227 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE 228 Ip6::InterfaceIdentifier mDuaResponseTargetMlIid; 229 uint8_t mDuaResponseStatus; 230 #endif 231 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE 232 ThreadStatusTlv::MlrStatus mMlrResponseStatus; 233 #endif 234 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE 235 bool mDuaResponseIsSpecified : 1; 236 #endif 237 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE 238 bool mMlrResponseIsSpecified : 1; 239 #endif 240 #endif 241 }; 242 243 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE 244 DeclareTmfHandler(Manager, kUriMlr); 245 #endif 246 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE 247 DeclareTmfHandler(Manager, kUriDuaRegistrationRequest); 248 DeclareTmfHandler(Manager, kUriBackboneQuery); 249 DeclareTmfHandler(Manager, kUriBackboneAnswer); 250 #endif 251 252 } // namespace BackboneRouter 253 254 /** 255 * @} 256 */ 257 258 } // namespace ot 259 260 #endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE 261 262 #endif // BACKBONE_ROUTER_MANAGER_HPP_ 263