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: 45 402 11.2 %
Date: 2026-08-03 02:19:58 Functions: 4 31 12.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14