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