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 * This file includes definition for ICMPv6 Neighbor Advertisement (ND) proxy management. 32 */ 33 34 #ifndef ND_PROXY_HPP_ 35 #define ND_PROXY_HPP_ 36 37 #if OTBR_ENABLE_DUA_ROUTING 38 39 #ifdef __APPLE__ 40 #define __APPLE_USE_RFC_3542 41 #endif 42 43 #include <inttypes.h> 44 #include <libnetfilter_queue/libnetfilter_queue.h> 45 #include <map> 46 #include <netinet/in.h> 47 #include <set> 48 #include <string> 49 #include <utility> 50 51 #include <openthread/backbone_router_ftd.h> 52 53 #include "common/code_utils.hpp" 54 #include "common/mainloop.hpp" 55 #include "common/types.hpp" 56 #include "ncp/ncp_openthread.hpp" 57 58 namespace otbr { 59 namespace BackboneRouter { 60 61 /** 62 * @addtogroup border-router-bbr 63 * 64 * @brief 65 * This module includes definition for ND Proxy manager. 66 * 67 * @{ 68 */ 69 70 /** 71 * This class implements ND Proxy manager. 72 * 73 */ 74 class NdProxyManager : public MainloopProcessor, private NonCopyable 75 { 76 public: 77 /** 78 * This constructor initializes a NdProxyManager instance. 79 * 80 */ NdProxyManager(otbr::Ncp::ControllerOpenThread & aNcp,std::string aBackboneInterfaceName)81 explicit NdProxyManager(otbr::Ncp::ControllerOpenThread &aNcp, std::string aBackboneInterfaceName) 82 : mNcp(aNcp) 83 , mBackboneInterfaceName(std::move(aBackboneInterfaceName)) 84 , mIcmp6RawSock(-1) 85 , mUnicastNsQueueSock(-1) 86 , mNfqHandler(nullptr) 87 , mNfqQueueHandler(nullptr) 88 { 89 } 90 91 /** 92 * This method initializes a ND Proxy manager instance. 93 * 94 */ 95 void Init(void); 96 97 /** 98 * This method enables the ND Proxy manager. 99 * 100 * @param[in] aDomainPrefix The Domain Prefix. 101 * 102 */ 103 void Enable(const Ip6Prefix &aDomainPrefix); 104 105 /** 106 * This method disables the ND Proxy manager. 107 * 108 */ 109 void Disable(void); 110 111 void Update(MainloopContext &aMainloop) override; 112 void Process(const MainloopContext &aMainloop) override; 113 114 /** 115 * This method handles a Backbone Router ND Proxy event. 116 * 117 * @param[in] aEvent The Backbone Router ND Proxy event type. 118 * @param[in] aDua The Domain Unicast Address of the ND Proxy, or `nullptr` if @p `aEvent` is 119 * `OT_BACKBONE_ROUTER_NDPROXY_CLEARED`. 120 * 121 */ 122 void HandleBackboneRouterNdProxyEvent(otBackboneRouterNdProxyEvent aEvent, const otIp6Address *aDua); 123 124 /** 125 * This method returns if the ND Proxy manager is enabled. 126 * 127 * @returns If the ND Proxy manager is enabled; 128 * 129 */ IsEnabled(void) const130 bool IsEnabled(void) const { return mIcmp6RawSock >= 0; } 131 132 private: 133 enum 134 { 135 kMaxICMP6PacketSize = 1500, ///< Max size of an ICMP6 packet in bytes. 136 }; 137 138 void SendNeighborAdvertisement(const Ip6Address &aTarget, const Ip6Address &aDst); 139 otbrError UpdateMacAddress(void); 140 otbrError InitIcmp6RawSocket(void); 141 void FiniIcmp6RawSocket(void); 142 otbrError InitNetfilterQueue(void); 143 void FiniNetfilterQueue(void); 144 void ProcessMulticastNeighborSolicition(void); 145 void ProcessUnicastNeighborSolicition(void); 146 void JoinSolicitedNodeMulticastGroup(const Ip6Address &aTarget) const; 147 void LeaveSolicitedNodeMulticastGroup(const Ip6Address &aTarget) const; 148 static int HandleNetfilterQueue(struct nfq_q_handle *aNfQueueHandler, 149 struct nfgenmsg * aNfMsg, 150 struct nfq_data * aNfData, 151 void * aContext); 152 int HandleNetfilterQueue(struct nfq_q_handle *aNfQueueHandler, struct nfgenmsg *aNfMsg, struct nfq_data *aNfData); 153 154 otbr::Ncp::ControllerOpenThread &mNcp; 155 std::string mBackboneInterfaceName; 156 std::set<Ip6Address> mNdProxySet; 157 uint32_t mBackboneIfIndex; 158 int mIcmp6RawSock; 159 int mUnicastNsQueueSock; 160 struct nfq_handle * mNfqHandler; ///< A pointer to an NFQUEUE handler. 161 struct nfq_q_handle * mNfqQueueHandler; ///< A pointer to a newly created queue. 162 MacAddress mMacAddress; 163 Ip6Prefix mDomainPrefix; 164 }; 165 166 /** 167 * @} 168 */ 169 170 } // namespace BackboneRouter 171 } // namespace otbr 172 173 #endif // OTBR_ENABLE_DUA_ROUTING 174 #endif // ND_PROXY_HPP_ 175