/* 简单数据通信用户态协议栈管理器 * * \author Lu Qiuwen * \date 2016-10-18 */ #include #include #include #include #include #include int __instance_setup_ctrlzone(struct mr_core_instance * core_instance, const char * symbol, uint8_t size, uint8_t * id) { uint8_t _id = 0; uint8_t _size = 0; int ret = mr_buffer_ctrlzone_lookup(core_instance, symbol, &_id, &_size); if (ret < 0) { MR_LOG(WARNING, STACK, "Lookup ctrlzone %s failed. " "Please setup the ctrlzone as size %d.", symbol, size); return -1; } if (_size < size) { MR_LOG(WARNING, STACK, "Ctrlzone %s's size is not enough, " "at least %d. Failed. ", symbol, size); return -2; } *id = _id; return 0; } struct sk_instance * sk_instance_create(struct mr_core_instance * core_instance, struct sk_param * param) { struct sk_instance * instance; // 分配空间 instance = rte_zmalloc(NULL, sizeof(struct sk_instance), 0); if(unlikely(instance == NULL)) { MR_LOG(WARNING, STACK, "Cannot alloc memory for stack instance. \n"); goto errout; } // 初始化参数 instance->param = *param; instance->core_instance = core_instance; TAILQ_INIT(&instance->dev_info_list); // 初始化邻居管理器 struct neighbour_manager * neigh_manager; neigh_manager = rte_zmalloc(NULL, sizeof(struct neighbour_manager), 0); if(unlikely(neigh_manager == NULL)) { MR_LOG(WARNING, STACK, "Cannot alloc memory for neighbour manager. \n"); goto errout; } instance->neigh_manager = neigh_manager; int ret = neighbour_mamanger_init(instance->neigh_manager, param->servsym, param->nr_neigh_max_neigh, param->t_neigh_timeout, param->t_neigh_arp_send); if (unlikely(ret < 0)) { MR_LOG(WARNING, STACK, "Neighbour manager init failed. \n"); goto errout; } // 初始化默认路由表 instance->default_route = route_tbl_create("StackDefaultR", 4096); if(unlikely(instance->default_route == NULL)) { MR_LOG(WARNING, STACK, "Cannot create default route table. \n"); goto errout; } // 初始化报文控制域ID ret = __instance_setup_ctrlzone(core_instance, SK_CTRLZONE_PKTINFO_SYMBOL, SK_CTRLZONE_PKTINFO_SIZE, &instance->ctrlzone_id_pktinfo); if (ret < 0) goto errout; ret = __instance_setup_ctrlzone(core_instance, SK_CTRLZONE_SOQINFO_SYMBOL, SK_CTRLZONE_SOQINFO_SIZE, &instance->ctrlzone_id_soqinfo); if (ret < 0) goto errout; return instance; errout: if (instance->neigh_manager) rte_free(instance->neigh_manager); if (instance) rte_free(instance); return NULL; } struct sk_app_instance * sk_app_instance_create(struct sk_instance * instance, const char* appsym) { struct sk_app_instance * app_instance; app_instance = rte_zmalloc(NULL, sizeof(struct sk_instance), 0); if (unlikely(app_instance == NULL)) { MR_LOG(WARNING, STACK, "Cannot alloc memory for stack slave instance. \n"); return NULL; } // 初始化内部句柄 app_instance->instance = instance; snprintf(app_instance->appsym, sizeof(app_instance->appsym), "%s", appsym); TAILQ_INIT(&app_instance->dev_desc_list); // 内存池 app_instance->def_direct_pktmbuf_pool = instance->param.def_direct_pktmbuf_pool; app_instance->def_indirect_pktmbuf_pool = instance->param.def_indirect_pktmbuf_pool; assert(app_instance->def_direct_pktmbuf_pool != NULL && app_instance->def_indirect_pktmbuf_pool != NULL); // 初始化UDP CTX rte_rwlock_init(&app_instance->udp_ctx.rwlock); portmap_init(&app_instance->udp_ctx.pbm_local, LPORT_START_BLK); app_instance->udp_ctx.app_instance_ = app_instance; return app_instance; }