• Главная
  • Карта сайта
Не найдено

Анатомія мережевого стека в Linux

  1. Введення в протоколи
  2. Малюнок 1. Інтернет-модель мережевого стека
  3. Архітектура базової мережі
  4. Малюнок 2. Високорівнева архітектура мережевого стека Linux
  5. Інтерфейс системного виклику
  6. Протокол-незалежний інтерфейс (Protocol agnostic interface)
  7. Мережеві протоколи
  8. Малюнок 3. Структура масиву Internet-протоколу
  9. Малюнок 4. Буфер сокета і його зв'язку з іншими структурами
  10. Пристрій-незалежний інтерфейс (Device agnostic interface)
  11. драйвери пристроїв
  12. Йдемо далі
  13. Ресурси для скачування

Від сокетов до драйверів пристроїв

Введення в протоколи

У той час як формальне введення в роботу в мережі відсилає нас до моделі взаємодії відкритих систем (OSI - Open Systems Interconnection), це введення в основний мережевий стек в Linux використовує чотирьохрівневу модель, відому як модель Інтернет (Internet model) (дивіться малюнок 1) .

Малюнок 1. Інтернет-модель мережевого стека
Від сокетов до драйверів пристроїв   Введення в протоколи   У той час як формальне введення в роботу в мережі відсилає нас до моделі взаємодії відкритих систем (OSI - Open Systems Interconnection), це введення в основний мережевий стек в Linux використовує чотирьохрівневу модель, відому як модель Інтернет (Internet model) (дивіться малюнок 1)

Внизу стека розташовується канальний рівень. Канальний рівень відноситься до драйверів пристроїв, що забезпечує доступ до фізичного рівня, який може складатися з численних середовищ, таких як послідовні канали або пристрою Ethernet. Над канальним знаходиться мережевий рівень, який відповідає за напрямок пакетів за призначенням. Наступний рівень під назвою транспортний відповідає за однорангові (peer-to-peer) комунікації (наприклад, в межах хоста). Мережевий рівень управляє зв'язком між хостами, а транспортний - взаємодією між кінцевими точками всередині цих хостів. Нарешті, існує прикладний рівень, який зазвичай є семантичним і розуміє переміщені дані. Наприклад, протокол передачі гіпертексту (HTTP - Hypertext Transfer Protocol) переміщує запити і відповіді для вмісту Web між сервером і клієнтом.

По суті, рівні мережевого стека проходять під більш впізнаваними назвами. На канальному рівні ви знайдете Ethernet, найбільш поширену високошвидкісну середу. До старішим протоколам канального рівня відносяться такі послідовні протоколи, як Internet-протокол для послідовної лінії (SLIP - Serial Line Internet Protocol), Compressed SLIP (CSLIP) і Point-to-Point Protocol (PPP). Найбільш поширеним протоколом мережевого рівня є Internet Protocol (IP), але існують і інші, які задовольняють іншим потребам, такі як Протокол керуючих повідомлень Internet (ICMP - Internet Control Message Protocol) і Протокол дозволу адрес (ARP - Address Resolution Protocol). На транспортному рівні це Протокол управління передачею (TCP - Transmission Control Protocol) і Протокол призначених для користувача датаграм (UDP - User Datagram Protocol). Нарешті, прикладний рівень включає в себе безліч звичних нам протоколів, в тому числі HTTP, стандартний Web-протокол, і SMTP (Simple Mail Transfer Protocol), протокол передачі електронної пошти.

Архітектура базової мережі

Тепер перейдемо до архітектури мережевого стека Linux і подивимося, як він реалізує модель Internet. На малюнку 2 представлений високорівнева вид мережевого стека Linux. Нагорі розташовується рівень робочих просторів або прикладний рівень, який визначає користувачів мережевого стека. Внизу знаходяться фізичні пристрої, які забезпечують можливість з'єднання з мережами (послідовні або високошвидкісні мережі, як Ethernet). У центрі, або в просторі ядра, - мережева підсистема, яка знаходиться в центрі уваги даної статті. Через внутрішню частину мережевого стека проходять буфери сокетов (sk_buffs), які переміщують дані пакета між джерелами і одержувачами. Коротко буде показана структура sk_buff.

Малюнок 2. Високорівнева архітектура мережевого стека Linux

По-перше, вам пропонується короткий огляд основних елементів мережевої підсистеми Linux з подробицями в наступних розділах. Нагорі (дивіться малюнок 2) знаходиться система під назвою інтерфейс системного виклику. Вона просто дає спосіб додатків з робочих просторів отримувати доступ до мережевої підсистеми ядра. Наступним йде протокол-незалежний (protocol agnostic) рівень, який надає загальний спосіб роботи з нижчими протоколами транспортного рівня. Далі слідують фактичні протоколи, до яких в системі Linux відносяться вбудовані протоколи TCP, UDP і, звичайно ж, IP. Наступний - ще один незалежний рівень, який забезпечує загальний інтерфейс до окремих доступним драйверампристроїв і від них, супроводжуваний в кінці самими цими драйверами.

