Line data Source code
1 : /*
2 : * Copyright (c) 2017 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : */
5 :
6 : #ifndef vnsw_agent_gmp_proto_h
7 : #define vnsw_agent_gmp_proto_h
8 :
9 : typedef struct gmp_intf_ gmp_intf;
10 : typedef struct _mgm_global_data mgm_global_data;
11 : class TaskMap;
12 : class GmpIntf;
13 : class GmpProto;
14 :
15 : #define GMP_TX_BUFF_LEN 512
16 :
17 : struct GmpPacket {
18 68 : GmpPacket(uint8_t *pkt, uint32_t pkt_len, IpAddress dst_addr)
19 68 : : pkt_(pkt), pkt_len_(pkt_len), dst_addr_(dst_addr) {}
20 :
21 : uint8_t *pkt_;
22 : uint32_t pkt_len_;
23 : IpAddress dst_addr_;
24 : };
25 :
26 : class GmpSourceGroup {
27 : public:
28 0 : GmpSourceGroup() {
29 0 : source_ = IpAddress();
30 0 : group_ = IpAddress();
31 0 : flags_ = 0;
32 0 : mode_ = GMP_MODE_INVALID;
33 0 : refcount_ = 0;
34 0 : }
35 0 : ~GmpSourceGroup() { }
36 :
37 : enum IgmpVersion {
38 : IGMP_VERSION_V1 = 1 << 0,
39 : IGMP_VERSION_V2 = 1 << 1,
40 : IGMP_VERSION_V3 = 1 << 2,
41 : };
42 :
43 : enum GmpMode {
44 : GMP_MODE_INVALID,
45 : GMP_MODE_INCLUDE,
46 : GMP_MODE_EXCLUDE,
47 : };
48 :
49 : IpAddress source_;
50 : IpAddress group_;
51 : uint8_t flags_;
52 : GmpMode mode_;
53 : uint32_t refcount_;
54 : };
55 :
56 : class VnGmpIntfState;
57 : class VnGmpDBState : public DBState {
58 : public:
59 : typedef std::set<GmpSourceGroup *> VnGmpIntfSGList;
60 : typedef VnGmpIntfSGList::iterator VnGmpSGIntfListIter;
61 :
62 : class VnGmpIntfState {
63 : public:
64 :
65 80 : VnGmpIntfState() { }
66 80 : ~VnGmpIntfState() { }
67 :
68 : GmpIntf *gmp_intf_;
69 : VnGmpIntfSGList gmp_intf_sg_list_;
70 : };
71 :
72 : typedef std::map<IpAddress, VnGmpIntfState *> VnGmpIntfMap;
73 : typedef std::set<GmpSourceGroup *> VnGmpSGList;
74 : typedef VnGmpSGList::iterator VnGmpSGListIter;
75 :
76 66 : VnGmpDBState() : DBState() { }
77 132 : ~VnGmpDBState() { }
78 :
79 : VnGmpIntfMap gmp_intf_map_;
80 : VnGmpSGList gmp_sg_list_;
81 : };
82 :
83 : class VmiGmpDBState : public DBState {
84 : public:
85 0 : VmiGmpDBState() : DBState(), vrf_name_(), vmi_v4_addr_() { }
86 0 : ~VmiGmpDBState() {}
87 :
88 : std::string vrf_name_;
89 : IpAddress vmi_v4_addr_;
90 : };
91 :
92 : class GmpIntf {
93 : public:
94 : GmpIntf(const GmpProto *);
95 80 : ~GmpIntf() {};
96 :
97 80 : void SetGif(gmp_intf *gif) { gif_ = gif; }
98 160 : gmp_intf *GetGif() { return gif_; }
99 68 : const IpAddress get_ip_address() { return ip_addr_; }
100 : bool set_ip_address(const IpAddress &ip_addr);
101 68 : const string &get_vrf_name() { return vrf_name_; }
102 : bool set_vrf_name(const std::string &vrf_name);
103 : bool set_gmp_querying(bool querying);
104 :
105 : private:
106 : const GmpProto *gmp_proto_;
107 : string vrf_name_;
108 : IpAddress ip_addr_;
109 : gmp_intf *gif_;
110 : bool querying_;
111 : };
112 :
113 : struct GmpType {
114 : enum Type {
115 : INVALID,
116 : IGMP,
117 : MAX_TYPE,
118 : };
119 : };
120 :
121 : class GmpProto {
122 : public:
123 : static const int kGmpTriggerRestartTimer = 100; /* milli-seconds */
124 : typedef boost::function<bool(const VrfEntry *, IpAddress, GmpPacket *)> Callback;
125 : struct GmpStats {
126 141 : GmpStats() { Reset(); }
127 181 : void Reset() {
128 181 : gmp_g_add_count_ = 0;
129 181 : gmp_g_del_count_ = 0;
130 :
131 181 : gmp_sg_add_count_ = 0;
132 181 : gmp_sg_del_count_ = 0;
133 181 : }
134 :
135 : uint32_t gmp_g_add_count_;
136 : uint32_t gmp_g_del_count_;
137 :
138 : uint32_t gmp_sg_add_count_;
139 : uint32_t gmp_sg_del_count_;
140 : };
141 :
142 : GmpProto(GmpType::Type type, Agent *agent, const std::string &task_name,
143 : int instance, boost::asio::io_context &io);
144 : ~GmpProto();
145 : GmpIntf *CreateIntf();
146 : bool DeleteIntf(GmpIntf *gif);
147 :
148 2 : void Register(Callback cb) { cb_ = cb; }
149 :
150 : bool Start();
151 : bool Stop();
152 :
153 : void GmpIntfSGClear(VnGmpDBState *state,
154 : VnGmpDBState::VnGmpIntfState *gmp_intf_state);
155 :
156 : DBTableBase::ListenerId vn_listener_id();
157 : DBTableBase::ListenerId itf_listener_id();
158 :
159 : bool GmpProcessPkt(const VmInterface *vm_itf, void *rcv_pkt,
160 : uint32_t packet_len, IpAddress ip_saddr,
161 : IpAddress ip_daddr);
162 : uint8_t *GmpBufferGet();
163 : void GmpBufferFree(uint8_t *pkt);
164 : bool GmpNotificationHandler();
165 : bool GmpNotificationTimer();
166 : void GmpNotificationReady();
167 : void GroupNotify(GmpIntf *gif, IpAddress source, IpAddress group,
168 : int group_action);
169 : void ResyncNotify(GmpIntf *gif, IpAddress source, IpAddress group);
170 : void UpdateHostInSourceGroup(GmpIntf *gif, bool join, IpAddress host,
171 : IpAddress source, IpAddress group);
172 : void TriggerMvpnNotification(const VmInterface *vm_intf, bool join,
173 : IpAddress source, IpAddress group);
174 : void TriggerEvpnNotification(const VmInterface *vm_intf, bool join,
175 : IpAddress source, IpAddress group);
176 : bool MulticastPolicyCheck(GmpIntf *gif, IpAddress source, IpAddress group);
177 : bool SendPacket(GmpIntf *gif, uint8_t *pkt, uint32_t pkt_len,
178 : IpAddress dest);
179 134 : const GmpStats &GetStats() const { return stats_; }
180 40 : void ClearStats() { stats_.Reset(); }
181 :
182 : private:
183 : void GmpVnNotify(DBTablePartBase *part, DBEntryBase *entry);
184 : void GmpVrfNotify(DBTablePartBase *part, DBEntryBase *entry);
185 : void GmpItfNotify(DBTablePartBase *part, DBEntryBase *entry);
186 :
187 : GmpType::Type type_;
188 : Agent *agent_;
189 : const std::string &name_;
190 : int instance_;
191 : boost::asio::io_context &io_;
192 :
193 : DBTableBase::ListenerId vn_listener_id_;
194 : DBTableBase::ListenerId itf_listener_id_;
195 :
196 : TaskMap *task_map_;
197 : Timer *gmp_trigger_timer_;
198 : TaskTrigger *gmp_notif_trigger_;
199 : mgm_global_data *gd_;
200 : Callback cb_;
201 :
202 : GmpStats stats_;
203 : int itf_attach_count_;
204 :
205 : typedef std::map<IpAddress, boost::uuids::uuid> VmIpInterfaceMap;
206 : VmIpInterfaceMap vm_ip_to_vmi_;
207 :
208 : friend class GmpIntf;
209 : };
210 :
211 : class GmpProtoManager {
212 : public:
213 : static GmpProto *CreateGmpProto(GmpType::Type type, Agent *agent,
214 : const std::string &name, int instance,
215 : boost::asio::io_context &io);
216 : static bool DeleteGmpProto(GmpProto *gmp_proto);
217 :
218 : friend class GmpProto;
219 : };
220 :
221 : #endif /* vnsw_agent_gmp_proto_h */
|