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