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