5 #include <boost/bind.hpp>
21 using namespace boost::asio;
25 boost::system::error_code err;
26 if (udp_sock_.get()) {
27 udp_sock_->close(err);
49 return std::unique_ptr<DBEntry>(
static_cast<DBEntry *
>(mirror_entry));
56 (agent()->resource_manager(),
59 (agent()->resource_manager()->Allocate(rkey).get())->index();
62 OnChange(mirror_entry, req);
69 bool valid_nh =
false;
89 AddResolvedVrfMirrorEntry(mirror_entry);
96 agent()->fabric_inet4_unicast_table()->FindLPM(mirror_entry->
dip_);
104 if (mirror_entry->
sip_.is_v4() && mirror_entry->
dip_.is_v4()) {
107 mirror_entry->
sip_.to_v4(),
108 mirror_entry->
dip_.to_v4(),
110 nh_req.
key.reset(nh_key);
111 nh_req.
data.reset(NULL);
112 agent()->nexthop_table()->Process(nh_req);
114 (agent()->nexthop_table()->FindActiveEntry(nh_key));
117 AddResolvedVrfMirrorEntry(mirror_entry);
127 (agent()->nexthop_table()->FindActiveEntry(&key));
128 AddUnresolved(mirror_entry);
131 if (mirror_entry->
nh_ != nh) {
133 mirror_entry->
nh_ = nh;
140 bool vrf_changed =
false;
150 DeleteMirrorVrf(mirror_entry,
true);
151 mirror_entry->
nh_ = NULL;
152 mirror_entry->
vrf_ = NULL;
170 DeleteMirrorVrf(mirror_entry, vrf_changed);
180 if (mirror_entry->
vni_ != data->
vni_) {
191 ret |= OnChange(mirror_entry);
199 nh_req.
key.reset(nh_key);
200 nh_req.
data.reset(NULL);
201 agent()->nexthop_table()->Process(nh_req);
205 bool check_for_vrf =
false;
209 vrf =
static_cast<VrfEntry *
>(agent()->vrf_table()->
210 FindActiveEntry(&key));
211 check_for_vrf =
true;
215 (agent()->nexthop_table()->FindActiveEntry(nh_key));
216 if (nh == NULL || (check_for_vrf && vrf == NULL)) {
220 AddUnresolved(mirror_entry);
223 (agent()->nexthop_table()->FindActiveEntry(&key));
225 AddResolvedVrfMirrorEntry(mirror_entry);
228 if (mirror_entry->
nh_ != nh) {
229 mirror_entry->
nh_ = nh;
231 agent()->vrf_table()->FindVrfFromName(data->
vrf_name_);
241 DeleteMirrorVrf(mirror_entry,
true);
246 if (del_from_vrf_list) {
247 RemoveUnresolved(entry);
248 DeleteResolvedVrfMirrorEntry(entry);
252 agent()->vrf_table()->FindVrfFromName(entry->
vrf_name_);
257 agent()->vrf_table()->DeleteVrfReq(entry->
vrf_name_,
264 VrfMirrorEntryList::iterator it = vrf_entry_map.find(entry->
vrf_name_);
266 if (it != vrf_entry_map.end()) {
267 MirrorEntryList::const_iterator list_it = it->second.begin();
268 for (; list_it != it->second.end(); list_it++) {
269 if (*list_it == entry) {
274 it->second.push_back(entry);
279 list.push_back(entry);
284 VrfMirrorEntryList::iterator it = list.find(entry->
vrf_name_);
285 if (it == list.end()) {
289 MirrorEntryList::iterator list_it = it->second.begin();
290 for(;list_it != it->second.end(); list_it++) {
291 if (*list_it == entry) {
292 it->second.erase(list_it);
300 VrfMirrorEntryList::iterator it = list.find(vrf->
GetName());
301 if (it == list.end()) {
305 MirrorEntryList::iterator list_it = it->second.begin();
306 for(;list_it != it->second.end(); list_it++) {
313 *((*list_it)->GetSip()),
314 (*list_it)->GetSPort(),
315 *((*list_it)->GetDip()),
316 (*list_it)->GetDPort(), (*list_it)->GetMirrorFlag(),
317 (*list_it)->GetVni(), *((*list_it)->GetMac()),
318 (*list_it)->GetCreatedVrf());
320 req.
data.reset(data);
327 Add(unresolved_entry_list_, entry);
331 Delete(unresolved_entry_list_, entry);
335 Add(resolved_entry_list_, entry);
339 Delete(resolved_entry_list_, entry);
343 ResyncMirrorEntry(resolved_entry_list_, vrf);
347 ResyncMirrorEntry(unresolved_entry_list_, vrf);
352 const std::string &vrf_name,
355 uint32_t vni, uint8_t mirror_flag,
358 bool createdvrf =
false;
361 if (dip.is_v6() && vrf_name == mirror_table_->agent()->fabric_vrf_name()) {
362 LOG(ERROR,
"Ipv6 as destination not supported on Fabric VRF: " <<
377 dport, mirror_flag, vni, mac,
381 req.
data.reset(data);
382 mirror_table_->Enqueue(&req);
386 const std::string &vrf_name,
392 if (dip.is_v6() && vrf_name == mirror_table_->agent()->fabric_vrf_name()) {
393 LOG(ERROR,
"Ipv6 as destination not supported on Fabric VRF: " <<
401 req.
key.reset(nh_key);
402 req.
data.reset(NULL);
403 mirror_table_->agent()->nexthop_table()->Enqueue(&req);
408 sport, dip, dport, 1, 0 ,
411 req.
data.reset(data);
412 mirror_table_->Enqueue(&req);
416 uint32_t nic_assisted_mirroring_vlan) {
422 req.
data.reset(data);
423 mirror_table_->Enqueue(&req);
432 req.
data.reset(NULL);
433 mirror_table_->Enqueue(&req);
443 mirror_table_->Init();
444 return mirror_table_;
452 vrf_listener_id_ = agent()->vrf_table()->
463 UnRegisterBridgeRouteTableListener(vrf, state);
468 ResyncResolvedMirrorEntry(vrf);
474 bool miror_vrf = UnresolvedMirrorVrf(vrf, unresolved_entry_list_);
475 if (state == NULL && miror_vrf) {
488 ResyncUnresolvedMirrorEntry(vrf);
493 VrfMirrorEntryList::iterator it = list.find(vrf->
GetName());
494 if (it == list.end()) {
498 MirrorEntryList::iterator list_it = it->second.begin();
499 for(;list_it != it->second.end(); list_it++) {
500 if ((*list_it)->GetMirrorFlag() ==
511 VrfMirrorEntryList::iterator it = list.find(vrf->
GetName());
512 if (it == list.end()) {
515 MirrorEntryList::iterator list_it = it->second.begin();
516 for(;list_it != it->second.end(); list_it++) {
517 const MacAddress &remote_vm_mac = *((*list_it)->GetMac());
518 if (remote_vm_mac == mac) {
530 ResyncResolvedMirrorEntry(bridge_rt->
vrf());
532 MirrorEntry *unresolved_mirror_entry = GetMirrorEntry(bridge_rt->
vrf(),
534 unresolved_entry_list_);
535 MirrorEntry *resolved_mirror_entry = GetMirrorEntry(bridge_rt->
vrf(),
537 resolved_entry_list_);
539 if (unresolved_mirror_entry &&
542 ResyncUnresolvedMirrorEntry(bridge_rt->
vrf());
543 }
else if (resolved_mirror_entry &&
545 (resolved_mirror_entry->nh_ !=
547 ResyncResolvedMirrorEntry(bridge_rt->
vrf());
563 size_t bytes_transferred) {
566 LOG(ERROR,
"Error reading from Mirror sock. Error : " <<
567 boost::system::system_error(ec).what());
571 udp_sock_->async_receive(boost::asio::buffer(rx_buff_,
sizeof(rx_buff_)),
573 boost::asio::placeholders::error,
574 boost::asio::placeholders::bytes_transferred));
580 event_mgr = agent()->event_manager();
581 boost::asio::io_service &io = *event_mgr->
io_service();
582 ip::udp::endpoint ep(ip::udp::v4(),
583 agent()->params()->mirror_client_port());
585 udp_sock_.reset(
new ip::udp::socket(io));
587 boost::system::error_code ec;
588 udp_sock_->open(ip::udp::v4(), ec);
589 assert(ec.value() == 0);
591 udp_sock_->bind(ep, ec);
592 if (ec.value() != 0) {
594 udp_sock_->bind(ep, ec);
595 assert(ec.value() == 0);
598 ip::udp::endpoint sock_ep = udp_sock_->local_endpoint(ec);
599 assert(ec.value() == 0);
600 agent()->set_mirror_port(sock_ep.port());
602 udp_sock_->async_receive(boost::asio::buffer(rx_buff_,
sizeof(rx_buff_)),
604 boost::asio::placeholders::error,
605 boost::asio::placeholders::bytes_transferred));
609 return agent()->vrf_table()->FindVrfFromName(vrf_name);
613 agent()->vrf_table()->Unregister(vrf_listener_id_);
617 VrfMirrorEntryList::iterator it;
618 for (it = resolved_entry_list_.begin(); it != resolved_entry_list_.end(); ++it) {
619 if (it->second.size() > 0) {
627 return vrf_ ? vrf_->vrf_id() : uint32_t(-1);
631 return vrf_ ? vrf_.get() : NULL;
635 data.set_analyzer_name(GetAnalyzerName());
636 data.set_sip(GetSip()->to_string());
637 data.set_dip(GetDip()->to_string());
638 data.set_vrf(GetVrf() ? GetVrf()->GetName() :
"");
639 data.set_sport(GetSPort());
640 data.set_dport(GetDPort());
641 data.set_ref_count(GetRefCount());
643 nh_->SetNHSandeshData(data.nh);
648 MirrorEntryResp *resp =
static_cast<MirrorEntryResp *
>(sresp);
650 MirrorEntrySandeshData data;
651 set_mirror_entrySandeshData(data);
652 std::vector<MirrorEntrySandeshData> &list =
653 const_cast<std::vector<MirrorEntrySandeshData>&
>
654 (resp->get_mirror_entry_list());
655 list.push_back(data);
660 void MirrorEntryReq::HandleRequest()
const {
662 sand->DoSandesh(sand);
666 const std::string &context) {
673 std::string str =
"static";
674 if (juniper_header) {
675 if (boost::iequals(nh_mode, str))
679 if (boost::iequals(nh_mode, str))
static const MacAddress & ZeroMac()
virtual std::unique_ptr< DBEntry > AllocEntry(const DBRequestKey *k) const
void CreateVrfReq(const string &name, uint32_t flags=VrfData::ConfigVrf)
static Agent * GetInstance()
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
std::string GetString(const std::string &key) const
VrfEntry * FindVrfFromName(const string &name)
void ReadHandler(const boost::system::error_code &error, size_t bytes)
bool nic_assisted_mirroring_
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
boost::asio::ip::address IpAddress
void DeleteResolvedVrfMirrorEntry(MirrorEntry *entry)
std::unique_ptr< DBRequestData > data
boost::shared_ptr< ResourceKey > KeyPtr
boost::asio::io_context * io_service()
void ResyncResolvedMirrorEntry(const VrfEntry *vrf)
std::map< std::string, MirrorEntryList > VrfMirrorEntryList
const string & GetName() const
std::unique_ptr< DBRequestKey > KeyPtr
void BridgeRouteTableNotify(DBTablePartBase *partition, DBEntryBase *e)
void AddResolvedVrfMirrorEntry(MirrorEntry *entry)
void Unregister(ListenerId listener)
uint16_t nic_assisted_mirroring_vlan_
void MirrorSockInit(void)
virtual void OnZeroRefcount(AgentDBEntry *e)
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
const AgentPath * GetActivePath() const
NextHop * nexthop() const
DBTableBase::ListenerId bridge_rt_table_listener_id_
const VrfEntry * GetVrf() const
std::pair< std::string, MirrorEntryList > VrfMirrorEntry
std::unique_ptr< DBRequestKey > key
AgentRouteTable * GetBridgeRouteTable() const
class boost::shared_ptr< AgentSandesh > AgentSandeshPtr
static MirrorEntryData::MirrorEntryFlags DecodeMirrorFlag(const std::string &nh_mode, bool juniper_header)
void DeleteMirrorVrf(MirrorEntry *entry, bool del_from_vrf_list)
virtual bool IsLess(const DBEntry &rhs) const
void ClearState(DBTableBase *tbl_base, ListenerId listener)
VrfEntry * FindVrfEntry(const std::string &vrf_name) const
virtual AgentSandeshPtr GetAgentSandesh(const AgentSandeshArguments *args, const std::string &context)
static void DelMirrorEntry(const std::string &analyzer_name)
virtual const PrefixType & prefix_address() const
Returns the value of a stored prefix address (IPv4, IPv6 or MAC address)
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)
VrfTable * vrf_table() const
void set_mirror_entrySandeshData(MirrorEntrySandeshData &data) const
virtual DBEntry * Add(const DBRequest *req)
uint32_t mirror_index() const
bool nic_assisted_mirroring_
void RemoveUnresolved(MirrorEntry *entry)
void ResyncUnresolvedMirrorEntry(const VrfEntry *vrf)
std::vector< MirrorEntry * > MirrorEntryList
bool UnresolvedMirrorVrf(const VrfEntry *vrf, VrfMirrorEntryList &list)
static const int kInvalidId
bool DBEntrySandesh(Sandesh *sresp, std::string &name) const
void VrfNotify(DBTablePartBase *root, DBEntryBase *entry)
#define LOG(_Level, _Msg)
virtual bool Delete(DBEntry *entry, const DBRequest *request)
const std::string GetAnalyzerName() const
static DBTableBase * CreateTable(DB *db, const std::string &name)
void AddUnresolved(MirrorEntry *entry)
void set_mirror_index(uint32_t index)
void UnRegisterBridgeRouteTableListener(const VrfEntry *entry, MirrorVrfState *state)
static MirrorTable * mirror_table_
virtual KeyPtr GetDBRequestKey() const
virtual bool OnChange(DBEntry *entry, const DBRequest *req)
std::string analyzer_name_
void ResyncMirrorEntry(VrfMirrorEntryList &list, const VrfEntry *vrf)
virtual void SetKey(const DBRequestKey *key)
uint16_t nic_assisted_mirroring_vlan_
MirrorEntry * GetMirrorEntry(VrfEntry *vrf, const MacAddress &mac, VrfMirrorEntryList &list)
virtual uint32_t GetActiveLabel() const