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