浅析ethx网卡发送函数sys_write简易流程
来源:互联网 发布:华为交换机端口应用acl 编辑:程序博客网 时间:2024/05/01 14:53
浅析ethx网卡发送函数sys_write简易流程
sys_write=>vfs_write=>do_sync_write=>
filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
{也就是对应socket_file_ops中的sock_aio_write}
sock_aio_write=>do_sock_write=>__sock_sendmsg=>
sock->ops->sendmsg(iocb, sock, msg, size);
{也就是对应inetsw_array[]中的inet_stream_ops下的tcp_sendmsg}
tcp_sendmsg=>经过skb拷贝之后,最终在退出之前调用tcp_push,将数据发送到网络=>
tcp_push=>__tcp_push_pending_frames=>tcp_write_xmit=>tcp_transmit_skb=>
icsk->icsk_af_ops->queue_xmit(skb, 0);
/*
在tcp_v4_init_sock中初始化的如下方法:
icsk->icsk_af_ops = &ipv4_specific;
icsk->icsk_ca_ops = &tcp_init_congestion_ops;
tp->reordering = sysctl_tcp_reordering;
sk->sk_write_space = sk_stream_write_space;
icsk->icsk_sync_mss = tcp_sync_mss;
tp->af_specific = &tcp_sock_ipv4_specific;
所以icsk_af_ops就是ipv4_specific,
struct inet_connection_sock_af_ops ipv4_specific = {
.queue_xmit = ip_queue_xmit,
.send_check = tcp_v4_send_check,
.rebuild_header = inet_sk_rebuild_header,
.conn_request = tcp_v4_conn_request,
.syn_recv_sock = tcp_v4_syn_recv_sock,
.remember_stamp = tcp_v4_remember_stamp,
.net_header_len = sizeof(struct iphdr),
.setsockopt = ip_setsockopt,
.getsockopt = ip_getsockopt,
.addr2sockaddr = inet_csk_addr2sockaddr,
.sockaddr_len = sizeof(struct sockaddr_in),
#ifdef CONFIG_COMPAT
.compat_setsockopt = compat_ip_setsockopt,
.compat_getsockopt = compat_ip_getsockopt,
#endif
};
*/
ip_queue_xmit=>
return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
dst_output);
也就是调用dst_output将package发送到网络中出去.
/* Output packet to network from transport. */
static inline int dst_output(struct sk_buff *skb)
{
return skb->dst->output(skb);
}
__mkroute_output=>dst_alloc=>
rth = dst_alloc(&ipv4_dst_ops);然后dst->ops = ipv4_dst_ops;
rth->u.dst.output=ip_output;
ip_output=>
return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
ip_finish_output,
!(IPCB(skb)->flags & IPSKB_REROUTED));
ip_finish_output=>ip_finish_output2=>
/*
if (dst->hh)
return neigh_hh_output(dst->hh, skb);
else if (dst->neighbour)
return dst->neighbour->output(skb);
*/
/*
static struct neigh_ops arp_generic_ops = {
.family = AF_INET,
.solicit = arp_solicit,
.error_report = arp_error_report,
.output = neigh_resolve_output,
.connected_output = neigh_connected_output,
.hh_output = dev_queue_xmit,
.queue_xmit = dev_queue_xmit,
};
static struct neigh_ops arp_hh_ops = {
.family = AF_INET,
.solicit = arp_solicit,
.error_report = arp_error_report,
.output = neigh_resolve_output,
.connected_output = neigh_resolve_output,
.hh_output = dev_queue_xmit,
.queue_xmit = dev_queue_xmit,
};
static struct neigh_ops arp_direct_ops = {
.family = AF_INET,
.output = dev_queue_xmit,
.connected_output = dev_queue_xmit,
.hh_output = dev_queue_xmit,
.queue_xmit = dev_queue_xmit,
};
struct neigh_ops arp_broken_ops = {
.family = AF_INET,
.solicit = arp_solicit,
.error_report = arp_error_report,
.output = neigh_compat_output,
.connected_output = neigh_compat_output,
.hh_output = dev_queue_xmit,
.queue_xmit = dev_queue_xmit,
};
*/
因为ip通信都是以arp开始来获取通信对端的mac地址,所以arp应该是网络通信的第一步,
这样就调用到了dev_queue_xmit()想物理网卡发送网络数据包,
dev_queue_xmit=>dev_hard_start_xmit=>
return dev->hard_start_xmit(skb, dev);
就是网卡驱动的发送函数wlan_hard_start_xmit,比较粗糙,凑活着看吧【gliethttp.Leith】
看看sys_socket()对空间结构的申请步骤:
sk->sk_prot = tcp_prot;
他的.obj_size = sizeof(struct tcp_sock),所以
struct tcp_sock {
/* inet_connection_sock has to be the first member of tcp_sock */
struct inet_connection_sock inet_conn;
...
}
struct inet_connection_sock {
/* inet_sock has to be the first member! */
struct inet_sock icsk_inet;
...
}
struct inet_sock {
/* sk and pinet6 has to be the first two members of inet_sock */
struct sock sk;
...
}
所以sk_alloc申请到的sk,指向的是tcp_sock下inet_connection_sock下inet_sock中的sk,
然后
__sock_create=>
pf->create(net, sock, protocol);
inet_create=>
sk->sk_prot->init(sk)也就是调用tcp_prot的init,也就是tcp_v4_init_sock【gliethttp.Leith】.
- 浅析ethx网卡发送函数sys_write简易流程
- 浅析ethx网卡控制函数ioctl实现具体流程【转】
- 浅析ethx网卡控制函数ioctl实现具体流程
- [转]浅析ethx网卡控制函数ioctl实现具体流程
- 浅析ethx网卡控制函数ioctl实现具体流程
- 浅析ethx网卡控制函数ioctl实现具体流程
- 浅析ethx网卡控制函数ioctl实现具体流程
- wpa_supplicant 的初始化&&浅析ethx网卡控制函数ioctl实现具体流程
- 底层网卡发送报文流程
- 更换LINUX虚拟机网卡的名称ethX
- 浅析sys_socket创建socket的简易流程
- 将网卡ethx与其相关的驱动解除绑定
- gentoo小技巧:调整ethX对应的网卡
- linux 系统 网卡 ethX没有显示IP的处理方式
- linux ubuntu操作系统修改网卡名称为ethx的方法
- 自动修改linux下/etc/sysconfig/network-scripts/ifcfg-ethX网卡文件的脚本
- linux 网络配置——解决redhat 6.x 网卡ethx 改名字的问题
- 浅析android通过jni控制service服务程序的简易流程
- 动态数组C语言实现
- poj1125 Floyd-Warshall算法
- 编写整数字符串转化函数(不用itoa与atoi)
- 浅析sys_socket创建socket的简易流程
- ASCII码表在线查询(1.0 beta 1)
- 浅析ethx网卡发送函数sys_write简易流程
- 浅析ethx网卡控制函数ioctl实现具体流程
- ARM 7 用户模式下禁止/使能中断的一种方法--使用软中断 for Keil MDK
- wireless extention扩展接口
- Axis 1.X 入门实例
- 编程学习指南
- PopupWindow,AlertDialog
- 编译原理学习导论
- 心情不爽