【Linux4.1.12源碼分析】vxlan報文發送之iptunnel_xmit

iptunnel_xmit函數是發送vxlan報文時,封裝UDP報文頭之後被調用的,主要作用是封裝IP頭,並調用三層發包函數,完成報文的發送,該函數相對比較簡單。

1、iptunnel_xmit函數

int iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
		  __be32 src, __be32 dst, __u8 proto,
		  __u8 tos, __u8 ttl, __be16 df, bool xnet)
{
	int pkt_len = skb->len;
	struct iphdr *iph;
	int err;

	skb_scrub_packet(skb, xnet);			//清空skb相關信息

	skb_clear_hash(skb);				//清空skb hash值
	skb_dst_set(skb, &rt->dst);			//rt必須根據外層報文的IP地址及相關信息獲取到的
	memset(IPCB(skb), 0, sizeof(*IPCB(skb)));	//清空skb IPCB的內容

	/* Push down and install the IP header. */
	skb_push(skb, sizeof(struct iphdr));		//skb報文添加IP頭
	skb_reset_network_header(skb);			//設置IP頭的偏移

	iph = ip_hdr(skb);

	iph->version	=	4;
	iph->ihl	=	sizeof(struct iphdr) >> 2;
	iph->frag_off	=	df;			//OVS2.5默認有df標記
	iph->protocol	=	proto;			//vxlan,該協議爲UDP
	iph->tos	=	tos;
	iph->daddr	=	dst;
	iph->saddr	=	src;
	iph->ttl	=	ttl;
	__ip_select_ident(dev_net(rt->dst.dev), iph,		//計算IP報文的ID值
			  skb_shinfo(skb)->gso_segs ?: 1);

	err = ip_local_out_sk(sk, skb);				//調用ip層發送函數
	if (unlikely(net_xmit_eval(err)))
		pkt_len = 0;
	return pkt_len;
}
vxlan報文的發送流程到此,就進入了標準的三層報文發送,與非vxlan封裝的報文是基本一致的(此類報文會標記encapsulation,會影響GSO分段)。

發佈了92 篇原創文章 · 獲贊 7 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章