ovs原理-内核流表-01

说明

linux kernel version:5.7.1 openvswitch version:2.15.0 source insight version:4.0

概要

本篇文章来介绍ovs内核部分的流表实现原理,这里采用带入式疗法来分析其代码实现,那么首先从内核收包开始说起,以e1000网卡为例开始阅读之旅。

设备收包

这里简单介绍一下驱动收包流程,当网卡收到数据包之后,会发送硬件中断通知cpu进行处理,网卡在打开的时候会注册对应的中断处理函数,这里e1000网卡在启动时候会调用e1000_open函数,在e1000_open函数中会调度e1000_request_irq函数进行网卡硬中断的注册:

static int e1000_request_irq(struct e1000_adapter *adapter)
{
    struct net_device *netdev = adapter->netdev;
    irq_handler_t handler = e1000_intr;
    int irq_flags = IRQF_SHARED;
    int err;
​
    err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
              netdev);
    if (err) {
        e_err(probe, "Unable to allocate interrupt Error: %d\n", err);
    }
​
    return err;
}

这里可以看到e1000的硬中断响应函数为e1000_intr,即当网卡触发中断时os将会调用到这个函数,在napi模式下触发软中断,然后进入e1000的poll函数,e1000的poll函数为e1000_clean,e1000_clean调用e1000_clean_rx_irq进行数据包的处理,即从dma驱动拷贝数据到内核skb,然后使用e1000_receive_skb进入skb的处理,首先进行gro(和tso对应,gro用于收包,tso用于发包)流程napi_gro_receive,gro的处理函数是dev_gro_receive,napi_skb_finish根据dev_gro_receive的返回结果决定是否将skb上送协议栈,如果dev_gro_receive返回GRO_NORMAL则调用gro_normal_one上送协议栈处理,然后在经过一系列的调用之后(netif_receive_skb_list_internal->__netif_receive_skb_list->__netif_receive_skb_list_core->__netif_receive_skb_core)进入协议栈处理函数__netif_receive_skb_core,从这开始就到了协议栈的部分。

协议栈处理

上面说到数据包来到了__netif_receive_skb_core,这个函数主要完成如下工作:

  • 打时间戳

  • 重置网络头部

  • xdp处理

  • vlan处理

  • tc处理

  • ptype_all处理(tcpdump、tap\tun等)

  • 二层网桥处理(rx_handler)

  • ptype_base处理(ip/arp等)

在二层往网桥处理部分,即rx_handler的处理中,就会到ovs的流程了,目前内核中这个rx_handler的值可能有两个:内核网桥的br_handle_frame(在将设备设置为混杂模式时就会将此设备的rx_handler设置为br_handle_frame)、ovs网桥的netdev_frame_hook(在将设备添加到ovs网桥设备时就会将rx_handler赋值为netdev_frame_hook),所以后面的分析就从netdev_frame_hook函数开始。

ovs设备入口

netdev_frame_hook分析,代码中一些关键点有注释:

/* Called with rcu_read_lock and bottom-halves disabled. */
/* Must be called with rcu_read_lock. */
static void netdev_port_receive(struct sk_buff *skb)
{
    struct vport *vport;
​
//vport信息保存在dev->rx_handler_data中的
    vport = ovs_netdev_get_vport(skb->dev);
    if (unlikely(!vport))
        goto error;
​
    if (unlikely(skb_warn_if_lro(skb)))
        goto error;
​
    /* Make our own copy of the pa
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值