Інтерфейс системного виклику

Інтерфейс системного виклику може бути описаний в двох ракурсах. Коли мережевий виклик виробляється користувачем, він мультиплексуюча через системний виклик в ядро. Це закінчується як виклик sys_socketcall в ./net/socket.c, який потім демультіплексіруются виклик наміченої мети. Інший ракурс інтерфейсу системного виклику - використання нормальних файлових операцій для мережевого вводу / виводу (I / O). Наприклад, звичайні операції читання і запису можуть бути виконані на мережевому сокеті (який представляється файловим дескриптором як нормальний файл). Тому поки існують операції, специфічні для роботи в мережі (створення сокета викликом socket, зв'язування його з дескриптором викликом connect і так далі), є також і деяку кількість стандартних файлових операцій, які застосовуються до мережевих об'єктів, як до звичайних файлів. Нарешті, інтерфейс системного виклику надає кошти для передачі управління між додатком в просторі користувача і ядром.

Протокол-незалежний інтерфейс (Protocol agnostic interface)

Рівень сокетів є Протокол-незалежним (protocol agnostic) інтерфейсом, який надає набір стандартних функцій для підтримки ряду різних протоколів. Цей рівень не тільки підтримує звичайні TCP- і UDP-протоколи, але також і IP, raw Ethernet і інші транспортні протоколи, такі як Протокол управління передачею потоків даних (SCTP - Stream Control Transmission Protocol).

Взаємодія через мережевий стек відбувається за допомогою сокета. Структура сокета в Linux -struct sock, певна в linux / include / net / sock.h. Ця велика структура містить всі необхідні стану окремого сокета, включаючи певний протокол, який використовується сокетом, і операції, які можна над ним здійснювати.

Мережева підсистема знає про доступні протоколах зі спеціальної структури, яка визначає її можливості. Кожен протокол містить структуру під назвою proto (вона знаходиться в linux / include / net / sock.h). Ця структура визначає окремі операції сокета, які можуть виконуватися з рівня сокетов на транспортний рівень (наприклад, як створити сокет, як встановити з'єднання з сокетом, як закрити сокет і т.д.).

Мережеві протоколи

Розділ мережевих протоколів визначає окремі доступні мережеві протоколи (такі як TCP, UDP і так далі). Вони не започатковано на початку дня в функції inet_init в linux / net / ipv4 / af_inet.c (так як TCP і UDP відносяться до сімейства протоколів inet). Функція inet_init реєструє кожен з вбудованих протоколів, що використовують функцію proto_register. Ця функція визначена в linux / net / core / sock.c, і крім додавання протоколу в список діючих, якщо потрібно, може виділяти один або більше slab-кешей.

Можна побачити, як окремі протоколи ідентифікують самі себе за допомогою структури proto в файлах tcp_ipv4.c, udp.c і raw.c, в linux / net / ipv4 /. Кожна з цих структур протоколів відображається у вигляді типу і протоколу в inetsw_array, який приписує вбудовані протоколи їх операціями. Структура inetsw_array і його зв'язки показані на малюнку 3. Кожен з протоколів в цьому масиві инициализируется на початку дня в inetsw викликом inet_register_protosw з inet_init. Функція inet_init також ініціалізує різні модулі inet, такі як ARP, ICMP, IP-модулі і TCP і UDP-модулі.

Малюнок 3. Структура масиву Internet-протоколу
Кореляція сокета і протоколу

Згадайте, що коли сокет створюється, він визначає тип і протокол, наприклад, my_sock = socket (AF_INET, SOCK_STREAM, 0). AF_INET вказує сімейство Internet-адрес з потоковим сокетом, певним як SOCK_STREAM (як показано тут, в inetsw_array).

Зверніть увагу на малюнку 3 , Що структура proto визначає транспортні методи сокета, в той час як структура proto_ops- загальні. Додаткові протоколи можна додати в перемикач протоколів inetsw за допомогою виклику inet_register_protosw. Наприклад, SCTP додає себе викликом sctp_init в linux / net / sctp / protocol.c. Більш детальну інформацію про SCTP можна знайти в розділі ресурси .

Переміщення даних для гнізд відбувається за допомогою основної структури під назвою буфер сокета (sk_buff). У sk_buff містяться дані пакета і дані про стан, які охоплюють кілька рівнів стека протоколу. Кожен відправлений або одержаний пакет представлений в sk_buff. Структура sk_buff визначається в linux / include / linux / skbuff.h і показана на малюнку 4.

Малюнок 4. Буфер сокета і його зв'язку з іншими структурами

Як можна помітити, наскільки структур sk_buff для даного з'єднання можуть бути пов'язані один з одним. Кожна з них ідентифікує структуру пристрою (net_device), якому пакет надсилається або від якого отримано. Так як кожен пакет представлений в sk_buff, заголовки пакетів зручно визначено набором покажчиків (th, iph і mac для Управління доступом до середовища (заголовок Media Access Control або MAC). Оскільки структури sk_buff є центральними в організації даних сокета, для управління ними був створений ряд функцій підтримки. Існують функції для створення, руйнування, клонування і управління черговістю sk_buff.

Буфери сокетов розроблені таким чином, щоб зв'язуватися один з одним для даного сокета і включати великий обсяг інформації, в тому числі посилання на заголовки протоколів, тимчасові мітки (коли пакет був відправлений або одержаний) і відповідний пристрій.

Пристрій-незалежний інтерфейс (Device agnostic interface)

Під рівнем протоколів розташовується інший незалежний рівень інтерфейсу, який пов'язує протоколи з різними драйверами фізичних пристроїв з різними можливостями. Цей рівень надає стандартний набір функцій, які використовуються низько-рівневими мережевими пристроями, щоб мати можливість взаємодіяти з високо-рівневим стеком протоколу.

Перш за все, драйвери пристроїв можуть реєструвати і разрегістріровать себе в ядрі викликом register_netdevice або unregister_netdevice. Зухвала команда спочатку заповнює структуру net_device, а потім передає її для реєстрації. Ядро викликає свою функцію init (якщо вона визначена), виконує кілька перевірок справності, створює запис sysfs і потім додає новий пристрій у свій телефон (пов'язаний список пристроїв, активних в ядрі). Структуру net_device можна знайти в linux / include / linux / netdevice.h. Деякі функції знаходяться в linux / net / core / dev.c.

Для відправлення sk_buff з рівня протоколу пристрою використовується функція dev_queue_xmit. Вона ставить в чергу sk_buff для можливої ​​пересилання відповідним драйвером пристрою (пристроєм, певним за допомогою net_device або покажчика sk_buff-> dev в sk_buff). Структура dev містить метод під назвою hard_start_xmit, який зберігає функцію драйвера для ініціалізації передачі sk_buff.

Отримання пакета виконується традиційно за допомогою netif_rx. Коли драйвер пристрою нижчого рівня отримує пакет (що міститься всередині виділеного sk_buff), sk_buff йде вище, на мережевий рівень, за допомогою виклику netif_rx. Ця функція потім ставить sk_buff в чергу на більш високий рівень протоколів для подальшої обробки за допомогою netif_rx_schedule. Функції dev_queue_xmit і netif_rx знаходяться в linux / net / core / dev.c.

Нарешті, для взаємодії з пристрій-незалежним рівнем (dev) в ядро ​​був введений новий інтерфейс прикладних програм (NAPI). Його використовують деякі драйвери, але переважна більшість все ще користується більш старим інтерфейсом отримання кадрів (за грубою оцінкою шість з семи). NAPI може давати кращу продуктивність при великих навантаженнях, уникаючи при цьому переривань при кожному вхідному кадрі.

драйвери пристроїв

Внизу мережевого стека знаходяться драйвери пристроїв, які керують фізичними мережевими пристроями. Прикладами пристроїв цього рівня можуть служити драйвер SLIP над послідовним інтерфейсом або драйвер Ethernet над пристроєм Ethernet.

Під час ініціалізації драйвер пристрою виділяє місце для структури net_device, а потім ініціалізує її необхідними подпрограммами. Одна з них, під назвою dev-> hard_start_xmit, визначає, як верхній рівень повинен поставити в чергу sk_buff для передачі. Їй передається sk_buff. Ця функція залежить від обладнання, але зазвичай пакет, описуваний в sk_buff, переміщається в так зване "апаратне кільце" (hardware ring) або "чергу" (queue). Надходження кадру, як описано на пристрій-незалежному рівні, використовує інтерфейс netif_rx або netif_receive_skb для NAPI-сумісного мережного драйвера. Драйвер NAPI накладає обмеження на можливості базового обладнання. Подробиці дивіться в розділі ресурси .

Після того як драйвер пристрою налаштував свої інтерфейси в структурі dev, виклик register_netdevice робить її доступною для використання. У linux / drivers / net можна знайти драйвери, характерні для мережевих пристроїв.

Йдемо далі

Вихідний код Linux - прекрасний спосіб дізнатися про конструкції драйверів для безлічі типів пристроїв, включаючи драйвери мережевих пристроїв. Ви виявите відмінності в конструкції і використанні доступних API ядра, але кожен буде корисний або інструкціями, або як відправна точка для нового драйвера. Решта код в мережевому стеку стандартний і використовується, поки не буде потрібно новий протокол. Але навіть тоді реалізації TCP (для потокового протоколу) або UDP (для протоколу на основі передачі повідомлень) служать корисними моделями для початку нової розробки.

Ресурси для скачування

Схожі теми

  • "Anatomy of the Linux networking stack" - оригінал цієї статті на developerWorks (EN).
  • Короткий вступ в TCP / IP, UDP і ICMP подивіться в статті "Введення в Internet-протоколи" ( "Introduction to the Internet Protocols") на www.linuxjunkies.org (EN).
  • "Передача команд ядру за допомогою системних викликів Linux" ( "Kernel command using Linux system calls") (DeveloperWorks, березень 2007) охоплює тему інтерфейсу системного виклику Linux, що є важливим шаром ядра Linux з підтримкою простору користувача від GNU C Library (glibc), яка активізує виклики функцій між призначеним для користувача простором і ядром (EN).
  • Стаття "Отримайте доступ до ядра, використовуючи файлову систему / proc" ( "Access the Linux kernel using the / proc filesystem") (DeveloperWorks, березень 2006) звернена до файлової системи / proc, віртуальної файлової системи, яка надає новий спосіб взаємодії додатків користувацького простору з ядром. У статті демонструється / proc, а також завантажувані модулі ядра (EN).
  • Linux, як і BSD, - велика операційна система, якщо вас цікавлять мережеві протоколи. Стаття "Краще працювати в мережі з SCTP" ( "Better networking with SCTP") (DeveloperWorks, лютий 2006) присвячена одному з найцікавіших мережевих протоколів, SCTP, який працює, як TCP, але додає кілька корисних властивостей, таких як обмін повідомленнями, багатоточкові підключення і багатопоточність (EN).
  • Стаття "Анатомія розподільника пам'яті slab в Linux" ( "Anatomy of the Linux slab allocator") (DeveloperWorks, травень 2007) присвячена одному з найцікавіших аспектів управління пам'яттю в Linux - механізму slab allocator. Він відбувається з SunOS, але добре вжився всередині ядра Linux (EN).
  • У NAPI-драйвера є переваги перед драйверами, що використовують більш старі засоби обробки пакетів, починаючи з кращого управління переривань і до дроселювання пакетів. Більш докладно про Інтерфейсі і конструкції NAPI можна прочитати на сайті OSDL.
  • Подивіться книгу Тіма Програмування Додатків під GNU / Linux (GNU / Linux Application Programming) (EN) на предмет більш докладної інформації про програмування в просторі користувача в Linux (EN).
  • З книги Тіма Використання BSD-сокетів в різних мовах програмування (BSD Sockets Programming from a Multi-Language Perspective) можна дізнатися про програмування сокетів з використанням BSD Sockets API (EN).
  • В розділі Linux developerWorks можна знайти більше ресурсів для розробників Linux, включаючи допомоги по Linux , а також улюблені статті та підручники наших читачів по Linux за останній місяць.
  • Свою наступну розробку в Linux створюйте з пробним ПО IBM , Доступним для скачування прямо з developerWorks. (EN)

Підпишіть мене на повідомлення до коментарів

Провайдеры:
  • 08.09.2015

    Batyevka.NET предоставляет услуги доступа к сети Интернет на территории Соломенского района г. Киева.Наша миссия —... 
    Читать полностью

  • 08.09.2015
    IPNET

    Компания IPNET — это крупнейший оператор и технологический лидер на рынке телекоммуникаций Киева. Мы предоставляем... 
    Читать полностью

  • 08.09.2015
    Boryspil.Net

    Интернет-провайдер «Boryspil.net» начал свою работу в 2008 году и на данный момент является одним из крупнейших поставщиков... 
    Читать полностью

  • 08.09.2015
    4OKNET

    Наша компания работает в сфере телекоммуникационных услуг, а именно — предоставлении доступа в сеть интернет.Уже... 
    Читать полностью

  • 08.09.2015
    Телегруп

    ДП «Телегруп-Украина» – IT-компания с 15-летним опытом работы на рынке телекоммуникационных услуг, а также официальный... 
    Читать полностью

  • 08.09.2015
    Софтлинк

    Высокая скоростьМы являемся участником Украинского центра обмена трафиком (UA — IX) с включением 10 Гбит / сек... 
    Читать полностью