LCOV - code coverage report
Current view: top level - vnsw/agent/pkt/flow_mgmt - flow_mgmt_dbclient.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 470 0.0 %
Date: 2026-10-05 02:12:29 Functions: 0 28 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #include "pkt/flow_mgmt/flow_mgmt_dbclient.h"
       2             : #include "pkt/flow_mgmt.h"
       3             : #include "oper/ecmp_load_balance.h"
       4             : #include "oper/ecmp.h"
       5             : #include <oper/tunnel_nh.h>
       6             : 
       7           0 : void FlowMgmtDbClient::Init() {
       8           0 :     acl_listener_id_ = agent_->acl_table()->Register
       9           0 :         (boost::bind(&FlowMgmtDbClient::AclNotify, this, _1, _2));
      10             : 
      11           0 :     interface_listener_id_ = agent_->interface_table()->Register
      12           0 :         (boost::bind(&FlowMgmtDbClient::InterfaceNotify, this, _1, _2));
      13             : 
      14           0 :     vn_listener_id_ = agent_->vn_table()->Register
      15           0 :         (boost::bind(&FlowMgmtDbClient::VnNotify, this, _1, _2));
      16             : 
      17           0 :     vrf_listener_id_ = agent_->vrf_table()->Register
      18           0 :             (boost::bind(&FlowMgmtDbClient::VrfNotify, this, _1, _2));
      19             : 
      20           0 :     nh_listener_id_ = agent_->nexthop_table()->Register
      21           0 :             (boost::bind(&FlowMgmtDbClient::NhNotify, this, _1, _2));
      22           0 :     return;
      23             : }
      24             : 
      25           0 : void FlowMgmtDbClient::Shutdown() {
      26           0 :     agent_->acl_table()->Unregister(acl_listener_id_);
      27           0 :     agent_->interface_table()->Unregister(interface_listener_id_);
      28           0 :     agent_->vn_table()->Unregister(vn_listener_id_);
      29           0 :     agent_->vm_table()->Unregister(vm_listener_id_);
      30           0 :     agent_->vrf_table()->Unregister(vrf_listener_id_);
      31           0 :     agent_->nexthop_table()->Unregister(nh_listener_id_);
      32           0 : }
      33             : 
      34           0 : FlowMgmtDbClient::FlowMgmtDbClient(Agent *agent, FlowMgmtManager *mgr) :
      35           0 :     agent_(agent),
      36           0 :     mgr_(mgr),
      37           0 :     acl_listener_id_(),
      38           0 :     interface_listener_id_(),
      39           0 :     vn_listener_id_(),
      40           0 :     vm_listener_id_(),
      41           0 :     vrf_listener_id_(),
      42           0 :     nh_listener_id_() {
      43           0 : }
      44             : 
      45           0 : FlowMgmtDbClient::~FlowMgmtDbClient() {
      46           0 : }
      47             : 
      48           0 : void FlowMgmtDbClient::AddEvent(const DBEntry *entry, FlowMgmtState *state) {
      49           0 :     mgr_->AddDBEntryEvent(entry, state->gen_id_);
      50           0 : }
      51             : 
      52           0 : void FlowMgmtDbClient::DeleteEvent(const DBEntry *entry, FlowMgmtState *state) {
      53           0 :     state->gen_id_++;
      54           0 :     state->deleted_ = true;
      55           0 :     mgr_->DeleteDBEntryEvent(entry, state->gen_id_);
      56           0 : }
      57             : 
      58           0 : void FlowMgmtDbClient::DeleteAllFlow(const DBEntry *entry,
      59             :                                      FlowMgmtState *state) {
      60           0 :     mgr_->DeleteDBEntryEvent(entry, state->gen_id_);
      61           0 : }
      62             : 
      63           0 : void FlowMgmtDbClient::ChangeEvent(const DBEntry *entry, FlowMgmtState *state) {
      64           0 :     mgr_->ChangeDBEntryEvent(entry, state->gen_id_);
      65           0 : }
      66             : 
      67           0 : void FlowMgmtDbClient::RouteNHChangeEvent(const DBEntry *entry,
      68             :                                           FlowMgmtState *state) {
      69           0 :     mgr_->RouteNHChangeEvent(entry, state->gen_id_);
      70           0 : }
      71             : 
      72             : ////////////////////////////////////////////////////////////////////////////
      73             : // Interface notification handler
      74             : ////////////////////////////////////////////////////////////////////////////
      75           0 : static DBState *ValidateGenId(DBTableBase *table, DBEntry *entry,
      76             :                               DBTableBase::ListenerId id, uint32_t gen_id) {
      77             :     FlowMgmtDbClient::FlowMgmtState *state =
      78           0 :         static_cast<FlowMgmtDbClient::FlowMgmtState *>(entry->GetState(table,
      79             :                                                                       id));
      80           0 :     if (state == NULL)
      81           0 :         return NULL;
      82             : 
      83             :     // If DBEntry is re-added in meanwhile, we do not want to free DBState
      84           0 :     if (state->deleted_ == false)
      85           0 :         return NULL;
      86             : 
      87           0 :     if (state->gen_id_ > gen_id)
      88           0 :         return NULL;
      89             : 
      90           0 :     return state;
      91             : }
      92             : 
      93           0 : void FlowMgmtDbClient::FreeInterfaceState(Interface *intf, uint32_t gen_id) {
      94           0 :     VmInterface *vm_port = dynamic_cast<VmInterface *>(intf);
      95           0 :     if (vm_port == NULL)
      96           0 :         return;
      97             : 
      98           0 :     DBState *state = ValidateGenId(intf->get_table(), intf,
      99             :                                    interface_listener_id_, gen_id);
     100           0 :     if (state == NULL)
     101           0 :         return;
     102             : 
     103           0 :     intf->ClearState(intf->get_table(), interface_listener_id_);
     104           0 :     delete state;
     105             : }
     106             : 
     107           0 : void FlowMgmtDbClient::InterfaceNotify(DBTablePartBase *part, DBEntryBase *e) {
     108           0 :     Interface *intf = static_cast<Interface *>(e);
     109           0 :     if (intf->type() != Interface::VM_INTERFACE) {
     110           0 :         return;
     111             :     }
     112             : 
     113           0 :     VmInterface *vm_port = static_cast<VmInterface *>(intf);
     114           0 :     if (vm_port->device_type() == VmInterface::VMI_ON_LR)
     115           0 :         return;
     116             : 
     117           0 :     const VnEntry *new_vn = vm_port->vn();
     118             : 
     119             :     VmIntfFlowHandlerState *state = static_cast<VmIntfFlowHandlerState *>
     120           0 :         (e->GetState(part->parent(), interface_listener_id_));
     121           0 :     if (intf->IsDeleted()) {
     122           0 :         if (state) {
     123           0 :             DeleteEvent(vm_port, state);
     124             :         }
     125           0 :         return;
     126             :     }
     127             : 
     128           0 :     const VmInterface::SecurityGroupEntryList &new_sg_l = vm_port->sg_list();
     129           0 :     bool changed = false;
     130             : 
     131           0 :     if (state == NULL) {
     132           0 :         state = new VmIntfFlowHandlerState(NULL);
     133           0 :         e->SetState(part->parent(), interface_listener_id_, state);
     134             :         // Force change for first time
     135           0 :         state->policy_ = vm_port->policy_enabled();
     136           0 :         state->sg_l_ = new_sg_l;
     137           0 :         state->vn_ = new_vn;
     138           0 :         state->vrf_assign_acl_ = vm_port->vrf_assign_acl();
     139           0 :         state->is_vn_qos_config_ = vm_port->is_vn_qos_config();
     140           0 :         state->qos_config_ = vm_port->qos_config();
     141           0 :         state->fw_policy_list_ = vm_port->fw_policy_list();
     142           0 :         state->fwaas_fw_policy_list_ = vm_port->fwaas_fw_policy_list();
     143           0 :         if (vm_port->forwarding_vrf()) {
     144           0 :             state->forwarding_vrf_id_ = vm_port->forwarding_vrf()->vrf_id();
     145             :         }
     146           0 :         changed = true;
     147             :     } else {
     148           0 :         if (state->deleted_) {
     149           0 :             state->deleted_ = false;
     150           0 :             changed = true;
     151             :         }
     152             : 
     153           0 :         if (state->vn_.get() != new_vn) {
     154           0 :             changed = true;
     155           0 :             state->vn_ = new_vn;
     156             :         }
     157           0 :         if (state->policy_ != vm_port->policy_enabled()) {
     158           0 :             changed = true;
     159           0 :             state->policy_ = vm_port->policy_enabled();
     160             :         }
     161           0 :         if (state->sg_l_.list_ != new_sg_l.list_) {
     162           0 :             changed = true;
     163           0 :             state->sg_l_ = new_sg_l;
     164             :         }
     165           0 :         if (state->vrf_assign_acl_.get() != vm_port->vrf_assign_acl()) {
     166           0 :             changed = true;
     167           0 :             state->vrf_assign_acl_ = vm_port->vrf_assign_acl();
     168             :         }
     169           0 :         if (state->is_vn_qos_config_ != vm_port->is_vn_qos_config()) {
     170           0 :             state->is_vn_qos_config_ = vm_port->is_vn_qos_config();
     171           0 :             changed = true;
     172             :         }
     173           0 :         if (state->qos_config_.get() != vm_port->qos_config()) {
     174           0 :             state->qos_config_ = vm_port->qos_config();
     175           0 :             changed = true;
     176             :         }
     177             : 
     178           0 :         if (state->fw_policy_list_ != vm_port->fw_policy_list()) {
     179           0 :             state->fw_policy_list_ = vm_port->fw_policy_list();
     180           0 :             changed = true;
     181             :         }
     182             : 
     183           0 :         if (state->fwaas_fw_policy_list_ != vm_port->fwaas_fw_policy_list()) {
     184           0 :             state->fwaas_fw_policy_list_ = vm_port->fwaas_fw_policy_list();
     185           0 :             changed = true;
     186             :         }
     187             : 
     188           0 :         uint32_t forwarding_vrf_id = VrfEntry::kInvalidIndex;
     189           0 :         if (vm_port->forwarding_vrf()) {
     190           0 :             forwarding_vrf_id = vm_port->forwarding_vrf()->vrf_id();
     191             :         }
     192             : 
     193           0 :         if (state->forwarding_vrf_id_ != forwarding_vrf_id) {
     194           0 :             state->forwarding_vrf_id_ = forwarding_vrf_id;
     195           0 :             DeleteAllFlow(vm_port, state);
     196           0 :             changed = true;
     197             :         }
     198             :     }
     199             : 
     200           0 :     if (changed) {
     201           0 :         AddEvent(vm_port, state);
     202             :     }
     203             : }
     204             : 
     205             : ////////////////////////////////////////////////////////////////////////////
     206             : // VN notification handler
     207             : ////////////////////////////////////////////////////////////////////////////
     208           0 : void FlowMgmtDbClient::FreeVnState(VnEntry *vn, uint32_t gen_id) {
     209           0 :     DBState *state = ValidateGenId(vn->get_table(), vn, vn_listener_id_,
     210             :                                    gen_id);
     211           0 :     if (state == NULL)
     212           0 :         return;
     213             : 
     214           0 :     vn->ClearState(vn->get_table(), vn_listener_id_);
     215           0 :     delete state;
     216             : }
     217             : 
     218           0 : void FlowMgmtDbClient::VnNotify(DBTablePartBase *part, DBEntryBase *e) {
     219             :     // Add/Delete Acl:
     220             :     // Resync all Vn flows with new VN network policies
     221           0 :     VnEntry *vn = static_cast<VnEntry *>(e);
     222             :     VnFlowHandlerState *state = static_cast<VnFlowHandlerState *>
     223           0 :         (e->GetState(part->parent(), vn_listener_id_));
     224           0 :     AclDBEntryConstRef acl = NULL;
     225           0 :     AclDBEntryConstRef macl = NULL;
     226           0 :     AclDBEntryConstRef mcacl = NULL;
     227           0 :     bool enable_rpf = true;
     228           0 :     bool flood_unknown_unicast = false;
     229             : 
     230           0 :     if (vn->IsDeleted()) {
     231           0 :         if (state) {
     232           0 :             DeleteEvent(vn, state);
     233             :         }
     234           0 :         return;
     235             :     }
     236             : 
     237           0 :     bool changed = false;
     238           0 :     if (state != NULL) {
     239           0 :         acl = state->acl_;
     240           0 :         macl = state->macl_;
     241           0 :         mcacl = state->mcacl_;
     242           0 :         enable_rpf = state->enable_rpf_;
     243           0 :         flood_unknown_unicast = state->flood_unknown_unicast_;
     244             :     }
     245             : 
     246           0 :     const AclDBEntry *new_acl = vn->GetAcl();
     247           0 :     const AclDBEntry *new_macl = vn->GetMirrorAcl();
     248           0 :     const AclDBEntry *new_mcacl = vn->GetMirrorCfgAcl();
     249           0 :     bool new_enable_rpf = vn->enable_rpf();
     250           0 :     bool new_flood_unknown_unicast = vn->flood_unknown_unicast();
     251             : 
     252           0 :     if (state == NULL) {
     253           0 :         state = new VnFlowHandlerState(new_acl, new_macl, new_mcacl,
     254             :                                        new_enable_rpf,
     255           0 :                                        new_flood_unknown_unicast);
     256           0 :         e->SetState(part->parent(), vn_listener_id_, state);
     257           0 :         changed = true;
     258             :     }
     259             : 
     260           0 :     if (acl != new_acl || macl != new_macl || mcacl !=new_mcacl ||
     261           0 :         enable_rpf != new_enable_rpf ||
     262             :         flood_unknown_unicast != new_flood_unknown_unicast) {
     263           0 :         state->acl_ = new_acl;
     264           0 :         state->macl_ = new_macl;
     265           0 :         state->mcacl_ = new_mcacl;
     266           0 :         state->enable_rpf_ = new_enable_rpf;
     267           0 :         state->flood_unknown_unicast_ = new_flood_unknown_unicast;
     268           0 :         changed = true;
     269             :     }
     270             : 
     271           0 :     if (state->deleted_) {
     272           0 :         state->deleted_ = false;
     273           0 :         changed = true;
     274             :     }
     275             : 
     276           0 :     if (changed) {
     277           0 :         AddEvent(vn, state);
     278             :     }
     279           0 : }
     280             : 
     281             : ////////////////////////////////////////////////////////////////////////////
     282             : // ACL notification handler
     283             : ////////////////////////////////////////////////////////////////////////////
     284           0 : void FlowMgmtDbClient::FreeAclState(AclDBEntry *acl, uint32_t gen_id) {
     285           0 :     DBState *state = ValidateGenId(acl->get_table(), acl, acl_listener_id_,
     286             :                                    gen_id);
     287           0 :     if (state == NULL)
     288           0 :         return;
     289             : 
     290           0 :     acl->ClearState(acl->get_table(), acl_listener_id_);
     291           0 :     delete state;
     292             : }
     293             : 
     294           0 : void FlowMgmtDbClient::AclNotify(DBTablePartBase *part, DBEntryBase *e) {
     295           0 :     AclDBEntry *acl = static_cast<AclDBEntry *>(e);
     296             :     AclFlowHandlerState *state =
     297           0 :         static_cast<AclFlowHandlerState *>(e->GetState(part->parent(),
     298             :                                                        acl_listener_id_));
     299           0 :     if (e->IsDeleted()) {
     300           0 :         if (state) {
     301           0 :             DeleteEvent(acl, state);
     302             :         }
     303           0 :         return;
     304             :     }
     305             : 
     306           0 :     if (!state) {
     307           0 :         state = new AclFlowHandlerState();
     308           0 :         e->SetState(part->parent(), acl_listener_id_, state);
     309             :     }
     310           0 :     state->deleted_ = false;
     311           0 :     AddEvent(acl, state);
     312             : }
     313             : 
     314             : ////////////////////////////////////////////////////////////////////////////
     315             : // NH notification handler
     316             : ////////////////////////////////////////////////////////////////////////////
     317           0 : void FlowMgmtDbClient::FreeNhState(NextHop *nh, uint32_t gen_id) {
     318           0 :     DBState *state = ValidateGenId(nh->get_table(), nh, nh_listener_id_,
     319             :                                    gen_id);
     320           0 :     if (state == NULL)
     321           0 :         return;
     322             : 
     323           0 :     nh->ClearState(nh->get_table(), nh_listener_id_);
     324           0 :     delete state;
     325             : }
     326             : 
     327           0 : void FlowMgmtDbClient::NhNotify(DBTablePartBase *part, DBEntryBase *e) {
     328           0 :     NextHop *nh = static_cast<NextHop *>(e);
     329             :     NhFlowHandlerState *state =
     330           0 :         static_cast<NhFlowHandlerState *>(e->GetState(part->parent(),
     331             :                                                       nh_listener_id_));
     332           0 :     bool is_tunnel_nh = false;
     333           0 :     bool changed = false;
     334           0 :     uint8_t curr_valid_encap_size = 0;
     335           0 :     uint8_t new_valid_encap_size = 0;
     336           0 :     if (nh->GetType() == NextHop::TUNNEL && agent_->is_l3mh()) {
     337             :         const TunnelNH *tunnel_nh =
     338           0 :             dynamic_cast<const TunnelNH *>(nh);
     339           0 :         if (tunnel_nh) {
     340           0 :             is_tunnel_nh = true;
     341           0 :             TunnelNH::EncapDataList encap_list = tunnel_nh->GetEncapDataList();
     342           0 :             for (uint8_t i = 0; i < tunnel_nh->GetEncapDataList().size(); i++) {
     343           0 :                 if (encap_list[i].get()->valid_)
     344           0 :                   new_valid_encap_size++;
     345             :             }
     346           0 :         }
     347             :     }
     348             : 
     349           0 :     if (nh->IsDeleted()) {
     350           0 :         if (state) {
     351           0 :             DeleteEvent(nh, state);
     352             :         }
     353           0 :         return;
     354             :     }
     355             : 
     356           0 :     if (state != NULL && is_tunnel_nh && agent_->is_l3mh() ) {
     357           0 :         curr_valid_encap_size = state->valid_encap_size_;
     358             :     }
     359             : 
     360           0 :     if (!state) {
     361           0 :         state = new NhFlowHandlerState(new_valid_encap_size);
     362           0 :         nh->SetState(part->parent(), nh_listener_id_, state);
     363           0 :         changed = true;
     364             :     }
     365             : 
     366           0 :     if (is_tunnel_nh && agent_->is_l3mh() && new_valid_encap_size != curr_valid_encap_size ) {
     367           0 :         state->valid_encap_size_ = new_valid_encap_size;
     368           0 :         changed = true;
     369             :     }
     370             : 
     371           0 :     if (state->deleted_) {
     372           0 :         state->deleted_ = false;
     373           0 :         changed = true;
     374             :     }
     375             : 
     376           0 :     if (changed) {
     377           0 :         AddEvent(nh, state);
     378             :     }
     379             : }
     380             : 
     381             : ////////////////////////////////////////////////////////////////////////////
     382             : // VRF Notification handlers
     383             : ////////////////////////////////////////////////////////////////////////////
     384           0 : void FlowMgmtDbClient::FreeVrfState(VrfEntry *vrf, uint32_t gen_id) {
     385           0 :     if (vrf->IsDeleted() == false)
     386           0 :         return;
     387             : 
     388             :     VrfFlowHandlerState *state = static_cast<VrfFlowHandlerState *>
     389           0 :         (ValidateGenId(vrf->get_table(), vrf, vrf_listener_id_, gen_id));
     390           0 :     if (state == NULL)
     391           0 :         return;
     392           0 :     if (state->Unregister(vrf)) {
     393           0 :         vrf->ClearState(vrf->get_table(), vrf_listener_id_);
     394           0 :         delete state;
     395             :     }
     396             : }
     397             : 
     398           0 : bool FlowMgmtDbClient::VrfFlowHandlerState::Unregister(VrfEntry *vrf) {
     399             :     // Register to the Inet4 Unicast Table
     400             :     InetUnicastAgentRouteTable *inet_table =
     401             :         static_cast<InetUnicastAgentRouteTable *>
     402           0 :         (vrf->GetInet4UnicastRouteTable());
     403           0 :     if (inet_table) {
     404           0 :         if (inet_table->Size() != 0)
     405           0 :             return false;
     406           0 :         if (inet_listener_id_ != DBTableBase::kInvalidId) {
     407           0 :             inet_table->Unregister(inet_listener_id_);
     408           0 :             FLOW_TRACE(RouteTableListener,
     409             :                        "ROUTE-TABLE-UNREGISTER",
     410             :                        vrf->GetName(),
     411             :                        inet_table->GetTableName(),
     412             :                        inet_listener_id_);
     413           0 :             inet_listener_id_ = DBTableBase::kInvalidId;
     414             :         }
     415             :     }
     416             : 
     417             :     inet_table = static_cast<InetUnicastAgentRouteTable *>
     418           0 :         (vrf->GetInet6UnicastRouteTable());
     419           0 :     if (inet_table) {
     420           0 :         if (inet_table->Size() != 0)
     421           0 :             return false;
     422           0 :         if (inet6_listener_id_ != DBTableBase::kInvalidId) {
     423           0 :             inet_table->Unregister(inet6_listener_id_);
     424           0 :             FLOW_TRACE(RouteTableListener,
     425             :                        "ROUTE-TABLE-UNREGISTER",
     426             :                        vrf->GetName(),
     427             :                        inet_table->GetTableName(),
     428             :                        inet6_listener_id_);
     429           0 :             inet6_listener_id_ = DBTableBase::kInvalidId;
     430             :         }
     431             :     }
     432             : 
     433             :     // Register to the Bridge Unicast Table
     434             :     BridgeAgentRouteTable *bridge_table =
     435             :         static_cast<BridgeAgentRouteTable *>
     436           0 :         (vrf->GetBridgeRouteTable());
     437           0 :     if (bridge_table) {
     438           0 :         if (bridge_table->Size() != 0)
     439           0 :             return false;
     440           0 :         if (bridge_listener_id_ != DBTableBase::kInvalidId) {
     441           0 :             bridge_table->Unregister(bridge_listener_id_);
     442           0 :             FLOW_TRACE(RouteTableListener,
     443             :                        "ROUTE-TABLE-UNREGISTER",
     444             :                        vrf->GetName(),
     445             :                        bridge_table->GetTableName(),
     446             :                        bridge_listener_id_);
     447           0 :             bridge_listener_id_ = DBTableBase::kInvalidId;
     448             :         }
     449             :     }
     450             : 
     451           0 :     return true;
     452             : }
     453             : 
     454           0 : void FlowMgmtDbClient::VrfFlowHandlerState::Register(FlowMgmtDbClient *client,
     455             :                                                      VrfEntry *vrf) {
     456             :     // Register to the Inet4 Unicast Table
     457             :     InetUnicastAgentRouteTable *inet_table =
     458             :         static_cast<InetUnicastAgentRouteTable *>
     459           0 :         (vrf->GetInet4UnicastRouteTable());
     460             : 
     461           0 :     inet_listener_id_ =
     462           0 :         inet_table->Register(boost::bind(&FlowMgmtDbClient::RouteNotify, client,
     463             :                                          this, Agent::INET4_UNICAST, _1, _2));
     464           0 :     FLOW_TRACE(RouteTableListener,
     465             :                "ROUTE-TABLE-REGISTER",
     466             :                vrf->GetName(),
     467             :                inet_table->GetTableName(),
     468             :                inet_listener_id_);
     469             : 
     470             :     inet_table = static_cast<InetUnicastAgentRouteTable *>
     471           0 :         (vrf->GetInet6UnicastRouteTable());
     472           0 :     inet6_listener_id_ =
     473           0 :         inet_table->Register(boost::bind(&FlowMgmtDbClient::RouteNotify, client,
     474             :                                          this, Agent::INET6_UNICAST, _1, _2));
     475           0 :     FLOW_TRACE(RouteTableListener,
     476             :                "ROUTE-TABLE-REGISTER",
     477             :                vrf->GetName(),
     478             :                inet_table->GetTableName(),
     479             :                inet6_listener_id_);
     480             : 
     481             :     // Register to the Bridge Unicast Table
     482             :     BridgeAgentRouteTable *bridge_table =
     483             :         static_cast<BridgeAgentRouteTable *>
     484           0 :         (vrf->GetBridgeRouteTable());
     485           0 :     bridge_listener_id_ =
     486           0 :         bridge_table->Register(boost::bind(&FlowMgmtDbClient::RouteNotify,
     487             :                                            client, this, Agent::BRIDGE, _1,
     488             :                                            _2));
     489           0 :     FLOW_TRACE(RouteTableListener,
     490             :                "ROUTE-TABLE-REGISTER",
     491             :                vrf->GetName(),
     492             :                bridge_table->GetTableName(),
     493             :                bridge_listener_id_);
     494           0 : }
     495             : 
     496           0 : void FlowMgmtDbClient::VrfNotify(DBTablePartBase *part, DBEntryBase *e) {
     497           0 :     VrfEntry *vrf = static_cast<VrfEntry *>(e);
     498             :     VrfFlowHandlerState *state = static_cast<VrfFlowHandlerState *>
     499           0 :         (e->GetState(part->parent(), vrf_listener_id_));
     500           0 :     if (vrf->IsDeleted()) {
     501           0 :         if (state ) {
     502           0 :             state->deleted_ = true;
     503           0 :             DeleteEvent(vrf, state);
     504             :         }
     505           0 :         return;
     506             :     }
     507           0 :     if (state == NULL) {
     508           0 :         state = new VrfFlowHandlerState();
     509           0 :         state->Register(this, vrf);
     510           0 :         vrf->SetState(part->parent(), vrf_listener_id_, state);
     511           0 :         AddEvent(vrf, state);
     512             :     }
     513           0 :     state->deleted_ = false;
     514           0 :     return;
     515             : }
     516             : 
     517             : /////////////////////////////////////////////////////////////////////////////
     518             : // FlowTableRequest handlers for Routes
     519             : /////////////////////////////////////////////////////////////////////////////
     520           0 : void FlowMgmtDbClient::TraceMsg(AgentRoute *entry, const AgentPath *path,
     521             :                          const SecurityGroupList &sg_list, bool deleted) {
     522           0 :     std::vector<std::string> vn_list;
     523           0 :     if (path) {
     524           0 :         path->GetDestinationVnList(&vn_list);
     525             :     }
     526           0 :     InetUnicastRouteEntry *inet = dynamic_cast<InetUnicastRouteEntry *>(entry);
     527           0 :     if (inet) {
     528           0 :         FLOW_TRACE(RouteUpdate,
     529             :                    inet->vrf()->GetName(),
     530             :                    inet->prefix_address().to_string(),
     531             :                    inet->prefix_length(),
     532             :                    vn_list,
     533             :                    inet->IsDeleted(),
     534             :                    deleted,
     535             :                    sg_list.size(),
     536             :                    sg_list);
     537             :     }
     538             : 
     539           0 :     BridgeRouteEntry *bridge = dynamic_cast<BridgeRouteEntry *>(entry);
     540           0 :     if (bridge) {
     541           0 :         FLOW_TRACE(RouteUpdate,
     542             :                    bridge->vrf()->GetName(),
     543             :                    bridge->prefix_address().ToString(),
     544             :                    bridge->prefix_length(),
     545             :                    vn_list,
     546             :                    bridge->IsDeleted(),
     547             :                    deleted,
     548             :                    sg_list.size(),
     549             :                    sg_list);
     550             :     }
     551           0 : }
     552             : 
     553           0 : void FlowMgmtDbClient::FreeRouteState(AgentRoute *route, uint32_t gen_id) {
     554           0 :     if (route->IsDeleted() == false)
     555           0 :         return;
     556             : 
     557           0 :     VrfEntry *vrf = route->vrf();
     558             :     VrfFlowHandlerState *vrf_state = static_cast<VrfFlowHandlerState *>
     559           0 :         (vrf->GetState(vrf->get_table(), vrf_listener_id_));
     560           0 :     if (vrf_state == NULL)
     561           0 :         return;
     562             : 
     563             :     DBTableBase::ListenerId id;
     564           0 :     if (dynamic_cast<InetUnicastRouteEntry *>(route)) {
     565           0 :         if (route->GetTableType() == Agent::INET4_UNICAST)
     566           0 :             id = vrf_state->inet_listener_id_;
     567             :         else
     568           0 :             id = vrf_state->inet6_listener_id_;
     569           0 :     } else if (dynamic_cast<BridgeRouteEntry *>(route)) {
     570           0 :         id = vrf_state->bridge_listener_id_;
     571             :     } else {
     572           0 :         return;
     573             :     }
     574             : 
     575           0 :     DBState *state = ValidateGenId(route->get_table(), route, id, gen_id);
     576           0 :     if (state == NULL)
     577           0 :         return;
     578             : 
     579           0 :     route->ClearState(route->get_table(), id);
     580           0 :     delete state;
     581             : }
     582             : 
     583           0 : bool FlowMgmtDbClient::HandleTrackingIpChange(const AgentRoute *rt,
     584             :                                               RouteFlowHandlerState *state) {
     585           0 :     bool ret = false;
     586           0 :     RouteFlowHandlerState::FixedIpMap new_map;
     587             : 
     588             :     //Maintain a list of interface to fixed-ip mapping for
     589             :     //a given route, we need this map because there can be
     590             :     //multiple path from different local vm path peer.
     591             :     //If the route has fixed-ip change then all the the flows
     592             :     //dependent on this route will be reevaluated.
     593           0 :     for(Route::PathList::const_iterator it = rt->GetPathList().begin();
     594           0 :             it != rt->GetPathList().end(); it++) {
     595           0 :         const AgentPath *path = static_cast<const AgentPath *>(it.operator->());
     596           0 :         const Peer *peer = path->peer();
     597           0 :         if (peer && peer->GetType() != Peer::LOCAL_VM_PORT_PEER) {
     598           0 :             continue;
     599             :         }
     600             : 
     601           0 :         if (path->nexthop() == NULL ||
     602           0 :             path->nexthop()->GetType() != NextHop::INTERFACE) {
     603           0 :             continue;
     604             :         }
     605             : 
     606           0 :         const InterfaceNH *nh = static_cast<InterfaceNH *>(path->nexthop());
     607           0 :         InterfaceConstRef intf = nh->GetInterface();
     608             : 
     609           0 :         IpAddress new_fixed_ip = path->GetFixedIp();
     610           0 :         if (new_fixed_ip == Ip4Address(0)) {
     611           0 :             continue;
     612             :         }
     613             : 
     614           0 :         new_map.insert(RouteFlowHandlerState::FixedIpEntry(intf, new_fixed_ip));
     615             : 
     616             :         RouteFlowHandlerState::FixedIpMap::const_iterator old_it =
     617           0 :             state->fixed_ip_map_.find(intf);
     618           0 :         if (old_it != state->fixed_ip_map_.end()) {
     619           0 :             if (new_fixed_ip != old_it->second) {
     620           0 :                 ret = true;
     621             :             }
     622             :         }
     623           0 :     }
     624             : 
     625             :     //Check if any path has been deleted
     626             :     RouteFlowHandlerState::FixedIpMap::const_iterator old_it =
     627           0 :         state->fixed_ip_map_.begin();
     628           0 :     for (;old_it != state->fixed_ip_map_.end(); old_it++) {
     629           0 :         if (new_map.find(old_it->first) == new_map.end()) {
     630           0 :             ret = true;
     631           0 :             break;
     632             :         }
     633             :     }
     634             : 
     635           0 :     state->fixed_ip_map_ = new_map;
     636           0 :     return ret;
     637           0 : }
     638             : 
     639           0 : void FlowMgmtDbClient::RouteNotify(VrfFlowHandlerState *vrf_state,
     640             :                                    Agent::RouteTableType type,
     641             :                                    DBTablePartBase *partition, DBEntryBase *e) {
     642           0 :     DBTableBase::ListenerId id = vrf_state->GetListenerId(type);
     643             :     RouteFlowHandlerState *state =
     644           0 :         static_cast<RouteFlowHandlerState *>(e->GetState(partition->parent(),
     645             :                                                          id));
     646           0 :     AgentRoute *route = static_cast<AgentRoute *>(e);
     647           0 :     const AgentPath *path = route->GetActivePath();
     648           0 :     SecurityGroupList new_sg_l;
     649             :     // Get new sg-list. Sort, the sg-list to aid in comparison
     650           0 :     if (path) {
     651           0 :         new_sg_l = route->GetActivePath()->sg_list();
     652           0 :         sort(new_sg_l.begin(), new_sg_l.end());
     653             :     }
     654           0 :     TraceMsg(route, path, new_sg_l, vrf_state->deleted_);
     655             : 
     656           0 :     if (route->IsDeleted()) {
     657           0 :         if (state) {
     658           0 :             DeleteEvent(route, state);
     659             :         }
     660           0 :         return;
     661             :     }
     662             : 
     663           0 :     if (vrf_state->deleted_) {
     664             :         // ignore route add/change for delete notified VRF.
     665           0 :         return;
     666             :     }
     667             : 
     668           0 :     if (route->is_multicast()) {
     669           0 :         return;
     670             :     }
     671             : 
     672           0 :     bool new_route = false;
     673           0 :     if (state == NULL) {
     674           0 :         state  = new RouteFlowHandlerState();
     675           0 :         route->SetState(partition->parent(), id, state);
     676           0 :         AddEvent(route, state);
     677           0 :         new_route = true;
     678             :     } else {
     679           0 :         if (state->deleted_) {
     680           0 :             state->deleted_ = false;
     681           0 :             new_route = true;
     682             :         }
     683             :     }
     684             : 
     685           0 :     bool changed = false;
     686           0 :     bool inet_rt_nh_changed = false;
     687             :     // Handle SG change
     688           0 :     if (state->sg_l_ != new_sg_l) {
     689           0 :         state->sg_l_ = new_sg_l;
     690           0 :         changed = true;
     691             :     }
     692             : 
     693             :     InetUnicastRouteEntry *inet_route =
     694           0 :         dynamic_cast<InetUnicastRouteEntry *>(route);
     695             :     //Trigger RPF NH sync, if active nexthop changes
     696           0 :     const NextHop *active_nh = route->GetActiveNextHop();
     697           0 :     const NextHop *local_nh = NULL;
     698           0 :     if (active_nh && (active_nh->GetType() == NextHop::COMPOSITE)) {
     699             :         //If destination is ecmp, all remote flow would
     700             :         //have RPF NH set to that local component NH
     701           0 :         local_nh = EcmpData::GetLocalNextHop(route);
     702             :     }
     703             : 
     704           0 :     if ((state->active_nh_ != active_nh) || (state->local_nh_ != local_nh)) {
     705           0 :         state->active_nh_ = active_nh;
     706           0 :         state->local_nh_ = local_nh;
     707             :         /* NH change can result in change of DMAC for the following routes, if
     708             :          * they point to L2 flows.So we need to delete these L2 flows to trigger
     709             :          * packet to be trapped again for flows which will have the new DMAC.
     710             :          * The InetRoutes whose NH change has to be tracked are
     711             :          * Ipv4 InetRoutes which have prefix < 32
     712             :          * Ipv6 InetRoutes which have prefix < 128
     713             :          */
     714           0 :         if (inet_route) {
     715           0 :             uint8_t plen = inet_route->prefix_length();
     716           0 :             if ((inet_route->prefix_address().is_v4() && plen < 32) ||
     717           0 :                 (inet_route->prefix_address().is_v6() && plen < 128)) {
     718           0 :                 inet_rt_nh_changed = true;
     719             :             } else {
     720           0 :                 new_route = true;
     721             :             }
     722             :         } else {
     723           0 :             new_route = true;
     724             :         }
     725             :     }
     726             : 
     727           0 :     if (HandleTrackingIpChange(route, state)) {
     728             :         //Tracking IP change can result in flow change
     729             :         //i.e in case of NAT new reverse flow might be
     730             :         //created, hence enqueue a ADD event so that flow will
     731             :         //be reevaluated.
     732           0 :         new_route = true;
     733             :     }
     734             : 
     735           0 :     if (state->ecmp_load_balance_ != path->ecmp_load_balance()) {
     736           0 :         state->ecmp_load_balance_ = path->ecmp_load_balance();
     737           0 :         changed = true;
     738             :     }
     739             : 
     740           0 :     if (state->tags_l_ != path->tag_list()) {
     741           0 :         state->tags_l_ = path->tag_list();
     742           0 :         changed = true;
     743             :     }
     744             : 
     745           0 :     if (state->tunnel_bmap_ != path->tunnel_bmap()) {
     746           0 :         state->tunnel_bmap_ = path->tunnel_bmap();
     747           0 :         changed = true;
     748             :     }
     749             : 
     750           0 :     if (new_route == true) {
     751           0 :         AddEvent(route, state);
     752           0 :     } else if (inet_rt_nh_changed == true) {
     753           0 :         RouteNHChangeEvent(route, state);
     754           0 :     } else if (changed == true) {
     755           0 :         ChangeEvent(route, state);
     756             :     }
     757           0 : }
     758             : 
     759             : /////////////////////////////////////////////////////////////////////////////
     760             : // FlowTableRequest message handler
     761             : /////////////////////////////////////////////////////////////////////////////
     762           0 : bool FlowMgmtDbClient::FreeDBState(const DBEntry *entry, uint32_t gen_id) {
     763           0 :     if (dynamic_cast<const Interface *>(entry)) {
     764           0 :         DBTable *table = agent_->interface_table();
     765           0 :         Interface *intf = static_cast<Interface *>(table->Find(entry));
     766           0 :         FreeInterfaceState(intf, gen_id);
     767           0 :         return true;
     768             :     }
     769             : 
     770           0 :     if (dynamic_cast<const VnEntry *>(entry)) {
     771           0 :         DBTable *table = agent_->vn_table();
     772           0 :         VnEntry *vn = static_cast<VnEntry *>(table->Find(entry));
     773           0 :         FreeVnState(vn, gen_id);
     774           0 :         return true;
     775             :     }
     776             : 
     777           0 :     if (dynamic_cast<const AclDBEntry *>(entry)) {
     778           0 :         DBTable *table = agent_->acl_table();
     779           0 :         AclDBEntry *acl = static_cast<AclDBEntry *> (table->Find(entry));
     780           0 :         FreeAclState(acl, gen_id);
     781           0 :         return true;
     782             :     }
     783             : 
     784           0 :     if (dynamic_cast<const NextHop *>(entry)) {
     785           0 :         DBTable *table = agent_->nexthop_table();
     786           0 :         NextHop *nh = static_cast<NextHop *> (table->Find(entry));
     787           0 :         FreeNhState(nh, gen_id);
     788           0 :         return true;
     789             :     }
     790             : 
     791           0 :     if (dynamic_cast<const VrfEntry *>(entry)) {
     792           0 :         DBTable *table = agent_->vrf_table();
     793           0 :         VrfEntry *vrf = static_cast<VrfEntry *> (table->Find(entry));
     794           0 :         FreeVrfState(vrf, gen_id);
     795           0 :         return true;
     796             :     }
     797             : 
     798           0 :     if (dynamic_cast<const AgentRoute *>(entry)) {
     799           0 :         VrfEntry *vrf = (static_cast<const AgentRoute *>(entry))->vrf();
     800           0 :         AgentRoute *rt = NULL;
     801           0 :         if (dynamic_cast<const InetUnicastRouteEntry *>(entry)) {
     802           0 :             DBTable *table = NULL;
     803           0 :             if ((dynamic_cast<const AgentRoute *>(entry))->GetTableType()
     804           0 :                 == Agent::INET4_UNICAST)
     805           0 :                 table = vrf->GetInet4UnicastRouteTable();
     806             :             else
     807           0 :                 table = vrf->GetInet6UnicastRouteTable();
     808           0 :             rt = static_cast<AgentRoute *>(table->Find(entry));
     809             :         } else {
     810           0 :             DBTable *table = vrf->GetBridgeRouteTable();
     811           0 :             rt = static_cast<AgentRoute *>(table->Find(entry));
     812             :         }
     813           0 :         FreeRouteState(rt, gen_id);
     814           0 :         return true;
     815             :     }
     816             : 
     817           0 :     assert(0);
     818             :     return true;
     819             : }

Generated by: LCOV version 1.14