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: 149 363 41.0 %
Date: 2026-11-09 02:10:49 Functions: 19 43 44.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14