LCOV - code coverage report
Current view: top level - vnsw/agent/vrouter/ksync - ksync_init.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 79 402 19.7 %
Date: 2026-11-09 02:10:49 Functions: 5 31 16.1 %
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/asio.hpp>
       7             : #include <boost/bind/bind.hpp>
       8             : 
       9             : #if defined(__linux__)
      10             : #include <linux/netlink.h>
      11             : #include <linux/rtnetlink.h>
      12             : #include <linux/genetlink.h>
      13             : #include <linux/if_ether.h>
      14             : #include <netinet/ether.h>
      15             : #endif
      16             : 
      17             : #include "ksync_init.h"
      18             : 
      19             : #include <sys/mman.h>
      20             : #include <net/if.h>
      21             : 
      22             : #include <io/event_manager.h>
      23             : #include <db/db_entry.h>
      24             : #include <db/db_table.h>
      25             : #include <db/db_table_partition.h>
      26             : #include <cmn/agent_cmn.h>
      27             : #include <pkt/flow_proto.h>
      28             : #include <ksync/ksync_index.h>
      29             : #include <ksync/ksync_entry.h>
      30             : #include <ksync/ksync_object.h>
      31             : #include <ksync/ksync_netlink.h>
      32             : #include <ksync/ksync_sock.h>
      33             : #include <init/agent_param.h>
      34             : 
      35             : #include <nl_util.h>
      36             : #include <vhost.h>
      37             : #include <vr_message.h>
      38             : #include <vr_mem.h>
      39             : 
      40             : #include "bridge_route_audit_ksync.h"
      41             : #include "interface_ksync.h"
      42             : #include "route_ksync.h"
      43             : #include "mirror_ksync.h"
      44             : #include "vrf_assign_ksync.h"
      45             : #include "vxlan_ksync.h"
      46             : #include "sandesh_ksync.h"
      47             : #include "qos_queue_ksync.h"
      48             : #include "forwarding_class_ksync.h"
      49             : #include "qos_config_ksync.h"
      50             : 
      51             : using namespace boost::placeholders;
      52             : 
      53             : #define    VNSW_GENETLINK_FAMILY_NAME  "vnsw"
      54             : 
      55           0 : void LogSockInitErrors(bool success_cond, bool use_errno, string err_str) {
      56           0 :     if(success_cond == false) {
      57           0 :         if (use_errno) {
      58           0 :             LOG(ERROR,
      59             :                 err_str << " Failed with " << errno << "syscall: " 
      60             :                 << strerror(errno) << ". BackTrace: " << AgentBackTrace(1));
      61             :         } else {
      62           0 :             LOG(ERROR,
      63             :                "Failed with " << err_str << ". BackTrace: " << AgentBackTrace(1));
      64             :         }
      65           0 :         _Exit(0);
      66             :     }
      67           0 :     return;
      68             : }
      69             : 
      70           2 : KSync::KSync(Agent *agent)
      71           2 :     : agent_(agent), interface_ksync_obj_(new InterfaceKSyncObject(this)),
      72           2 :       flow_table_ksync_obj_list_(),
      73           2 :       mpls_ksync_obj_(new MplsKSyncObject(this)),
      74           2 :       nh_ksync_obj_(new NHKSyncObject(this)),
      75           2 :       mirror_ksync_obj_(new MirrorKSyncObject(this)),
      76           2 :       vrf_ksync_obj_(new VrfKSyncObject(this)),
      77           2 :       vxlan_ksync_obj_(new VxLanKSyncObject(this)),
      78           2 :       vrf_assign_ksync_obj_(new VrfAssignKSyncObject(this)),
      79           2 :       vnsw_interface_listner_(new VnswInterfaceListener(agent)),
      80           2 :       ksync_flow_memory_(new KSyncFlowMemory(this, VR_MEM_FLOW_TABLE_OBJECT)),
      81           2 :       ksync_flow_index_manager_(new KSyncFlowIndexManager(this)),
      82           2 :       qos_queue_ksync_obj_(new QosQueueKSyncObject(this)),
      83           2 :       forwarding_class_ksync_obj_(new ForwardingClassKSyncObject(this)),
      84           2 :       qos_config_ksync_obj_(new QosConfigKSyncObject(this)),
      85           2 :       bridge_route_audit_ksync_obj_(new BridgeRouteAuditKSyncObject(this)),
      86           4 :       ksync_bridge_memory_(new KSyncBridgeMemory(this, VR_MEM_BRIDGE_TABLE_OBJECT)) {
      87          10 :       for (uint16_t i = 0; i < kHugePageFiles; i++) {
      88           8 :           huge_fd_[i] = -1;
      89           8 :           huge_pages_[i] = NULL;
      90             :       }
      91           2 :       btable_huge_pages_index_ = 0;
      92           2 :       ftable_huge_pages_index_ = 0;
      93           4 :       for (uint16_t i = 0; i < agent->flow_thread_count(); i++) {
      94           2 :           FlowTableKSyncObject *obj = new FlowTableKSyncObject(this);
      95           2 :           flow_table_ksync_obj_list_.push_back(obj);
      96             :       }
      97           2 : }
      98             : 
      99           2 : KSync::~KSync() {
     100          10 :       for (uint16_t i = 0; i < kHugePageFiles; i++) {
     101           8 :           if (huge_fd_[i] != -1)
     102           0 :               close (huge_fd_[i]);
     103             :       }
     104           2 :     STLDeleteValues(&flow_table_ksync_obj_list_);
     105           2 : }
     106             : 
     107           0 : void KSync::RegisterDBClients(DB *db) {
     108           0 :     KSyncObjectManager::Init();
     109           0 :     interface_ksync_obj_.get()->RegisterDBClients();
     110           0 :     vrf_ksync_obj_.get()->RegisterDBClients();
     111           0 :     nh_ksync_obj_.get()->RegisterDBClients();
     112           0 :     mpls_ksync_obj_.get()->RegisterDBClients();
     113           0 :     mirror_ksync_obj_.get()->RegisterDBClients();
     114           0 :     vrf_assign_ksync_obj_.get()->RegisterDBClients();
     115           0 :     vxlan_ksync_obj_.get()->RegisterDBClients();
     116           0 :     qos_queue_ksync_obj_.get()->RegisterDBClients();
     117           0 :     forwarding_class_ksync_obj_.get()->RegisterDBClients();
     118           0 :     qos_config_ksync_obj_.get()->RegisterDBClients();
     119           0 :     agent_->set_router_id_configured(false);
     120           0 : }
     121             : 
     122           0 : void KSync::Init(bool create_vhost) {
     123           0 :     NetlinkInit();
     124           0 :     SetHugePages();
     125           0 :     InitFlowMem();
     126           0 :     ResetVRouter(true);
     127           0 :     if (create_vhost) {
     128           0 :         CreateVhostIntf();
     129             :     }
     130           0 :     interface_ksync_obj_.get()->Init();
     131           0 :     for (uint16_t i = 0; i < flow_table_ksync_obj_list_.size(); i++) {
     132           0 :         FlowTable *flow_table = agent_->pkt()->get_flow_proto()->GetTable(i);
     133           0 :         flow_table->set_ksync_object(flow_table_ksync_obj_list_[i]);
     134           0 :         flow_table_ksync_obj_list_[i]->Init();
     135             :     }
     136           0 :     ksync_flow_memory_.get()->Init();
     137           0 :     ksync_bridge_memory_.get()->Init();
     138           0 : }
     139             : 
     140           2 : void KSync::InitDone() {
     141           4 :     for (uint16_t i = 0; i < flow_table_ksync_obj_list_.size(); i++) {
     142           2 :         FlowTable *flow_table = agent_->pkt()->get_flow_proto()->GetTable(i);
     143           2 :         flow_table_ksync_obj_list_[i]->set_flow_table(flow_table);
     144           2 :         flow_table->set_ksync_object(flow_table_ksync_obj_list_[i]);
     145             :     }
     146           2 :     uint32_t count = ksync_flow_memory_->table_entries_count();
     147           2 :     ksync_flow_index_manager_->InitDone(count);
     148           2 :     AgentProfile *profile = agent_->oper_db()->agent_profile();
     149           2 :     profile->RegisterKSyncStatsCb(boost::bind(&KSync::SetProfileData,
     150             :                                               this, _1));
     151           2 :     KSyncSock::Get(0)->SetMeasureQueueDelay(agent_->MeasureQueueDelay());
     152           2 : }
     153             : 
     154           0 : void KSync::InitFlowMem() {
     155           0 :     ksync_flow_memory_.get()->InitMem(ftable_huge_page_mem_get());
     156           0 :     ksync_bridge_memory_.get()->InitMem(btable_huge_page_mem_get());
     157           0 : }
     158             : 
     159           0 : void KSync::NetlinkInit() {
     160             :     EventManager *event_mgr;
     161           0 :     bool use_work_queue = false;
     162             : 
     163           0 :     event_mgr = agent_->event_manager();
     164           0 :     boost::asio::io_context &io = *event_mgr->io_service();
     165             : 
     166           0 :     KSyncSockNetlink::Init(io, NETLINK_GENERIC, use_work_queue,
     167           0 :                            agent_->params()->ksync_thread_cpu_pin_policy());
     168           0 :     for (int i = 0; i < KSyncSock::kRxWorkQueueCount; i++) {
     169             :         KSyncSock::SetAgentSandeshContext
     170           0 :             (new KSyncSandeshContext(this), i);
     171             :     }
     172           0 :     GenericNetlinkInit();
     173           0 : }
     174             : 
     175           2 : int KSync::Encode(Sandesh &encoder, uint8_t *buf, int buf_len) {
     176             :     int len, error;
     177           2 :     len = encoder.WriteBinary(buf, buf_len, &error);
     178           2 :     return len;
     179             : }
     180             : 
     181           5 : void KSync::SetProfileData(ProfileData *data) {
     182           5 :     KSyncSock *sock = KSyncSock::Get(0);
     183           5 :     const KSyncTxQueue *tx_queue = sock->send_queue();
     184             : 
     185           5 :     ProfileData::WorkQueueStats *stats = &data->ksync_tx_queue_count_;
     186           5 :     stats->name_ = "KSync Send Queue";
     187           5 :     stats->queue_count_ = tx_queue->queue_len();
     188           5 :     stats->enqueue_count_ = tx_queue->enqueues();
     189           5 :     stats->dequeue_count_ = tx_queue->dequeues();
     190           5 :     stats->max_queue_count_ = tx_queue->max_queue_len();
     191           5 :     stats->start_count_ = tx_queue->read_events();
     192           5 :     stats->busy_time_ = tx_queue->busy_time();
     193           5 :     tx_queue->set_measure_busy_time(agent()->MeasureQueueDelay());
     194           5 :     if (agent()->MeasureQueueDelay()) {
     195           0 :         tx_queue->ClearStats();
     196             :     }
     197             : 
     198           5 :     stats = &data->ksync_rx_queue_count_;
     199           5 :     stats->queue_count_ = 0;
     200           5 :     stats->enqueue_count_ = 0;
     201           5 :     stats->dequeue_count_ = 0;
     202           5 :     stats->max_queue_count_ = 0;
     203           5 :     stats->start_count_ = 0;
     204           5 :     stats->busy_time_ = 0;
     205             : 
     206          15 :     for (int i = 0; i < IoContext::MAX_WORK_QUEUES; i++) {
     207             :         const KSyncSock::KSyncReceiveQueue *rx_queue =
     208          10 :             sock->get_receive_work_queue(i);
     209          10 :         if (i == 0)
     210           5 :             stats->name_ = rx_queue->Description();
     211          10 :         stats->queue_count_ += rx_queue->Length();
     212          10 :         stats->enqueue_count_ += rx_queue->NumEnqueues();
     213          10 :         stats->dequeue_count_ += rx_queue->NumDequeues();
     214          10 :         if (stats->max_queue_count_ < rx_queue->max_queue_len()) {
     215           5 :             stats->max_queue_count_ = rx_queue->max_queue_len();
     216             :         }
     217          10 :         stats->start_count_ += rx_queue->task_starts();
     218          10 :         stats->busy_time_ += rx_queue->busy_time();
     219          10 :         rx_queue->set_measure_busy_time(agent()->MeasureQueueDelay());
     220          10 :         if (agent()->MeasureQueueDelay()) {
     221           0 :             rx_queue->ClearStats();
     222             :         }
     223             :     }
     224           5 : }
     225             : 
     226           0 : void KSync::InitVrouterOps(vrouter_ops *v) {
     227           0 :     v->set_vo_rid(0);
     228           0 :     v->set_vo_mpls_labels(-1);
     229           0 :     v->set_vo_mpls_labels(-1);
     230           0 :     v->set_vo_nexthops(-1);
     231           0 :     v->set_vo_bridge_entries(-1);
     232           0 :     v->set_vo_oflow_bridge_entries(-1);
     233           0 :     v->set_vo_flow_entries(-1);
     234           0 :     v->set_vo_oflow_entries(-1);
     235           0 :     v->set_vo_interfaces(-1);
     236           0 :     v->set_vo_mirror_entries(-1);
     237           0 :     v->set_vo_vrfs(-1);
     238           0 :     v->set_vo_log_level(0);
     239           0 :     v->set_vo_perfr(-1);
     240           0 :     v->set_vo_perfs(-1);
     241           0 :     v->set_vo_from_vm_mss_adj(-1);
     242           0 :     v->set_vo_to_vm_mss_adj(-1);
     243           0 :     v->set_vo_perfr1(-1);
     244           0 :     v->set_vo_perfr2(-1);
     245           0 :     v->set_vo_perfr3(-1);
     246           0 :     v->set_vo_perfp(-1);
     247           0 :     v->set_vo_perfq1(-1);
     248           0 :     v->set_vo_perfq2(-1);
     249           0 :     v->set_vo_perfq3(-1);
     250           0 :     v->set_vo_udp_coff(-1);
     251           0 :     v->set_vo_flow_hold_limit(-1);
     252           0 :     v->set_vo_mudp(-1);
     253           0 :     v->set_vo_burst_tokens(-1);
     254           0 :     v->set_vo_burst_interval(-1);
     255           0 :     v->set_vo_burst_step(-1);
     256           0 :     v->set_vo_memory_alloc_checks(-1);
     257           0 : }
     258             : 
     259           0 : void KSync::SetHugePages() {
     260           0 :     vr_hugepage_config encoder;
     261             :     bool fail[kHugePageFiles];
     262           0 :     std::string filename[kHugePageFiles];
     263             :     uint32_t filesize[kHugePageFiles];
     264             :     uint32_t flags[kHugePageFiles];
     265             :     uint32_t pagesize[kHugePageFiles];
     266             :     uint16_t i, j;
     267             :     uint32_t bridge_table_size, flow_table_size;
     268             : 
     269             :     // get the table size for bridge and flow
     270           0 :     bridge_table_size = ksync_bridge_memory_.get()->GetKernelTableSize();
     271           0 :     flow_table_size = ksync_flow_memory_.get()->GetKernelTableSize();
     272             : 
     273           0 :     LOG(INFO, __FUNCTION__ << ": " << "Bridge table size:" << bridge_table_size
     274             :                      << " Flow table size:" << flow_table_size << "\n");
     275             : 
     276           0 :     for (i = 0; i < kHugePageFiles / 2; ++i) {
     277           0 :         filename[i] = agent_->params()->huge_page_file_1G(i);
     278           0 :         if ((i % 2) == 0) {
     279           0 :             filesize[i] = bridge_table_size;
     280             :         } else {
     281           0 :             filesize[i] = flow_table_size;
     282             :         }
     283             :         // set pagesize array
     284           0 :         pagesize[i] = 1024 * 1024 * 1024;
     285           0 :         flags[i] = O_CREAT | O_RDWR;
     286           0 :         fail[i] = false;
     287             :     }
     288           0 :     for (j = i; j < kHugePageFiles; ++j) {
     289           0 :         filename[j] = agent_->params()->huge_page_file_2M(j - i);
     290           0 :         if ((j % 2) == 0) {
     291           0 :             filesize[j] = bridge_table_size;
     292             :         } else {
     293           0 :             filesize[j] = flow_table_size;
     294             :         }
     295             :         // set pagesize array
     296           0 :         pagesize[j] = 2 * 1024 * 1024;
     297           0 :         flags[j] = O_CREAT | O_RDWR;
     298           0 :         fail[j] = false;
     299             :     }
     300             : 
     301           0 :     for (i = 0; i < kHugePageFiles; ++i) {
     302           0 :         if (filename[i].empty()) {
     303           0 :             fail[i] = true;
     304           0 :             continue;
     305             :         }
     306             : 
     307           0 :         huge_fd_[i] = open(filename[i].c_str(), flags[i], 0755);
     308           0 :         if (huge_fd_[i] < 0) {
     309           0 :             fail[i] = true;
     310           0 :             continue;
     311             :         }
     312             : 
     313           0 :         LOG(INFO, "Mem mapping hugepage file:" << filename[i].c_str()
     314             :                   << " size:" << filesize[i] << "\n");
     315           0 :         huge_pages_[i] = (void *) mmap(NULL, filesize[i],
     316             :                                        PROT_READ | PROT_WRITE, MAP_SHARED,
     317           0 :                                        huge_fd_[i], 0);
     318           0 :         if (huge_pages_[i] == MAP_FAILED) {
     319           0 :             LOG(ERROR, "Failed to Mmap hugepage file:" << filename[i].c_str() << "\n");
     320           0 :             huge_pages_[i] = NULL;
     321           0 :             fail[i] = true;
     322             :         } else {
     323           0 :             LOG(INFO, "Mem mapped hugepage file:" << filename[i].c_str()
     324             :                       << " to addr:" << huge_pages_[i] << "\n");
     325           0 :             if ((i % 2) == 0) {
     326           0 :                 btable_huge_pages_index_ = i;
     327             :             } else {
     328           0 :                 ftable_huge_pages_index_ = i;
     329             :             }
     330             :         }
     331             :     }
     332             : 
     333           0 :     encoder.set_vhp_op(sandesh_op::ADD);
     334             : 
     335           0 :     std::vector<uint64_t> huge_mem;
     336           0 :     std::vector<uint32_t> huge_mem_size;
     337           0 :     std::vector<uint32_t> huge_page_size;
     338           0 :     std::vector<int8_t>   huge_page_paths;
     339           0 :     std::vector<uint32_t> huge_page_paths_sz;
     340             : 
     341           0 :     for (uint16_t i = 0; i < kHugePageFiles; ++i) {
     342           0 :         if (fail[i] == false) {
     343           0 :             huge_mem.push_back((uint64_t) huge_pages_[i]);
     344           0 :             huge_page_size.push_back(pagesize[i]);
     345           0 :             huge_mem_size.push_back(filesize[i]);
     346           0 :             const char *path = filename[i].c_str();
     347           0 :             uint32_t len = strlen(path) + 1;
     348           0 :             for (uint32_t c = 0; c < len; c++) {
     349           0 :                 huge_page_paths.push_back(path[c]);
     350             :             }
     351           0 :             huge_page_paths_sz.push_back(len);
     352             :         }
     353             :     }
     354           0 :     encoder.set_vhp_mem(huge_mem);
     355           0 :     encoder.set_vhp_psize(huge_page_size);
     356             :     // set huge_mem_size
     357           0 :     encoder.set_vhp_mem_sz(huge_mem_size);
     358           0 :     encoder.set_vhp_file_paths(huge_page_paths);
     359           0 :     encoder.set_vhp_file_path_sz(huge_page_paths_sz);
     360           0 :     encoder.set_vhp_resp(VR_HPAGE_CFG_RESP_HPAGE_SUCCESS);
     361             : 
     362             :     uint8_t msg[KSYNC_DEFAULT_MSG_SIZE];
     363           0 :     int len = Encode(encoder, msg, KSYNC_DEFAULT_MSG_SIZE);
     364             : 
     365           0 :     LOG(INFO, "Sending Huge Page configuration to VROUTER\n");
     366           0 :     KSyncSock *sock = KSyncSock::Get(0);
     367           0 :     sock->BlockingSend((char *)msg, len);
     368           0 :     if (sock->BlockingRecv()) {
     369           0 :         LOG(ERROR, "Error sending Huge Page configuration to VROUTER. Skipping KSync Start");
     370             :     }
     371           0 : }
     372             : 
     373           0 : void KSync::ResetVRouter(bool run_sync_mode) {
     374           0 :     int len = 0;
     375           0 :     vrouter_ops encoder;
     376           0 :     encoder.set_h_op(sandesh_op::RESET);
     377             :     uint8_t msg[KSYNC_DEFAULT_MSG_SIZE];
     378           0 :     len = Encode(encoder, msg, KSYNC_DEFAULT_MSG_SIZE);
     379             : 
     380           0 :     KSyncSock *sock = KSyncSock::Get(0);
     381           0 :     sock->BlockingSend((char *)msg, len);
     382           0 :     if (sock->BlockingRecv()) {
     383           0 :         LOG(ERROR, "Error resetting VROUTER. Skipping KSync Start");
     384           0 :         return;
     385             :     }
     386             : 
     387             :     //configure vrouter with priority_tagging configuration
     388           0 :     encoder.set_h_op(sandesh_op::ADD);
     389           0 :     encoder.set_vo_priority_tagging(agent_->params()->qos_priority_tagging());
     390             :     //Initialize rest of the fields to values so that vrouter does not take any
     391             :     //action on those field values
     392           0 :     InitVrouterOps(&encoder);
     393           0 :     len = Encode(encoder, msg, KSYNC_DEFAULT_MSG_SIZE);
     394           0 :     sock->BlockingSend((char *)msg, len);
     395           0 :     if (sock->BlockingRecv()) {
     396           0 :         LOG(ERROR, "Error setting Qos priority-tagging for vrouter");
     397             :     }
     398             : 
     399             :     //Get configured mpls, vmi, vni and nexthop parameters
     400             :     //from vrouter
     401           0 :     encoder.set_h_op(sandesh_op::GET);
     402           0 :     len = Encode(encoder, msg, KSYNC_DEFAULT_MSG_SIZE);
     403           0 :     sock->BlockingSend((char *)msg, len);
     404           0 :     if (sock->BlockingRecv()) {
     405           0 :         LOG(ERROR, "Error getting configured parameter for vrouter");
     406             :     }
     407             : 
     408           0 :     KSyncSock::Start(run_sync_mode);
     409           0 : }
     410             : 
     411           0 : void KSync::VnswInterfaceListenerInit() {
     412           0 :     vnsw_interface_listner_->Init();
     413           0 : }
     414             : 
     415           0 : void KSync::CreateVhostIntf() {
     416             : #if defined(__linux__)
     417             :     struct  nl_client *cl;
     418             :         int ret;
     419             : 
     420           0 :     assert((cl = nl_register_client()) != NULL);
     421           0 :     LogSockInitErrors((cl->cl_sock < 0), false, "cl_sock EEXIST");
     422           0 :     LogSockInitErrors((nl_socket(cl, AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE) > 0), true, "socket");
     423           0 :     ret = nl_connect(cl, 0, 0, 0);
     424           0 :     if(ret != 0) {
     425           0 :         if(!(cl->cl_sa))
     426           0 :             LogSockInitErrors(false, false, "cl_sa malloc failure");
     427             :         else
     428           0 :             LogSockInitErrors(false, true, "connect");
     429             :     }
     430             : 
     431             :     struct vn_if ifm;
     432             :     struct nl_response *resp;
     433             : 
     434           0 :     memset(&ifm, 0, sizeof(ifm));
     435           0 :     strncpy(ifm.if_name, agent_->vhost_interface_name().c_str(),
     436             :             IFNAMSIZ);
     437           0 :     ifm.if_name[IFNAMSIZ - 1] = '\0';
     438           0 :     strcpy(ifm.if_kind, VHOST_KIND);
     439           0 :     ifm.if_flags = IFF_UP;
     440             : 
     441           0 :     assert(nl_build_if_create_msg(cl, &ifm, 1) == 0);
     442           0 :         LogSockInitErrors((nl_sendmsg(cl) > 0), true, "sendmsg");
     443           0 :     ret = nl_recvmsg(cl);
     444           0 :     if(ret == -EOPNOTSUPP) {
     445           0 :       LogSockInitErrors(false, false, "cl->cl_recv_len > cl->cl_buf_len");
     446           0 :     } else if (ret < 0) {
     447           0 :       LogSockInitErrors(false, true, "recvmsg");
     448             :     }
     449           0 :     assert((resp = nl_parse_reply(cl)) != NULL);
     450           0 :     assert(resp->nl_type == NL_MSG_TYPE_ERROR);
     451           0 :     nl_free_client(cl);
     452             : #endif
     453           0 : }
     454             : 
     455           0 : void KSync::UpdateVhostMac() {
     456             : #if defined(__linux__)
     457             :     struct  nl_client *cl;
     458             : 
     459           0 :     assert((cl = nl_register_client()) != NULL);
     460           0 :     assert(nl_socket(cl,AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE) > 0);
     461           0 :     assert(nl_connect(cl, 0, 0, 0) == 0);
     462             : 
     463             :     struct vn_if ifm;
     464             :     struct nl_response *resp;
     465             : 
     466           0 :     memset(&ifm, 0, sizeof(ifm));
     467           0 :     strncpy(ifm.if_name, agent_->vhost_interface_name().c_str(),
     468             :             IFNAMSIZ);
     469           0 :     ifm.if_name[IFNAMSIZ - 1] = '\0';
     470           0 :     strcpy(ifm.if_kind, VHOST_KIND);
     471           0 :     ifm.if_flags = IFF_UP;
     472             : 
     473             :     //on l3mh compute vhost0 mac is set to vrrp mac instead of phy interface mac
     474           0 :     if (agent_->is_l3mh()) {
     475           0 :         agent_->vrrp_mac().ToArray((u_int8_t *)ifm.if_mac, sizeof(ifm.if_mac));
     476             :     } else {
     477           0 :         PhysicalInterfaceKey key(agent_->fabric_interface_name());
     478           0 :         Interface *eth = static_cast<Interface *>
     479           0 :             (agent_->interface_table()->FindActiveEntry(&key));
     480           0 :         eth->mac().ToArray((u_int8_t *)ifm.if_mac, sizeof(ifm.if_mac));
     481           0 :     }
     482           0 :     assert(nl_build_if_create_msg(cl, &ifm, 1) == 0);
     483           0 :     assert(nl_sendmsg(cl) > 0);
     484           0 :     assert(nl_recvmsg(cl) > 0);
     485           0 :     assert((resp = nl_parse_reply(cl)) != NULL);
     486           0 :     assert(resp->nl_type == NL_MSG_TYPE_ERROR);
     487           0 :     nl_free_client(cl);
     488             : #endif
     489           0 : }
     490             : 
     491           0 : void KSync::Shutdown() {
     492           0 :     vnsw_interface_listner_->Shutdown();
     493           0 :     vnsw_interface_listner_.reset(NULL);
     494           0 :     interface_ksync_obj_.reset(NULL);
     495           0 :     vrf_ksync_obj_.get()->Shutdown();
     496           0 :     vrf_ksync_obj_.reset(NULL);
     497           0 :     nh_ksync_obj_.reset(NULL);
     498           0 :     mpls_ksync_obj_.reset(NULL);
     499           0 :     ksync_flow_memory_.reset(NULL);
     500           0 :     ksync_bridge_memory_.reset(NULL);
     501           0 :     mirror_ksync_obj_.reset(NULL);
     502           0 :     vrf_assign_ksync_obj_.reset(NULL);
     503           0 :     vxlan_ksync_obj_.reset(NULL);
     504           0 :     qos_queue_ksync_obj_.reset(NULL);
     505           0 :     forwarding_class_ksync_obj_.reset(NULL);
     506           0 :     qos_config_ksync_obj_.reset(NULL);
     507           0 :     STLDeleteValues(&flow_table_ksync_obj_list_);
     508           0 :     KSyncSock::Shutdown();
     509           0 :     KSyncObjectManager::Shutdown();
     510           0 : }
     511             : 
     512           0 : void GenericNetlinkInit() {
     513             :     struct nl_client    *cl;
     514             :     int    family;
     515             : 
     516           0 :     assert((cl = nl_register_client()) != NULL);
     517           0 :     assert(nl_socket(cl, AF_NETLINK, SOCK_DGRAM, NETLINK_GENERIC) >= 0);
     518           0 :     assert(nl_connect(cl, 0, 0, 0) == 0);
     519             : 
     520           0 :     family = vrouter_obtain_family_id(cl);
     521           0 :     LOG(DEBUG, "Vrouter family is " << family);
     522           0 :     KSyncSock::SetNetlinkFamilyId(family);
     523           0 :     nl_free_client(cl);
     524           0 : }
     525             : 
     526           0 : KSyncTcp::KSyncTcp(Agent *agent): KSync(agent) {
     527           0 : }
     528             : 
     529           0 : void KSyncTcp::InitFlowMem() {
     530           0 :     ksync_flow_memory_.get()->MapSharedMemory();
     531           0 :     ksync_bridge_memory_.get()->MapSharedMemory();
     532           0 : }
     533             : 
     534           0 : void KSyncTcp::TcpInit() {
     535             :     EventManager *event_mgr;
     536           0 :     event_mgr = agent_->event_manager();
     537           0 :     boost::system::error_code ec;
     538           0 :     boost::asio::ip::address ip;
     539           0 :     ip = agent_->vrouter_server_ip();
     540           0 :     uint32_t port = agent_->vrouter_server_port();
     541           0 :     KSyncSockTcp::Init(event_mgr, ip, port,
     542           0 :                        agent_->params()->ksync_thread_cpu_pin_policy());
     543           0 :     KSyncSock::SetNetlinkFamilyId(24);
     544             : 
     545           0 :     for (int i = 0; i < KSyncSock::kRxWorkQueueCount; i++) {
     546             :         KSyncSock::SetAgentSandeshContext
     547           0 :             (new KSyncSandeshContext(this), i);
     548             :     }
     549           0 :     KSyncSockTcp *sock = static_cast<KSyncSockTcp *>(KSyncSock::Get(0));
     550           0 :     while (sock->connect_complete() == false) {
     551           0 :         sleep(1);
     552             :     }
     553           0 : }
     554             : 
     555           0 : KSyncTcp::~KSyncTcp() { }
     556             : 
     557           0 : void KSyncTcp::Init(bool create_vhost) {
     558           0 :     TcpInit();
     559           0 :     InitFlowMem();
     560           0 :     ResetVRouter(false);
     561             :     //Start async read of socket
     562           0 :     KSyncSockTcp *sock = static_cast<KSyncSockTcp *>(KSyncSock::Get(0));
     563           0 :     sock->AsyncReadStart();
     564           0 :     interface_ksync_obj_.get()->Init();
     565           0 :     for (uint16_t i = 0; i < flow_table_ksync_obj_list_.size(); i++) {
     566           0 :         flow_table_ksync_obj_list_[i]->Init();
     567             :     }
     568           0 :     ksync_flow_memory_.get()->Init();
     569           0 :     ksync_bridge_memory_.get()->Init();
     570           0 : }
     571             : 
     572           0 : KSyncUds::KSyncUds(Agent *agent): KSync(agent) {
     573           0 : }
     574             : 
     575           0 : void KSyncUds::InitFlowMem() {
     576           0 :     ksync_flow_memory_.get()->MapSharedMemory();
     577           0 :     ksync_bridge_memory_.get()->MapSharedMemory();
     578           0 : }
     579             : 
     580           0 : void KSyncUds::UdsInit() {
     581             :     EventManager *event_mgr;
     582           0 :     event_mgr = agent_->event_manager();
     583           0 :     boost::asio::io_context &io = *event_mgr->io_service();
     584           0 :     boost::system::error_code ec;
     585             : 
     586           0 :     string ksync_agent_vrouter_sock_path = KSYNC_AGENT_VROUTER_SOCK_PATH;
     587             : 
     588           0 :     ksync_agent_vrouter_sock_path = agent_->params()->cat_is_agent_mocked() ?
     589           0 :         agent_->params()->cat_ksocketdir() +
     590           0 :         "dpdk_netlink":ksync_agent_vrouter_sock_path;
     591             : 
     592           0 :     KSyncSockUds::Init(io, agent_->params()->ksync_thread_cpu_pin_policy(),
     593             :        ksync_agent_vrouter_sock_path);
     594           0 :     KSyncSock::SetNetlinkFamilyId(24);
     595             : 
     596           0 :     for (int i = 0; i < KSyncSock::kRxWorkQueueCount; i++) {
     597             :         KSyncSock::SetAgentSandeshContext
     598           0 :             (new KSyncSandeshContext(this), i);
     599             :     }
     600           0 : }
     601             : 
     602           0 : KSyncUds::~KSyncUds() { }
     603             : 
     604           0 : void KSyncUds::Init(bool create_vhost) {
     605           0 :     UdsInit();
     606           0 :     InitFlowMem();
     607           0 :     ResetVRouter(false);
     608           0 :     interface_ksync_obj_.get()->Init();
     609           0 :     for (uint16_t i = 0; i < flow_table_ksync_obj_list_.size(); i++) {
     610           0 :         flow_table_ksync_obj_list_[i]->Init();
     611             :     }
     612           0 :     ksync_flow_memory_.get()->Init();
     613           0 :     ksync_bridge_memory_.get()->Init();
     614           0 : }

Generated by: LCOV version 1.14