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" 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 infrastructure network interface. 32 */ 33 34 #ifndef INFRA_IF_HPP_ 35 #define INFRA_IF_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE 40 41 #include <openthread/platform/infra_if.h> 42 43 #include "common/data.hpp" 44 #include "common/error.hpp" 45 #include "common/locator.hpp" 46 #include "common/string.hpp" 47 #include "net/ip6.hpp" 48 49 namespace ot { 50 namespace BorderRouter { 51 52 /** 53 * Represents the infrastructure network interface on a border router. 54 */ 55 class InfraIf : public InstanceLocator 56 { 57 public: 58 static constexpr uint16_t kInfoStringSize = 20; ///< Max chars for the info string (`ToString()`). 59 60 typedef String<kInfoStringSize> InfoString; ///< String type returned from `ToString()`. 61 typedef Data<kWithUint16Length> Icmp6Packet; ///< An IMCPv6 packet (data containing the IP payload) 62 typedef otPlatInfraIfLinkLayerAddress LinkLayerAddress; ///< A link-layer address 63 64 /** 65 * Initializes the `InfraIf`. 66 * 67 * @param[in] aInstance A OpenThread instance. 68 */ 69 explicit InfraIf(Instance &aInstance); 70 71 /** 72 * Initializes the `InfraIf`. 73 * 74 * @param[in] aIfIndex The infrastructure interface index. 75 * 76 * @retval kErrorNone Successfully initialized the `InfraIf`. 77 * @retval kErrorInvalidArgs The index of the infra interface is not valid. 78 * @retval kErrorInvalidState The `InfraIf` is already initialized. 79 */ 80 Error Init(uint32_t aIfIndex); 81 82 /** 83 * Deinitilaizes the `InfraIf`. 84 */ 85 void Deinit(void); 86 87 /** 88 * Indicates whether or not the `InfraIf` is initialized. 89 * 90 * @retval TRUE The `InfraIf` is initialized. 91 * @retval FALSE The `InfraIf` is not initialized. 92 */ IsInitialized(void) const93 bool IsInitialized(void) const { return mInitialized; } 94 95 /** 96 * Indicates whether or not the infra interface is running. 97 * 98 * @retval TRUE The infrastructure interface is running. 99 * @retval FALSE The infrastructure interface is not running. 100 */ IsRunning(void) const101 bool IsRunning(void) const { return mIsRunning; } 102 103 /** 104 * Returns the infrastructure interface index. 105 * 106 * @returns The interface index or zero if not initialized. 107 */ GetIfIndex(void) const108 uint32_t GetIfIndex(void) const { return mIfIndex; } 109 110 /** 111 * Sets the infrastructure interface index. 112 * 113 * @param[in] aIfIndex The infrastructure interface index. 114 */ SetIfIndex(uint32_t aIfIndex)115 void SetIfIndex(uint32_t aIfIndex) { mIfIndex = aIfIndex; } 116 117 /** 118 * Gets the infrastructure interface link-layer address. 119 * 120 * @param[out] aLinkLayerAddress A reference to return the interface link-layer address. 121 * 122 * @retval kErrorNone Successfully get the infrastructure interface link-layer address. 123 * @retval kErrorFailed Failed to get the infrastructure interface link-layer address. 124 */ 125 Error GetLinkLayerAddress(LinkLayerAddress &aLinkLayerAddress); 126 127 /** 128 * Indicates whether or not the infra interface has the given IPv6 address assigned. 129 * 130 * MUST be used when interface is initialized. 131 * 132 * @param[in] aAddress The IPv6 address. 133 * 134 * @retval TRUE The infrastructure interface has @p aAddress. 135 * @retval FALSE The infrastructure interface does not have @p aAddress. 136 */ 137 bool HasAddress(const Ip6::Address &aAddress) const; 138 139 /** 140 * Sends an ICMPv6 Neighbor Discovery packet on the infrastructure interface. 141 * 142 * MUST be used when interface is initialized. 143 * 144 * @param[in] aPacket The ICMPv6 packet to send. 145 * @param[in] aDestination The destination address. 146 * 147 * @retval kErrorNone Successfully sent the ICMPv6 message. 148 * @retval kErrorFailed Failed to send the ICMPv6 message. 149 */ 150 Error Send(const Icmp6Packet &aPacket, const Ip6::Address &aDestination) const; 151 152 /** 153 * Processes a received ICMPv6 Neighbor Discovery packet from an infrastructure interface. 154 * 155 * @param[in] aIfIndex The infrastructure interface index on which the ICMPv6 message is received. 156 * @param[in] aSource The IPv6 source address. 157 * @param[in] aPacket The ICMPv6 packet. 158 */ 159 void HandledReceived(uint32_t aIfIndex, const Ip6::Address &aSource, const Icmp6Packet &aPacket); 160 161 /** 162 * Sends a request to discover the NAT64 prefix on the infrastructure interface. 163 * 164 * @note This method MUST be used when interface is initialized. 165 * 166 * @retval kErrorNone Successfully request NAT64 prefix discovery. 167 * @retval kErrorFailed Failed to request NAT64 prefix discovery. 168 */ 169 Error DiscoverNat64Prefix(void) const; 170 171 /** 172 * Processes the discovered NAT64 prefix. 173 * 174 * @param[in] aIfIndex The infrastructure interface index on which the host address is received. 175 * @param[in] aPrefix The NAT64 prefix on the infrastructure link. 176 */ 177 void DiscoverNat64PrefixDone(uint32_t aIfIndex, const Ip6::Prefix &aPrefix); 178 179 /** 180 * Handles infrastructure interface state changes. 181 * 182 * @param[in] aIfIndex The infrastructure interface index. 183 * @param[in] aIsRunning A boolean that indicates whether the infrastructure interface is running. 184 * 185 * @retval kErrorNone Successfully updated the infra interface status. 186 * @retval kErrorInvalidState The `InfraIf` is not initialized. 187 * @retval kErrorInvalidArgs The @p IfIndex does not match the interface index of `InfraIf`. 188 */ 189 Error HandleStateChanged(uint32_t aIfIndex, bool aIsRunning); 190 191 /** 192 * Converts the `InfraIf` to a human-readable string. 193 * 194 * @returns The string representation of `InfraIf`. 195 */ 196 InfoString ToString(void) const; 197 198 private: 199 bool mInitialized : 1; 200 bool mIsRunning : 1; 201 uint32_t mIfIndex; 202 }; 203 204 } // namespace BorderRouter 205 } // namespace ot 206 207 #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE 208 209 #endif // INFRA_IF_HPP_ 210