Сергей Присяжный   [email_address] OpenBSD. Сетевая подсистема в деталях
Почему  OpenBSD? (goals) SMP ? HW SECURE
Вместо содержания Заглянем немного в историю Оценим нынешнее состояние сетевого стека Перейдём от теории к практике Рассмотрим  OpenBSD made stuff (pf, bgpd, ospfd, carp, etc)
Ты помнишь, как всё начиналось ? Создание  MULTICS (ARPA) первый сетевой стек ( MIT, 1970 ) стек  MULTICS  – основа большинства иных стеков Первый  TCP/IP  стек ( MULTICS, 1980 ) Первая  UNIX  реализация ( Berkeley, 1983 ) Основа стека  OpenBSD  –   стек 4.4 BSD TCP/IP Illustrated, vol. 2  всё ещё руководство № 1
 
Краткий обзор Socket API взаимодействие с  userland mbuf “API” управление памятью Сетевой стек реализации протоколов Маршрутизация независимая реализация на уровне ядра
Socket API Используется  userland -ом для осуществления сетевого взаимодействия IPC  де факто стандарт socket(), bind(), connect(), accept() recv(), send(), … setsockopt(), getsockopt() Тема отдельного разговора (выходит далеко за рамки данного доклада) косвенное упоминание для полноты «картины»
mbufs
mbufs Аллокация памяти для пакетов  ( 256  байт каждый ) иногда используются для иных данных Могут образовывать цепочки и расширяться за счёт внешних буферов  ( кластер - 2 K ) Формируются посредством системного  pool(9) Неформальный  API ==  набор функций 1-я причина сетевых багов – неправильная работа с  mbuf !
 
mbuf   tags Ядро может имплементировать метаданные в пакет чаще всего для предотвращения петлей  ( IPsec, gif(4), gre(4) ) Структура TLV – type, length, value динамический размер,  выделяемый  malloc(9) элементы формируют линейный список
mbuf   tags
mbuf tags –  хак  pf(4) pf(4)  –  активный пользователь  mbuf tags Каждый  пакет получал  tag  до того, пока … Метаданные  pf  не были имплементированы непосредственно в заголовок пакета заголовок немного увеличился отсутствие   «холостого хода»  malloc(9) оставшегося места достаточно для малых пакетов Пример –  x2  прирост сквозь  SOEKRIS  коробку
Сетевой стек
Сетевой стек (обзор) 4-х уровневая система интерфейс:   драйвера устройств   ( OSI   1+2 ) сеть:  IP, IPv6, ICMP (OSI 3) транспорт:  TCP, UDP (OSI 4) приложение:  userland  приложения  (OSI 5+7) В основном – код определения пакетов и выяснения их «дальнейшей судьбы» устойчив к наличию багов со стороны-участника процесса
 
Уровень интерфейса ( input )
Обработчик  RX  прерывания драйвера «достаёт» пакет из  DMA  кольца Данные попадают на канальный уровень пример  -   ether_input() определение сетевого протокола Пакет передаётся во входящую протокольную очередь с последующим планированием программного прерывания пример -  schednetisr(NETISR_IP); inq = &ipintrq; netisr – splnet() vs. splsoftnet()  ( зона демаркации прерываний ) оставшиеся части стека выполняются на более низком   уровне Уровень интерфейса ( input )
Сетевой уровень ( input )
Netisr  вызывает сетевой обработчик пример –  ipintr()  ==  программное прерывание при условии наличия данных Входящие  pf(4)  фильтрации Назначение пакета не локально? перенаправить  (if enabled) , иначе  drop восстановление пакета ( TTL,   checksum ) передать на обработку  ip_output() Переход на следующий уровень посредством  protosw / inetsw []   структуры каждый   протокол уровня содержит структуру  protosw Сетевой уровень ( input )
Транспортный уровень ( input )
Определение блока контроля протокола ( PCB ) каждое открытое соединение имеет  PCB вмещает всю необходимую информацию для установления соединения Надёжным протоколам – сложный код  ( TCP –  целая  философия ) управление потоком повторная передача логика повторной сборки подтверждения SYN  кеш Передача в очередь буфера сокета и активизация  userland Транспортный уровень ( input )
 
