• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2021, 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 implements the infrastructure interface for posix.
32  */
33 
34 #ifndef OT_POSIX_PLATFORM_INFRA_IF_HPP_
35 #define OT_POSIX_PLATFORM_INFRA_IF_HPP_
36 
37 #include "openthread-posix-config.h"
38 
39 #include <net/if.h>
40 #include <openthread/nat64.h>
41 #include <openthread/openthread-system.h>
42 
43 #include "core/common/non_copyable.hpp"
44 
45 #include "logger.hpp"
46 #include "mainloop.hpp"
47 #include "multicast_routing.hpp"
48 
49 #if OPENTHREAD_POSIX_CONFIG_INFRA_IF_ENABLE
50 
51 namespace ot {
52 namespace Posix {
53 
54 /**
55  * Manages infrastructure network interface.
56  */
57 class InfraNetif : public Mainloop::Source, public Logger<InfraNetif>, private NonCopyable
58 {
59 public:
60     static const char kLogModuleName[]; ///< Module name used for logging.
61 
62     /**
63      * Updates the fd_set and timeout for mainloop.
64      *
65      * @param[in,out]   aContext    A reference to the mainloop context.
66      */
67     void Update(otSysMainloopContext &aContext) override;
68 
69     /**
70      * Performs infrastructure network interface processing.
71      *
72      * @param[in]   aContext   A reference to the mainloop context.
73      */
74     void Process(const otSysMainloopContext &aContext) override;
75 
76     /**
77      * Initializes the infrastructure network interface.
78      *
79      * To specify the infrastructure network interface, you need to call SetInfraNetif() after Init().
80      *
81      * @note This method is called before OpenThread instance is created.
82      */
83     void Init(void);
84 
85     /**
86      * Sets the infrastructure network interface.
87      *
88      * @param[in]  aIfName       A pointer to infrastructure network interface name.
89      * @param[in]  aIcmp6Socket  A SOCK_RAW socket for sending/receiving ICMPv6 messages. If you don't need border
90      *                           routing feature, you can pass in -1.
91      */
92     void SetInfraNetif(const char *aIfName, int aIcmp6Socket);
93 
94     /**
95      * Sets up the infrastructure network interface.
96      *
97      * @note This method is called after OpenThread instance is created.
98      */
99     void SetUp(void);
100 
101     /**
102      * Tears down the infrastructure network interface.
103      *
104      * @note This method is called before OpenThread instance is destructed.
105      */
106     void TearDown(void);
107 
108     /**
109      * Deinitializes the infrastructure network interface.
110      *
111      * @note This method is called after OpenThread instance is destructed.
112      */
113     void Deinit(void);
114 
115     /**
116      * Checks whether the infrastructure network interface is running.
117      */
118     bool IsRunning(void) const;
119 
120     /**
121      * Returns the ifr_flags of the infrastructure network interface.
122      *
123      * @returns The ifr_flags of the infrastructure network interface.
124      */
125     uint32_t GetFlags(void) const;
126 
127     /**
128      * This functions counts the number of addresses on the infrastructure network interface.
129      *
130      * @param[out] aAddressCounters  The counters of addresses on infrastructure network interface.
131      */
132     void CountAddresses(otSysInfraNetIfAddressCounters &aAddressCounters) const;
133 
134     /**
135      * Handles the backbone state change events.
136      *
137      * @param[in] aInstance  A pointer to the OpenThread instance.
138      * @param[in] aFlags     Flags that denote the state change events.
139      */
140     void HandleBackboneStateChange(otInstance *aInstance, otChangedFlags aFlags);
141 
142     /**
143      * Sends an ICMPv6 Neighbor Discovery message on given infrastructure interface.
144      *
145      * See RFC 4861: https://tools.ietf.org/html/rfc4861.
146      *
147      * @param[in]  aInfraIfIndex  The index of the infrastructure interface this message is sent to.
148      * @param[in]  aDestAddress   The destination address this message is sent to.
149      * @param[in]  aBuffer        The ICMPv6 message buffer. The ICMPv6 checksum is left zero and the
150      *                            platform should do the checksum calculate.
151      * @param[in]  aBufferLength  The length of the message buffer.
152      *
153      * @note  Per RFC 4861, the implementation should send the message with IPv6 link-local source address
154      *        of interface @p aInfraIfIndex and IP Hop Limit 255.
155      *
156      * @retval OT_ERROR_NONE    Successfully sent the ICMPv6 message.
157      * @retval OT_ERROR_FAILED  Failed to send the ICMPv6 message.
158      */
159     otError SendIcmp6Nd(uint32_t            aInfraIfIndex,
160                         const otIp6Address &aDestAddress,
161                         const uint8_t      *aBuffer,
162                         uint16_t            aBufferLength);
163 
164 #if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE && OPENTHREAD_POSIX_CONFIG_NAT64_AIL_PREFIX_ENABLE
165     /**
166      * Sends an asynchronous address lookup for the well-known host name "ipv4only.arpa"
167      * to discover the NAT64 prefix.
168      *
169      * @param[in]  aInfraIfIndex  The index of the infrastructure interface the address look-up is sent to.
170      *
171      * @retval  OT_ERROR_NONE    Successfully request address look-up.
172      * @retval  OT_ERROR_FAILED  Failed to request address look-up.
173      */
174     otError DiscoverNat64Prefix(uint32_t aInfraIfIndex);
175 #endif
176 
177     /**
178      * Gets the infrastructure network interface name.
179      *
180      * @returns The infrastructure network interface name, or `nullptr` if not specified.
181      */
GetNetifName(void) const182     const char *GetNetifName(void) const { return (mInfraIfIndex != 0) ? mInfraIfName : nullptr; }
183 
184     /**
185      * Gets the infrastructure network interface index.
186      *
187      * @returns The infrastructure network interface index.
188      */
GetNetifIndex(void) const189     uint32_t GetNetifIndex(void) const { return mInfraIfIndex; }
190 
191     /**
192      * Gets the infrastructure network interface singleton.
193      *
194      * @returns The singleton object.
195      */
196     static InfraNetif &Get(void);
197 
198     /**
199      * Creates a socket for sending/receiving ICMPv6 messages.
200      *
201      * @param[in] aInfraIfName  The infrastructure network interface name.
202      *
203      * @returns The file descriptor of the socket.
204      */
205     static int CreateIcmp6Socket(const char *aInfraIfName);
206 
207 private:
208     static const char         kWellKnownIpv4OnlyName[];   // "ipv4only.arpa"
209     static const otIp4Address kWellKnownIpv4OnlyAddress1; // 192.0.0.170
210     static const otIp4Address kWellKnownIpv4OnlyAddress2; // 192.0.0.171
211     static const uint8_t      kValidNat64PrefixLength[];
212 
213     char     mInfraIfName[IFNAMSIZ];
214     uint32_t mInfraIfIndex = 0;
215 
216 #ifdef __linux__
217     int mNetLinkSocket = -1;
218 #endif
219 
220 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
221     int mInfraIfIcmp6Socket = -1;
222 #endif
223 #if OPENTHREAD_POSIX_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
224     MulticastRoutingManager mMulticastRoutingManager;
225 #endif
226 
227     bool HasLinkLocalAddress(void) const;
228 
229 #ifdef __linux__
230     void ReceiveNetLinkMessage(void);
231 #endif
232 
233 #if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE && OPENTHREAD_POSIX_CONFIG_NAT64_AIL_PREFIX_ENABLE
234 #ifdef __linux__
235     static void DiscoverNat64PrefixDone(union sigval sv);
236 #endif // #ifdef __linux__
237 #endif
238 
239 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
240     void SetInfraNetifIcmp6SocketForBorderRouting(int aIcmp6Socket);
241     void ReceiveIcmp6Message(void);
242 #endif
243 };
244 
245 } // namespace Posix
246 } // namespace ot
247 #endif // OPENTHREAD_POSIX_CONFIG_INFRA_IF_ENABLE
248 
249 #endif // OT_POSIX_PLATFORM_INFRA_IF_HPP_
250