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