5 #include <boost/bind/bind.hpp>
21 using namespace boost::asio;
22 using namespace boost::placeholders;
26 boost::system::error_code err;
27 if (udp_sock_.get()) {
28 udp_sock_->close(err);
50 return std::unique_ptr<DBEntry>(
static_cast<DBEntry *
>(mirror_entry));
57 (agent()->resource_manager(),
60 (agent()->resource_manager()->Allocate(rkey).get())->index();
63 OnChange(mirror_entry, req);
70 bool valid_nh =
false;
90 AddResolvedVrfMirrorEntry(mirror_entry);
97 agent()->fabric_inet4_unicast_table()->FindLPM(mirror_entry->
dip_);
105 if (mirror_entry->
sip_.is_v4() && mirror_entry->
dip_.is_v4()) {
108 mirror_entry->
sip_.to_v4(),
109 mirror_entry->
dip_.to_v4(),
111 nh_req.
key.reset(nh_key);
112 nh_req.
data.reset(NULL);
113 agent()->nexthop_table()->Process(nh_req);
115 (agent()->nexthop_table()->FindActiveEntry(nh_key));
118 AddResolvedVrfMirrorEntry(mirror_entry);
128 (agent()->nexthop_table()->FindActiveEntry(&key));
129 AddUnresolved(mirror_entry);
132 if (mirror_entry->
nh_ != nh) {
134 mirror_entry->
nh_ = nh;
141 bool vrf_changed =
false;
151 DeleteMirrorVrf(mirror_entry,
true);
152 mirror_entry->
nh_ = NULL;
153 mirror_entry->
vrf_ = NULL;
171 DeleteMirrorVrf(mirror_entry, vrf_changed);
181 if (mirror_entry->
vni_ != data->
vni_) {
192 ret |= OnChange(mirror_entry);
200 nh_req.
key.reset(nh_key);
201 nh_req.
data.reset(NULL);
202 agent()->nexthop_table()->Process(nh_req);
206 bool check_for_vrf =
false;
210 vrf =
static_cast<VrfEntry *
>(agent()->vrf_table()->
211 FindActiveEntry(&key));
212 check_for_vrf =
true;
216 (agent()->nexthop_table()->FindActiveEntry(nh_key));
217 if (nh == NULL || (check_for_vrf && vrf == NULL)) {
221 AddUnresolved(mirror_entry);
224 (agent()->nexthop_table()->FindActiveEntry(&key));
226 AddResolvedVrfMirrorEntry(mirror_entry);
229 if (mirror_entry->
nh_ != nh) {
230 mirror_entry->
nh_ = nh;
232 agent()->vrf_table()->FindVrfFromName(data->
vrf_name_);
242 DeleteMirrorVrf(mirror_entry,
true);
247 if (del_from_vrf_list) {
248 RemoveUnresolved(entry);
249 DeleteResolvedVrfMirrorEntry(entry);
253 agent()->vrf_table()->FindVrfFromName(entry->
vrf_name_);
258 agent()->vrf_table()->DeleteVrfReq(entry->
vrf_name_,
265 VrfMirrorEntryList::iterator it = vrf_entry_map.find(entry->
vrf_name_);
267 if (it != vrf_entry_map.end()) {
268 MirrorEntryList::const_iterator list_it = it->second.begin();
269 for (; list_it != it->second.end(); list_it++) {
270 if (*list_it == entry) {
275 it->second.push_back(entry);
280 list.push_back(entry);
285 VrfMirrorEntryList::iterator it = list.find(entry->
vrf_name_);
286 if (it == list.end()) {
290 MirrorEntryList::iterator list_it = it->second.begin();
291 for(;list_it != it->second.end(); list_it++) {
292 if (*list_it == entry) {
293 it->second.erase(list_it);
301 VrfMirrorEntryList::iterator it = list.find(vrf->
GetName());
302 if (it == list.end()) {
306 MirrorEntryList::iterator list_it = it->second.begin();
307 for(;list_it != it->second.end(); list_it++) {
314 *((*list_it)->GetSip()),
315 (*list_it)->GetSPort(),
316 *((*list_it)->GetDip()),
317 (*list_it)->GetDPort(), (*list_it)->GetMirrorFlag(),
318 (*list_it)->GetVni(), *((*list_it)->GetMac()),
319 (*list_it)->GetCreatedVrf());
321 req.
data.reset(data);
328 Add(unresolved_entry_list_, entry);
332 Delete(unresolved_entry_list_, entry);
336 Add(resolved_entry_list_, entry);
340 Delete(resolved_entry_list_, entry);
344 ResyncMirrorEntry(resolved_entry_list_, vrf);
348 ResyncMirrorEntry(unresolved_entry_list_, vrf);
353 const std::string &vrf_name,
356 uint32_t vni, uint8_t mirror_flag,
359 bool createdvrf =
false;
362 if (dip.is_v6() && vrf_name == mirror_table_->agent()->fabric_vrf_name()) {
363 LOG(ERROR,
"Ipv6 as destination not supported on Fabric VRF: " <<
378 dport, mirror_flag, vni, mac,
382 req.
data.reset(data);
383 mirror_table_->Enqueue(&req);
387 const std::string &vrf_name,
393 if (dip.is_v6() && vrf_name == mirror_table_->agent()->fabric_vrf_name()) {
394 LOG(ERROR,
"Ipv6 as destination not supported on Fabric VRF: " <<
402 req.
key.reset(nh_key);
403 req.
data.reset(NULL);
404 mirror_table_->agent()->nexthop_table()->Enqueue(&req);
409 sport, dip, dport, 1, 0 ,
412 req.
data.reset(data);
413 mirror_table_->Enqueue(&req);
417 uint32_t nic_assisted_mirroring_vlan) {
423 req.
data.reset(data);
424 mirror_table_->Enqueue(&req);
433 req.
data.reset(NULL);
434 mirror_table_->Enqueue(&req);
444 mirror_table_->Init();
445 return mirror_table_;
453 vrf_listener_id_ = agent()->vrf_table()->
464 UnRegisterBridgeRouteTableListener(vrf, state);
469 ResyncResolvedMirrorEntry(vrf);
475 bool miror_vrf = UnresolvedMirrorVrf(vrf, unresolved_entry_list_);
476 if (state == NULL && miror_vrf) {
489 ResyncUnresolvedMirrorEntry(vrf);
494 VrfMirrorEntryList::iterator it = list.find(vrf->
GetName());
495 if (it == list.end()) {
499 MirrorEntryList::iterator list_it = it->second.begin();
500 for(;list_it != it->second.end(); list_it++) {
501 if ((*list_it)->GetMirrorFlag() ==
512 VrfMirrorEntryList::iterator it = list.find(vrf->
GetName());
513 if (it == list.end()) {
516 MirrorEntryList::iterator list_it = it->second.begin();
517 for(;list_it != it->second.end(); list_it++) {
518 const MacAddress &remote_vm_mac = *((*list_it)->GetMac());
519 if (remote_vm_mac == mac) {
531 ResyncResolvedMirrorEntry(bridge_rt->
vrf());
533 MirrorEntry *unresolved_mirror_entry = GetMirrorEntry(bridge_rt->
vrf(),
535 unresolved_entry_list_);
536 MirrorEntry *resolved_mirror_entry = GetMirrorEntry(bridge_rt->
vrf(),
538 resolved_entry_list_);
540 if (unresolved_mirror_entry &&
543 ResyncUnresolvedMirrorEntry(bridge_rt->
vrf());
544 }
else if (resolved_mirror_entry &&
546 (resolved_mirror_entry->
nh_ !=
548 ResyncResolvedMirrorEntry(bridge_rt->
vrf());
564 size_t bytes_transferred) {
567 LOG(ERROR,
"Error reading from Mirror sock. Error : " <<
568 boost::system::system_error(ec).what());
572 udp_sock_->async_receive(boost::asio::buffer(rx_buff_,
sizeof(rx_buff_)),
574 boost::asio::placeholders::error,
575 boost::asio::placeholders::bytes_transferred));
581 event_mgr = agent()->event_manager();
583 ip::udp::endpoint ep(ip::udp::v4(),
584 agent()->params()->mirror_client_port());
586 udp_sock_.reset(
new ip::udp::socket(
io));
588 boost::system::error_code ec;
589 udp_sock_->open(ip::udp::v4(), ec);
590 assert(ec.value() == 0);
592 udp_sock_->bind(ep, ec);
593 if (ec.value() != 0) {
595 udp_sock_->bind(ep, ec);
596 assert(ec.value() == 0);
599 ip::udp::endpoint sock_ep = udp_sock_->local_endpoint(ec);
600 assert(ec.value() == 0);
601 agent()->set_mirror_port(sock_ep.port());
603 udp_sock_->async_receive(boost::asio::buffer(rx_buff_,
sizeof(rx_buff_)),
605 boost::asio::placeholders::error,
606 boost::asio::placeholders::bytes_transferred));
610 return agent()->vrf_table()->FindVrfFromName(vrf_name);
614 agent()->vrf_table()->Unregister(vrf_listener_id_);
618 VrfMirrorEntryList::iterator it;
619 for (it = resolved_entry_list_.begin(); it != resolved_entry_list_.end(); ++it) {
620 if (it->second.size() > 0) {
628 return vrf_ ? vrf_->vrf_id() : uint32_t(-1);
632 return vrf_ ? vrf_.get() : NULL;
636 data.set_analyzer_name(GetAnalyzerName());
637 data.set_sip(GetSip()->to_string());
638 data.set_dip(GetDip()->to_string());
639 data.set_vrf(GetVrf() ? GetVrf()->GetName() :
"");
640 data.set_sport(GetSPort());
641 data.set_dport(GetDPort());
642 data.set_ref_count(GetRefCount());
644 nh_->SetNHSandeshData(data.nh);
649 MirrorEntryResp *resp =
static_cast<MirrorEntryResp *
>(sresp);
651 MirrorEntrySandeshData data;
652 set_mirror_entrySandeshData(data);
653 std::vector<MirrorEntrySandeshData> &list =
654 const_cast<std::vector<MirrorEntrySandeshData>&
>
655 (resp->get_mirror_entry_list());
656 list.push_back(data);
661 void MirrorEntryReq::HandleRequest()
const {
663 sand->DoSandesh(sand);
667 const std::string &context) {
674 std::string str =
"static";
675 if (juniper_header) {
676 if (boost::iequals(nh_mode, str))
680 if (boost::iequals(nh_mode, str))
boost::asio::ip::address IpAddress
class boost::shared_ptr< AgentSandesh > AgentSandeshPtr
NextHop * nexthop() const
virtual const PrefixType & prefix_address() const
Returns the value of a stored prefix address (IPv4, IPv6 or MAC address)
const AgentPath * GetActivePath() const
std::string GetString(const std::string &key) const
VrfTable * vrf_table() const
static Agent * GetInstance()
virtual uint32_t GetActiveLabel() const
std::unique_ptr< DBRequestKey > KeyPtr
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
void ClearState(DBTableBase *tbl_base, ListenerId listener)
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
static const int kInvalidId
void Unregister(ListenerId listener)
boost::asio::io_context * io_service()
static const MacAddress & ZeroMac()
virtual KeyPtr GetDBRequestKey() const
bool DBEntrySandesh(Sandesh *sresp, std::string &name) const
const std::string GetAnalyzerName() const
const VrfEntry * GetVrf() const
bool nic_assisted_mirroring_
virtual bool IsLess(const DBEntry &rhs) const
uint16_t nic_assisted_mirroring_vlan_
virtual void SetKey(const DBRequestKey *key)
void set_mirror_index(uint32_t index)
void set_mirror_entrySandeshData(MirrorEntrySandeshData &data) const
uint32_t mirror_index() const
static void AddMirrorEntry(const std::string &analyzer_name, const std::string &vrf_name, const IpAddress &sip, uint16_t sport, const IpAddress &dip, uint16_t dport)
static DBTableBase * CreateTable(DB *db, const std::string &name)
MirrorEntry * GetMirrorEntry(VrfEntry *vrf, const MacAddress &mac, VrfMirrorEntryList &list)
static MirrorEntryData::MirrorEntryFlags DecodeMirrorFlag(const std::string &nh_mode, bool juniper_header)
void BridgeRouteTableNotify(DBTablePartBase *partition, DBEntryBase *e)
void AddUnresolved(MirrorEntry *entry)
void UnRegisterBridgeRouteTableListener(const VrfEntry *entry, MirrorVrfState *state)
void ReadHandler(const boost::system::error_code &error, size_t bytes)
std::vector< MirrorEntry * > MirrorEntryList
std::pair< std::string, MirrorEntryList > VrfMirrorEntry
VrfEntry * FindVrfEntry(const std::string &vrf_name) const
void ResyncUnresolvedMirrorEntry(const VrfEntry *vrf)
virtual bool Delete(DBEntry *entry, const DBRequest *request)
virtual AgentSandeshPtr GetAgentSandesh(const AgentSandeshArguments *args, const std::string &context)
void DeleteMirrorVrf(MirrorEntry *entry, bool del_from_vrf_list)
virtual void OnZeroRefcount(AgentDBEntry *e)
virtual bool OnChange(DBEntry *entry, const DBRequest *req)
void MirrorSockInit(void)
void RemoveUnresolved(MirrorEntry *entry)
std::map< std::string, MirrorEntryList > VrfMirrorEntryList
static MirrorTable * mirror_table_
bool UnresolvedMirrorVrf(const VrfEntry *vrf, VrfMirrorEntryList &list)
void DeleteResolvedVrfMirrorEntry(MirrorEntry *entry)
void AddResolvedVrfMirrorEntry(MirrorEntry *entry)
void ResyncResolvedMirrorEntry(const VrfEntry *vrf)
void ResyncMirrorEntry(VrfMirrorEntryList &list, const VrfEntry *vrf)
virtual std::unique_ptr< DBEntry > AllocEntry(const DBRequestKey *k) const
virtual DBEntry * Add(const DBRequest *req)
static void DelMirrorEntry(const std::string &analyzer_name)
void VrfNotify(DBTablePartBase *root, DBEntryBase *entry)
boost::shared_ptr< ResourceKey > KeyPtr
const string & GetName() const
AgentRouteTable * GetBridgeRouteTable() const
VrfEntry * FindVrfFromName(const string &name)
void CreateVrfReq(const string &name, uint32_t flags=VrfData::ConfigVrf)
#define LOG(_Level, _Msg)
std::unique_ptr< DBRequestKey > key
std::unique_ptr< DBRequestData > data
uint16_t nic_assisted_mirroring_vlan_
@ StaticNH_With_JuniperHdr
@ DynamicNH_With_JuniperHdr
@ StaticNH_Without_JuniperHdr
@ DynamicNH_Without_JuniperHdr
bool nic_assisted_mirroring_
std::string analyzer_name_
DBTableBase::ListenerId bridge_rt_table_listener_id_