Транспортный уровень ( output )
Userland:  write () , send(), … Уровень сокета использует структуру  protows  для передачи данных каждая операция сокета в контексте – вызов функции  pr_usrreq() , где  pr  –  конкретный протокол  ( например,  tcp_usrreq() ) pr_usrreq()  вызывает  output   функцию управление потоком, повторная передача, …   для  TCP вызов сетевой  output   функции напрямую ( без   protosw ) специфика работы  UDP ( псевдо  IP == PIP) причина необходимости использования  udp_output()   и  udp6_output() Транспортный уровень ( output )
Сетевой уровень ( output )
Формирование сетевого ( IP, IPv6 )   заголовка Поиск маршрута ( route lookup ) В большинстве случаев – маршруты из кеша Исходящие  pf(4)  фильтрации Вызов  output   функции интерфейса интерфейс определяется на стадии   поиска маршрута структура интерфейса содержит указатели на функцию подобно  protosw  структуре Сетевой уровень ( output )
Уровень интерфейса ( output )
Формирование канального заголовка ( Ethernet  заголовка) или произведение специфических инкапсуляций ( natm, ppp ) Может быть цепью виртуальных интерфейсов Пакет готов к передаче в интерфейсную очередь   hint:   альтернативная организация очереди ( ALTQ )   происходит на данном этапе необходим  splnet()   уровень По факту вызова  ifp -> if_start драйвер направляет пакет в кольцо передачи ( TX DMA ring ) Подобно всему драйвероспецифичному   TX  прерывание или иное подобное действие высвободит пакет сквозь трансивер Уровень интерфейса ( output )
Маршрутизация
 
Форвард данные ( forwarding info ) Адреса канального уровня в этом же дереве Адресная группа ( aka Address Family ) независима каждая  AF  имеет отдельное дерево «Там чудеса: там леший бродит, … » не там , чудеса начинаются здесь!   Маршрутизация (обзор)
Маршрутизация (обзор)
Метки Домены  aka VRF Приоритеты Маршрутизация (рассмотрим)
Маршрут может быть оттагированным ядром Метка заменяется на  integer  в ядре    мысли? (идея: сравнение строк) == скорость, память pf  «умеет» фильтровать или тагировать трафик на основе  rtlabels bgpd   может помечать маршруты   посредством  BGP path  атрибутов ospfd   в состоянии устанавливать метки маршрута, основанные на  внешних  маршрутных тагах Маршрутизация (метки)
Расширенная версия множественных маршрутных таблиц максимум 256 таблиц таблица по умолчанию –  ID 0  Набору интерфейсов определяется специфическая таблица одна и та же сеть может быть определена множество раз Маршрутный сокет маркирует сообщения различными  ID  таблиц Маршрутизация (домены)
Маршрутные демоны должны содержать свои таблицы «в чистоте» (синхронизированными) Разные приоритеты на случай конфликтов OSPF  более предпочтителен   системой чем  BGP   Синхронизация в  userland –  это тяжело «ресурсные войны» маршрутный сокет – потери Необходимо лучшее решение Маршрутизация (приоритеты)
Дополнительная маршрутная преференция –  метрика Каждый маршрутный источник имеет свой тип #define RTP_STATIC 8 /* static routes */ #define RTP_OSPF 16 /* OSPF routes */ #define RTP_RIP 24 /* RIP routes */ #define RTP_BGP 32 /* BGP routes */ иные Маршрутизация (приоритеты)
Маршрутизация (приоритеты)
От теории к практике
Применение sysctl(8) kern.maxclusters управление  mbuf(9) net.inet.ip.ifq.maxlen управление очередью net.inet.ip.maxqueue управление очередью net.inet. { tcp ,udp} . { send ,recv} space   размер окна net. { inet ,inet6} . { ip ,ip6} . { forwarding , mforwarding } В большинстве случаев достаточно системного  ifconfig(8) + pfctl(8) От теории к практике
OpenBSD made stuff
OpenSSH http://www.openssh.com/ OpenBGPD http://www.openbgpd.org/ OpenOSPFD http://www.openbgpd.org/ OpenNTPD http://www.openntpd.org/ OpenCVS http://www.opencvs.org/ иные http://www.openbsd.org/ OpenBSD made stuff
Компании  ATMNIS http://www.atmnis.com/ Друзьям konstantyn @atmnis.com gregor @atmnis.com Отдельно, Claudio Jeker  [email_address] Организаторам RootConf – 2009 Большое спасибо
Вопросы?

