LCOV - code coverage report
Current view: top level - vnsw/agent/oper - evpn_route.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 139 363 38.3 %
Date: 2026-06-04 02:06:09 Functions: 18 43 41.9 %
Legend: Lines: hit not hit

          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/ecmp_load_balance.h>
      11             : #include <oper/route_common.h>
      12             : #include <oper/vrf.h>
      13             : #include <oper/tunnel_nh.h>
      14             : #include <oper/mpls.h>
      15             : #include <oper/mirror_table.h>
      16             : #include <controller/controller_export.h>
      17             : #include <controller/controller_peer.h>
      18             : #include <controller/controller_route_path.h>
      19             : #include <oper/agent_sandesh.h>
      20             : #include <pkt/pkt_init.h>
      21             : #include <pkt/pkt_handler.h>
      22             : 
      23             : using namespace std;
      24             : using namespace boost::asio;
      25             : 
      26             : /////////////////////////////////////////////////////////////////////////////
      27             : // Utility functions
      28             : /////////////////////////////////////////////////////////////////////////////
      29          11 : static void EvpnTableEnqueue(Agent *agent, DBRequest *req) {
      30          11 :     AgentRouteTable *table = agent->fabric_evpn_table();
      31          11 :     if (table) {
      32          11 :         table->Enqueue(req);
      33             :     }
      34          11 : }
      35             : 
      36         132 : static void EvpnTableProcess(Agent *agent, const string &vrf_name,
      37             :                                DBRequest &req) {
      38             :     AgentRouteTable *table =
      39         132 :         agent->vrf_table()->GetEvpnRouteTable(vrf_name);
      40         132 :     if (table) {
      41         132 :         table->Process(req);
      42             :     }
      43         132 : }
      44             : 
      45             : /////////////////////////////////////////////////////////////////////////////
      46             : // EvpnRouteKey methods
      47             : /////////////////////////////////////////////////////////////////////////////
      48           0 : string EvpnRouteKey::ToString() const {
      49           0 :     std::stringstream str;
      50           0 :     str << ethernet_tag_;
      51           0 :     str << "-";
      52           0 :     str << dmac_.ToString();
      53           0 :     str << "-";
      54           0 :     str << ip_addr_.to_string();
      55           0 :     return str.str();
      56           0 : }
      57             : 
      58           1 : EvpnRouteKey *EvpnRouteKey::Clone() const {
      59           1 :     return new EvpnRouteKey(peer(), vrf_name_, dmac_, ip_addr_,
      60           1 :                             plen_, ethernet_tag_);
      61             : }
      62             : 
      63             : AgentRoute *
      64         264 : EvpnRouteKey::AllocRouteEntry(VrfEntry *vrf, bool is_multicast) const
      65             : {
      66         264 :     EvpnRouteEntry *entry = new EvpnRouteEntry(vrf, dmac_, ip_addr_, plen_,
      67         264 :                                                ethernet_tag_, is_multicast);
      68         264 :     return static_cast<AgentRoute *>(entry);
      69             : }
      70             : 
      71             : /////////////////////////////////////////////////////////////////////////////
      72             : // EvpnAgentRouteTable methods
      73             : /////////////////////////////////////////////////////////////////////////////
      74          24 : DBTableBase *EvpnAgentRouteTable::CreateTable(DB *db,
      75             :                                               const std::string &name) {
      76          24 :     AgentRouteTable *table = new EvpnAgentRouteTable(db, name);
      77          24 :     table->Init();
      78          24 :     return table;
      79             : }
      80             : 
      81           0 : EvpnRouteEntry *EvpnAgentRouteTable::FindRoute(const MacAddress &mac,
      82             :                                                const IpAddress &ip_addr,
      83             :                                                uint32_t plen,
      84             :                                                uint32_t ethernet_tag) {
      85           0 :     EvpnRouteKey key(NULL, vrf_name(), mac, ip_addr, plen, ethernet_tag);
      86             :     EvpnRouteEntry *route =
      87           0 :         static_cast<EvpnRouteEntry *>(FindActiveEntry(&key));
      88           0 :     return route;
      89           0 : }
      90             : 
      91           9 : EvpnRouteEntry *EvpnAgentRouteTable::FindRouteNoLock(const MacAddress &mac,
      92             :                                                      const IpAddress &ip_addr,
      93             :                                                      uint32_t plen,
      94             :                                                      uint32_t ethernet_tag) {
      95           9 :     EvpnRouteKey key(NULL, vrf_name(), mac, ip_addr, plen, ethernet_tag);
      96             :     EvpnRouteEntry *route =
      97           9 :         static_cast<EvpnRouteEntry *>(FindActiveEntryNoLock(&key));
      98           9 :     return route;
      99           9 : }
     100             : 
     101           0 : EvpnRouteEntry *EvpnAgentRouteTable::FindRoute(const Agent *agent,
     102             :                                                    const string &vrf_name,
     103             :                                                    const MacAddress &mac,
     104             :                                                    const IpAddress &ip_addr,
     105             :                                                    uint32_t plen,
     106             :                                                    uint32_t ethernet_tag) {
     107           0 :     VrfEntry *vrf = agent->vrf_table()->FindVrfFromName(vrf_name);
     108           0 :     if (vrf == NULL)
     109           0 :         return NULL;
     110             : 
     111             :     EvpnAgentRouteTable *table = static_cast<EvpnAgentRouteTable *>
     112           0 :         (vrf->GetEvpnRouteTable());
     113           0 :     return table->FindRoute(mac, ip_addr, plen, ethernet_tag);
     114             : }
     115             : 
     116             : /////////////////////////////////////////////////////////////////////////////
     117             : // EvpnAgentRouteTable utility methods to add/delete routes
     118             : /////////////////////////////////////////////////////////////////////////////
     119           0 : void EvpnAgentRouteTable::AddOvsPeerMulticastRouteInternal(const Peer *peer,
     120             :                                                            uint32_t vxlan_id,
     121             :                                                            const std::string &vn_name,
     122             :                                                            Ip4Address tsn,
     123             :                                                            Ip4Address tor_ip,
     124             :                                                            bool enqueue,
     125             :                                                            bool ha_stale) {
     126           0 :     const VrfEntry *vrf = vrf_entry();
     127           0 :     DBRequest nh_req(DBRequest::DB_ENTRY_ADD_CHANGE);
     128           0 :     nh_req.key.reset(new TunnelNHKey(vrf->GetName(), tsn, tor_ip,
     129           0 :                                      false, TunnelType::VXLAN));
     130           0 :     nh_req.data.reset(new TunnelNHData());
     131             : 
     132           0 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     133           0 :     req.key.reset(new EvpnRouteKey(peer,
     134           0 :                                vrf->GetName(),
     135           0 :                                MacAddress::BroadcastMac(),
     136             :                                tor_ip,
     137           0 :                                EvpnAgentRouteTable::ComputeHostIpPlen(tor_ip),
     138           0 :                                vxlan_id));
     139           0 :     req.data.reset(new MulticastRoute(vn_name, 0, vxlan_id,
     140           0 :                                       TunnelType::VxlanType(),
     141             :                                       nh_req, Composite::L2COMP,
     142           0 :                                       peer->sequence_number(),
     143           0 :                                       ha_stale));
     144           0 :     if (enqueue) {
     145           0 :         EvpnTableEnqueue(agent(), &req);
     146             :     } else {
     147           0 :         EvpnTableProcess(agent(), vrf_name(), req);
     148             :     }
     149           0 : }
     150             : 
     151           0 : void EvpnAgentRouteTable::AddOvsPeerMulticastRoute(const Peer *peer,
     152             :                                                    uint32_t vxlan_id,
     153             :                                                    const std::string &vn_name,
     154             :                                                    Ip4Address tsn,
     155             :                                                    Ip4Address tor_ip,
     156             :                                                    bool ha_stale) {
     157           0 :     AddOvsPeerMulticastRouteInternal(peer, vxlan_id, vn_name, tsn, tor_ip,
     158             :                                      false, ha_stale);
     159           0 : }
     160             : 
     161           0 : void EvpnAgentRouteTable::AddOvsPeerMulticastRouteReq(const Peer *peer,
     162             :                                                       uint32_t vxlan_id,
     163             :                                                       const std::string &vn_name,
     164             :                                                       Ip4Address tsn,
     165             :                                                       Ip4Address tor_ip) {
     166           0 :     AddOvsPeerMulticastRouteInternal(peer, vxlan_id, vn_name, tsn, tor_ip, true,
     167             :                                      false);
     168           0 : }
     169             : 
     170           0 : void EvpnAgentRouteTable::AddControllerReceiveRouteReq(const Peer *peer,
     171             :                                              const string &vrf_name,
     172             :                                              uint32_t label,
     173             :                                              const MacAddress &mac,
     174             :                                              const IpAddress &ip_addr,
     175             :                                              uint32_t ethernet_tag,
     176             :                                              const string &vn_name,
     177             :                                              const PathPreference &path_pref,
     178             :                                              uint64_t sequence_number) {
     179           0 :     const BgpPeer *bgp_peer = dynamic_cast<const BgpPeer *>(peer);
     180           0 :     assert(bgp_peer != NULL);
     181             : 
     182           0 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     183           0 :     req.key.reset(new EvpnRouteKey(peer, vrf_name, mac, ip_addr,
     184           0 :                                EvpnAgentRouteTable::ComputeHostIpPlen(ip_addr),
     185           0 :                                ethernet_tag));
     186           0 :     req.data.reset(new L2ReceiveRoute(vn_name, ethernet_tag,
     187             :                                                 label, path_pref,
     188           0 :                                                 sequence_number));
     189           0 :     agent()->fabric_evpn_table()->Enqueue(&req);
     190           0 : }
     191             : 
     192           0 : void EvpnAgentRouteTable::AddReceiveRouteReq(const Peer *peer,
     193             :                                              const string &vrf_name,
     194             :                                              uint32_t label,
     195             :                                              const MacAddress &mac,
     196             :                                              const IpAddress &ip_addr,
     197             :                                              uint32_t ethernet_tag,
     198             :                                              const string &vn_name,
     199             :                                              const PathPreference &pref) {
     200           0 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     201           0 :     req.key.reset(new EvpnRouteKey(peer, vrf_name, mac, ip_addr,
     202           0 :                                EvpnAgentRouteTable::ComputeHostIpPlen(ip_addr),
     203           0 :                                ethernet_tag));
     204           0 :     req.data.reset(new L2ReceiveRoute(vn_name, ethernet_tag, label, pref,
     205           0 :                                       peer->sequence_number()));
     206           0 :     agent()->fabric_evpn_table()->Enqueue(&req);
     207           0 : }
     208             : 
     209           0 : void EvpnAgentRouteTable::AddReceiveRoute(const Peer *peer,
     210             :                                           const string &vrf_name,
     211             :                                           uint32_t label,
     212             :                                           const MacAddress &mac,
     213             :                                           const IpAddress &ip_addr,
     214             :                                           uint32_t ethernet_tag,
     215             :                                           const string &vn_name,
     216             :                                           const PathPreference &pref) {
     217           0 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     218           0 :     req.key.reset(new EvpnRouteKey(peer, vrf_name, mac, ip_addr,
     219           0 :                                EvpnAgentRouteTable::ComputeHostIpPlen(ip_addr),
     220           0 :                                ethernet_tag));
     221           0 :     req.data.reset(new L2ReceiveRoute(vn_name, ethernet_tag, label, pref,
     222           0 :                                       peer->sequence_number()));
     223           0 :     Process(req);
     224           0 : }
     225             : 
     226           0 : void EvpnAgentRouteTable::AddLocalVmRouteReq(const Peer *peer,
     227             :                                              const string &vrf_name,
     228             :                                              const MacAddress &mac,
     229             :                                              const IpAddress &ip_addr,
     230             :                                              uint32_t ethernet_tag,
     231             :                                              LocalVmRoute *data) {
     232           0 :     assert(peer);
     233           0 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     234             : 
     235           0 :     req.key.reset(new EvpnRouteKey(peer, vrf_name, mac, ip_addr,
     236           0 :                                EvpnAgentRouteTable::ComputeHostIpPlen(ip_addr),
     237           0 :                                ethernet_tag));
     238           0 :     data->set_tunnel_bmap(TunnelType::AllType());
     239           0 :     req.data.reset(data);
     240           0 :     EvpnTableEnqueue(Agent::GetInstance(), &req);
     241           0 : }
     242             : 
     243          80 : void EvpnAgentRouteTable::AddLocalVmRoute(const Peer *peer,
     244             :                                           const string &vrf_name,
     245             :                                           const MacAddress &mac,
     246             :                                           const VmInterface *intf,
     247             :                                           const IpAddress &ip,
     248             :                                           uint32_t label,
     249             :                                           const string &vn_name,
     250             :                                           const SecurityGroupList &sg_id_list,
     251             :                                           const TagList &tag_id_list,
     252             :                                           const PathPreference &path_pref,
     253             :                                           uint32_t ethernet_tag,
     254             :                                           bool etree_leaf,
     255             :                                           const std::string &name) {
     256          80 :     assert(peer);
     257             : 
     258          80 :     Agent *agent = static_cast<AgentDBTable *>(intf->get_table())->agent();
     259          80 :     VmInterfaceKey intf_key(AgentKey::ADD_DEL_CHANGE, intf->GetUuid(), name);
     260          80 :     VnListType vn_list;
     261          80 :     vn_list.insert(vn_name);
     262             :     LocalVmRoute *data = new LocalVmRoute(intf_key, label,
     263          80 :                                           intf->vxlan_id(), false,
     264             :                                           vn_list,
     265             :                                           InterfaceNHFlags::BRIDGE,
     266             :                                           sg_id_list, tag_id_list,
     267          80 :                                           CommunityList(),
     268             :                                           path_pref,
     269          80 :                                           IpAddress(),
     270         160 :                                           EcmpLoadBalance(), false, false,
     271          80 :                                           peer->sequence_number(),
     272          80 :                                           etree_leaf, false);
     273          80 :     data->set_tunnel_bmap(TunnelType::AllType());
     274             : 
     275          80 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     276          80 :     req.key.reset(new EvpnRouteKey(peer, vrf_name, mac, ip,
     277          80 :                                EvpnAgentRouteTable::ComputeHostIpPlen(ip),
     278          80 :                                ethernet_tag));
     279          80 :     req.data.reset(data);
     280          80 :     EvpnTableProcess(agent, vrf_name, req);
     281          80 : }
     282             : 
     283           0 : void EvpnAgentRouteTable::AddLocalVmRouteReq(const Peer *peer,
     284             :                                           const string &vrf_name,
     285             :                                           const MacAddress &mac,
     286             :                                           const VmInterface *intf,
     287             :                                           const IpAddress &ip,
     288             :                                           uint32_t label,
     289             :                                           const string &vn_name,
     290             :                                           const SecurityGroupList &sg_id_list,
     291             :                                           const TagList &tag_id_list,
     292             :                                           const PathPreference &path_pref,
     293             :                                           uint32_t ethernet_tag,
     294             :                                           bool etree_leaf) {
     295           0 :     assert(peer);
     296             : 
     297           0 :     Agent *agent = static_cast<AgentDBTable *>(intf->get_table())->agent();
     298           0 :     VmInterfaceKey intf_key(AgentKey::ADD_DEL_CHANGE, intf->GetUuid(), "");
     299           0 :     VnListType vn_list;
     300           0 :     vn_list.insert(vn_name);
     301             :     LocalVmRoute *data = new LocalVmRoute(intf_key, label,
     302           0 :                                           intf->vxlan_id(), false,
     303             :                                           vn_list,
     304             :                                           InterfaceNHFlags::BRIDGE,
     305             :                                           sg_id_list, tag_id_list,
     306           0 :                                           CommunityList(),
     307             :                                           path_pref,
     308           0 :                                           IpAddress(),
     309           0 :                                           EcmpLoadBalance(), false, false,
     310           0 :                                           peer->sequence_number(),
     311           0 :                                           etree_leaf, false);
     312           0 :     data->set_tunnel_bmap(TunnelType::AllType());
     313             : 
     314           0 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     315           0 :     req.key.reset(new EvpnRouteKey(peer, vrf_name, mac, ip,
     316           0 :                                EvpnAgentRouteTable::ComputeHostIpPlen(ip),
     317           0 :                                ethernet_tag));
     318           0 :     req.data.reset(data);
     319           0 :     EvpnTableEnqueue(agent, &req);
     320           0 : }
     321             : 
     322           0 : void EvpnAgentRouteTable::DeleteOvsPeerMulticastRouteInternal(const Peer *peer,
     323             :                                                               uint32_t vxlan_id,
     324             :                                                               const Ip4Address &tor_ip,
     325             :                                                               bool enqueue) {
     326           0 :     const VrfEntry *vrf = vrf_entry();
     327           0 :     DBRequest req(DBRequest::DB_ENTRY_DELETE);
     328           0 :     req.key.reset(new EvpnRouteKey(peer,
     329           0 :                                    vrf->GetName(),
     330           0 :                                    MacAddress::BroadcastMac(),
     331             :                                    tor_ip,
     332           0 :                                    EvpnAgentRouteTable::ComputeHostIpPlen(tor_ip),
     333           0 :                                    vxlan_id));
     334           0 :     req.data.reset(NULL);
     335           0 :     if (enqueue) {
     336           0 :         EvpnTableEnqueue(agent(), &req);
     337             :     } else {
     338           0 :         EvpnTableProcess(agent(), vrf->GetName(), req);
     339             :     }
     340           0 : }
     341             : 
     342           0 : void EvpnAgentRouteTable::DeleteOvsPeerMulticastRouteReq(const Peer *peer,
     343             :                                                          uint32_t vxlan_id,
     344             :                                                          const Ip4Address &tor_ip) {
     345           0 :     DeleteOvsPeerMulticastRouteInternal(peer, vxlan_id, tor_ip, true);
     346           0 : }
     347             : 
     348           0 : void EvpnAgentRouteTable::DeleteOvsPeerMulticastRoute(const Peer *peer,
     349             :                                                       uint32_t vxlan_id,
     350             :                                                       const Ip4Address &tor_ip) {
     351           0 :     DeleteOvsPeerMulticastRouteInternal(peer, vxlan_id, tor_ip, false);
     352           0 : }
     353             : 
     354          52 : void EvpnAgentRouteTable::DelLocalVmRoute(const Peer *peer,
     355             :                                           const string &vrf_name,
     356             :                                           const MacAddress &mac,
     357             :                                           const VmInterface *intf,
     358             :                                           const IpAddress &ip,
     359             :                                           uint32_t ethernet_tag) {
     360          52 :     assert(peer);
     361          52 :     Agent *agent = static_cast<AgentDBTable *>(intf->get_table())->agent();
     362          52 :     DBRequest req(DBRequest::DB_ENTRY_DELETE);
     363         104 :     req.key.reset(new EvpnRouteKey(peer, vrf_name, mac, IpAddress(ip),
     364          52 :                                    EvpnAgentRouteTable::ComputeHostIpPlen(ip),
     365          52 :                                    ethernet_tag));
     366          52 :     req.data.reset(NULL);
     367          52 :     EvpnTableProcess(agent, vrf_name, req);
     368          52 : }
     369             : 
     370           0 : void EvpnAgentRouteTable::ResyncVmRoute(const Peer *peer,
     371             :                                         const string &vrf_name,
     372             :                                         const MacAddress &mac,
     373             :                                         const IpAddress &ip_addr,
     374             :                                         uint32_t ethernet_tag,
     375             :                                         AgentRouteData *data) {
     376           0 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     377             :     EvpnRouteKey *key = new EvpnRouteKey(peer, vrf_name, mac, ip_addr,
     378           0 :                                 EvpnAgentRouteTable::ComputeHostIpPlen(ip_addr),
     379           0 :                                 ethernet_tag);
     380           0 :     key->sub_op_ = AgentKey::RESYNC;
     381           0 :     req.key.reset(key);
     382           0 :     req.data.reset(data);
     383             : 
     384           0 :     EvpnTableProcess(Agent::GetInstance(), vrf_name, req);
     385           0 : }
     386             : 
     387           6 : void EvpnAgentRouteTable::AddRemoteVmRouteReq(const Peer *peer,
     388             :                                               const string &vrf_name,
     389             :                                               const MacAddress &mac,
     390             :                                               const IpAddress &ip_addr,
     391             :                                               uint32_t plen,
     392             :                                               uint32_t ethernet_tag,
     393             :                                               AgentRouteData *data) {
     394           6 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     395           6 :     req.key.reset(new EvpnRouteKey(peer, vrf_name, mac, ip_addr,
     396           6 :                                    plen, ethernet_tag));
     397           6 :     req.data.reset(data);
     398             : 
     399           6 :     EvpnTableEnqueue(Agent::GetInstance(), &req);
     400           6 : }
     401             : 
     402           0 : void EvpnAgentRouteTable::AddRemoteVmRoute(const Peer *peer,
     403             :                                            const string &vrf_name,
     404             :                                            const MacAddress &mac,
     405             :                                            const IpAddress &ip_addr,
     406             :                                            uint32_t plen,
     407             :                                            uint32_t ethernet_tag,
     408             :                                            AgentRouteData *data) {
     409           0 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     410           0 :     req.key.reset(new EvpnRouteKey(peer, vrf_name, mac, ip_addr,
     411           0 :                                    plen, ethernet_tag));
     412           0 :     req.data.reset(data);
     413             : 
     414           0 :     EvpnTableProcess(Agent::GetInstance(), vrf_name, req);
     415           0 : }
     416             : 
     417           0 : void EvpnAgentRouteTable::AddType5Route(const Peer *peer,
     418             :                                         const string &vrf_name,
     419             :                                         const IpAddress &ip_addr,
     420             :                                         uint32_t ethernet_tag,
     421             :                                         EvpnRoutingData *data, uint8_t plen) {
     422           0 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     423           0 :     if ( !plen && !ip_addr.is_unspecified()) {
     424           0 :         req.key.reset(new EvpnRouteKey(peer, vrf_name, MacAddress(), ip_addr,
     425           0 :                                    EvpnAgentRouteTable::ComputeHostIpPlen(ip_addr),
     426           0 :                                    ethernet_tag));
     427             :     } else {
     428           0 :         req.key.reset(new EvpnRouteKey(peer, vrf_name, MacAddress(), ip_addr,
     429             :                                    plen,
     430           0 :                                    ethernet_tag));
     431             :     }
     432           0 :     req.data.reset(data);
     433             : 
     434           0 :     EvpnTableEnqueue(agent(), &req);
     435           0 : }
     436             : 
     437           5 : void EvpnAgentRouteTable::DeleteReq(const Peer *peer, const string &vrf_name,
     438             :                                       const MacAddress &mac,
     439             :                                       const IpAddress &ip_addr,
     440             :                                       uint32_t plen,
     441             :                                       uint32_t ethernet_tag,
     442             :                                       AgentRouteData *data) {
     443           5 :     DBRequest req(DBRequest::DB_ENTRY_DELETE);
     444           5 :     req.key.reset(new EvpnRouteKey(peer, vrf_name, mac, ip_addr,
     445           5 :                                    plen, ethernet_tag));
     446           5 :     req.data.reset(data);
     447           5 :     EvpnTableEnqueue(Agent::GetInstance(), &req);
     448           5 : }
     449             : 
     450           0 : void EvpnAgentRouteTable::Delete(const Peer *peer, const string &vrf_name,
     451             :                                    const MacAddress &mac,
     452             :                                    const IpAddress &ip_addr,
     453             :                                    uint32_t ethernet_tag) {
     454           0 :     DBRequest req(DBRequest::DB_ENTRY_DELETE);
     455           0 :     req.key.reset(new EvpnRouteKey(peer, vrf_name, mac, ip_addr,
     456           0 :                                    EvpnAgentRouteTable::ComputeHostIpPlen(ip_addr),
     457           0 :                                    ethernet_tag));
     458           0 :     req.data.reset(NULL);
     459           0 :     EvpnTableProcess(Agent::GetInstance(), vrf_name, req);
     460           0 : }
     461             : 
     462           0 : void EvpnAgentRouteTable::AddClonedLocalPathReq(const Peer *peer,
     463             :                                                 const string &vrf_name,
     464             :                                                 const MacAddress &mac,
     465             :                                                 const IpAddress &ip_addr,
     466             :                                                 uint32_t ethernet_tag,
     467             :                                                 ClonedLocalPath *data) {
     468           0 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     469           0 :     req.key.reset(new EvpnRouteKey(peer, vrf_name, mac, ip_addr,
     470           0 :                                    EvpnAgentRouteTable::ComputeHostIpPlen(ip_addr),
     471           0 :                                    ethernet_tag));
     472           0 :     req.data.reset(data);
     473           0 :     EvpnTableEnqueue(Agent::GetInstance(), &req);
     474           0 : }
     475             : 
     476         151 : uint32_t EvpnAgentRouteTable::ComputeHostIpPlen(const IpAddress &addr) {
     477         151 :     if (addr.is_v4())
     478         151 :         return 32;
     479           0 :     if (addr.is_v6())
     480           0 :         return 128;
     481             : 
     482           0 :     assert(0);
     483             :     return 0;
     484             : }
     485             : 
     486             : /////////////////////////////////////////////////////////////////////////////
     487             : // EvpnRouteEntry methods
     488             : /////////////////////////////////////////////////////////////////////////////
     489         264 : EvpnRouteEntry::EvpnRouteEntry(VrfEntry *vrf,
     490             :                                const MacAddress &mac,
     491             :                                const IpAddress &ip_addr,
     492             :                                uint8_t plen,
     493             :                                uint32_t ethernet_tag,
     494         264 :                                bool is_multicast) :
     495             :     AgentRoute(vrf, is_multicast), AgentRoutePrefix(ip_addr, plen),
     496         264 :     mac_(mac),
     497         264 :     ethernet_tag_(ethernet_tag),
     498         264 :     publish_to_inet_route_table_(true),
     499         264 :     publish_to_bridge_route_table_(true) {
     500         264 :         if (IsType5()) {
     501           0 :             publish_to_inet_route_table_ = false;
     502           0 :             publish_to_bridge_route_table_ = false;
     503             :         }
     504         264 : }
     505             : 
     506         619 : string EvpnRouteEntry::ToString() const {
     507         619 :     std::stringstream str;
     508         619 :     if (is_multicast()) {
     509           0 :         str << mac_.ToString();
     510             :     } else {
     511         619 :         str << ethernet_tag_;
     512         619 :         str << "-";
     513         619 :         str << mac_.ToString();
     514         619 :         str << "-";
     515         619 :         str << prefix_address_.to_string();
     516         619 :         str << "/";
     517         619 :         str << int(prefix_length());
     518             :     }
     519        1238 :     return str.str();
     520         619 : }
     521             : 
     522         816 : int EvpnRouteEntry::CompareTo(const Route &rhs) const {
     523         816 :     const EvpnRouteEntry &a = static_cast<const EvpnRouteEntry &>(rhs);
     524             : 
     525         816 :     if (ethernet_tag_ < a.ethernet_tag_)
     526           1 :         return -1;
     527             : 
     528         815 :     if (ethernet_tag_ > a.ethernet_tag_)
     529           1 :         return 1;
     530             : 
     531         814 :     int cmp = mac_.CompareTo(a.mac_);
     532         814 :     if (cmp != 0)
     533         194 :         return cmp;
     534             : 
     535         620 :     if (prefix_address_ < a.prefix_address_)
     536         142 :         return -1;
     537             : 
     538         478 :     if (prefix_address_ > a.prefix_address_)
     539          80 :         return 1;
     540             : 
     541         398 :     if (prefix_length() < a.prefix_length())
     542           0 :         return -1;
     543             : 
     544         398 :     if (prefix_length() > a.prefix_length())
     545           0 :         return 1;
     546             : 
     547         398 :     return 0;
     548             : }
     549             : 
     550          42 : DBEntryBase::KeyPtr EvpnRouteEntry::GetDBRequestKey() const {
     551             :     EvpnRouteKey *key =
     552          42 :         new EvpnRouteKey(Agent::GetInstance()->local_vm_peer(),
     553          42 :                            vrf()->GetName(), mac_, prefix_address_,
     554          42 :                            prefix_length(), ethernet_tag_);
     555          42 :     return DBEntryBase::KeyPtr(key);
     556             : }
     557             : 
     558           0 : void EvpnRouteEntry::SetKey(const DBRequestKey *key) {
     559           0 :     const EvpnRouteKey *k = static_cast<const EvpnRouteKey *>(key);
     560           0 :     SetVrf(Agent::GetInstance()->vrf_table()->FindVrfFromName(k->vrf_name()));
     561           0 :     mac_ = k->GetMac();
     562           0 :     prefix_address_ = k->ip_addr();
     563           0 :     ethernet_tag_ = k->ethernet_tag();
     564           0 : }
     565             : 
     566           0 : uint32_t EvpnRouteEntry::GetActiveLabel() const {
     567           0 :     return GetActivePath()->GetActiveLabel();
     568             : }
     569             : 
     570           0 : const AgentPath *EvpnRouteEntry::FindOvsPath() const {
     571           0 :     for(Route::PathList::const_iterator it = GetPathList().begin();
     572           0 :         it != GetPathList().end(); it++) {
     573           0 :         const AgentPath *path = static_cast<const AgentPath *>(it.operator->());
     574           0 :         if (path->peer()->GetType() == Peer::OVS_PEER) {
     575           0 :             return const_cast<AgentPath *>(path);
     576             :         }
     577             :     }
     578           0 :     return NULL;
     579             : }
     580             : 
     581             : //Notify L2 route corresponding to MAC in evpn route.
     582             : //On addition of evpn routes, update bridge route using mac of evpn and inet
     583             : //route using ip of evpn.
     584             : //NH of bridge route is same as of EVPN as bridge rt is programmed in kernel.
     585             : //NH of Inet route will be of subnet route to which it belongs. This makes sure
     586             : //that n absence of any directly installed Inet route for this IP packets are
     587             : //forwarded as per the subnet route decision.
     588         118 : void EvpnRouteEntry::UpdateDerivedRoutes(AgentRouteTable *table,
     589             :                                          const AgentPath *path,
     590             :                                          bool active_path_changed) {
     591             :     //As active path is picked from route, any modification in non-active
     592             :     //path need not rebake agent route.
     593             :     //Path is NULL when resync is issued on route, hence no need to check flag
     594         118 :     if ((path != NULL) && !active_path_changed)
     595           0 :         return;
     596             : 
     597             : 
     598         118 :     if (publish_to_bridge_route_table()) {
     599         118 :         BridgeAgentRouteTable *bridge_table = NULL;
     600             :         bridge_table = static_cast<BridgeAgentRouteTable *>
     601         118 :             (table->vrf_entry()->GetBridgeRouteTable());
     602         118 :         if (bridge_table)
     603         118 :             bridge_table->AddBridgeRoute(this);
     604             :     }
     605         118 :     if (publish_to_inet_route_table()) {
     606             :         InetUnicastAgentRouteTable *inet_table =
     607         118 :             table->vrf_entry()->GetInetUnicastRouteTable(prefix_address());
     608         118 :         if (inet_table)
     609         118 :             inet_table->AddEvpnRoute(this);
     610             :     }
     611             : }
     612             : 
     613             : //Delete path from L2 route corresponding to MAC+IP in evpn route.
     614          56 : void EvpnRouteEntry::DeleteDerivedRoutes(AgentRouteTable *table) {
     615             :     //Delete from bridge table
     616             :     BridgeAgentRouteTable *bridge_table = static_cast<BridgeAgentRouteTable *>
     617          56 :         (table->vrf_entry()->GetBridgeRouteTable());
     618          56 :     if (bridge_table)
     619          56 :         bridge_table->DeleteBridgeRoute(this);
     620             : 
     621             :     //Delete from Inet table
     622             :     InetUnicastAgentRouteTable *inet_table =
     623          56 :         table->vrf_entry()->GetInetUnicastRouteTable(prefix_address());
     624          56 :     if (inet_table)
     625          56 :         inet_table->DeleteEvpnRoute(this);
     626          56 : }
     627             : 
     628             : /////////////////////////////////////////////////////////////////////////////
     629             : // Sandesh related methods
     630             : /////////////////////////////////////////////////////////////////////////////
     631           0 : void EvpnRouteReq::HandleRequest() const {
     632             :     VrfEntry *vrf =
     633           0 :         Agent::GetInstance()->vrf_table()->FindVrfFromId(get_vrf_index());
     634           0 :     if (!vrf) {
     635           0 :         ErrorResp *resp = new ErrorResp();
     636           0 :         resp->set_context(context());
     637           0 :         resp->Response();
     638           0 :         return;
     639             :     }
     640             : 
     641           0 :     AgentSandeshPtr sand(new AgentEvpnRtSandesh(vrf, context(), "",
     642           0 :                                                 get_stale()));
     643           0 :     sand->DoSandesh(sand);
     644           0 : }
     645             : 
     646           0 : AgentSandeshPtr EvpnAgentRouteTable::GetAgentSandesh
     647             : (const AgentSandeshArguments *args, const std::string &context) {
     648           0 :     return AgentSandeshPtr(new AgentEvpnRtSandesh(vrf_entry(), context, "",
     649           0 :                                                   false));
     650             : }
     651             : 
     652           0 : bool EvpnRouteEntry::DBEntrySandesh(Sandesh *sresp, bool stale) const {
     653           0 :     EvpnRouteResp *resp = static_cast<EvpnRouteResp *>(sresp);
     654           0 :     RouteEvpnSandeshData data;
     655           0 :     data.set_mac(ToString());
     656           0 :     data.set_ip_addr(prefix_address_.to_string());
     657             : 
     658           0 :     for (Route::PathList::const_iterator it = GetPathList().begin();
     659           0 :          it != GetPathList().end(); it++) {
     660           0 :         const AgentPath *path = static_cast<const AgentPath *>(it.operator->());
     661           0 :         if (path) {
     662           0 :             PathSandeshData pdata;
     663           0 :             path->SetSandeshData(pdata);
     664           0 :             data.path_list.push_back(pdata);
     665           0 :         }
     666             :     }
     667             :     std::vector<RouteEvpnSandeshData> &list =
     668           0 :         const_cast<std::vector<RouteEvpnSandeshData>&>(resp->get_route_list());
     669           0 :     list.push_back(data);
     670           0 :     return true;
     671           0 : }
     672             : 
     673          57 : bool EvpnRouteEntry::ReComputePathDeletion(AgentPath *path) {
     674          57 :     bool ret = false;
     675          57 :     Agent *agent = static_cast<AgentRouteTable *>(get_table())->agent();
     676          57 :     EvpnRoutingPath *evpn_path = dynamic_cast<EvpnRoutingPath *>(path);
     677          57 :     if (evpn_path) {
     678           0 :         evpn_path->DeleteEvpnType5Route(agent, this);
     679             :     }
     680          57 :     return ret;
     681             : }

Generated by: LCOV version 1.14