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 #ifndef OT_POSIX_PLATFORM_MULTICAST_ROUTING_HPP_
30 #define OT_POSIX_PLATFORM_MULTICAST_ROUTING_HPP_
31 
32 #include "openthread-posix-config.h"
33 
34 #if OPENTHREAD_POSIX_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
35 
36 #include <stdio.h>
37 #include <stdlib.h>
38 
39 #include <openthread/backbone_router_ftd.h>
40 #include <openthread/openthread-system.h>
41 
42 #include "platform-posix.h"
43 #include "core/common/non_copyable.hpp"
44 #include "core/net/ip6_address.hpp"
45 #include "lib/url/url.hpp"
46 #include "posix/platform/mainloop.hpp"
47 
48 namespace ot {
49 namespace Posix {
50 
51 class MulticastRoutingManager : public Mainloop::Source, private NonCopyable
52 {
53 public:
MulticastRoutingManager()54     explicit MulticastRoutingManager()
55 
56         : mLastExpireTime(0)
57         , mMulticastRouterSock(-1)
58     {
59     }
60 
IsEnabled(void) const61     bool IsEnabled(void) const { return mMulticastRouterSock >= 0; }
62     void SetUp(void);
63     void TearDown(void);
64     void Update(otSysMainloopContext &aContext) override;
65     void Process(const otSysMainloopContext &aContext) override;
66     void HandleStateChange(otInstance *aInstance, otChangedFlags aFlags);
67 
68 private:
69     enum
70     {
71         kMulticastForwardingCacheExpireTimeout    = 300, //< Expire timeout of Multicast Forwarding Cache (in seconds)
72         kMulticastForwardingCacheExpiringInterval = 60,  //< Expire interval of Multicast Forwarding Cache (in seconds)
73         kMulticastForwardingCacheTableSize =
74             OPENTHREAD_POSIX_CONFIG_MAX_MULTICAST_FORWARDING_CACHE_TABLE, //< The max size of MFC table.
75     };
76 
77     enum MifIndex : uint8_t
78     {
79         kMifIndexNone     = 0xff,
80         kMifIndexThread   = 0,
81         kMifIndexBackbone = 1,
82     };
83 
84     class MulticastForwardingCache
85     {
86         friend class MulticastRoutingManager;
87 
88     private:
MulticastForwardingCache()89         MulticastForwardingCache()
90             : mIif(kMifIndexNone)
91         {
92         }
93 
IsValid() const94         bool IsValid() const { return mIif != kMifIndexNone; }
95         void Set(MifIndex aIif, MifIndex aOif);
96         void Set(const Ip6::Address &aSrcAddr, const Ip6::Address &aGroupAddr, MifIndex aIif, MifIndex aOif);
Erase(void)97         void Erase(void) { mIif = kMifIndexNone; }
98         void SetValidPktCnt(unsigned long aValidPktCnt);
99 
100         Ip6::Address  mSrcAddr;
101         Ip6::Address  mGroupAddr;
102         uint64_t      mLastUseTime;
103         unsigned long mValidPktCnt;
104         MifIndex      mIif;
105         MifIndex      mOif;
106     };
107 
108     void    Enable(void);
109     void    Disable(void);
110     void    Add(const Ip6::Address &aAddress);
111     void    Remove(const Ip6::Address &aAddress);
112     void    UpdateMldReport(const Ip6::Address &aAddress, bool isAdd);
113     bool    HasMulticastListener(const Ip6::Address &aAddress) const;
114     void    InitMulticastRouterSock(void);
115     void    FinalizeMulticastRouterSock(void);
116     void    ProcessMulticastRouterMessages(void);
117     otError AddMulticastForwardingCache(const Ip6::Address &aSrcAddr, const Ip6::Address &aGroupAddr, MifIndex aIif);
118     void    SaveMulticastForwardingCache(const Ip6::Address &aSrcAddr,
119                                          const Ip6::Address &aGroupAddr,
120                                          MifIndex            aIif,
121                                          MifIndex            aOif);
122     void    UnblockInboundMulticastForwardingCache(const Ip6::Address &aGroupAddr);
123     void    RemoveInboundMulticastForwardingCache(const Ip6::Address &aGroupAddr);
124     void    ExpireMulticastForwardingCache(void);
125     bool    UpdateMulticastRouteInfo(MulticastForwardingCache &aMfc) const;
126     void    RemoveMulticastForwardingCache(MulticastForwardingCache &aMfc) const;
127     static const char *MifIndexToString(MifIndex aMif);
128     void               DumpMulticastForwardingCache(void) const;
129     static void        HandleBackboneMulticastListenerEvent(void                                  *aContext,
130                                                             otBackboneRouterMulticastListenerEvent aEvent,
131                                                             const otIp6Address                    *aAddress);
132     void               HandleBackboneMulticastListenerEvent(otBackboneRouterMulticastListenerEvent aEvent,
133                                                             const Ip6::Address                    &aAddress);
134 
135     MulticastForwardingCache mMulticastForwardingCacheTable[kMulticastForwardingCacheTableSize];
136     uint64_t                 mLastExpireTime;
137     int                      mMulticastRouterSock;
138 };
139 
140 } // namespace Posix
141 } // namespace ot
142 
143 #endif // OPENTHREAD_POSIX_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
144 
145 #endif // OT_POSIX_PLATFORM_MULTICAST_ROUTING_HPP_
146