Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include <boost/uuid/uuid_io.hpp>
6 :
7 : #include <cmn/agent_cmn.h>
8 : #include <route/route.h>
9 :
10 : #include <oper/route_common.h>
11 : #include <oper/vrf.h>
12 : #include <oper/tunnel_nh.h>
13 : #include <oper/mpls.h>
14 : #include <oper/vxlan.h>
15 : #include <oper/mirror_table.h>
16 : #include <oper/multicast.h>
17 : #include <controller/controller_export.h>
18 : #include <controller/controller_peer.h>
19 : #include <controller/controller_init.h>
20 : #include <oper/agent_sandesh.h>
21 :
22 : using namespace std;
23 : using namespace boost::asio;
24 :
25 0 : static void MulticastTableEnqueue(Agent *agent, DBRequest *req) {
26 0 : AgentRouteTable *table = agent->fabric_inet4_multicast_table();
27 0 : if (table) {
28 0 : table->Enqueue(req);
29 : }
30 0 : }
31 :
32 0 : static void MulticastTableProcess(Agent *agent, const string &vrf_name,
33 : DBRequest &req) {
34 : AgentRouteTable *table =
35 0 : agent->vrf_table()->GetInet4MulticastRouteTable(vrf_name);
36 0 : if (table) {
37 0 : table->Process(req);
38 : }
39 0 : }
40 :
41 12 : DBTableBase *Inet4MulticastAgentRouteTable::CreateTable(DB *db,
42 : const std::string &name) {
43 12 : AgentRouteTable *table = new Inet4MulticastAgentRouteTable(db, name);
44 12 : table->Init();
45 : //table->InitRouteTable(db, table, name, Agent::INET4_MULTICAST);
46 12 : return table;
47 : }
48 :
49 : void
50 0 : Inet4MulticastAgentRouteTable::AddMulticastRoute(const string &vrf_name,
51 : const string &vn_name,
52 : const Ip4Address &src_addr,
53 : const Ip4Address &grp_addr,
54 : ComponentNHKeyList
55 : &component_nh_key_list) {
56 0 : DBRequest nh_req;
57 : NextHopKey *nh_key;
58 : CompositeNHData *nh_data;
59 :
60 0 : nh_key = new CompositeNHKey(Composite::L3COMP, true, component_nh_key_list,
61 0 : vrf_name);
62 0 : nh_req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
63 0 : nh_req.key.reset(nh_key);
64 0 : nh_data = new CompositeNHData();
65 0 : nh_req.data.reset(nh_data);
66 :
67 0 : DBRequest req;
68 0 : req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
69 : Inet4MulticastRouteKey *rt_key = new Inet4MulticastRouteKey(vrf_name,
70 : grp_addr,
71 0 : src_addr);
72 : MulticastRoute *data = new MulticastRoute(vn_name,
73 : MplsTable::kInvalidLabel,
74 : VxLanTable::kInvalidvxlan_id,
75 0 : TunnelType::AllType(),
76 0 : nh_req, Composite::L3COMP, 0);
77 0 : req.key.reset(rt_key);
78 0 : req.data.reset(data);
79 0 : MulticastTableEnqueue(Agent::GetInstance(), &req);
80 0 : }
81 :
82 : void
83 0 : Inet4MulticastAgentRouteTable::AddMulticastRoute(const Peer *peer,
84 : const string &vrf_name,
85 : const Ip4Address &src_addr,
86 : const Ip4Address &grp_addr,
87 : uint32_t ethernet_tag,
88 : AgentRouteData *data) {
89 :
90 0 : DBRequest req;
91 0 : req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
92 : Inet4MulticastRouteKey *rt_key = new Inet4MulticastRouteKey(peer, vrf_name,
93 0 : grp_addr, src_addr, ethernet_tag);
94 0 : req.key.reset(rt_key);
95 0 : req.data.reset(data);
96 0 : MulticastTableEnqueue(Agent::GetInstance(), &req);
97 0 : }
98 :
99 : void
100 0 : Inet4MulticastAgentRouteTable::AddVHostRecvRoute(const string &vm_vrf,
101 : const string &interface_name,
102 : const Ip4Address &addr,
103 : bool policy)
104 : {
105 0 : DBRequest req;
106 :
107 0 : req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
108 0 : Inet4MulticastRouteKey *rt_key = new Inet4MulticastRouteKey(vm_vrf, addr);
109 0 : req.key.reset(rt_key);
110 : VmInterfaceKey intf_key(AgentKey::ADD_DEL_CHANGE,
111 0 : boost::uuids::nil_uuid(), interface_name);
112 : ReceiveRoute *data =
113 : new ReceiveRoute(intf_key, MplsTable::kInvalidLabel,
114 0 : TunnelType::AllType(), policy,
115 0 : Agent::GetInstance()->fabric_vn_name());
116 : //data->SetMulticast(true);
117 0 : req.data.reset(data);
118 0 : MulticastTableEnqueue(Agent::GetInstance(), &req);
119 0 : }
120 :
121 : void
122 0 : Inet4MulticastAgentRouteTable::DeleteMulticastRoute(const string &vrf_name,
123 : const Ip4Address &src_addr,
124 : const Ip4Address &grp_addr)
125 : {
126 0 : DBRequest req;
127 :
128 0 : req.oper = DBRequest::DB_ENTRY_DELETE;
129 : Inet4MulticastRouteKey *rt_key = new Inet4MulticastRouteKey(vrf_name,
130 : grp_addr,
131 0 : src_addr);
132 :
133 0 : req.key.reset(rt_key);
134 0 : req.data.reset(NULL);
135 0 : MulticastTableEnqueue(Agent::GetInstance(), &req);
136 0 : }
137 :
138 : void
139 0 : Inet4MulticastAgentRouteTable::DeleteMulticastRoute(const Peer *peer,
140 : const string &vrf_name,
141 : const Ip4Address &src_addr,
142 : const Ip4Address &grp_addr,
143 : uint32_t ethernet_tag,
144 : COMPOSITETYPE type) {
145 :
146 0 : DBRequest req(DBRequest::DB_ENTRY_DELETE);
147 : Inet4MulticastRouteKey *rt_key = new Inet4MulticastRouteKey(peer, vrf_name,
148 0 : grp_addr, src_addr, ethernet_tag);
149 0 : req.key.reset(rt_key);
150 :
151 0 : DBRequest nh_req;
152 0 : const BgpPeer *bgp_peer = dynamic_cast<const BgpPeer *>(peer);
153 0 : if (bgp_peer) {
154 0 : req.data.reset(new MulticastRoute("", 0, ethernet_tag,
155 0 : TunnelType::AllType(), nh_req, type,
156 0 : bgp_peer->sequence_number()));
157 : } else {
158 0 : req.data.reset(new MulticastRoute("", 0, ethernet_tag,
159 0 : TunnelType::AllType(), nh_req, type, 0));
160 : }
161 :
162 0 : MulticastTableEnqueue(Agent::GetInstance(), &req);
163 0 : }
164 :
165 0 : void Inet4MulticastAgentRouteTable::Delete(const string &vrf_name,
166 : const Ip4Address &src_addr,
167 : const Ip4Address &grp_addr) {
168 0 : DBRequest req(DBRequest::DB_ENTRY_DELETE);
169 0 : req.key.reset(new Inet4MulticastRouteKey(vrf_name, grp_addr, src_addr));
170 0 : req.data.reset(NULL);
171 0 : MulticastTableProcess(Agent::GetInstance(), vrf_name, req);
172 0 : }
173 :
174 : AgentRoute *
175 0 : Inet4MulticastRouteKey::AllocRouteEntry(VrfEntry *vrf, bool is_multicast) const
176 : {
177 0 : Inet4MulticastRouteEntry * entry = new Inet4MulticastRouteEntry(vrf, dip_,
178 0 : sip_);
179 0 : return static_cast<AgentRoute *>(entry);
180 : }
181 :
182 0 : AgentRouteKey *Inet4MulticastRouteKey::Clone() const {
183 0 : return (new Inet4MulticastRouteKey(vrf_name_, dip_, sip_));
184 : }
185 :
186 : Inet4MulticastRouteEntry *
187 0 : Inet4MulticastAgentRouteTable::FindRoute(const Ip4Address &grp_addr,
188 : const Ip4Address &src_addr) {
189 :
190 0 : Inet4MulticastRouteEntry entry(vrf_entry(), grp_addr, src_addr);
191 0 : return static_cast<Inet4MulticastRouteEntry *>(FindActiveEntry(&entry));
192 0 : }
193 :
194 0 : string Inet4MulticastRouteKey::ToString() const {
195 0 : ostringstream str;
196 0 : str << "Group:";
197 0 : str << dip_.to_string();
198 0 : str << " Src:";
199 0 : str << sip_.to_string();
200 0 : return str.str();
201 0 : }
202 :
203 0 : string Inet4MulticastRouteEntry::ToString() const {
204 0 : ostringstream str;
205 0 : str << "Group:";
206 0 : str << dst_addr_.to_string();
207 0 : str << " Src:";
208 0 : str << src_addr_.to_string();
209 0 : return str.str();
210 0 : }
211 :
212 0 : int Inet4MulticastRouteEntry::CompareTo(const Route &rhs) const {
213 0 : const Inet4MulticastRouteEntry &a =
214 : static_cast<const Inet4MulticastRouteEntry &>(rhs);
215 :
216 0 : if (src_addr_ < a.src_addr_)
217 0 : return -1;
218 :
219 0 : if (src_addr_ > a.src_addr_)
220 0 : return 1;
221 :
222 0 : if (dst_addr_ < a.dst_addr_)
223 0 : return -1;
224 :
225 0 : if (dst_addr_ > a.dst_addr_)
226 0 : return 1;
227 :
228 0 : return 0;
229 : }
230 :
231 0 : DBEntryBase::KeyPtr Inet4MulticastRouteEntry::GetDBRequestKey() const {
232 : Inet4MulticastRouteKey *key =
233 0 : new Inet4MulticastRouteKey(vrf()->GetName(), dst_addr_,
234 0 : src_addr_);
235 0 : return DBEntryBase::KeyPtr(key);
236 : }
237 :
238 0 : void Inet4MulticastRouteEntry::SetKey(const DBRequestKey *key) {
239 0 : const Inet4MulticastRouteKey *k =
240 : static_cast<const Inet4MulticastRouteKey *>(key);
241 0 : SetVrf(Agent::GetInstance()->vrf_table()->FindVrfFromName(k->vrf_name()));
242 0 : Ip4Address grp(k->dest_ip_addr());
243 0 : Ip4Address src(k->src_ip_addr());
244 0 : set_dest_ip_addr(grp);
245 0 : set_src_ip_addr(src);
246 0 : }
247 :
248 0 : bool Inet4MulticastRouteEntry::ReComputePathAdd(AgentPath *path) {
249 0 : return ReComputeMulticastPaths(path, false);
250 : }
251 :
252 0 : bool Inet4MulticastRouteEntry::ReComputePathDeletion(AgentPath *path) {
253 0 : return ReComputeMulticastPaths(path, true);
254 : }
255 :
256 0 : bool Inet4MulticastRouteEntry::DBEntrySandesh(Sandesh *sresp, bool stale) const {
257 0 : Inet4McRouteResp *resp = static_cast<Inet4McRouteResp *>(sresp);
258 :
259 0 : RouteMcSandeshData data;
260 0 : data.set_src(src_ip_addr().to_string());
261 0 : data.set_grp(dest_ip_addr().to_string());
262 : MulticastGroupObject *mc_obj = MulticastHandler::GetInstance()->
263 0 : FindGroupObject(vrf()->GetName(), Ip4Address(), dest_ip_addr());
264 0 : Agent *agent = (static_cast<AgentRouteTable *>(get_table()))->agent();
265 0 : const NextHop *anh = GetActiveNextHop();
266 0 : if (!stale || anh || (mc_obj && (mc_obj->peer_identifier() != agent->controller()->
267 0 : multicast_sequence_number()))) {
268 0 : anh->SetNHSandeshData(data.nh);
269 : }
270 :
271 : std::vector<RouteMcSandeshData> &list =
272 0 : const_cast<std::vector<RouteMcSandeshData>&>(resp->get_route_list());
273 0 : list.push_back(data);
274 0 : return true;
275 0 : }
276 :
277 0 : bool Inet4MulticastRouteEntry::DBEntrySandesh(Sandesh *sresp,
278 : const Ip4Address &src_addr,
279 : const Ip4Address &dst_addr,
280 : bool stale) const {
281 :
282 0 : if (src_addr_ == src_addr && dst_addr_ == dst_addr) {
283 0 : return DBEntrySandesh(sresp, stale);
284 : }
285 :
286 0 : return false;
287 : }
288 :
289 0 : void Inet4McRouteReq::HandleRequest() const {
290 : VrfEntry *vrf =
291 0 : Agent::GetInstance()->vrf_table()->FindVrfFromId(get_vrf_index());
292 0 : if (!vrf) {
293 0 : ErrorResp *resp = new ErrorResp();
294 0 : resp->set_context(context());
295 0 : resp->Response();
296 0 : return;
297 : }
298 :
299 0 : AgentSandeshPtr sand(new AgentInet4McRtSandesh(vrf, context(), "",
300 0 : get_stale()));
301 0 : boost::system::error_code ec;
302 0 : Ip4Address zero_addr = IpAddress::from_string("0.0.0.0", ec).to_v4();
303 0 : Ip4Address src_ip, grp_ip;
304 0 : if (get_src_ip().empty()) {
305 0 : src_ip = zero_addr;
306 : } else {
307 0 : src_ip = Ip4Address::from_string(get_src_ip(), ec);
308 : }
309 0 : if (get_grp_ip().empty()) {
310 0 : sand.reset(new AgentInet4McRtSandesh(vrf, context(), "", get_stale()));
311 : } else {
312 0 : grp_ip = Ip4Address::from_string(get_grp_ip(), ec);
313 0 : sand.reset(new AgentInet4McRtSandesh(vrf, context(), "", src_ip,
314 0 : grp_ip, get_stale()));
315 : }
316 0 : sand->DoSandesh(sand);
317 0 : }
318 :
319 0 : AgentSandeshPtr Inet4MulticastAgentRouteTable::GetAgentSandesh
320 : (const AgentSandeshArguments *args, const std::string &context) {
321 0 : return AgentSandeshPtr(new AgentInet4McRtSandesh(vrf_entry(), context, "",
322 0 : false));
323 : }
|