присяжный Root Conf2009 Beta 1

  • 1.
    Сергей Присяжный [email_address] OpenBSD. Сетевая подсистема в деталях
  • 2.
    Почему OpenBSD?(goals) SMP ? HW SECURE
  • 3.
    Вместо содержания Заглянемнемного в историю Оценим нынешнее состояние сетевого стека Перейдём от теории к практике Рассмотрим OpenBSD made stuff (pf, bgpd, ospfd, carp, etc)
  • 4.
    Ты помнишь, каквсё начиналось ? Создание MULTICS (ARPA) первый сетевой стек ( MIT, 1970 ) стек MULTICS – основа большинства иных стеков Первый TCP/IP стек ( MULTICS, 1980 ) Первая UNIX реализация ( Berkeley, 1983 ) Основа стека OpenBSD – стек 4.4 BSD TCP/IP Illustrated, vol. 2 всё ещё руководство № 1
  • 5.
  • 6.
    Краткий обзор SocketAPI взаимодействие с userland mbuf “API” управление памятью Сетевой стек реализации протоколов Маршрутизация независимая реализация на уровне ядра
  • 7.
    Socket API Используется userland -ом для осуществления сетевого взаимодействия IPC де факто стандарт socket(), bind(), connect(), accept() recv(), send(), … setsockopt(), getsockopt() Тема отдельного разговора (выходит далеко за рамки данного доклада) косвенное упоминание для полноты «картины»
  • 8.
  • 9.
    mbufs Аллокация памятидля пакетов ( 256 байт каждый ) иногда используются для иных данных Могут образовывать цепочки и расширяться за счёт внешних буферов ( кластер - 2 K ) Формируются посредством системного pool(9) Неформальный API == набор функций 1-я причина сетевых багов – неправильная работа с mbuf !
  • 10.
  • 11.
    mbuf tags Ядро может имплементировать метаданные в пакет чаще всего для предотвращения петлей ( IPsec, gif(4), gre(4) ) Структура TLV – type, length, value динамический размер, выделяемый malloc(9) элементы формируют линейный список
  • 12.
    mbuf tags
  • 13.
    mbuf tags – хак pf(4) pf(4) – активный пользователь mbuf tags Каждый пакет получал tag до того, пока … Метаданные pf не были имплементированы непосредственно в заголовок пакета заголовок немного увеличился отсутствие «холостого хода» malloc(9) оставшегося места достаточно для малых пакетов Пример – x2 прирост сквозь SOEKRIS коробку
  • 14.
  • 15.
    Сетевой стек (обзор)4-х уровневая система интерфейс: драйвера устройств ( OSI 1+2 ) сеть: IP, IPv6, ICMP (OSI 3) транспорт: TCP, UDP (OSI 4) приложение: userland приложения (OSI 5+7) В основном – код определения пакетов и выяснения их «дальнейшей судьбы» устойчив к наличию багов со стороны-участника процесса
  • 16.
  • 17.
  • 18.
    Обработчик RX прерывания драйвера «достаёт» пакет из DMA кольца Данные попадают на канальный уровень пример - ether_input() определение сетевого протокола Пакет передаётся во входящую протокольную очередь с последующим планированием программного прерывания пример - schednetisr(NETISR_IP); inq = &ipintrq; netisr – splnet() vs. splsoftnet() ( зона демаркации прерываний ) оставшиеся части стека выполняются на более низком уровне Уровень интерфейса ( input )
  • 19.
  • 20.
    Netisr вызываетсетевой обработчик пример – ipintr() == программное прерывание при условии наличия данных Входящие pf(4) фильтрации Назначение пакета не локально? перенаправить (if enabled) , иначе drop восстановление пакета ( TTL, checksum ) передать на обработку ip_output() Переход на следующий уровень посредством protosw / inetsw [] структуры каждый протокол уровня содержит структуру protosw Сетевой уровень ( input )
  • 21.
  • 22.
    Определение блока контроляпротокола ( PCB ) каждое открытое соединение имеет PCB вмещает всю необходимую информацию для установления соединения Надёжным протоколам – сложный код ( TCP – целая философия ) управление потоком повторная передача логика повторной сборки подтверждения SYN кеш Передача в очередь буфера сокета и активизация userland Транспортный уровень ( input )
  • 23.
  • 24.
  • 25.
    Userland: write() , send(), … Уровень сокета использует структуру protows для передачи данных каждая операция сокета в контексте – вызов функции pr_usrreq() , где pr – конкретный протокол ( например, tcp_usrreq() ) pr_usrreq() вызывает output функцию управление потоком, повторная передача, … для TCP вызов сетевой output функции напрямую ( без protosw ) специфика работы UDP ( псевдо IP == PIP) причина необходимости использования udp_output() и udp6_output() Транспортный уровень ( output )
  • 26.
  • 27.
    Формирование сетевого (IP, IPv6 ) заголовка Поиск маршрута ( route lookup ) В большинстве случаев – маршруты из кеша Исходящие pf(4) фильтрации Вызов output функции интерфейса интерфейс определяется на стадии поиска маршрута структура интерфейса содержит указатели на функцию подобно protosw структуре Сетевой уровень ( output )
  • 28.
  • 29.
    Формирование канального заголовка( Ethernet заголовка) или произведение специфических инкапсуляций ( natm, ppp ) Может быть цепью виртуальных интерфейсов Пакет готов к передаче в интерфейсную очередь hint: альтернативная организация очереди ( ALTQ ) происходит на данном этапе необходим splnet() уровень По факту вызова ifp -> if_start драйвер направляет пакет в кольцо передачи ( TX DMA ring ) Подобно всему драйвероспецифичному  TX прерывание или иное подобное действие высвободит пакет сквозь трансивер Уровень интерфейса ( output )
  • 30.
  • 31.
  • 32.
    Форвард данные (forwarding info ) Адреса канального уровня в этом же дереве Адресная группа ( aka Address Family ) независима каждая AF имеет отдельное дерево «Там чудеса: там леший бродит, … » не там , чудеса начинаются здесь!  Маршрутизация (обзор)
  • 33.
  • 34.
    Метки Домены aka VRF Приоритеты Маршрутизация (рассмотрим)
  • 35.
    Маршрут может бытьоттагированным ядром Метка заменяется на integer в ядре  мысли? (идея: сравнение строк) == скорость, память pf «умеет» фильтровать или тагировать трафик на основе rtlabels bgpd может помечать маршруты посредством BGP path атрибутов ospfd в состоянии устанавливать метки маршрута, основанные на внешних маршрутных тагах Маршрутизация (метки)
  • 36.
    Расширенная версия множественныхмаршрутных таблиц максимум 256 таблиц таблица по умолчанию – ID 0 Набору интерфейсов определяется специфическая таблица одна и та же сеть может быть определена множество раз Маршрутный сокет маркирует сообщения различными ID таблиц Маршрутизация (домены)
  • 37.
    Маршрутные демоны должнысодержать свои таблицы «в чистоте» (синхронизированными) Разные приоритеты на случай конфликтов OSPF более предпочтителен системой чем BGP Синхронизация в userland – это тяжело «ресурсные войны» маршрутный сокет – потери Необходимо лучшее решение Маршрутизация (приоритеты)
  • 38.
    Дополнительная маршрутная преференция– метрика Каждый маршрутный источник имеет свой тип #define RTP_STATIC 8 /* static routes */ #define RTP_OSPF 16 /* OSPF routes */ #define RTP_RIP 24 /* RIP routes */ #define RTP_BGP 32 /* BGP routes */ иные Маршрутизация (приоритеты)
  • 39.
  • 40.
    От теории кпрактике
  • 41.
    Применение sysctl(8) kern.maxclustersуправление mbuf(9) net.inet.ip.ifq.maxlen управление очередью net.inet.ip.maxqueue управление очередью net.inet. { tcp ,udp} . { send ,recv} space размер окна net. { inet ,inet6} . { ip ,ip6} . { forwarding , mforwarding } В большинстве случаев достаточно системного ifconfig(8) + pfctl(8) От теории к практике
  • 42.
  • 43.
    OpenSSH http://www.openssh.com/ OpenBGPDhttp://www.openbgpd.org/ OpenOSPFD http://www.openbgpd.org/ OpenNTPD http://www.openntpd.org/ OpenCVS http://www.opencvs.org/ иные http://www.openbsd.org/ OpenBSD made stuff
  • 44.
    Компании ATMNIShttp://www.atmnis.com/ Друзьям konstantyn @atmnis.com gregor @atmnis.com Отдельно, Claudio Jeker [email_address] Организаторам RootConf – 2009 Большое спасибо
  • 45.