-
Notifications
You must be signed in to change notification settings - Fork 390
/
multicast.h
276 lines (242 loc) · 10.7 KB
/
multicast.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
/*
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/
#ifndef multicast_agent_oper_hpp
#define multicast_agent_oper_hpp
#include <netinet/in.h>
#include <net/ethernet.h>
#include <cmn/agent_cmn.h>
#include <cmn/agent.h>
#include <oper/nexthop.h>
#include <oper/vn.h>
extern SandeshTraceBufferPtr MulticastTraceBuf;
#define MCTRACE(obj, ...) \
do { \
Multicast##obj::TraceMsg(MulticastTraceBuf, __FILE__, __LINE__, __VA_ARGS__);\
} while (false); \
#define IS_BCAST_MCAST(grp) ((grp.to_ulong() == 0xFFFFFFFF) || \
((grp.to_ulong() & 0xF0000000) == 0xE0000000))
struct OlistTunnelEntry {
OlistTunnelEntry(const boost::uuids::uuid &device_uuid,
uint32_t label,
const Ip4Address &addr,
TunnelType::TypeBmap bmap) :
device_uuid_(device_uuid),
label_(label),
daddr_(addr),
tunnel_bmap_(bmap) { }
virtual ~OlistTunnelEntry() { }
boost::uuids::uuid device_uuid_;
uint32_t label_;
Ip4Address daddr_;
TunnelType::TypeBmap tunnel_bmap_;
};
struct MulticastDBState : DBState {
MulticastDBState(const std::string &vrf_name, const uint32_t vxlan_id) :
vrf_name_(vrf_name), vxlan_id_(vxlan_id) { }
std::string vrf_name_;
uint32_t vxlan_id_;
};
typedef std::vector<OlistTunnelEntry> TunnelOlist;
class MulticastGroupObject {
public:
MulticastGroupObject(const std::string &vrf_name,
const Ip4Address &grp_addr,
const std::string &vn_name) :
vrf_name_(vrf_name), grp_address_(grp_addr), vn_name_(vn_name),
vxlan_id_(0), peer_identifier_(0), deleted_(false), vn_(NULL) {
boost::system::error_code ec;
src_address_ = IpAddress::from_string("0.0.0.0", ec).to_v4();
local_olist_.clear();
};
MulticastGroupObject(const std::string &vrf_name,
const Ip4Address &grp_addr,
const Ip4Address &src_addr) :
vrf_name_(vrf_name), grp_address_(grp_addr), src_address_(src_addr),
vxlan_id_(0), peer_identifier_(0), deleted_(false), vn_(NULL) {
local_olist_.clear();
};
virtual ~MulticastGroupObject() { };
bool CanBeDeleted() const;
//Add local member is local VM in server.
bool AddLocalMember(const boost::uuids::uuid &intf_uuid) {
if (std::find(local_olist_.begin(), local_olist_.end(), intf_uuid) !=
local_olist_.end()) {
return false;
}
local_olist_.push_back(intf_uuid);
return true;
};
//Delete local member from VM list in server
bool DeleteLocalMember(const boost::uuids::uuid &intf_uuid) {
std::list<uuid>::iterator it = std::find(local_olist_.begin(),
local_olist_.end(), intf_uuid);
if (it != local_olist_.end()) {
local_olist_.erase(it);
return true;
}
return false;
};
uint32_t GetLocalListSize() { return local_olist_.size(); };
//Labels for server + server list + ingress source label
void FlushAllPeerInfo(const Agent *agent,
const Peer *peer,
uint64_t peer_identifier);
//Gets
const std::string &vrf_name() { return vrf_name_; };
const Ip4Address &GetGroupAddress() { return grp_address_; };
const Ip4Address &GetSourceAddress() { return src_address_; };
const std::list<boost::uuids::uuid> &GetLocalOlist() {
return local_olist_;}
const std::string &GetVnName() { return vn_name_; };
bool IsDeleted() { return deleted_; };
void Deleted(bool val) { deleted_ = val; };
bool CanUnsubscribe() const {return (deleted_);}
void set_vxlan_id(uint32_t vxlan_id) {vxlan_id_ = vxlan_id;}
uint32_t vxlan_id() const {return vxlan_id_;}
void set_peer_identifier(uint64_t peer_id) {peer_identifier_ = peer_id;}
uint64_t peer_identifier() {return peer_identifier_;}
void set_vn(const VnEntry *vn);
void reset_vn();
const VnEntry *vn() const {return vn_.get();}
private:
std::string vrf_name_;
Ip4Address grp_address_;
std::string vn_name_;
Ip4Address src_address_;
uint32_t vxlan_id_;
uint64_t peer_identifier_;
bool deleted_;
std::list<boost::uuids::uuid> local_olist_; /* UUID of local i/f */
VnEntryConstRef vn_;
friend class MulticastHandler;
DISALLOW_COPY_AND_ASSIGN(MulticastGroupObject);
};
/* Static class for handling multicast objects common functionalities */
class MulticastHandler {
public:
static const uint32_t kMulticastTimeout = 5 * 60 * 1000;
MulticastHandler(Agent *agent);
virtual ~MulticastHandler() { }
MulticastGroupObject *CreateMulticastGroupObject(const string &vrf_name,
const Ip4Address &ip_addr,
const VnEntry *vn,
uint32_t vxlan_id);
/* Called by XMPP to add ctrl node sent olist and label */
void ModifyFabricMembers(const Peer *peer,
const std::string &vrf_name,
const Ip4Address &group,
const Ip4Address &source,
uint32_t source_label,
const TunnelOlist &olist,
uint64_t peer_identifier = 0);
/* Called as a result of XMPP message received with OLIST of
* evpn endpoints with mpls or vxlan encap
*/
void ModifyEvpnMembers(const Peer *peer,
const std::string &vrf_name,
const TunnelOlist &olist,
uint32_t ethernet_tag,
uint64_t peer_identifier = 0);
void ModifyTorMembers(const Peer *peer,
const std::string &vrf_name,
const TunnelOlist &olist,
uint32_t ethernet_tag,
uint64_t peer_identifier = 0);
//Registered for VN notification
void ModifyVN(DBTablePartBase *partition, DBEntryBase *e);
//Registered for VM notification
void ModifyVmInterface(DBTablePartBase *partition, DBEntryBase *e);
//Register VM and VN notification
void Register();
//Singleton object reference
static MulticastHandler *GetInstance() {
return obj_;
};
void TriggerLocalRouteChange(MulticastGroupObject *obj, const Peer *peer);
void TriggerRemoteRouteChange(MulticastGroupObject *obj,
const Peer *peer,
const string &vrf_name,
const TunnelOlist &olist,
uint64_t peer_identifier,
bool delete_op,
COMPOSITETYPE comp_type,
uint32_t label,
bool fabric,
uint32_t ethernet_tag);
void HandleIpam(const VnEntry *vn);
void HandleVxLanChange(const VnEntry *vn);
void HandleVnParametersChange(DBTablePartBase *partition,
DBEntryBase *e);
//For test routines to clear all routes and mpls label
void Shutdown();
//Multicast obj list addition deletion
MulticastGroupObject *FindFloodGroupObject(const std::string &vrf_name);
MulticastGroupObject *FindActiveGroupObject(const std::string &vrf_name,
const Ip4Address &dip);
std::set<MulticastGroupObject *> &GetMulticastObjList() {
return multicast_obj_list_;
};
MulticastGroupObject *FindGroupObject(const std::string &vrf_name,
const Ip4Address &dip);
ComponentNHKeyList GetInterfaceComponentNHKeyList(MulticastGroupObject *obj,
uint8_t flags);
bool FlushPeerInfo(uint64_t peer_sequence);
void DeleteBroadcast(const Peer *peer,
const std::string &vrf_name,
uint32_t ethernet_tag,
COMPOSITETYPE type);
void DeleteMulticastObject(const std::string &vrf_name,
const Ip4Address &grp_addr);
const Agent *agent() const {return agent_;}
void Terminate();
private:
//operations on list of all objectas per group/source/vrf
void AddToMulticastObjList(MulticastGroupObject *obj) {
multicast_obj_list_.insert(obj);
};
//VM intf add-delete
void DeleteVmInterface(const Interface *intf);
void AddVmInterfaceInFloodGroup(const VmInterface *vm_itf);
//broadcast rt add /delete
void AddL2BroadcastRoute(MulticastGroupObject *obj,
const std::string &vrf_name,
const std::string &vn_name,
const Ip4Address &addr,
uint32_t label,
int vxlan_id,
uint32_t ethernet_tag);
//VM itf to multicast ob
void AddVmToMulticastObjMap(const boost::uuids::uuid &vm_itf_uuid,
MulticastGroupObject *obj) {
this->vm_to_mcobj_list_[vm_itf_uuid].push_back(obj);
};
void DeleteVmToMulticastObjMap(const boost::uuids::uuid &vm_itf_uuid) {
if (this->vm_to_mcobj_list_[vm_itf_uuid].size() == 0) {
std::map<uuid, std::list<MulticastGroupObject *> >::iterator it =
this->vm_to_mcobj_list_.find(vm_itf_uuid);
if (it != this->vm_to_mcobj_list_.end()) {
this->vm_to_mcobj_list_.erase(it);
}
}
};
std::list<MulticastGroupObject *> &
GetVmToMulticastObjMap(const boost::uuids::uuid &uuid)
{
return this->vm_to_mcobj_list_[uuid];
};
static MulticastHandler *obj_;
Agent *agent_;
std::map<std::string, std::vector<VnIpam> > vrf_ipam_mapping_;
//VN uuid to VRF name mapping
std::map<uuid, string> vn_vrf_mapping_;
//VM uuid <-> VN uuid
//List of all multicast objects(VRF/G/S)
std::set<MulticastGroupObject *> multicast_obj_list_;
//Reference mapping of VM to participating multicast object list
std::map<uuid, std::list<MulticastGroupObject *> > vm_to_mcobj_list_;
DBTable::ListenerId vn_listener_id_;
DBTable::ListenerId interface_listener_id_;
DISALLOW_COPY_AND_ASSIGN(MulticastHandler);
};
#endif /* multicast_agent_oper_hpp */