OVS代码阅读-internal_port收发

internal_port作用

OVS没有使用内核提供的桥,重新造了一套和桥等同的模块叫dp,为啥叫dp?叫switch不行么。

有一种情况是不可避免的:机器只有一张物理网卡,既要跑OVS,又要跑内核协议栈,怎么处理?

internal_port就是解决这个问题的,所以就至少要有两个能力:从dp上面把该送到本机的报文送上去,把本机发出去的报文最终通过物理口发出去。

internal_port创建

用户态通过命令创建dp(ovs_dp_cmd_new)时,会创建一个和dp同名字的端口,端口类型为OVS_VPORT_TYPE_INTERNAL

也就是说internal类型的端口原则上是不能通过外部命令创建的

    parms.name = nla_data(a[OVS_DP_ATTR_NAME]);

    parms.type = OVS_VPORT_TYPE_INTERNAL;

    parms.options = NULL;

    parms.dp = dp;

    parms.port_no = OVSP_LOCAL;

    parms.upcall_portids = a[OVS_DP_ATTR_UPCALL_PID];

    vport = new_vport(&parms);

internal_port收方向

挂在dp上的硬件网卡收到包(netdev_frame_hook)后

查询流表根据action选择不同的后续流程

对于internal_port来说是action为OVS_ACTION_ATTR_OUTPUT,调用do_output,接下来调用send函数,对于internal_port来说就是internal_dev_recv

收流程调用堆栈

internal_dev_recv函数

skb->pkt_type = PACKET_HOST和linux内核原生的桥一样,指示该报文为本机关注报文

netif_rx函数会调用netif_receive_skb接着调用网络协议栈,就像真正的物理口收到报文一样送到协议栈。

总结下就是:internal_port收包是把包送给主机协议栈了

internal_port发方向

这里的发指的是主机协议栈通过该接口发送报文出去,创建设备时注册了发送函数:internal_dev_xmit

static const struct net_device_ops internal_dev_netdev_ops = {
	.ndo_open = internal_dev_open,
	.ndo_stop = internal_dev_stop,
	.ndo_start_xmit = internal_dev_xmit,
	.ndo_set_mac_address = eth_mac_addr,
#if	!defined(HAVE_NET_DEVICE_WITH_MAX_MTU) && !defined(HAVE_RHEL7_MAX_MTU)
	.ndo_change_mtu = internal_dev_change_mtu,
#endif
	.ndo_get_stats64 = (void *)internal_get_stats,
};

internal_dev_xmit:

函数实现比较简单,直接调用ovs_vport_receive函数,走dp那一套流程,计算flow_key根据action做后续动作,最终会调用物理网卡发送出去,对于ovs来说就是OVS_VPORT_TYPE_NETDEV这种类型的发送函数dev_queue_xmit

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值