packet在内核空间匹配失败后传到用户空间的处理逻辑是什么?

本文探讨了当packet在内核空间匹配失败后,如何通过dpif_upcall、handle_upcalls等机制传递到用户空间的过程,详细解析了dpif_recv、dpif_linux_class中的关键步骤,并讲解了nl_sock_recv在接收这些信息时的作用。
摘要由CSDN通过智能技术生成

     我们知道当packet到达交换机之后会提取出flow key->查询流表,如果匹配成功就执行对应的action,否则构造netlink attribute发送到用户空间对应的进程,这里vswitchd会调用handle_upcalls(ofproto/ofproto-dpif.c)来处理。主要流程图是:



结构体 dpif_upcall 表征的是从datapath传到userspace的一个packet(lib/dpif.h)。
(如果key或者action非空的话,那么其指向的数据从属于这个packet,所以不能单独被释放;)
struct dpif_upcall {
    /* All types. */
    enum dpif_upcall_type type;
    struct ofpbuf *packet;      /* Packet data. 是全部数据包,还是根据of协议 ??
    struct nlattr *key;         /* Flow key. */
    size_t key_len;             /* Length of 'key' in bytes. */

    /* DPIF_UC_ACTION only. */
    uint64_t userdata;          /* Argument to OVS_ACTION_ATTR_USERSPACE. */
};

upcall的类型有:
enum dpif_upcall_type {
    DPIF_UC_MISS,               /* Miss in flow table. */
    DPIF_UC_ACTION,             /* OVS_ACTION_ATTR_USERSPACE action. */
    DPIF_N_UC_TYPES
};


static int  handle_upcalls(struct ofproto_dpif *ofproto, unsigned int max_batch) {
    struct dpif_upcall misses[FLOW_MISS_MAX_BATCH];
    struct ofpbuf miss_bufs[FLOW_MISS_MAX_BATCH];
    uint64_t miss_buf_stubs[FLOW_MISS_MAX_BATCH][4096 / 8];
    int n_processed;
    int n_misses;
    int i;

    assert(max_batch <= FLOW_MISS_MAX_BATCH);

    n_misses = 0;
    for (n_processed = 0; n_processed < max_batch; n_processed++) {
        struct dpif_upcall *upcall = &misses[n_misses];
        struct ofpbuf *buf = &miss_bufs[n_misses];
        int error;

        ofpbuf_use_stub(buf, miss_buf_stubs[n_misses], sizeof miss_buf_stubs[n_misses]);  
          //这个函数的作用是初始化从某个基址开始,一定大小的ofbuf缓冲区,并且base应该指向一个栈的缓冲区并且要对齐;
          //使用uint32_t,uint64_t类型可以确保合适的对齐;一个ofbuf缓冲区操作如果需要重新分配数据的话需要将STUB上的
          //数据拷贝到malloc缓冲区中,由于这个buf可能扩展到堆上,所以最后应该调用ofpbuf_uninit来释放相应的内存。(??)

        error = dpif_recv(ofproto->dpif, upcall, buf);
        //通过具体的datapath类型,调用其中的recv方法(这里的dpif class 是dpif_linux_class,表示本机);
        //dpif_linux_class表示的是通过netlink和本地的datapath通信,而dpif_netdev_class通过网络协议和远程的datapath通信;

        switch (classify_upcall(upcall)) {
        case MISS_UPCALL:
             n_misses++;    /* Handle it later. */
            break;

        case SFLOW_UPCALL:
            if (ofproto->sflow) {
                handle_sflow_upcall(ofproto, upcall);
               //对于SFLOW_UPCALL 和 BAD_UPCALL,进行对应处理后释放存有 upcall 消息的 buf,而对于
               //MISS_UPCALL 类型,则调用 handle_miss_upcalls 进行后续的处理。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值