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 */ 62 class Manager : public InstanceLocator, private NonCopyable 63 { 64 friend class ot::Notifier; 65 friend class Tmf::Agent; 66 friend class BackboneTmfAgent; 67 68 public: 69 /** 70 * Initializes the Backbone Router manager. 71 * 72 * @param[in] aInstance A reference to the OpenThread instance. 73 * 74 */ 75 explicit Manager(Instance &aInstance); 76 77 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE 78 /** 79 * Returns the NdProxy Table. 80 * 81 * @returns The NdProxy Table. 82 * 83 */ 84 NdProxyTable &GetNdProxyTable(void); 85 #endif 86 87 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 88 /** 89 * Configures response status for next DUA registration. 90 * 91 * Note: available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled. 92 * Only used for test and certification. 93 * 94 * @param[in] aMlIid A pointer to the Mesh Local IID. If `nullptr`, respond with @p aStatus for any 95 * coming DUA.req, otherwise only respond the one with matching @p aMlIid. 96 * @param[in] aStatus The status to respond. 97 * 98 */ 99 void ConfigNextDuaRegistrationResponse(const Ip6::InterfaceIdentifier *aMlIid, uint8_t aStatus); 100 101 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE 102 /** 103 * Configures response status for next Multicast Listener Registration. 104 * 105 * Note: available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled. 106 * Only used for test and certification. 107 * 108 * @param[in] aStatus The status to respond. 109 * 110 */ 111 void ConfigNextMulticastListenerRegistrationResponse(ThreadStatusTlv::MlrStatus aStatus); 112 #endif 113 #endif 114 115 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE 116 /** 117 * Gets the Multicast Listeners Table. 118 * 119 * @returns The Multicast Listeners Table. 120 * 121 */ GetMulticastListenersTable(void)122 MulticastListenersTable &GetMulticastListenersTable(void) { return mMulticastListenersTable; } 123 #endif 124 125 /** 126 * Returns if messages destined to a given Domain Unicast Address should be forwarded to the Backbone 127 * link. 128 * 129 * @param aAddress The Domain Unicast Address. 130 * 131 * @retval TRUE If messages destined to the Domain Unicast Address should be forwarded to the Backbone link. 132 * @retval FALSE If messages destined to the Domain Unicast Address should not be forwarded to the Backbone link. 133 * 134 */ 135 bool ShouldForwardDuaToBackbone(const Ip6::Address &aAddress); 136 137 /** 138 * Returns a reference to the Backbone TMF agent. 139 * 140 * @returns A reference to the Backbone TMF agent. 141 * 142 */ GetBackboneTmfAgent(void)143 BackboneTmfAgent &GetBackboneTmfAgent(void) { return mBackboneTmfAgent; } 144 145 /** 146 * Sends BB.qry on the Backbone link. 147 * 148 * @param[in] aDua The Domain Unicast Address to query. 149 * @param[in] aRloc16 The short address of the address resolution initiator or `Mac::kShortAddrInvalid` for 150 * DUA DAD. 151 * 152 * @retval kErrorNone Successfully sent BB.qry on backbone link. 153 * @retval kErrorInvalidState If the Backbone Router is not primary, or not enabled. 154 * @retval kErrorNoBufs If insufficient message buffers available. 155 * 156 */ 157 Error SendBackboneQuery(const Ip6::Address &aDua, uint16_t aRloc16 = Mac::kShortAddrInvalid); 158 159 /** 160 * Send a Proactive Backbone Notification (PRO_BB.ntf) on the Backbone link. 161 * 162 * @param[in] aDua The Domain Unicast Address to notify. 163 * @param[in] aMeshLocalIid The Mesh-Local IID to notify. 164 * @param[in] aTimeSinceLastTransaction Time since last transaction (in seconds). 165 * 166 * @retval kErrorNone Successfully sent PRO_BB.ntf on backbone link. 167 * @retval kErrorNoBufs If insufficient message buffers available. 168 * 169 */ 170 Error SendProactiveBackboneNotification(const Ip6::Address &aDua, 171 const Ip6::InterfaceIdentifier &aMeshLocalIid, 172 uint32_t aTimeSinceLastTransaction); 173 174 private: 175 static constexpr uint8_t kDefaultHoplimit = 1; 176 static constexpr uint32_t kTimerInterval = 1000; 177 178 template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 179 180 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE 181 void HandleMulticastListenerRegistration(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 182 183 void SendMulticastListenerRegistrationResponse(const Coap::Message &aMessage, 184 const Ip6::MessageInfo &aMessageInfo, 185 ThreadStatusTlv::MlrStatus aStatus, 186 Ip6::Address *aFailedAddresses, 187 uint8_t aFailedAddressNum); 188 void SendBackboneMulticastListenerRegistration(const Ip6::Address *aAddresses, 189 uint8_t aAddressNum, 190 uint32_t aTimeout); 191 #endif 192 193 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE 194 void HandleDuaRegistration(const Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); 195 Error SendBackboneAnswer(const Ip6::MessageInfo &aQueryMessageInfo, 196 const Ip6::Address &aDua, 197 uint16_t aSrcRloc16, 198 const NdProxyTable::NdProxy &aNdProxy); 199 Error SendBackboneAnswer(const Ip6::Address &aDstAddr, 200 const Ip6::Address &aDua, 201 const Ip6::InterfaceIdentifier &aMeshLocalIid, 202 uint32_t aTimeSinceLastTransaction, 203 uint16_t aSrcRloc16); 204 void HandleDadBackboneAnswer(const Ip6::Address &aDua, const Ip6::InterfaceIdentifier &aMeshLocalIid); 205 void HandleExtendedBackboneAnswer(const Ip6::Address &aDua, 206 const Ip6::InterfaceIdentifier &aMeshLocalIid, 207 uint32_t aTimeSinceLastTransaction, 208 uint16_t aSrcRloc16); 209 void HandleProactiveBackboneNotification(const Ip6::Address &aDua, 210 const Ip6::InterfaceIdentifier &aMeshLocalIid, 211 uint32_t aTimeSinceLastTransaction); 212 void SendDuaRegistrationResponse(const Coap::Message &aMessage, 213 const Ip6::MessageInfo &aMessageInfo, 214 const Ip6::Address &aTarget, 215 ThreadStatusTlv::DuaStatus aStatus); 216 #endif 217 void HandleNotifierEvents(Events aEvents); 218 219 void HandleTimer(void); 220 221 void LogError(const char *aText, Error aError) const; 222 223 using BbrTimer = TimerMilliIn<Manager, &Manager::HandleTimer>; 224 225 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE 226 NdProxyTable mNdProxyTable; 227 #endif 228 229 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE 230 MulticastListenersTable mMulticastListenersTable; 231 #endif 232 BbrTimer mTimer; 233 234 BackboneTmfAgent mBackboneTmfAgent; 235 236 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 237 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE 238 Ip6::InterfaceIdentifier mDuaResponseTargetMlIid; 239 uint8_t mDuaResponseStatus; 240 #endif 241 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE 242 ThreadStatusTlv::MlrStatus mMlrResponseStatus; 243 #endif 244 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE 245 bool mDuaResponseIsSpecified : 1; 246 #endif 247 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE 248 bool mMlrResponseIsSpecified : 1; 249 #endif 250 #endif 251 }; 252 253 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE 254 DeclareTmfHandler(Manager, kUriMlr); 255 #endif 256 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE 257 DeclareTmfHandler(Manager, kUriDuaRegistrationRequest); 258 DeclareTmfHandler(Manager, kUriBackboneQuery); 259 DeclareTmfHandler(Manager, kUriBackboneAnswer); 260 #endif 261 262 } // namespace BackboneRouter 263 264 /** 265 * @} 266 */ 267 268 } // namespace ot 269 270 #endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE 271 272 #endif // BACKBONE_ROUTER_MANAGER_HPP_ 273