zoukankan      html  css  js  c++  java
  • 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;
    }

  • 相关阅读:
    Asp.net Json 解析 与 直接用ip访问返回josn
    mysql 时间函数
    Android之TelephonyManager类的使用案例
    android:screenOrientation的说明 固定屏幕显示方向
    在android.app.Application中定义全局变量
    Android开发实例详解之IMF(Android SDK Sample—SoftKeyboard)
    Android InputMethodManager输入法简介
    android ImageView的属性android:scaleType,即ImageView.setScaleType(ImageView.ScaleType)
    VS编译常见错误枚举01
    Visual C++ Samples-------------Code Project
  • 原文地址:https://www.cnblogs.com/dream397/p/12618319.html
Copyright © 2011-2022 走看看