5 #include <boost/asio.hpp>
6 #include <boost/bind.hpp>
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>
36 #include <vr_message.h>
50 #define VNSW_GENETLINK_FAMILY_NAME "vnsw"
53 if(success_cond ==
false) {
56 err_str <<
" Failed with " << errno <<
"syscall: "
60 "Failed with " << err_str <<
". BackTrace: " <<
AgentBackTrace(1));
69 flow_table_ksync_obj_list_(),
77 ksync_flow_memory_(new
KSyncFlowMemory(this, VR_MEM_FLOW_TABLE_OBJECT)),
158 bool use_work_queue =
false;
161 boost::asio::io_context &io = *event_mgr->
io_service();
183 stats->
name_ =
"KSync Send Queue";
191 if (
agent()->MeasureQueueDelay()) {
217 if (
agent()->MeasureQueueDelay()) {
225 v->set_vo_mpls_labels(-1);
226 v->set_vo_mpls_labels(-1);
227 v->set_vo_nexthops(-1);
228 v->set_vo_bridge_entries(-1);
229 v->set_vo_oflow_bridge_entries(-1);
230 v->set_vo_flow_entries(-1);
231 v->set_vo_oflow_entries(-1);
232 v->set_vo_interfaces(-1);
233 v->set_vo_mirror_entries(-1);
235 v->set_vo_log_level(0);
238 v->set_vo_from_vm_mss_adj(-1);
239 v->set_vo_to_vm_mss_adj(-1);
240 v->set_vo_perfr1(-1);
241 v->set_vo_perfr2(-1);
242 v->set_vo_perfr3(-1);
244 v->set_vo_perfq1(-1);
245 v->set_vo_perfq2(-1);
246 v->set_vo_perfq3(-1);
247 v->set_vo_udp_coff(-1);
248 v->set_vo_flow_hold_limit(-1);
250 v->set_vo_burst_tokens(-1);
251 v->set_vo_burst_interval(-1);
252 v->set_vo_burst_step(-1);
253 v->set_vo_memory_alloc_checks(-1);
257 vr_hugepage_config encoder;
264 uint32_t bridge_table_size, flow_table_size;
270 LOG(INFO, __FUNCTION__ <<
": " <<
"Bridge table size:" << bridge_table_size
271 <<
" Flow table size:" << flow_table_size <<
"\n");
276 filesize[i] = bridge_table_size;
278 filesize[i] = flow_table_size;
281 pagesize[i] = 1024 * 1024 * 1024;
282 flags[i] = O_CREAT | O_RDWR;
288 filesize[j] = bridge_table_size;
290 filesize[j] = flow_table_size;
293 pagesize[j] = 2 * 1024 * 1024;
294 flags[j] = O_CREAT | O_RDWR;
299 if (filename[i].empty()) {
304 huge_fd_[i] = open(filename[i].c_str(), flags[i], 0755);
310 LOG(INFO,
"Mem mapping hugepage file:" << filename[i].c_str()
311 <<
" size:" << filesize[i] <<
"\n");
313 PROT_READ | PROT_WRITE, MAP_SHARED,
316 LOG(ERROR,
"Failed to Mmap hugepage file:" << filename[i].c_str() <<
"\n");
320 LOG(INFO,
"Mem mapped hugepage file:" << filename[i].c_str()
330 encoder.set_vhp_op(sandesh_op::ADD);
332 std::vector<uint64_t> huge_mem;
333 std::vector<uint32_t> huge_mem_size;
334 std::vector<uint32_t> huge_page_size;
335 std::vector<int8_t> huge_page_paths;
336 std::vector<uint32_t> huge_page_paths_sz;
339 if (fail[i] ==
false) {
341 huge_page_size.push_back(pagesize[i]);
342 huge_mem_size.push_back(filesize[i]);
343 const char *path = filename[i].c_str();
344 uint32_t len = strlen(path) + 1;
345 for (uint32_t c = 0; c < len; c++) {
346 huge_page_paths.push_back(path[c]);
348 huge_page_paths_sz.push_back(len);
351 encoder.set_vhp_mem(huge_mem);
352 encoder.set_vhp_psize(huge_page_size);
354 encoder.set_vhp_mem_sz(huge_mem_size);
355 encoder.set_vhp_file_paths(huge_page_paths);
356 encoder.set_vhp_file_path_sz(huge_page_paths_sz);
357 encoder.set_vhp_resp(VR_HPAGE_CFG_RESP_HPAGE_SUCCESS);
362 LOG(INFO,
"Sending Huge Page configuration to VROUTER\n");
366 LOG(ERROR,
"Error sending Huge Page configuration to VROUTER. Skipping KSync Start");
373 encoder.set_h_op(sandesh_op::RESET);
380 LOG(ERROR,
"Error resetting VROUTER. Skipping KSync Start");
385 encoder.set_h_op(sandesh_op::ADD);
393 LOG(ERROR,
"Error setting Qos priority-tagging for vrouter");
398 encoder.set_h_op(sandesh_op::GET);
402 LOG(ERROR,
"Error getting configured parameter for vrouter");
413 #if defined(__linux__)
414 struct nl_client *cl;
417 assert((cl = nl_register_client()) != NULL);
419 LogSockInitErrors((nl_socket(cl, AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE) > 0),
true,
"socket");
420 ret = nl_connect(cl, 0, 0, 0);
429 struct nl_response *resp;
431 memset(&ifm, 0,
sizeof(ifm));
434 ifm.if_name[IFNAMSIZ - 1] =
'\0';
435 strcpy(ifm.if_kind, VHOST_KIND);
436 ifm.if_flags = IFF_UP;
438 assert(nl_build_if_create_msg(cl, &ifm, 1) == 0);
440 ret = nl_recvmsg(cl);
441 if(ret == -EOPNOTSUPP) {
443 }
else if (ret < 0) {
446 assert((resp = nl_parse_reply(cl)) != NULL);
447 assert(resp->nl_type == NL_MSG_TYPE_ERROR);
453 #if defined(__linux__)
454 struct nl_client *cl;
456 assert((cl = nl_register_client()) != NULL);
457 assert(nl_socket(cl,AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE) > 0);
458 assert(nl_connect(cl, 0, 0, 0) == 0);
461 struct nl_response *resp;
463 memset(&ifm, 0,
sizeof(ifm));
466 ifm.if_name[IFNAMSIZ - 1] =
'\0';
467 strcpy(ifm.if_kind, VHOST_KIND);
468 ifm.if_flags = IFF_UP;
477 eth->
mac().
ToArray((u_int8_t *)ifm.if_mac,
sizeof(ifm.if_mac));
479 assert(nl_build_if_create_msg(cl, &ifm, 1) == 0);
480 assert(nl_sendmsg(cl) > 0);
481 assert(nl_recvmsg(cl) > 0);
482 assert((resp = nl_parse_reply(cl)) != NULL);
483 assert(resp->nl_type == NL_MSG_TYPE_ERROR);
510 struct nl_client *cl;
513 assert((cl = nl_register_client()) != NULL);
514 assert(nl_socket(cl, AF_NETLINK, SOCK_DGRAM, NETLINK_GENERIC) >= 0);
515 assert(nl_connect(cl, 0, 0, 0) == 0);
517 family = vrouter_obtain_family_id(cl);
518 LOG(DEBUG,
"Vrouter family is " << family);
534 boost::system::error_code ec;
535 boost::asio::ip::address ip;
580 boost::asio::io_context &io = *event_mgr->
io_service();
581 boost::system::error_code ec;
587 "dpdk_netlink":ksync_agent_vrouter_sock_path;
590 ksync_agent_vrouter_sock_path);
uint32_t task_starts() const
static const int kRxWorkQueueCount
boost::scoped_ptr< VxLanKSyncObject > vxlan_ksync_obj_
bool qos_priority_tagging() const
void STLDeleteValues(Container *container)
std::string cat_ksocketdir() const
std::size_t BlockingSend(char *msg, int msg_len)
int Encode(Sandesh &encoder, uint8_t *buf, int buf_len)
bool ToArray(u_int8_t *p, size_t s) const
size_t max_queue_len() const
virtual void Init(bool create_vhost)
virtual int32_t WriteBinary(u_int8_t *buf, u_int32_t buf_len, int *error)
size_t NumDequeues() const
void * btable_huge_page_mem_get() const
static const MacAddress & vrrp_mac()
virtual void RegisterDBClients(DB *db)
WorkQueueStats ksync_rx_queue_count_
boost::scoped_ptr< NHKSyncObject > nh_ksync_obj_
std::vector< FlowTableKSyncObject * > flow_table_ksync_obj_list_
boost::asio::io_context * io_service()
const std::string & vhost_interface_name() const
AgentDBEntry * FindActiveEntry(const DBEntry *key)
InterfaceTable * interface_table() const
void set_ksync_object(FlowTableKSyncObject *obj)
virtual void InitFlowMem()
const MacAddress & mac() const
int ftable_huge_pages_index_
uint32_t read_events() const
virtual void Init(bool create_vhost)
virtual void Init(bool create_vhost)
uint64_t max_queue_count_
void LogSockInitErrors(bool success_cond, bool use_errno, string err_str)
void RegisterKSyncStatsCb(ProfileCb cb)
boost::scoped_ptr< VnswInterfaceListener > vnsw_interface_listner_
uint32_t max_queue_len() const
void ResetVRouter(bool run_sync_mode)
FlowTable * GetTable(uint16_t index) const
boost::scoped_ptr< InterfaceKSyncObject > interface_ksync_obj_
boost::scoped_ptr< VrfKSyncObject > vrf_ksync_obj_
static void Init(boost::asio::io_context &ios, int protocol, bool use_work_queue, const std::string &cpu_pin_policy)
virtual void InitFlowMem()
#define KSYNC_DEFAULT_MSG_SIZE
static KSyncSock * Get(DBTablePartBase *partition)
static void Start(bool read_inline)
static const int kHugePageFiles
const uint32_t vrouter_server_port() const
const std::string & fabric_interface_name() const
bool connect_complete() const
int btable_huge_pages_index_
EventManager * event_manager() const
boost::scoped_ptr< KSyncFlowMemory > ksync_flow_memory_
void SetMeasureQueueDelay(bool val)
boost::scoped_ptr< ForwardingClassKSyncObject > forwarding_class_ksync_obj_
void InitVrouterOps(vrouter_ops *v)
uint64_t busy_time() const
void set_measure_busy_time(bool val) const
boost::scoped_ptr< MplsKSyncObject > mpls_ksync_obj_
AgentParam * params() const
void set_router_id_configured(bool value)
#define KSYNC_AGENT_VROUTER_SOCK_PATH
static void Init(boost::asio::io_context &ios, const std::string &cpu_pin_policy, const std::string &sockpathvr="")
const KSyncReceiveQueue * get_receive_work_queue(uint16_t index) const
const std::string huge_page_file_1G(uint16_t index) const
FlowProto * get_flow_proto() const
boost::scoped_ptr< VrfAssignKSyncObject > vrf_assign_ksync_obj_
std::string Description() const
std::string AgentBackTrace(int skip=1)
void GenericNetlinkInit()
static void SetAgentSandeshContext(AgentSandeshContext *ctx, uint32_t idx)
static void Init(EventManager *evm, boost::asio::ip::address ip_addr, int port, const std::string &cpu_pin_policy)
int huge_fd_[kHugePageFiles]
std::string ksync_thread_cpu_pin_policy() const
virtual void InitFlowMem()
boost::scoped_ptr< QosQueueKSyncObject > qos_queue_ksync_obj_
#define LOG(_Level, _Msg)
static void SetNetlinkFamilyId(int id)
WorkQueueStats ksync_tx_queue_count_
boost::scoped_ptr< KSyncBridgeMemory > ksync_bridge_memory_
const Ip4Address vrouter_server_ip() const
static KSyncObjectManager * Init()
void VnswInterfaceListenerInit()
uint64_t busy_time() const
size_t NumEnqueues() const
const std::string huge_page_file_2M(uint16_t index) const
boost::scoped_ptr< MirrorKSyncObject > mirror_ksync_obj_
uint16_t flow_thread_count() const
AgentProfile * agent_profile() const
boost::scoped_ptr< KSyncFlowIndexManager > ksync_flow_index_manager_
boost::scoped_ptr< QosConfigKSyncObject > qos_config_ksync_obj_
void SetProfileData(ProfileData *data)
void * ftable_huge_page_mem_get() const
bool cat_is_agent_mocked() const
void set_measure_busy_time(bool val) const
const KSyncTxQueue * send_queue() const
void * huge_pages_[kHugePageFiles]