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 : }
|