Linux - статьи




Реализация сети в операционной - часть 9


dev_queue_xmit() - net/core/dev.c spin_lock_bh() -блокируем девайс если у него есть очередь calls enqueue() добавляем пакет calls qdis() пробуждаем девайс else calls dev->hard_start_xmit() calls spin_unlock_bh() освобождаем девайс

DEVICE->hard_start_xmit() - зависит от девайса, drivers/net/DEVICE.c в общем проверяет открыто ли устройство посылает заголовок говорит системной шине послать пакет обновляет статус

inet_sendmsg() - net/ipv4/af_inet.c int inet_sendmsg(struct socket *sock, struct msghdr *msg, int size, struct scm_cookie *scm) { struct sock *sk = sock->sk;

/*биндим сокет. */ if (sk->num==0 && inet_autobind(sk) != 0) return -EAGAIN; вызываем функцию протокола чтоб послать данные return sk->prot->sendmsg(sk, msg, size); }

    ip_build_xmit - net/ipv4/ip_output.c (604) calls sock_alloc_send_skb() выделяем память

=заголовочек=

if(!sk->protinfo.af_inet.hdrincl) { iph->version=4; iph->ihl=5; iph->tos=sk->protinfo.af_inet.tos; iph->tot_len = htons(length); iph->frag_off = df; iph->ttl=sk->protinfo.af_inet.mc_ttl; ip_select_ident(iph, &rt->u.dst, sk); if (rt->rt_type != RTN_MULTICAST) iph->ttl=sk->protinfo.af_inet.ttl; iph->protocol=sk->protocol; iph->saddr=rt->rt_src; iph->daddr=rt->rt_dst; iph->check=0; iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); err = getfrag(frag, ((char *)iph)+iph->ihl*4,0, length-iph->ihl*4); }

  calls getfrag() копируем данные у юзера returns rt->u.dst.output() [= dev_queue_xmit()]

ip_queue_xmit() - net/ipv4/ip_output.c (234) cмотри маршрут достраиваем ip заголовок фрагментирум если надо adds IP checksum calls skb->dst->output() [= dev_queue_xmit()]

qdisc_restart() - net/sched/sch_generic.c (50) вырываем пакет из очереди calls dev->hard_start_xmit() обновляем статистику if если ошибка опять стввим пакет в очередь

sock_sendmsg() - net/socket.c (325) проверяем права и всё такое calls scm_sendmsg() [socket control message] шлёмс данные calls sock->ops[inet]->sendmsg() and destroys scm




Содержание  Назад  Вперед