- 论坛徽章:
- 0
|
本帖最后由 yiyuandao 于 2012-07-05 17:23 编辑
在prerouting新分配一个new_skb,从old_skb拷贝ip头,传输层及负载,查找路由填充mac地址,最后调用dev_queue_xmit发出去,抓包发现
包发出去的速度很慢:
正常来说直接发送应该很快啊
代码:- void build_ipv4_packet(struct sk_buff* sock_skb, struct sk_buff* new_skb)
- {
- struct iphdr* iph;
- iph = ip_hdr(sock_skb);
- if(!iph){
- printk("iph error\n");
- return NF_ACCEPT;
- }
- new_skb = dev_alloc_skb(sock_skb->len + ETH_HLEN + 40 + 5);
- if(!new_skb){
- printk("low memory....\n");
- }
- skb_reserve(new_skb, 2);
- skb_put(new_skb, ETH_HLEN + sock_skb->len);
- construct_eth_header(sock_skb, new_skb, 0x800);
- memcpy((new_skb->data + ETH_HLEN), sock_skb->data, sock_skb->len);
- new_skb->ip_summed = CHECKSUM_UNNECESSARY;
- //new_skb->pkt_type = PACKET_HOST;
- //new_skb->pkt_type = PACKET_OUTGOING;
- new_skb->pkt_type = PACKET_OTHERHOST;
- new_skb->protocol = htons(ETH_P_IP);
- new_skb->dev = sock_skb->dev;
- skb_pull(new_skb, ETH_HLEN);
- if (skb_dst(new_skb) == NULL)
- {
- //printk("##############ipv4 not found route###begin#########\n");
- }
- struct timeval tv;
- struct timeval end_tv;
- do_gettimeofday(&tv);
- printk("before lookup route: second: %ld mircsecond: %ld\n", tv.tv_sec, tv.tv_usec);
- //struct net *net = dev_net(sock_skb->dev);
- int flags = RT6_LOOKUP_F_HAS_SADDR;
- struct rtable *rt;
- struct flowi fl = {
- .nl_u = {
- .ip4_u = {
- .daddr = iph->daddr
- }
- }
- };
- // lookup ipv4 route
- __be32 dest = 0;
- if (ip_route_output_key(&init_net, &rt, &fl) != 0)
- {
- kfree_skb(sock_skb);
- printk("not found ipv4 route-----------------------------------######\n");
- return;
- }
- dest = rt->rt_gateway;
- struct neighbour *neighbor_entry = neigh_lookup(&arp_tbl, &dest, sock_skb->dev);
- if (neighbor_entry != NULL)
- {
- //printk("##############found ipv4 route############\n");
- //print_buf(neighbor_entry->ha, 6);
- }
- skb_push(new_skb, ETH_HLEN);
- //print_buf(new_skb->data, 14);
- memcpy(new_skb->data, neighbor_entry->ha, 6);
- //print_buf(new_skb->data, 34);
- do_gettimeofday(&end_tv);
- printk("before send: second: %ld mircsecond: %ld\n", end_tv.tv_sec, end_tv.tv_usec);
- dev_queue_xmit(new_skb);
- do_gettimeofday(&end_tv);
- printk("after send: second: %ld mircsecond: %ld\n", end_tv.tv_sec, end_tv.tv_usec);
- //kfree_skb(sock_skb);
- }
复制代码 测试log:
!!!!!!!!!!!!!!start: second: 1341398275 mircsecond: 201298
Jul 4 18:37:55 ubuntu kernel: [ 7232.734796] ------!!!!!!!!!!!!!!!!!!!!!!!!!!------------------------------ipv4 ICMP Data Recv:
Jul 4 18:37:55 ubuntu kernel: [ 7232.734800] before lookup route: second: 1341398275 mircsecond: 201308
Jul 4 18:37:55 ubuntu kernel: [ 7232.734805] before send: second: 1341398275 mircsecond: 201313
Jul 4 18:37:55 ubuntu kernel: [ 7232.734843] after send: second: 1341398275 mircsecond: 201349
从log看到 dev_queue_xmit处理完成并没有花什么时间。
是不是dev_queue_xmit处理过程中把skb添加到发送队列去了,等待发送浪费了时间?
解决方法:
在32行以前添加:skb_reset_network_header(new_skb);
设置网络层头
但是不知道为什么添加了就能快速发送出去,估计在dev_queue_xmit中会需要skb->network_header |
|