zoukankan      html  css  js  c++  java
  • OVS中对于用户层和datapath层的多个通道利用epoll进行控制

    这里先临时记录下代码流程,有待完好。


    static int
    construct(struct ofproto *ofproto_)
    {
        struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
        const char *name = ofproto->up.name;
        int max_ports;
        int error;
        int i;
    
        error = dpif_create_and_open(name, ofproto->up.type, &ofproto->dpif);
        if (error) {
            VLOG_ERR("failed to open datapath %s: %s", name, strerror(error));
            return error;
        }
    
        max_ports = dpif_get_max_ports(ofproto->dpif);
        ofproto_init_max_ports(ofproto_, MIN(max_ports, OFPP_MAX));
    
        ofproto->n_matches = 0;
    
        dpif_flow_flush(ofproto->dpif);
        dpif_recv_purge(ofproto->dpif);
    	
    	// 设置'dpif'可以调用dpif_recv()来接收包
        error = dpif_recv_set(ofproto->dpif, true);
    	
        if (error) {
            VLOG_ERR("failed to listen on datapath %s: %s", name, strerror(error));
            dpif_close(ofproto->dpif);
            return error;
        }
    
        ofproto->netflow = NULL;
        ofproto->sflow = NULL;
        ofproto->stp = NULL;
        hmap_init(&ofproto->bundles);
        ofproto->ml = mac_learning_create(MAC_ENTRY_DEFAULT_IDLE_TIME);
        for (i = 0; i < MAX_MIRRORS; i++) {
            ofproto->mirrors[i] = NULL;
        }
        ofproto->has_bonded_bundles = false;
    
        timer_set_duration(&ofproto->next_expiration, 1000);
    
        hmap_init(&ofproto->facets);
        hmap_init(&ofproto->subfacets);
        ofproto->governor = NULL;
    
        for (i = 0; i < N_TABLES; i++) {
            struct table_dpif *table = &ofproto->tables[i];
    
            table->catchall_table = NULL;
            table->other_table = NULL;
            table->basis = random_uint32();
        }
        ofproto->need_revalidate = 0;
        tag_set_init(&ofproto->revalidate_set);
    
        list_init(&ofproto->completions);
    
        ofproto_dpif_unixctl_init();
    
        ofproto->has_mirrors = false;
        ofproto->has_bundle_action = false;
    
        hmap_init(&ofproto->vlandev_map);
        hmap_init(&ofproto->realdev_vid_map);
    
        hmap_insert(&all_ofproto_dpifs, &ofproto->all_ofproto_dpifs_node,
                    hash_string(ofproto->up.name, 0));
        memset(&ofproto->stats, 0, sizeof ofproto->stats);
    
        ofproto_init_tables(ofproto_, N_TABLES);
        error = add_internal_flows(ofproto);
        ofproto->up.tables[TBL_INTERNAL].flags = OFTABLE_HIDDEN | OFTABLE_READONLY;
    
        return error;
    }
    


    设置dpif可以接收来自datapath的netlink包。

    int
    dpif_recv_set(struct dpif *dpif, bool enable)
    {
        int error = dpif->dpif_class->recv_set(dpif, enable);
        log_operation(dpif, "recv_set", error);
        return error;
    }

    详细是dpif_linux_class的实现:

    static int
    dpif_linux_recv_set(struct dpif *dpif_, bool enable)
    {
        struct dpif_linux *dpif = dpif_linux_cast(dpif_);
    
        if ((dpif->epoll_fd >= 0) == enable) {
            return 0;
        }
    
        if (!enable) {
            destroy_channels(dpif);
        } else {
            struct dpif_channel *ch;
            int error;
    
            dpif->epoll_fd = epoll_create(N_CHANNELS);
    		// 用户层和datapath的通信纳入epoll管理,有17个通道。
            if (dpif->epoll_fd < 0) {
                return errno;
            }
    
            for (ch = dpif->channels; ch < &dpif->channels[N_CHANNELS]; ch++) {
                int indx = ch - dpif->channels;
                struct epoll_event event;
    
                error = nl_sock_create(NETLINK_GENERIC, &ch->sock);
                if (error) {
                    destroy_channels(dpif);
                    return error;
                }
    
                memset(&event, 0, sizeof event);
                event.events = EPOLLIN;
                event.data.u32 = indx;
                if (epoll_ctl(dpif->epoll_fd, EPOLL_CTL_ADD, nl_sock_fd(ch->sock),
                              &event) < 0) {
                    error = errno;
                    destroy_channels(dpif);
                    return error;
                }
    
                memset(ch->sketches, 0, sizeof ch->sketches);
                ch->last_poll = LLONG_MIN;
            }
    
            dpif->ready_mask = 0;
            dpif->next_scale = time_msec() + SCALE_INTERVAL;
        }
    
        set_upcall_pids(dpif_);
    
        return 0;
    }
    





  • 相关阅读:
    记录一则ORACLE MOVE操作后重建索引过程被强制中断导致的ORA-8104案例
    Sybase数据库,普通表修改分区表步骤
    JavaWeb request对象常用操作
    JavaWeb 获取请求网络协议、IP、端口号、项目根路径
    java 从spring容器中获取注入的bean对象
    eclipse Java注释修改
    JavaWeb 获取ip地址
    jQuery源代码解析(1)—— jq基础、data缓存系统
    Http状态码
    Item 24: 区分右值引用和universal引用
  • 原文地址:https://www.cnblogs.com/llguanli/p/7151831.html
Copyright © 2011-2022 走看看