• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *    Copyright (c) 2022, 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" AND
17  *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20  *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /**
29  * @file
30  *   This file implements infrastructure network interface.
31  */
32 
33 #include "infra_if.hpp"
34 
35 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
36 
37 #include "border_router/routing_manager.hpp"
38 #include "common/as_core_type.hpp"
39 #include "common/instance.hpp"
40 #include "common/locator_getters.hpp"
41 #include "common/logging.hpp"
42 #include "net/icmp6.hpp"
43 
44 namespace ot {
45 namespace BorderRouter {
46 
47 RegisterLogModule("InfraIf");
48 
InfraIf(Instance & aInstance)49 InfraIf::InfraIf(Instance &aInstance)
50     : InstanceLocator(aInstance)
51     , mInitialized(false)
52     , mIsRunning(false)
53     , mIfIndex(0)
54 {
55 }
56 
Init(uint32_t aIfIndex)57 Error InfraIf::Init(uint32_t aIfIndex)
58 {
59     Error error = kErrorNone;
60 
61     VerifyOrExit(!mInitialized, error = kErrorInvalidState);
62     VerifyOrExit(aIfIndex > 0, error = kErrorInvalidArgs);
63 
64     mIfIndex     = aIfIndex;
65     mInitialized = true;
66 
67     LogInfo("Init %s", ToString().AsCString());
68 
69 exit:
70     return error;
71 }
72 
Deinit(void)73 void InfraIf::Deinit(void)
74 {
75     mInitialized = false;
76     mIsRunning   = false;
77     mIfIndex     = 0;
78 
79     LogInfo("Deinit");
80 }
81 
HasAddress(const Ip6::Address & aAddress)82 bool InfraIf::HasAddress(const Ip6::Address &aAddress)
83 {
84     OT_ASSERT(mInitialized);
85 
86     return otPlatInfraIfHasAddress(mIfIndex, &aAddress);
87 }
88 
Send(const Icmp6Packet & aPacket,const Ip6::Address & aDestination)89 Error InfraIf::Send(const Icmp6Packet &aPacket, const Ip6::Address &aDestination)
90 {
91     OT_ASSERT(mInitialized);
92 
93     return otPlatInfraIfSendIcmp6Nd(mIfIndex, &aDestination, aPacket.GetBytes(), aPacket.GetLength());
94 }
95 
HandledReceived(uint32_t aIfIndex,const Ip6::Address & aSource,const Icmp6Packet & aPacket)96 void InfraIf::HandledReceived(uint32_t aIfIndex, const Ip6::Address &aSource, const Icmp6Packet &aPacket)
97 {
98     Error error = kErrorNone;
99 
100     VerifyOrExit(mInitialized && mIsRunning, error = kErrorInvalidState);
101     VerifyOrExit(aIfIndex == mIfIndex, error = kErrorDrop);
102     VerifyOrExit(aPacket.GetBytes() != nullptr, error = kErrorInvalidArgs);
103     VerifyOrExit(aPacket.GetLength() >= sizeof(Ip6::Icmp::Header), error = kErrorParse);
104 
105     Get<RoutingManager>().HandleReceived(aPacket, aSource);
106 
107 exit:
108     if (error != kErrorNone)
109     {
110         LogDebg("Dropped ICMPv6 message: %s", ErrorToString(error));
111     }
112 }
113 
HandleStateChanged(uint32_t aIfIndex,bool aIsRunning)114 Error InfraIf::HandleStateChanged(uint32_t aIfIndex, bool aIsRunning)
115 {
116     Error error = kErrorNone;
117 
118     VerifyOrExit(mInitialized, error = kErrorInvalidState);
119     VerifyOrExit(aIfIndex == mIfIndex, error = kErrorInvalidArgs);
120 
121     VerifyOrExit(aIsRunning != mIsRunning);
122     LogInfo("State changed: %sRUNNING -> %sRUNNING", mIsRunning ? "" : "NOT ", aIsRunning ? "" : "NOT ");
123 
124     mIsRunning = aIsRunning;
125 
126     Get<RoutingManager>().HandleInfraIfStateChanged();
127 
128 exit:
129     return error;
130 }
131 
ToString(void) const132 InfraIf::InfoString InfraIf::ToString(void) const
133 {
134     InfoString string;
135 
136     string.Append("infra netif %u", mIfIndex);
137     return string;
138 }
139 
140 //---------------------------------------------------------------------------------------------------------------------
141 
otPlatInfraIfRecvIcmp6Nd(otInstance * aInstance,uint32_t aInfraIfIndex,const otIp6Address * aSrcAddress,const uint8_t * aBuffer,uint16_t aBufferLength)142 extern "C" void otPlatInfraIfRecvIcmp6Nd(otInstance *        aInstance,
143                                          uint32_t            aInfraIfIndex,
144                                          const otIp6Address *aSrcAddress,
145                                          const uint8_t *     aBuffer,
146                                          uint16_t            aBufferLength)
147 {
148     InfraIf::Icmp6Packet packet;
149 
150     packet.Init(aBuffer, aBufferLength);
151     AsCoreType(aInstance).Get<InfraIf>().HandledReceived(aInfraIfIndex, AsCoreType(aSrcAddress), packet);
152 }
153 
otPlatInfraIfStateChanged(otInstance * aInstance,uint32_t aInfraIfIndex,bool aIsRunning)154 extern "C" otError otPlatInfraIfStateChanged(otInstance *aInstance, uint32_t aInfraIfIndex, bool aIsRunning)
155 {
156     return AsCoreType(aInstance).Get<InfraIf>().HandleStateChanged(aInfraIfIndex, aIsRunning);
157 }
158 
159 } // namespace BorderRouter
160 } // namespace ot
161 
162 #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
163