• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  *   The file implements the Thread Backbone agent.
32  */
33 
34 #define OTBR_LOG_TAG "BBA"
35 
36 #include "backbone_router/backbone_agent.hpp"
37 
38 #if OTBR_ENABLE_BACKBONE_ROUTER
39 
40 #include <assert.h>
41 #include <net/if.h>
42 
43 #include <openthread/backbone_router_ftd.h>
44 
45 #include "common/code_utils.hpp"
46 
47 namespace otbr {
48 namespace BackboneRouter {
49 
BackboneAgent(otbr::Ncp::ControllerOpenThread & aNcp,std::string aInterfaceName,std::string aBackboneInterfaceName)50 BackboneAgent::BackboneAgent(otbr::Ncp::ControllerOpenThread &aNcp,
51                              std::string                      aInterfaceName,
52                              std::string                      aBackboneInterfaceName)
53     : mNcp(aNcp)
54     , mBackboneRouterState(OT_BACKBONE_ROUTER_STATE_DISABLED)
55 #if OTBR_ENABLE_DUA_ROUTING
56     , mNdProxyManager(aNcp, aBackboneInterfaceName)
57     , mDuaRoutingManager(aInterfaceName, aBackboneInterfaceName)
58 #endif
59 {
60     OTBR_UNUSED_VARIABLE(aInterfaceName);
61     OTBR_UNUSED_VARIABLE(aBackboneInterfaceName);
62 }
63 
Init(void)64 void BackboneAgent::Init(void)
65 {
66     mNcp.AddThreadStateChangedCallback([this](otChangedFlags aFlags) { HandleThreadStateChanged(aFlags); });
67     otBackboneRouterSetDomainPrefixCallback(mNcp.GetInstance(), &BackboneAgent::HandleBackboneRouterDomainPrefixEvent,
68                                             this);
69 #if OTBR_ENABLE_DUA_ROUTING
70     otBackboneRouterSetNdProxyCallback(mNcp.GetInstance(), &BackboneAgent::HandleBackboneRouterNdProxyEvent, this);
71     mNdProxyManager.Init();
72 #endif
73 
74 #if OTBR_ENABLE_BACKBONE_ROUTER_ON_INIT
75     otBackboneRouterSetEnabled(mNcp.GetInstance(), /* aEnabled */ true);
76 #endif
77 }
78 
HandleThreadStateChanged(otChangedFlags aFlags)79 void BackboneAgent::HandleThreadStateChanged(otChangedFlags aFlags)
80 {
81     if (aFlags & OT_CHANGED_THREAD_BACKBONE_ROUTER_STATE)
82     {
83         HandleBackboneRouterState();
84     }
85 }
86 
HandleBackboneRouterState(void)87 void BackboneAgent::HandleBackboneRouterState(void)
88 {
89     otBackboneRouterState state      = otBackboneRouterGetState(mNcp.GetInstance());
90     bool                  wasPrimary = (mBackboneRouterState == OT_BACKBONE_ROUTER_STATE_PRIMARY);
91 
92     otbrLogDebug("BackboneAgent: HandleBackboneRouterState: state=%d, mBackboneRouterState=%d", state,
93                  mBackboneRouterState);
94     VerifyOrExit(mBackboneRouterState != state);
95 
96     mBackboneRouterState = state;
97 
98     if (IsPrimary())
99     {
100         OnBecomePrimary();
101     }
102     else if (wasPrimary)
103     {
104         OnResignPrimary();
105     }
106 
107 exit:
108     return;
109 }
110 
OnBecomePrimary(void)111 void BackboneAgent::OnBecomePrimary(void)
112 {
113     otbrLogNotice("BackboneAgent: Backbone Router becomes Primary!");
114 
115 #if OTBR_ENABLE_DUA_ROUTING
116     if (mDomainPrefix.IsValid())
117     {
118         mDuaRoutingManager.Enable(mDomainPrefix);
119         mNdProxyManager.Enable(mDomainPrefix);
120     }
121 #endif
122 }
123 
OnResignPrimary(void)124 void BackboneAgent::OnResignPrimary(void)
125 {
126     otbrLogNotice("BackboneAgent: Backbone Router resigns Primary to %s!", StateToString(mBackboneRouterState));
127 
128 #if OTBR_ENABLE_DUA_ROUTING
129     mDuaRoutingManager.Disable();
130     mNdProxyManager.Disable();
131 #endif
132 }
133 
StateToString(otBackboneRouterState aState)134 const char *BackboneAgent::StateToString(otBackboneRouterState aState)
135 {
136     const char *ret = "Unknown";
137 
138     switch (aState)
139     {
140     case OT_BACKBONE_ROUTER_STATE_DISABLED:
141         ret = "Disabled";
142         break;
143     case OT_BACKBONE_ROUTER_STATE_SECONDARY:
144         ret = "Secondary";
145         break;
146     case OT_BACKBONE_ROUTER_STATE_PRIMARY:
147         ret = "Primary";
148         break;
149     }
150 
151     return ret;
152 }
153 
HandleBackboneRouterDomainPrefixEvent(void * aContext,otBackboneRouterDomainPrefixEvent aEvent,const otIp6Prefix * aDomainPrefix)154 void BackboneAgent::HandleBackboneRouterDomainPrefixEvent(void                             *aContext,
155                                                           otBackboneRouterDomainPrefixEvent aEvent,
156                                                           const otIp6Prefix                *aDomainPrefix)
157 {
158     static_cast<BackboneAgent *>(aContext)->HandleBackboneRouterDomainPrefixEvent(aEvent, aDomainPrefix);
159 }
160 
HandleBackboneRouterDomainPrefixEvent(otBackboneRouterDomainPrefixEvent aEvent,const otIp6Prefix * aDomainPrefix)161 void BackboneAgent::HandleBackboneRouterDomainPrefixEvent(otBackboneRouterDomainPrefixEvent aEvent,
162                                                           const otIp6Prefix                *aDomainPrefix)
163 {
164     if (aEvent == OT_BACKBONE_ROUTER_DOMAIN_PREFIX_REMOVED)
165     {
166         mDomainPrefix.Clear();
167     }
168     else
169     {
170         assert(aDomainPrefix != nullptr);
171         mDomainPrefix.Set(*aDomainPrefix);
172         assert(mDomainPrefix.IsValid());
173     }
174 
175     VerifyOrExit(IsPrimary() && aEvent != OT_BACKBONE_ROUTER_DOMAIN_PREFIX_REMOVED);
176 
177 #if OTBR_ENABLE_DUA_ROUTING
178     mDuaRoutingManager.Disable();
179     mNdProxyManager.Disable();
180 
181     mDuaRoutingManager.Enable(mDomainPrefix);
182     mNdProxyManager.Enable(mDomainPrefix);
183 #endif
184 
185 exit:
186     return;
187 }
188 
189 #if OTBR_ENABLE_DUA_ROUTING
HandleBackboneRouterNdProxyEvent(void * aContext,otBackboneRouterNdProxyEvent aEvent,const otIp6Address * aAddress)190 void BackboneAgent::HandleBackboneRouterNdProxyEvent(void                        *aContext,
191                                                      otBackboneRouterNdProxyEvent aEvent,
192                                                      const otIp6Address          *aAddress)
193 {
194     static_cast<BackboneAgent *>(aContext)->HandleBackboneRouterNdProxyEvent(aEvent, aAddress);
195 }
196 
HandleBackboneRouterNdProxyEvent(otBackboneRouterNdProxyEvent aEvent,const otIp6Address * aDua)197 void BackboneAgent::HandleBackboneRouterNdProxyEvent(otBackboneRouterNdProxyEvent aEvent, const otIp6Address *aDua)
198 {
199     mNdProxyManager.HandleBackboneRouterNdProxyEvent(aEvent, aDua);
200 }
201 #endif
202 
203 } // namespace BackboneRouter
204 } // namespace otbr
205 
206 #endif // OTBR_ENABLE_BACKBONE_ROUTER
207