• ovs流表


    流表分为两大类:

    1、 内核中flow table 也称为fast path

    2、找用户态中flow table被称为slow path

    一个数据报文接收后,会经过多个流表,每个流表负责特定的功能,
    ovs中的多级流表存放在用户空间,内核态存放的是流表的缓存。

    网卡收到报文时,Openvswitch.ko是这么处理数据报文的: 

    1、通过key查找内核中的flow table,得到action,然后执行action之后,直接发送这个包;

    2、在内核无法查找到流表项的时候,通过netlink的方式发送到用户空间,接着会去查找用户态的流表。 真个过程是通过upcall来调用用户态ovs-vswtichd中的flow table实现的

    3、如果用户态命中则将对应的信息丢给内核态进行缓存。用户空间没有查到,用户态还要继续将报文的信息丢给控制器,由控制器下发对应的规则

    key的组成

    MAC层的key :key->eth

    网络层的key:key->ip

    传输层的key:key->tp

     

    流表发送
    流表下发一般是通过以下两种方式:
    controller通过openflow协议下发FLOW_MOD命令给ovs的Userspace流表。
    ovs-ofctl通过openflow协议下发FLOW_MOD给ovs的Userspace流表。ovs-ofctl add-flow最终调用 ofctl_flow_mod(ctx->argc, ctx->argv, OFPFC_ADD);
    ofctl_flow_mod
       handle_openflow
            handle_flow_mod

    ovs-vsctl add-port br0 eth1实现

    linux 中调用ip link set eht1 master br0会调用netdev_rx_handler_register注册沟子函数,这样当网卡收到报文时,会走钩子函数

    struct netdev_vport {
    struct rcu_head rcu;
    struct net_device *dev;
    };
    const struct vport_ops ovs_netdev_vport_ops = {
    .create = netdev_create,
    .send = netdev_send,
    };
    --datapath/vport-netdev.c
    static struct vport *netdev_create(const struct vport_parms *parms)
    {
    struct vport *vport;
    struct netdev_vport *netdev_vport;
    vport = ovs_vport_alloc(sizeof(struct netdev_vport), &ovs_netdev_vport_ops, parms);
    netdev_vport = netdev_vport_priv(vport);
    netdev_vport->dev = dev_get_by_name(ovs_dp_get_net(vport->dp), parms->name);
    //通过interface name比如eth0 得到eht0 net_device 结构体

    err = netdev_rx_handler_register(netdev_vport->dev, netdev_frame_hook, vport);
    //核心,收到packet后会调用 netdev_frame_hook处理;
    dev_set_promiscuity(netdev_vport->dev, 1); //设置为混杂模式;
    return vport;
    }

    netdev_frame_hook最终会调用ovs_dp_process_packet, ovs_dp_process_packet是一个非常重要的函数

     用户态处理流表

    内核差找不到失败时会通过upcall来调用用户态ovs-vswtichd中的flow table,

    用户态找到找到rule之后,会通过handle_upcalls将flow rule添加到内核中的datapath

    handle_upcalls


         dpif_operate


                    dpif->dpif_class->operate(dpif, ops, chunk);

                              dpif_netlink_operate()会调用netlink修改内核中datapath的规则。

    ovs system接口类型 

    当接口类型为system时,vport->ops->send函数为netdev_send

    /*此函数即为OVS流表output action 发送数据包时的函数*/
    static int
    netdev_send(struct vport *vport, struct sk_buff *skb)
    {
    struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
    int mtu = netdev_vport->dev->mtu;
    int len;
    /*如果未开启gso且数据包长度大于MTU,则释放数据包*/
    if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) {
    net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d ",
    netdev_vport->dev->name,
    packet_length(skb), mtu);
    goto drop;
    }
    /*设置skb->dev为output action网口*/
    skb->dev = netdev_vport->dev;
    len = skb->len;
    /*最后调用dev_queue_xmit发送数据包*/
    dev_queue_xmit(skb);
    return len;
    drop:
    kfree_skb(skb);
    return 0;
    }

  • 相关阅读:
    windows下wchar_t* 转char*
    VS2010的调试参数/Zi /DEBUG
    fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'X86'
    使用opencv传中文文件崩溃
    【20160924】GOCVHelper综述
    编译ITK
    几款开源图像处理软件评测研究
    新注册域名greenopen.site,向专业道路进军
    openmp在图像处理上面的运用
    实现multbandblend
  • 原文地址:https://www.cnblogs.com/dream397/p/12618319.html
Copyright © 2020-2023  润新知