⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inet_lro.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
}static void lro_flush(struct net_lro_mgr *lro_mgr,		      struct net_lro_desc *lro_desc){	if (lro_desc->pkt_aggr_cnt > 1)		lro_update_tcp_ip_header(lro_desc);	skb_shinfo(lro_desc->parent)->gso_size = lro_desc->mss;	if (lro_desc->vgrp) {		if (lro_mgr->features & LRO_F_NAPI)			vlan_hwaccel_receive_skb(lro_desc->parent,						 lro_desc->vgrp,						 lro_desc->vlan_tag);		else			vlan_hwaccel_rx(lro_desc->parent,					lro_desc->vgrp,					lro_desc->vlan_tag);	} else {		if (lro_mgr->features & LRO_F_NAPI)			netif_receive_skb(lro_desc->parent);		else			netif_rx(lro_desc->parent);	}	LRO_INC_STATS(lro_mgr, flushed);	lro_clear_desc(lro_desc);}static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb,			  struct vlan_group *vgrp, u16 vlan_tag, void *priv){	struct net_lro_desc *lro_desc;	struct iphdr *iph;	struct tcphdr *tcph;	u64 flags;	int vlan_hdr_len = 0;	if (!lro_mgr->get_skb_header	    || lro_mgr->get_skb_header(skb, (void *)&iph, (void *)&tcph,				       &flags, priv))		goto out;	if (!(flags & LRO_IPV4) || !(flags & LRO_TCP))		goto out;	lro_desc = lro_get_desc(lro_mgr, lro_mgr->lro_arr, iph, tcph);	if (!lro_desc)		goto out;	if ((skb->protocol == htons(ETH_P_8021Q))	    && !(lro_mgr->features & LRO_F_EXTRACT_VLAN_ID))		vlan_hdr_len = VLAN_HLEN;	if (!lro_desc->active) { /* start new lro session */		if (lro_tcp_ip_check(iph, tcph, skb->len - vlan_hdr_len, NULL))			goto out;		skb->ip_summed = lro_mgr->ip_summed_aggr;		lro_init_desc(lro_desc, skb, iph, tcph, vlan_tag, vgrp);		LRO_INC_STATS(lro_mgr, aggregated);		return 0;	}	if (lro_desc->tcp_next_seq != ntohl(tcph->seq))		goto out2;	if (lro_tcp_ip_check(iph, tcph, skb->len, lro_desc))		goto out2;	lro_add_packet(lro_desc, skb, iph, tcph);	LRO_INC_STATS(lro_mgr, aggregated);	if ((lro_desc->pkt_aggr_cnt >= lro_mgr->max_aggr) ||	    lro_desc->parent->len > (0xFFFF - lro_mgr->dev->mtu))		lro_flush(lro_mgr, lro_desc);	return 0;out2: /* send aggregated SKBs to stack */	lro_flush(lro_mgr, lro_desc);out:  /* Original SKB has to be posted to stack */	skb->ip_summed = lro_mgr->ip_summed;	return 1;}static struct sk_buff *lro_gen_skb(struct net_lro_mgr *lro_mgr,				   struct skb_frag_struct *frags,				   int len, int true_size,				   void *mac_hdr,				   int hlen, __wsum sum,				   u32 ip_summed){	struct sk_buff *skb;	struct skb_frag_struct *skb_frags;	int data_len = len;	int hdr_len = min(len, hlen);	skb = netdev_alloc_skb(lro_mgr->dev, hlen + lro_mgr->frag_align_pad);	if (!skb)		return NULL;	skb_reserve(skb, lro_mgr->frag_align_pad);	skb->len = len;	skb->data_len = len - hdr_len;	skb->truesize += true_size;	skb->tail += hdr_len;	memcpy(skb->data, mac_hdr, hdr_len);	skb_frags = skb_shinfo(skb)->frags;	while (data_len > 0) {		*skb_frags = *frags;		data_len -= frags->size;		skb_frags++;		frags++;		skb_shinfo(skb)->nr_frags++;	}	skb_shinfo(skb)->frags[0].page_offset += hdr_len;	skb_shinfo(skb)->frags[0].size -= hdr_len;	skb->ip_summed = ip_summed;	skb->csum = sum;	skb->protocol = eth_type_trans(skb, lro_mgr->dev);	return skb;}static struct sk_buff *__lro_proc_segment(struct net_lro_mgr *lro_mgr,					  struct skb_frag_struct *frags,					  int len, int true_size,					  struct vlan_group *vgrp,					  u16 vlan_tag, void *priv, __wsum sum){	struct net_lro_desc *lro_desc;	struct iphdr *iph;	struct tcphdr *tcph;	struct sk_buff *skb;	u64 flags;	void *mac_hdr;	int mac_hdr_len;	int hdr_len = LRO_MAX_PG_HLEN;	int vlan_hdr_len = 0;	if (!lro_mgr->get_frag_header	    || lro_mgr->get_frag_header(frags, (void *)&mac_hdr, (void *)&iph,					(void *)&tcph, &flags, priv)) {		mac_hdr = page_address(frags->page) + frags->page_offset;		goto out1;	}	if (!(flags & LRO_IPV4) || !(flags & LRO_TCP))		goto out1;	hdr_len = (int)((void *)(tcph) + TCP_HDR_LEN(tcph) - mac_hdr);	mac_hdr_len = (int)((void *)(iph) - mac_hdr);	lro_desc = lro_get_desc(lro_mgr, lro_mgr->lro_arr, iph, tcph);	if (!lro_desc)		goto out1;	if (!lro_desc->active) { /* start new lro session */		if (lro_tcp_ip_check(iph, tcph, len - mac_hdr_len, NULL))			goto out1;		skb = lro_gen_skb(lro_mgr, frags, len, true_size, mac_hdr,				  hdr_len, 0, lro_mgr->ip_summed_aggr);		if (!skb)			goto out;		if ((skb->protocol == htons(ETH_P_8021Q))		    && !(lro_mgr->features & LRO_F_EXTRACT_VLAN_ID))			vlan_hdr_len = VLAN_HLEN;		iph = (void *)(skb->data + vlan_hdr_len);		tcph = (void *)((u8 *)skb->data + vlan_hdr_len				+ IP_HDR_LEN(iph));		lro_init_desc(lro_desc, skb, iph, tcph, 0, NULL);		LRO_INC_STATS(lro_mgr, aggregated);		return NULL;	}	if (lro_desc->tcp_next_seq != ntohl(tcph->seq))		goto out2;	if (lro_tcp_ip_check(iph, tcph, len - mac_hdr_len, lro_desc))		goto out2;	lro_add_frags(lro_desc, len, hdr_len, true_size, frags, iph, tcph);	LRO_INC_STATS(lro_mgr, aggregated);	if ((skb_shinfo(lro_desc->parent)->nr_frags >= lro_mgr->max_aggr) ||	    lro_desc->parent->len > (0xFFFF - lro_mgr->dev->mtu))		lro_flush(lro_mgr, lro_desc);	return NULL;out2: /* send aggregated packets to the stack */	lro_flush(lro_mgr, lro_desc);out1:  /* Original packet has to be posted to the stack */	skb = lro_gen_skb(lro_mgr, frags, len, true_size, mac_hdr,			  hdr_len, sum, lro_mgr->ip_summed);out:	return skb;}void lro_receive_skb(struct net_lro_mgr *lro_mgr,		     struct sk_buff *skb,		     void *priv){	if (__lro_proc_skb(lro_mgr, skb, NULL, 0, priv)) {		if (lro_mgr->features & LRO_F_NAPI)			netif_receive_skb(skb);		else			netif_rx(skb);	}}EXPORT_SYMBOL(lro_receive_skb);void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr,				  struct sk_buff *skb,				  struct vlan_group *vgrp,				  u16 vlan_tag,				  void *priv){	if (__lro_proc_skb(lro_mgr, skb, vgrp, vlan_tag, priv)) {		if (lro_mgr->features & LRO_F_NAPI)			vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag);		else			vlan_hwaccel_rx(skb, vgrp, vlan_tag);	}}EXPORT_SYMBOL(lro_vlan_hwaccel_receive_skb);void lro_receive_frags(struct net_lro_mgr *lro_mgr,		       struct skb_frag_struct *frags,		       int len, int true_size, void *priv, __wsum sum){	struct sk_buff *skb;	skb = __lro_proc_segment(lro_mgr, frags, len, true_size, NULL, 0,				 priv, sum);	if (!skb)		return;	if (lro_mgr->features & LRO_F_NAPI)		netif_receive_skb(skb);	else		netif_rx(skb);}EXPORT_SYMBOL(lro_receive_frags);void lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr,				    struct skb_frag_struct *frags,				    int len, int true_size,				    struct vlan_group *vgrp,				    u16 vlan_tag, void *priv, __wsum sum){	struct sk_buff *skb;	skb = __lro_proc_segment(lro_mgr, frags, len, true_size, vgrp,				 vlan_tag, priv, sum);	if (!skb)		return;	if (lro_mgr->features & LRO_F_NAPI)		vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag);	else		vlan_hwaccel_rx(skb, vgrp, vlan_tag);}EXPORT_SYMBOL(lro_vlan_hwaccel_receive_frags);void lro_flush_all(struct net_lro_mgr *lro_mgr){	int i;	struct net_lro_desc *lro_desc = lro_mgr->lro_arr;	for (i = 0; i < lro_mgr->max_desc; i++) {		if (lro_desc[i].active)			lro_flush(lro_mgr, &lro_desc[i]);	}}EXPORT_SYMBOL(lro_flush_all);void lro_flush_pkt(struct net_lro_mgr *lro_mgr,		  struct iphdr *iph, struct tcphdr *tcph){	struct net_lro_desc *lro_desc;	lro_desc = lro_get_desc(lro_mgr, lro_mgr->lro_arr, iph, tcph);	if (lro_desc->active)		lro_flush(lro_mgr, lro_desc);}EXPORT_SYMBOL(lro_flush_pkt);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -