понедельник, 4 февраля 2013 г.

Перевод статьи описания структуры данных sk_buff


Попытка точного перевода статьи sk_buff

Все связанные с сетью очереди и буферы в ядре использую структуру общих данных -  sk_buff. Это большая структура, содержащая всю необходимую для управления пакетом информацию (дейтаграмма, ячейка, что-нибудь еще). Элементы sk_buff организованы как двухсвязный список таким образом, что очень эффективно  можно перемещать элемент sk_buff из начала/конца списка в начало/конец другого списка. Очередь определена как структура sk_buff_head, которая содержит указатели на начало и конец элементов sk_buff.

Все структуры очередей включают структуры sk_buff_head, представляющих собой очередь. Например, структура сокета sock  включает очередь приема и отправки. Функции для управления очередями ( skb_queue_head(), skb_queue_tail(), skb_dequeue(), skb_dequeue_tail() ) воздействуют на sk_buff_head. Однако в действительности sk_buff_head включает двухсвязный список структур sk_buff (таким образом фактически формирует кольцо).

Когда выделяется sk_buff, также его пространство данных отделено от памяти ядра. Выделение sk_buff выполнено с  alloc_skb() или dev_alloc_skb(); драйверы используют dev_alloc_skb() (освобождение памяти с помощью kfree_skb() и dev_kfree_skb() ).  Однако sk_buff обеспечивает дополнительный уровень управления. Пространство данных разделено на область заголовков и область данных. Это позволяет функциям ядра резервировать пространство для заголовка, чтобы не пришлось копировать эти данные вновь и вновь. Как правило, после выделения sk_buff область заголовка резервируется с помощью skb_reserve(). skb_pull( int LEN) – удаляет данные из начала буфера (перескакивая существующий заголовок), расширяя область данныx  до размера DATA+LEN и уменьшая LEN.

Структура sk_buff имеет поля, которые указать на определенные заголовки сетевого уровня:
  • transport_header (ранее назывался h) – для уровня 4, транспортный уровень (может включать TCP/UDP/ICMP-заголовок и другие)
  • network_header – (ранее назывался nh) для уровня 3, сетевой уровень (может включать IPv4/IPv6/ARP-заголовок).
  • mac_header – (ранее назывался mac) для уровня 2, канальный уровень.
  • skb_network_header(skb), skb_transport_header(skb) и skb_mac_header(skb) - возвращают указатель на заголовок sk_buff.
Сами объекты структур sk_buff явлюятся приватными для каждого сетевого уровня. Когда пакет переходит с одного уровня на другой, структура sk_buff клонируется. Однако его данные в этом случае не копируются. Заметьте, что структура sk_buff довольно большая, но чаще всего большинство ее элементов не используется.. Издержки копирования возникают по причини ограничения клонирования(* м.б. неверно).
  • почти всегда экземпляры sk_buff именуются как  “skb” в коде ядра.
  • структура dst_entry *dst – маршрут для sk_buff; этот маршрут определен подсистемой маршрутизации.
    • она имеет два важных функциональных указателя:
      • int (*input)(struct sk_buff*);
      • int (*output)(struct sk_buff*);
    • input() может быть присвоен одному из списка : 
      • ip_local_deliver
      • ip_forward
      • ip_mr_input
      • ip_error
      • dst_discard_in.
    • output() может быть назначен одну из : 
      • ip_output
      • ip_mc_output
      • ip_rt_bug
      • dst_discard_out.
    • мы будем больше иметь дело с местом назначения при разговоре о маршрутизации
    • в обычном случае существует только один место назначения  dst_entry для каждого skb.
    • при использовании IPsec существует связный список  места назначения dst_entries и последнего маршрута до него; все остальные записи мест назначения для преобразований IPSec ; этим записям устанавливается флаг DST_NOHASH. Записи с таким установленным флагом не сохраняются в кэше маршрутизации, но вместо этого сохраняются в кэше потока.
  • tstamp (of type ktime_t ) :  временная метка получения пакета
    • net_enable_timestamp() должен вызываться, чтобы получить значение.

Комментариев нет:

Отправить комментарий