if (unlikely(skb->len > dst_mtu(&rt->u.dst) && (ip_hdr(skb)->frag_off & htons(IP_DF))) { icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(dst_mtu(&rt->u.dst))); goto drop; } /*检查是否有足够的空间用于输出网络设备中的MAC报头dst.header_len() *调用skb_cow来创...
return skb_dst(skb)->input(skb); } skb_dst(skb)->input调用的input方法就是路由子系统赋的ip_local_deliver。 //file: net/ipv4/ip_input.c int ip_local_deliver(struct sk_buff *skb) { /* * Reassemble IP fragments. */ if (ip_is_fragment(ip_hdr(skb))) { if (ip_defrag(skb, IP_...
{structiphdr *iph =ip_hdr(skb);//ip头允许分片,则执行分片逻辑if((iph->frag_off & htons(IP_DF)) ==0)returnip_do_fragment(net, sk, skb, output);//不允许本地分段&&此时ip 头部禁止分段 || 分片最大长度>MTU 则发送无法到达的icmp_dest_unreach的消息if(unlikely(!skb->ignore_df ||(IPC...
skb_set_owner_w(new_skb, skb->sk); dev_kfree_skb(skb); skb = new_skb; old_iph = ip_hdr(skb); } skb->transport_header = skb->network_header;/* 重新设置传输层的头位置 */ skb_push(skb,sizeof(structiphdr)); skb_reset_network_header(skb); memset(&(IPCB(skb)->opt), 0,siz...
函数名称:ip_hdr 函数原型:static inline struct iphdr *ip_hdr(const struct sk_buff *skb) 返回类型:struct iphdr 参数: 类型参数名称 const struct sk_buff * skb 21 返回:skb_network_header(skb) 调用者 名称描述 selinux_netlbl_sctp_assoc_request selinux_netlbl_sctp_assoc_request - Label an inc...
skb_set_owner_w(new_skb, skb->sk); dev_kfree_skb(skb); skb = new_skb; old_iph = ip_hdr(skb); } skb->transport_header = skb->network_header; /* 重新设置传输层的头位置 */ skb_push(skb, sizeof(struct iphdr)); skb_reset_network_header(skb); ...
接下来,确保 skb 结构有足够的空间容纳需要添加的任何链路层头。如果空间不够,则调用skb_realloc_headroom分配额外的空间,并且新的 skb 的费用(charge)记在相关的 socket 上。 rcu_read_lock_bh(); nexthop = (__force u32) rt_nexthop(rt, ip_hdr(skb)->daddr); neigh = __ipv4_neigh_lookup_noref...
struct ipv6hdr *iph; struct ipv6_destopt_hdr *dstopt; struct ipv6_destopt_hao *hao; u8 nexthdr; int len; skb_push(skb, -skb_network_offset(skb)); iph = ipv6_hdr(skb); nexthdr = *skb_mac_header(skb); *skb_mac_header(skb) = IPPROTO_DSTOPTS; ...
skb_put:添加用户层数据。 skb_push:向header空间添加协议头。 skb_pull:复位data至数据区。 操作sk_buf的简单示意图如下: 3.4.2 net_device 在网络适配器硬件和软件协议栈之间需要一个接口,共同完成操作系统内核中协议栈数据处理与异步收发的功能。在Linux网络体系结构中,这个接口要满足以下要求: ...
// 重组成功后构造完整的ip报文staticstruct sk_buff*ip_glue(struct ipq*qp){struct sk_buff*skb;struct iphdr*iph;struct ipfrag*fp;unsigned char*ptr;int count,len;// 重组后整个包的长度等于mac头长度+ip头长度+数据长度len=qp->maclen+qp->ihlen+qp->len;// 分配新的skb,skb->data指向len大小...