【OVS2.5.0源码分析】vxlan发包流程分析

本文深入剖析OVS2.5.0中vxlan的发包流程,从ovs_vport_send函数开始,详细讲解如何通过vport_ops的send函数实现数据包的传输,特别关注udp_tunnel_xmit_skb函数的关键作用。
摘要由CSDN通过智能技术生成

发包处理函数最终会调用到ovs_vport_send函数,该函数最终会调用vport_ops的send函数。

1、ovs_vport_send函数

void ovs_vport_send(struct vport *vport, struct sk_buff *skb)
{
	int mtu = vport->dev->mtu;

	if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) {
		net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n",
				     vport->dev->name,
				     packet_length(skb), mtu);
		vport->dev->stats.tx_errors++;
		goto drop;
	}

	skb->dev = vport->dev;		//vport关联的设备,vxlan端口的设备为vxlan_4789
	vport->ops->send(skb);<span style="white-space:pre">		</span>//实际调用ovs_vxlan_netdev_vport_ops的vxlan_xmit函数
	return;

drop:
	kfree_skb(skb);
}
2、vxlan_xmit函数

#define vxlan_xmit rpl_vxlan_xmit<span style="white-space:pre">			</span>//在3.18内核中,OVS还是使用自己的vxlan实现
netdev_tx_t rpl_vxlan_xmit(struct sk_buff *skb)
{
	struct net_device *dev = skb->dev;<span style="white-space:pre">		</span>//ovs_vport_send函数中完成设置
	struct vxlan_dev *vxlan = netdev_priv(dev);<span style="white-space:pre">	</span>//该信息在创建vxlan端口对应的net_device时就初始化了
	const struct ip_tunnel_info *info;

	info = skb_tunnel_info(skb);    //得到tunnel信息,即execute_set_action函数设置的内容

	skb_reset_mac_header(skb);

	if ((vxlan->flags & VXLAN_F_PROXY))<span style="white-space:pre">	</span>//当前没有此标记
		goto out;

	if (vxlan->flags & VXLAN_F_COLLECT_METADATA &&
	    info && info->mode & IP_TUNNEL_INFO_TX) {
		vxlan_xmit_one(skb, dev, NULL, false);<span style="white-space:pre">	</span>//发送报文
		return NETDEV_TX_OK;
	}
out:
	pr_warn("vxlan: unsupported flag set %x", vxlan->flags);
	kfree_skb(skb);
	return NETDEV_TX_OK;
}
3、vxlan_xmit_one函数

static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
			   struct vxlan_rdst *rdst, bool did_rsc)
{
	struct ip_tunnel_info *info;
	struct vxlan_dev *vxlan = netdev_priv(dev);
	struct sock *sk = vxlan->vn_sock->sock->sk;
	unsigned short family = vxlan_get_sk_family(vxlan->vn_sock);	//通过sock判断是IPV4还是IPV6
	struct rtable *rt = NULL;
	const struct iphdr *old_iph;
	struct flowi4 fl4;
	union vxlan_addr *dst;
	union vxlan_addr remote_ip;
	struct vxlan_metadata _md;
	struct vxlan_metadata *md = &_md;
	__be16 src_port = 0, dst_port;
	u32 vni;
	__be16 df = 0;
	__u8 tos, ttl;
	int err;
	u32 flags = vxlan->flags;

	info = skb_tunnel_info(skb);		//从skb中获取tunnel info

	if (rdst) {		//不进入此分支
		dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port;
		vni = rdst->remote_vni;
		dst = &rdst->remote_ip;
	} else {
		if (!info) {		//说明当前实现,对于报文从
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值