• 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     otBackboneRouterSetEnabled(mNcp.GetInstance(), /* aEnabled */ true);
75 }
76 
HandleThreadStateChanged(otChangedFlags aFlags)77 void BackboneAgent::HandleThreadStateChanged(otChangedFlags aFlags)
78 {
79     if (aFlags & OT_CHANGED_THREAD_BACKBONE_ROUTER_STATE)
80     {
81         HandleBackboneRouterState();
82     }
83 }
84 
HandleBackboneRouterState(void)85 void BackboneAgent::HandleBackboneRouterState(void)
86 {
87     otBackboneRouterState state      = otBackboneRouterGetState(mNcp.GetInstance());
88     bool                  wasPrimary = (mBackboneRouterState == OT_BACKBONE_ROUTER_STATE_PRIMARY);
89 
90     otbrLogDebug("BackboneAgent: HandleBackboneRouterState: state=%d, mBackboneRouterState=%d", state,
91                  mBackboneRouterState);
92     VerifyOrExit(mBackboneRouterState != state);
93 
94     mBackboneRouterState = state;
95 
96     if (IsPrimary())
97     {
98         OnBecomePrimary();
99     }
100     else if (wasPrimary)
101     {
102         OnResignPrimary();
103     }
104 
105 exit:
106     return;
107 }
108 
OnBecomePrimary(void)109 void BackboneAgent::OnBecomePrimary(void)
110 {
111     otbrLogNotice("BackboneAgent: Backbone Router becomes Primary!");
112 
113 #if OTBR_ENABLE_DUA_ROUTING
114     if (mDomainPrefix.IsValid())
115     {
116         mDuaRoutingManager.Enable(mDomainPrefix);
117         mNdProxyManager.Enable(mDomainPrefix);
118     }
119 #endif
120 }
121 
OnResignPrimary(void)122 void BackboneAgent::OnResignPrimary(void)
123 {
124     otbrLogNotice("BackboneAgent: Backbone Router resigns Primary to %s!", StateToString(mBackboneRouterState));
125 
126 #if OTBR_ENABLE_DUA_ROUTING
127     mDuaRoutingManager.Disable();
128     mNdProxyManager.Disable();
129 #endif
130 }
131 
StateToString(otBackboneRouterState aState)132 const char *BackboneAgent::StateToString(otBackboneRouterState aState)
133 {
134     const char *ret = "Unknown";
135 
136     switch (aState)
137     {
138     case OT_BACKBONE_ROUTER_STATE_DISABLED:
139         ret = "Disabled";
140         break;
141     case OT_BACKBONE_ROUTER_STATE_SECONDARY:
142         ret = "Secondary";
143         break;
144     case OT_BACKBONE_ROUTER_STATE_PRIMARY:
145         ret = "Primary";
146         break;
147     }
148 
149     return ret;
150 }
151 
HandleBackboneRouterDomainPrefixEvent(void * aContext,otBackboneRouterDomainPrefixEvent aEvent,const otIp6Prefix * aDomainPrefix)152 void BackboneAgent::HandleBackboneRouterDomainPrefixEvent(void *                            aContext,
153                                                           otBackboneRouterDomainPrefixEvent aEvent,
154                                                           const otIp6Prefix *               aDomainPrefix)
155 {
156     static_cast<BackboneAgent *>(aContext)->HandleBackboneRouterDomainPrefixEvent(aEvent, aDomainPrefix);
157 }
158 
HandleBackboneRouterDomainPrefixEvent(otBackboneRouterDomainPrefixEvent aEvent,const otIp6Prefix * aDomainPrefix)159 void BackboneAgent::HandleBackboneRouterDomainPrefixEvent(otBackboneRouterDomainPrefixEvent aEvent,
160                                                           const otIp6Prefix *               aDomainPrefix)
161 {
162     if (aEvent == OT_BACKBONE_ROUTER_DOMAIN_PREFIX_REMOVED)
163     {
164         mDomainPrefix.Clear();
165     }
166     else
167     {
168         assert(aDomainPrefix != nullptr);
169         mDomainPrefix.Set(*aDomainPrefix);
170         assert(mDomainPrefix.IsValid());
171     }
172 
173     VerifyOrExit(IsPrimary() && aEvent != OT_BACKBONE_ROUTER_DOMAIN_PREFIX_REMOVED);
174 
175 #if OTBR_ENABLE_DUA_ROUTING
176     mDuaRoutingManager.Disable();
177     mNdProxyManager.Disable();
178 
179     mDuaRoutingManager.Enable(mDomainPrefix);
180     mNdProxyManager.Enable(mDomainPrefix);
181 #endif
182 
183 exit:
184     return;
185 }
186 
187 #if OTBR_ENABLE_DUA_ROUTING
HandleBackboneRouterNdProxyEvent(void * aContext,otBackboneRouterNdProxyEvent aEvent,const otIp6Address * aAddress)188 void BackboneAgent::HandleBackboneRouterNdProxyEvent(void *                       aContext,
189                                                      otBackboneRouterNdProxyEvent aEvent,
190                                                      const otIp6Address *         aAddress)
191 {
192     static_cast<BackboneAgent *>(aContext)->HandleBackboneRouterNdProxyEvent(aEvent, aAddress);
193 }
194 
HandleBackboneRouterNdProxyEvent(otBackboneRouterNdProxyEvent aEvent,const otIp6Address * aDua)195 void BackboneAgent::HandleBackboneRouterNdProxyEvent(otBackboneRouterNdProxyEvent aEvent, const otIp6Address *aDua)
196 {
197     mNdProxyManager.HandleBackboneRouterNdProxyEvent(aEvent, aDua);
198 }
199 #endif
200 
201 } // namespace BackboneRouter
202 } // namespace otbr
203 
204 #endif // OTBR_ENABLE_BACKBONE_ROUTER
205