xref: /aosp_15_r20/external/ot-br-posix/src/backbone_router/backbone_agent.cpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
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::RcpHost & aHost,std::string aInterfaceName,std::string aBackboneInterfaceName)50 BackboneAgent::BackboneAgent(otbr::Ncp::RcpHost &aHost, std::string aInterfaceName, std::string aBackboneInterfaceName)
51     : mHost(aHost)
52     , mBackboneRouterState(OT_BACKBONE_ROUTER_STATE_DISABLED)
53 #if OTBR_ENABLE_DUA_ROUTING
54     , mNdProxyManager(aHost, aBackboneInterfaceName)
55     , mDuaRoutingManager(aInterfaceName, aBackboneInterfaceName)
56 #endif
57 {
58     OTBR_UNUSED_VARIABLE(aInterfaceName);
59     OTBR_UNUSED_VARIABLE(aBackboneInterfaceName);
60 }
61 
Init(void)62 void BackboneAgent::Init(void)
63 {
64     mHost.AddThreadStateChangedCallback([this](otChangedFlags aFlags) { HandleThreadStateChanged(aFlags); });
65     otBackboneRouterSetDomainPrefixCallback(mHost.GetInstance(), &BackboneAgent::HandleBackboneRouterDomainPrefixEvent,
66                                             this);
67 #if OTBR_ENABLE_DUA_ROUTING
68     otBackboneRouterSetNdProxyCallback(mHost.GetInstance(), &BackboneAgent::HandleBackboneRouterNdProxyEvent, this);
69     mNdProxyManager.Init();
70 #endif
71 
72 #if OTBR_ENABLE_BACKBONE_ROUTER_ON_INIT
73     otBackboneRouterSetEnabled(mHost.GetInstance(), /* aEnabled */ true);
74 #endif
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(mHost.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