1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors-dpvs

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
tutorial.md 60 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 30.11.2024 06:21 aae3abb

DPVS Tutorial

  • Терминология
    • One-arm и two-arm
    • KNI Device
  • Full-NAT Mode
    • Простой Full-NAT (two-arm)
      • Что-то о LIP, routes и TOA
    • Full-NAT с OSPF/ECMP (two-arm)
    • Full-NAT с Keepalived (one-arm)
  • DR Mode (one-arm)
  • Tunnel Mode(one-arm)
  • NAT Mode(one-arm)
  • SNAT Mode (two-arm)
  • Поддержка IPv6
  • Виртуальные устройства
    • Bonding Device
    • VLAN Device
    • Tunnel Device
    • KNI для виртуального устройства
  • UDP Option of Address (UOA)
  • Запуск DPVS в виртуальной машине (Ubuntu)
  • Traffic Control(TC)
  • Несколько экземпляров
  • Отладка DPVS
    • Отладка с помощью журнала
    • Захват пакетов и Tcpdump

Для компиляции и запуска DPVS, пожалуйста, проверьте README.md для этого проекта.

Терминология

О концепциях Full-NAT (FNAT), DR, Tunnel, TOA, OSPF/ECMP и keepalived, пожалуйста, обратитесь к LVS и Alibaba/LVS.

Обратите внимание, что DPVS поддерживает режимы пересылки FNAT, DR, Tunnel, NAT, SNAT, и каждый режим может быть настроен как топология one-arm или two-arm, с или без OSPF/ECMP/keepalived. Существует слишком много комбинаций, я не могу перечислить все примеры здесь. Давайте просто приведём несколько популярных рабочих моделей, используемых в нашей повседневной работе.

One-arm и two-arm

Термин two-arm означает, что у вас есть клиенты на одной стороне балансировщика нагрузки (LB) и серверы (RS) на другой стороне, затем LB пересылает пакеты между двумя своими логическими сетевыми интерфейсами. Например, балансировка нагрузки WAN-to-LAN.

С другой стороны, one-arm означает, что все клиенты и серверы находятся на одной стороне от балансировщика нагрузки, LB пересылает трафик через один и тот же логический сетевой интерфейс.

Логический интерфейс (или устройство) может быть физическим интерфейсом DPDK или виртуальными устройствами DPVS, такими как bonding, vlan и tunnel.

Чтобы упростить задачу, мы пока не рассматриваем виртуальные устройства. Таким образом, топологии two-arm требуется:

  • два интерфейса DPDK, загруженных драйвером PMD (например, igb_uio), и
  • /etc/dpvs.conf также должен быть настроен с двумя интерфейсами. Пожалуйста, обратитесь к файлу conf/dpvs.conf.sample.

Для one-arm нужен только один интерфейс DPDK, и вы можете обратиться к conf/dpvs.conf.single-nic.sample.

KNI Device

Как и LVS, DPVS можно развернуть в различных моделях кластеров для обеспечения высокой доступности (HA). Поддерживаются модели OSPF/ECMP и Master/Backup. Для модели OSPF/ECMP требуется пакет quagga и его программы zebra и ospfd. А для модели master/back требуется Keepalived.

Учитывая, что приложение DPDK полностью управляет сетевым интерфейсом (за исключением дополнительного управляющего сетевого адаптера, если он существует), программы Linux, работающие на стеке TCP/IP ядра, не могут напрямую получать пакеты от интерфейса DPDK. Чтобы программы Linux, такие как sshd, zebra/ospfd и keepalived работали, используется устройство DPDK kni. Затем программы Linux могут работать на устройстве kni со стеком TCP/IP Linux. Фактически, DPVS передаёт пакеты, которые ему не интересны, на устройство kni. Например, пакеты OSPF/VRRP/ssh. Так что программы, «работающие» на стеке Linux, могут их обрабатывать.

Следует отметить, что Keepalived — это... LVS

UCloud TOA

Huawei TOA

IPVS CA

Исходный код TOA включён в проект DPVS (в каталоге kmod/toa) начиная с версии 1.7 для поддержки IPv6 и NAT64. Он получен из Alibaba TOA. Для приложений IPv6, которым требуется реальный IP-адрес клиента, рекомендуется использовать эту версию TOA.

Обратите внимание, что приложению могут потребоваться некоторые изменения, если вы используете NAT64. Необходимо вызвать дополнительный getsockopt, чтобы получить реальный IPv6-адрес клиента из сокета IPv4 на RS. В качестве примера приведён патч NAT64 для nginx-1.14 (../kmod/toa/example_nat64/nginx/nginx-1.14.0-nat64-toa.patch). Кстати, если вам не нужен реальный IP-адрес клиента, приложение не требует изменений.

Full-NAT с OSPF/ECMP (двухрукавный)

Для работы с OSPF необходимо применить патч в patch/dpdk-xxx/ к соответствующим исходным кодам DPDK и установить правильный rte_kni.ko.

Модель кластера OSPF DPVS выглядит следующим образом, она использует OSPF / ECMP для обеспечения высокой доступности и масштабируемости. Эта модель широко используется на практике.

Для DPVS всё становится сложнее. Как упоминалось выше, программа DPDK (здесь dpvs) полностью контролирует сетевые адаптеры DPDK, поэтому программе Linux (ospfd) необходимо получать/отправлять пакеты через устройство kni (dpdk1.kni), связанное с устройством DPDK (dpdk1).

Таким образом, внутренняя взаимосвязь между интерфейсами и программами выглядит следующим образом:

Теперь конфигурация состоит из двух частей: одна для dpvs, а другая для zebra/ospfd.

Часть dpvs почти такая же, как в примере простого fnat, за исключением того, что:

  • необходим ещё один адрес/маршрут для связи между dpvs и wan-стороной L3-коммутатора. Для пакетов ospf dpvs будет просто отправлять их в ядро.
  • VIP должен быть установлен не только в dpvs с помощью dpip addr, но также должен быть установлен в kni, чтобы ospfd мог его распознать и затем опубликовать.

Если вы добавляете какой-либо маршрут kni_host, который означает, что все пакеты будут отправляться в ядро с помощью dpvs, префикс длины kni_host должен быть равен 32.

#!/bin/sh -

# routes for LAN access
./dpip route add 192.168.100.0/24 dev dpdk0

# add service <VIP:vport> to forwarding, scheduling mode is RR.
# use ipvsadm --help for more info.
./ipvsadm -A -t 123.1.2.3:80 -s rr

# add two RS-es for service, forwarding mode is FNAT (-b)
./ipvsadm -a -t 123.1.2.3:80 -r 192.168.100.2 -b
./ipvsadm -a -t 123.1.2.3:80 -r 192.168.100.3 -b

# add at Local-IPs (LIPs) for FNAT on LAN interface
./ipvsadm --add-laddr -z 192.168.100.200 -t 123.1.2.3:80 -F dpdk0
./ipvsadm --add-laddr -z 192.168.100.201 -t 123.1.2.3:80 -F dpdk0

# add addr/route for dpvs.
./dpip addr add 123.1.2.3/32 dev dpdk1
./dpip addr add 172.10.0.2/30 dev dpdk1
./dpip route add default via 172.10.0.1 dev dpdk1

Затем часть zebra/ospfd. Во-первых, запустите протокол OSPF между сервером DPVS и wan-стороне L3-коммутатором с «интерконнект-сетью» (здесь 172.10.0.2/30). Для DPVS мы устанавливаем межсетевой IP на dpdk1.kni.

Предполагая, что пакет quagga установлен, если нет, пожалуйста, используйте yum (CentOS) или apt-get (Ubuntu) для его установки. После установки у вас должны быть zebra и ospfd, а также их конфигурационные файлы.

$ ip link set dpdk1.kni up
$ ip addr add 172.10.0.2/30 dev dpdk1.kni
$ ip addr add 123.1.2.3/32 dev dpdk1.kni # add VIP to kni for ospfd
$ ip route add default via 172.10.0.1 dev dpdk1.kni

VIP должен быть добавлен в устройство kni, чтобы позволить ospfd опубликовать его.

Проверьте работу межсетевого соединения с помощью ping коммутатора. 172.10.0.1: icmp_seq=1 ttl=255 time=2,19 ms

Теперь настроим zebra и ospfd. Для zebra ничего особенного, просто используем конфигурацию по умолчанию.

$ cat /etc/quagga/zebra.conf  # может быть установлен в другой путь
! -*- zebra -*-
!
! zebra sample configuration file
!
! Id: zebra.conf.sample,v 1.1 2002/12/13 20:15:30 paul Exp $
!
hostname localhost.localdomain # изменить на реальное имя хоста
password ****
enable password ****

log file /var/log/quagga/zebra.log
service password-encryption

Для ospfd необходимо установить следующие параметры:

  • interface: это WAN-интерфейс dpdk1.kni;
  • route-id: не так важно, просто используйте LAN IP;
  • network: сеть, которую нужно анонсировать:
    • межсетевая сеть 172.10.0.0/30,
    • VIP 123.1.2.3/32;
  • area-ID: должен совпадать с коммутатором, здесь, например, 0.0.0.0;
  • Другие параметры, такие как «p2p», «authentication» и т. д., должны соответствовать настройкам коммутатора.
$ cat /etc/quagga/ospfd.conf       # может быть установлен в другой путь
log file /var/log/quagga/ospf.log
log stdout
log syslog
password ****
enable password ****
interface dpdk1.kni                # должно быть устройство kni на стороне wan
ip ospf hello-interval 10
ip ospf dead-interval 40
router ospf
ospf router-id 192.168.100.200     # просто использовать LAN IP
log-adjacency-changes
auto-cost reference-bandwidth 1000
network 172.10.0.0/30 area 0.0.0.0 # анонсировать межсетевую сеть
network 123.1.2.3/32 area 0.0.0.0  # анонсировать VIP

Учитывая, что маршрут VIP настроен на интерфейсе KNI, альтернативным способом публикации VIP является разрешение ospfd перераспределять подключённые маршруты, которые соответствуют VIP. Таким образом, вам не нужно изменять файл ospfd.conf и перезагружать ospfd каждый раз, когда вы хотите добавить больше VIP-адресов.

$ cat /etc/quagga/ospfd.conf               # может быть установлен в другой путь
log file /var/log/quagga/ospf.log
log stdout
log syslog
password ****
enable password ****

access-list 1 permit 123.1.2.0 0.0.0.255   # access-list 1 разрешает сегмент VIP 123.1.2.0/24
route-map ecmp permit 10                   # route-map «ecmp» соответствует IP-адресу из access-list 1
match ip address 1

interface dpdk1.kni                        # должно быть устройство KNI на стороне WAN
ip ospf hello-interval 10
ip ospf dead-interval 40
router ospf
ospf router-id 192.168.100.200             # просто использовать LAN IP
log-adjacency-changes
auto-cost reference-bandwidth 1000
redistribute connected route-map ecmp      # перераспределить VIP в route-map «ecmp», route-map не обязателен, но рекомендуется

Обратите внимание, что OSPF также должен быть настроен на L3-коммутаторе. Этот учебник не о конфигурации OSPF, поэтому больше ничего о коммутаторе здесь нет.

Теперь запустите zebra и ospfd:

service restart zebra
service restart ospfd

Надеемся (если OSPF работает), что VIP будет доступен клиенту:

client: curl 123.1.2.3

Существуют и другие решения для достижения модели кластера OSPF и тому подобного. Например, OSPF и quagga можно заменить на BGP и bird, соответственно. Если вам интересно, пожалуйста, обратитесь к соответствующим документам или проконсультируйтесь с сетевым администратором.

Full-NAT с Keepalived (one-arm)

Это пример использования FullNAT во внутренней сети (LAN). Keepalived (модифицированная версия DPVS) используется для того, чтобы DPVS работал как модель Master/Backup.

Используя keepalived, маршруты, LIP, VIP и RS можно настроить через конфигурационный файл keepalived. Обратите внимание, что параметры конфигурации для DPVS модифицированного keepalived немного отличаются от оригинального keepalived.

$ cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
    notification_email {
        foo@example.com
    }
    notification_email_from bar@example.com
    smtp_server 1.2.3.4
    smtp_connect_timeout 60
    router_id DPVS_DEVEL
}

local_address_group laddr_g1 {
    192.168.100.200 dpdk0    # использовать интерфейс DPDK
    192.168.100.201 dpdk0    # использовать DPDK ```
interface
}

#
# VRRP section
#
vrrp_instance VI_1 {
    state MASTER                  # master
    interface dpdk0.kni           # должен быть интерфейс kni
    dpdk_interface dpdk0          # должен быть DPDK интерфейс
    virtual_router_id 123         # VID должен быть уникальным в сети
    priority 100                  # приоритет мастера больше, чем у рабочего
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass ****
    }

    virtual_ipaddress {
        192.168.100.254
    }
}

#
# Virtual Server Section
#
virtual_server_group 192.168.100.254-80 {
    192.168.100.254 80
}

virtual_server group 192.168.100.254-80 {
    delay_loop 3
    lb_algo rr         # алгоритм планирования Round-Robin
    lb_kind FNAT       # режим пересылки Full-NAT
    protocol TCP       # протокол TCP

    laddr_group_name laddr_g1   # имя группы локальных IP-адресов

    real_server 192.168.100.2 80 { # реальный сервер
        weight 100
        inhibit_on_failure
        TCP_CHECK {    # проверка работоспособности
            nb_sock_retry 2
            connect_timeout 3
            connect_port 80
        }
    }

    real_server 192.168.100.3 80 { # реальный сервер
        weight 100
        inhibit_on_failure
        TCP_CHECK { # проверка работоспособности
            nb_sock_retry 2
            connect_timeout 3
            connect_port 80
        }
    }
}

Конфигурация keepalived для резервного копирования такая же, как и для основного сервера, за исключением:

  • локальный адрес не совпадает с основным сервером;
  • состояние vrrp_instance должно быть «BACKUP»;
  • приоритет vrrp_instance должен быть ниже.
local_address_group laddr_g1 {
    192.168.100.202 dpdk0    # использовать интерфейс DPDK
    192.168.100.203 dpdk0    # использовать интерфейс DPDK
}

... ...

vrrp_instance VI_1 {
    состояние BACKUP
    приоритет 80
    ... ...
}

Запустите keepalived на основном сервере и резервном сервере.

./keepalived -f /etc/keepalived/keepalived.conf

Затем добавьте маршруты к интерфейсу DPDK вручную на основном и резервном серверах.

./dpip route add 192.168.100.0/24 dev dpdk0

Наконец, настройте dpdk0.kni, чтобы keepalived работал правильно.

ip link set dpdk0.kni up
ip addr add 192.168.100.28/24 dev dpdk0.kni               # назначить IP для dpdk0.kni
dpip route add 192.168.100.28/32 scope kni_host dev dpdk0 # направить пакеты, предназначенные для 192.168.100.28, на dpdk0.kni

Обратите внимание, что IP-адреса dpdk0.kni должны отличаться для основного и резервного серверов.

Проверьте правильность установленных параметров:

$ ./ipvsadm  -ln
IP Virtual Server version 0.0.0 (size=0)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.100.254:80 rr
  -> 192.168.100.2:80             FullNat 100    0          0
  -> 192.168.100.3:80             FullNat 100    0          0

$ ./dpip addr show -s
inet 192.168.100.254/32 scope global dpdk0
     valid_lft forever preferred_lft forever
inet 192.168.100.201/32 scope global dpdk0
     valid_lft forever preferred_lft forever sa_used 0 sa_free 1032176 sa_miss 0
inet 192.168.100.200/32 scope global dpdk0
     valid_lft forever preferred_lft forever sa_used 0 sa_free 1032176 sa_miss 0

$ ./dpip route show
inet 192.168.100.28/32 via 0.0.0.0 src 0.0.0.0 dev dpdk0 mtu 1500 tos 0 scope kni_host metric 0 proto auto
inet 192.168.100.200/32 via 0.0.0.0 src 0.0.0.0 dev dpdk0 mtu 1500 tos 0 scope host metric 0 proto auto
inet 192.168.100.201/32 via 0.0.0.0 src 0.0.0.0 dev dpdk0 mtu 1500 tos 0 scope host metric 0 proto auto
inet 192.168.100.254/32 via 0.0.0.0 src 0.0.0.0 dev dpdk0 mtu 1500 tos 0 scope host metric 0 proto auto
inet 192.168.100.0/24 via 0.0.0.0 src 0.0.0.0 dev dpdk0 mtu 1500 tos 0 scope link metric 0 proto auto

$ ./ipvsadm  -G
VIP:VPORT            TOTAL    SNAT_IP              CONFLICTS  CONNS
192.168.100.254:80   2
                              192.168.100.200      0          0
                              192.168.100.201      0          0

Кажется, всё хорошо, затем попробуйте получить доступ к VIP от клиента.

client$ curl 192.168.100.254
Your ip:port : 192.168.100.146:42394
``` **Перевод текста на русский язык:**

Keepalived, и не проверять, работает ли функция master/backup, предоставляемая Keepalived. При необходимости обратитесь к документации LVS.
> 2. Отказоустойчивость master/backup Keepalived может не сработать, если коммутатор включил подавление широковещательной рассылки ARP (к сожалению, это часто бывает). Если вы не хотите изменять конфигурацию своего коммутатора, уменьшение количества бесплатных пакетов ARP, отправляемых Keepalived (dpvs) при переключении, может помочь.

global_defs { ... ... vrrp_garp_master_repeat 1 # количество повторов для основного состояния gratuitous arp vrrp_garp_master_delay 1 # время перезапуска gratuitous arp после переключения на основной режим, в секундах vrrp_garp_master_refresh 600 # интервал времени для периодического обновления gratuitous arp (0 = нет), в секундах vrrp_garp_master_refresh_repeat 1 # количество повторений для периодического обновления gratuitous arp ... ... }


<a id='dr'/>

# DR-режим (одноплечевой)

Давайте рассмотрим простой пример DR-режима, который может понадобиться некоторым пользователям.

![dr-one-arm](./pics/dr-one-arm.png)

Чтобы использовать DR:

* dpvs сначала нужен IP-адрес локальной сети. (для одноплечевого режима он должен отличаться от VIP).
* RS и DPVS должны находиться в одной подсети (*on-link*).
* На RS: VIP должен быть добавлен к его интерфейсу lo.
* На RS: arp_ignore должен быть установлен для интерфейса lo.

> DPVS требуется IP-адрес, обращённый к RS (здесь означает «IP-адрес со стороны LAN», это не та концепция, что Local-IP (LIP), используемый FNAT, просто обычный IP-адрес). Потому что DPVS необходимо взаимодействовать с RS. Для одноплечевого режима этот IP-адрес LAN и VIP находятся на одном и том же интерфейсе DPDK. Но они не могут быть одинаковыми, потому что VIP также будет установлен на RS, если мы не используем отдельный IP-адрес LAN, RS не ответит на запрос ARP. Кроме того, IP-адрес LAN DPVS должен быть добавлен **перед** VIP.
> Для двухплечевого DR DPVS также требуется IP-адрес со стороны локальной сети для взаимодействия с хостами со стороны локальной сети, а VIP настроен на клиентском интерфейсе (WAN).

На DPVS конфигурация DR может быть следующей:

```bash
# на DPVS

# добавить IP-адрес для DPVS, он должен отличаться от VIP
# и должен быть добавлен перед VIP.
./dpip addr add 192.168.100.1/24 dev dpdk0
# добавить VIP, и маршрут будет создан автоматически.
./dpip addr add 192.168.100.254/32 dev dpdk0

# маршрут для сети LAN, просто подсказка.
#./dpip route add 192.168.100.0/24 dev dpdk0

# добавьте сервис <VIP:vport> для пересылки, режим планирования — RR.
# используйте ipvsadm --help для получения дополнительной информации.
./ipvsadm -A -t 192.168.100.254:80 -s rr

# добавьте два RS для сервиса, режим пересылки — DR
./ipvsadm -a -t 192.168.100.254:80 -r 192.168.100.2 -g
./ipvsadm -a -t 192.168.100.254:80 -r 192.168.100.3 -g

А затем на RS:

# для каждого реального сервера
rs$ ip addr add 192.168.100.254/32 dev lo    # добавить VIP к каждому RS's lo
rs$ sysctl -w net.ipv4.conf.lo.arp_ignore=1  # игнорировать ARP на lo
net.ipv4.conf.lo.arp_ignore = 1

Попробуйте, сможет ли клиент получить доступ к VIP в режиме DR.

client$ curl 192.168.100.254
Your ip:port : 192.168.100.46:13862

Режим DR для двухплечевого аналогичен двухплечевому FNAT, пожалуйста, измените режим пересылки с помощью ipvsadm -g, и вам НЕ нужно настраивать LIP. Конфигурация RS такая же, как и для одноплечевого.

Туннельный режим (одноплечевой)

Поток трафика туннельного режима такой же, как у DR-режима. Он перенаправляет пакеты на RS, а затем RS отправляет ответы клиентам напрямую. В отличие от DR-режима, туннельный режим может пересылать пакеты через сеть L2 через ipip-туннели между DPVS и RS.

tunnel-one-arm

Конфигурации DPVS на приведённой выше диаграмме следующие.

## Конфигурации DPVS ##
# настроить сеть LAN на dpdk0
./dpip addr add 10.140.16.48/20 dev dpdk0
# настроить маршрут по умолчанию, `src` должен быть установлен для туннельного режима
./dpip route add default via 10.140.31.254 src 10.140.16.48 dev dpdk0
# добавить сервис <VIP:vport> для переадресации, режим планирования — RR
./ipvsadm -A -t 10.140.31.48:80 -s rr
# добавить RS в той же подсети, что и DPVS, режим переадресации — туннельный
./ipvsadm -a -t 10.140.31.48:80 -r 10.140.18.33 -i
# добавить ещё один RS в другой подсети с DPVS, режим переадресации — туннельный
./ipvsadm -a -t 10.140.31.48:80 -r 10.40.84.170 -i
# добавить VIP и маршрут будет сгенерирован автоматически

**Примечание**: в тексте запроса присутствуют фрагменты кода на языке программирования Bash, которые были оставлены без перевода. **Текст запроса написан на языке программирования bash.**

uses "match" service instead of *<vip:vport>* for TCP/UDP,
* default route may be needed on DPVS WAN interface.

> `match` supports `proto`, `src-range`, `dst-range`, `oif` and `iif`. For example: `proto=tcp,src-range=192.168.0.0-192.168.0.254,dst-range=0.0.0.0:1-1024,oif=dpdk1`.

The SNAT setting could be:
```bash
#!/bin/sh -

WAN_IP=123.1.2.3        # WAN IP can access Internet.
WAN_PREF=24             # WAN side network prefix length.
GATEWAY=123.1.2.1       # WAN side gateway

LAN_IP=192.168.100.1
LAN_PREF=24

# add WAN-side IP with sapool
./dpip addr add $WAN_IP/$WAN_PREF dev dpdk1 sapool # must add sapool for WAN-side IP
# add LAN-side IP as well as LAN route (generated)
./dpip addr add $LAN_IP/$LAN_PREF dev dpdk0

# add default route for WAN interface
./dpip route add default via $GATEWAY dev dpdk1

# SNAT section
# -H MATCH       SNAT uses -H for "match" service instead of -t or -u
#                MATCH support "proto", "src-range", "oif" and "iif".
# -r <WIP:0>     used to specify the WAN IP after SNAT translation,
#                the "port" part must be 0.
# -J             for "SNAT" forwarding mode.
MATCH0='proto=tcp,src-range=192.168.100.0-192.168.100.254,oif=dpdk1'
MATCH1='proto=icmp,src-range=192.168.100.0-192.168.100.254,oif=dpdk1'

./ipvsadm -A -s rr -H $MATCH0
./ipvsadm -a -H $MATCH0 -r $WAN_IP:0 -w 100 -J

./ipvsadm -A -s rr -H $MATCH1
./ipvsadm -a -H $MATCH1 -r $WAN_IP:0 -w 100 -J

You can also use keepalived to configure SNAT instead of using ipvsadm. Every SNAT serivce should has parameter 'match':

virtual_server match SNAT1 {
    protocol UDP
    lb_algo rr
    lb_kind SNAT
    src-range 192.168.100.0-192.168.100.254
    oif dpdk1

    real_server 123.1.2.1  0 {
        weight 4
    }
}

virtual_server match SNAT2 {
    protocol ICMP
    lb_algo wrr
    lb_kind SNAT
    src-range 192.168.100.1-192.168.100.254
    dst-range 123.1.2.0-123.1.2.254
    oif dpdk1
    iif dpdk0

    real_server 123.1.2.1  0 {
        weight 4
    }
}

If you also want to use keepalived instead of using dpip to configure WAN/LAN IP, you can using 'alpha' and 'omega' to configure keepalived. Healthy check is needed in alpha mode, so you have to make a healthy check. And the result of the healthy check must always be true or RS(LAN IP in fact) will be deleted. You can use MISC_CHECK to make real_server/WAN IP always be healthy:

virtual_server match SNAT {
    protocol UDP
    delay_loop 3
    lb_algo rr
    lb_kind SNAT
    src-range 192.168.100.0-192.168.100.254
    oif dpdk1
    alpha
    omega
    quorum 1
    quorum_up "dpip addr add XXX;" ##Here is your cmd, you can also use a script.
    quorum_down "dpip addr del XXX;"

    real_server 123.1.2.2 0 {
        weight 4
        MISC_CHECK {
           misc_path "exit 0"##Just make a healthy check which will always judge real_server healthy
           misc_timeout 10
        }
    }
}

For hosts in "LAN", the default route should be set to DPVS server's LAN IP.

host$ ip route add default via 192.168.100.1 dev eth0

Then try Internet access from hosts through SNAT DPVS server.

host$ ping www.iqiyi.com
host$ curl www.iqiyi.com

IPv6 Support

DPVS support IPv6-IPv6 since v1.7 which means VIP/client IP/local IP/rs IP can be IPv6. You can configure IPv6 fullnat just like IPv4:

#!/bin/sh -

# add VIP to WAN interface
./dpip addr add 2001::1/128 dev dpdk1

# route for WAN/LAN access
# add routes for other network or default route if needed.
./dpip route -6 add 2001::/64 dev dpdk1

# add service <VIP:vport> to forwarding, scheduling mode is RR.
# use ipvsadm --help for more info.
./ipvsadm -A -t [2001::1]:80 -s rr

# add two RS for service, forwarding mode is FNAT (-b)
./ipvsadm -a -t [2001::1]:80 -r 2001::3 -b
./ipvsadm -a -t [2001::1]:80 -r 2001::4 -b

# add at least one Local-IP (LIP) for FNAT on LAN interface
./ipvsadm --add-laddr -z 2001::2 -t [2001::1]:80 -F dpdk0

You can use commands to check what's you have set like IPv4 except route:

$./dpip route -6 show
inet6 **Конфигурация IPv6 OSPF:**

```bash
$ cat /etc/quagga/ospf6d.conf   # может быть установлен в другой путь
log file /var/log/quagga/ospf6.log
log stdout
log syslog
password ****
enable password ****
interface dpdk1.kni
ipv6 ospf6 network point-to-point
ipv6 ospf6 hello-interval 10
ipv6 ospf6 dead-interval 40
!
router ospf6
router-id 192.168.100.200
area 0.0.0.0 range 2001::1/64 # объявить VIP
area 0.0.0.0 range fec0::172:10:10:11/127 # объявить сеть межсоединения
interface dpdk1.kni area 0.0.0.0
!

Если вы предпочитаете keepalived, вы можете настроить его следующим образом:

$ cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
    notification_email {
        foo@example.com
    }
    notification_email_from bar@example.com
    smtp_server 1.2.3.4
    smtp_connect_timeout 60
    router_id DPVS_DEVEL
}

local_address_group laddr_g1 {
    2001::2 dpdk0    # использовать интерфейс DPDK
}

#
# VRRP раздел
#
vrrp_instance VI_1 {
    state MASTER                  # мастер
    interface dpdk0.kni           # должен быть интерфейс kni, и IPv4 должен быть настроен для vrrp
    dpdk_interface dpdk0          # должен быть интерфейс DPDK
    virtual_router_id 123         # VID должен быть уникальным в сети
    priority 100                  # приоритет мастера больше, чем у рабочего
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass ****
    }

    virtual_ipaddress {
        2001::1
    }
}

#
# Раздел виртуального сервера
#
virtual_server_group 2001-1-80 {
    2001::1 80
}

virtual_server group 2001-1-80 {
    delay_loop 3
    lb_algo rr         # алгоритм планирования Round-Robin
    lb_kind FNAT       # режим переадресации Full-NAT
    protocol TCP       # протокол TCP

    laddr_group_name laddr_g1   # Идентификатор группы локальных IP-адресов

    real_server 2001::3 80 { # реальный сервер
        weight 100
        inhibit_on_failure
        TCP_CHECK {    # проверка работоспособности
            nb_sock_retry 2
            connect_timeout 3
            connect_port 80
        }
    }

    real_server 2001::4 80 { # реальный сервер
        weight 100
        inhibit_on_failure
        TCP_CHECK { # проверка работоспособности
            nb_sock_retry 2
            connect_timeout 3
            connect_port 80
        }
    }
}

DPVS поддерживает IPv6-IPv4 для fullnat, что означает, что VIP/клиентский IP может быть IPv6, а локальный IP/RS IP может быть IPv4, вы можете настроить это следующим образом:

#!/bin/sh -
# добавить VIP на WAN-интерфейс
./dpip addr add 2001::1/128 dev dpdk1

# маршрут для доступа WAN/LAN
# добавьте маршруты для других сетей или по умолчанию, если необходимо.
./dpip route -6 add 2001::/64 dev dpdk1
./dpip route add 10.0.0.0/8 dev dpdk0

# добавить сервис <VIP:vport> в переадресацию, режим планирования — RR.
# используйте ipvsadm --help для получения дополнительной информации.
./ipvsadm -A -t [2001::1]:80 -s rr

# добавить два RS для сервиса, режим переадресации — FNAT (-b)
./ipvsadm -a -t [2001::1]:80 -r 10.0.0.1 -b
./ipvsadm -a -t [2001::1]:80 -r 10.0.0.2 -b

# добавить хотя бы один Local-IP (LIP) для FNAT на LAN-интерфейсе
./ipvsadm --add-laddr -z 10.0.0.3 -t [2001::1]:80 -F dpdk0

OSPF можно настроить так же, как IPv6-IPv6. Если вы предпочитаете keepalived, то можете настроить его так же, как и IPv6-IPv6, за исключением real_server/local_address_group.

IPv6 и управление потоком

Мы обнаружили, что некоторые сетевые карты не поддерживают (полностью) управление потоком IPv6, требуемое IPv6. Например, rte_flow контроллера 82599 10GE (ixgbe PMD) опирается на старый тип потока flow director (fdir), который не поддерживает IPv6 в своём идеальном режиме и поддерживает только один локальный IPv4 или IPv6 в сигнатурном режиме. DPVS поддерживает конфигурацию режима fdir для совместимости.

netif_defs {
    ...
    mode                signature
}

Другой способ избежать проблемы с не полностью поддерживаемым rte_flow — использовать перенаправление пересылки, которое перенаправляет полученные пакеты на правильный рабочий lcore, где находится сессия, с помощью незаблокированных колец DPDK. Если вы хотите попробовать этот метод, включите: Перенаправление (redirect) в файле dpvs.conf:

ipvs_defs {
    conn {
        ...
        redirect    on
    }
    ...
}

Следует отметить, что перенаправление может в определённой степени снизить производительность. Не используйте его, если у вас нет других решений.

Сохраняйте состояние «off», если только у вас нет иных решений.

Виртуальные устройства

DPVS поддерживает виртуальные устройства, такие как Bonding, VLAN, IP-in-IP и GRE туннель.

Устройство Bonding

Для устройства Bonding и DPVS, и подключённый коммутатор/маршрутизатор должны установить интерфейсы Bonding с одинаковым режимом Bonding. Обратите внимание, что DPVS пока поддерживает режимы Bonding 0 и 4. Чтобы включить устройство Bonding на DPVS, обратитесь к conf/dpvs.bond.conf.sample. Каждому устройству Bonding требуется один или несколько DPDK физических устройств (dpdk0, ...) для работы в качестве ведомых.

VLAN-устройство

Чтобы использовать устройство VLAN, вы можете использовать инструмент dpip. Устройство VLAN можно создать на основе реального физического устройства DPDK (например, dpdk0, dpdk1) или устройства Bonding (например, bond0). Но нельзя создать устройство VLAN на устройстве VLAN.

Это пример VLAN, проверьте dpip vlan help для получения дополнительной информации.

$ dpip vlan add dpdk0.100 link dpdk0 proto 802.1q id 100
$ dpip vann add link dpdk0 proto 802.1q id 101            # автогенерация имени устройства
$ dpip vlan add link dpdk1 id 102
$ dpip vlan add link bond1 id 103

Туннельное устройство

DPVS поддерживает туннельные устройства, включая IP-in-IP и GRE туннели. Это можно использовать, например, для кластера «SNAT-GRE», где удалённые хосты используют туннель для доступа в Интернет через SNAT-кластер DPVS.

Настройка туннельного устройства аналогична тому, что мы делаем в Linux, но используем dpip вместо ip(8).

$ dpip tunnel add mode ipip ipip1 local 1.1.1.1 remote 2.2.2.2
$ dpip tunnel add gre1 mode gre local 1.1.1.1 remote 2.2.2.2 dev dpdk0

Вы также можете использовать keepalived для настройки туннеля вместо использования ipvsadm.

tunnel_group tunnel_gre {
    tunnel_entry gre100 {
        kind gre
        local 10.62.5.10
        remote 10.62.5.20
    }
    tunnel_entry gre200 {
        kind gre
        local 10.62.5.10
        remote 10.62.6.10
   }
   tunnel_entry gre300 {
        kind gre
        local 10.62.5.10
        remote 10.62.6.11
   }
}

Также проверьте dpip tunnel help для подробностей.

Примечания:

  1. RSS распределяет все пакеты по одной очереди/ЦП, поскольку исходный IP-адрес подслоя может быть одинаковым. Если одно ядро lcore получает полный sa_pool, происходит sa_miss. Это не проблема для некоторых сетевых карт, которые поддерживают внутренний RSS для туннелирования. 2. rte_flow/rss не будут хорошо работать на туннельном устройстве, не используйте туннель для FNAT.

KNI для Bonding/VLAN

Как и физические устройства DPDK, виртуальные устройства Bonding и VLAN (например, bond0 и dpdk0.100) имеют свои собственные связанные устройства KNI в среде Linux (например, bond0.kni, dpdk0.100.kni).

Пример взаимосвязи между физическими устройствами, устройствами vlan, bonding и устройствами KNI.

bond-vlan-kni

Настроить DPVS (FNAT/DR/Tunnel/SNAT, one-arm/two-arm, keepalived/ospfd) для виртуального устройства не составляет труда. Просто «замените» логические интерфейсы в разделах выше (например, dpdk0, dpdk1, dpdk1.kni) соответствующими виртуальными устройствами.

UDP Option of Address (UOA)

Как известно, TOA используется для получения реального клиентского IP/порта TCP в режиме LVS FNAT. Мы представляем UDP Option of Address или UOA, чтобы позволить RS получать реальный клиентский IP/порт для сценария, когда исходный IP/порт изменены промежуточными устройствами (такими как UDP FNAT).

Для этого необходимо:

  1. Установить модуль ядра uoa.ko на RS.
  2. Программе на RS нужен всего лишь вызов getsockopt(2), чтобы получить реальный клиентский IP/порт.

Пример кода C для RS, чтобы получить реальный IP клиента, можно найти здесь.

rs$ insmod uoa.ko
rs$ cat /proc/net/uoa_stats
 Success     Miss  Invalid|UOA  Got     None    Saved Ack-Fail
12866352 317136864        0  3637127 341266254  3628560        0

Статистика поддерживается для целей отладки. Обратите внимание на то, что... PID-файл, конфигурационный файл и файл сокета IPC, которые задаются следующими опциями DPVS соответственно:

  • -p, --pid-file FILE;
  • -c, --conf FILE;
  • -x, --ipc-file FILE.

Например:

./bin/dpvs -c /etc/dpvs1.conf -p /var/run/dpvs1.pid -x /var/run/dpvs1.ipc -- --file-prefix=dpvs1 -a 0000:4b:00.0 -a 0000:4b:00.1 -l 0-8 --main-lcore 0

Изоляция процесса Keepalived

Один экземпляр DPVS соответствует одному экземпляру keepalived, и наоборот. Аналогично, разные процессы keepalived должны иметь уникальные конфигурационные файлы и PID-файлы. Обратите внимание, что в зависимости от конфигурации keepalived для DPVS может состоять из трёх процессов-демонов: основного процесса, подпроцесса проверки работоспособности и подпроцесса VRRP. Конфигурационные файлы и файлы PID для разных экземпляров keepalived можно задать с помощью следующих опций соответственно:

  • -f, --use-file=FILE;
  • -p, --pid=FILE;
  • -c, --checkers_pid=FILE;
  • -r, --vrrp_pid=FILE.

Например:

./bin/keepalived -D -f etc/keepalived/keepalived1.conf --pid=/var/run/keepalived1.pid --vrrp_pid=/var/run/vrrp1.pid --checkers_pid=/var/run/checkers1.pid

Взаимодействие с различными экземплярами DPVS с помощью dpip/ipvsadm

Dpip и ipvsadm — это инструменты, используемые для настройки DPVS. По умолчанию они хорошо работают на сервере с одним экземпляром DPVS без каких-либо дополнительных настроек. Но на сервере с несколькими экземплярами DPVS следует предварительно установить переменную среды DPVS_IPC_FILE как файл сокетов IPC DPVS, с которым хотят взаимодействовать ipvsadm/dpip. Обратитесь к предыдущей части «Изоляция процессов DPVS» для получения информации о том, как указать различные файлы сокетов IPC для нескольких экземпляров DPVS. Например:

DPVS_IPC_FILE=/var/run/dpvs1.ipc ipvsadm -ln
# или эквивалентно:
export DPVS_IPC_FILE=/var/run/dpvs1.ipc
ipvsadm -ln

Порты NIC, KNI и маршруты

Несколько экземпляров DPVS, работающих на сервере, независимы, то есть DPVS использует модель развёртывания Running Multiple Independent DPDK Applications, которая требует, чтобы экземпляры не могли совместно использовать порты NIC. Мы можем использовать опции EAL -a, --allow или -b, --block, чтобы разрешить/запретить использование портов NIC для экземпляра DPVS. Однако модуль ядра Linux KNI поддерживает только один экземпляр DPVS в конкретном сетевом пространстве имён (см. kernel/linux/kni/kni_misc.c). В основном DPVS предлагает два решения этой проблемы.

  • Решение 1: Отключить KNI на всех других экземплярах DPVS, кроме первого. С этого момента в DPVS добавлен глобальный элемент конфигурации kni.
# dpvs.conf
global_defs {
    ...
    <init> kni                  on                  <default on, on|off>
    ...
}
  • Решение 2: Запустить экземпляры DPVS в разных сетевых пространствах имён. Это также устраняет конфликты маршрутов для нескольких портов KNI в сети разных экземпляров DPVS. Ниже показана типичная процедура запуска экземпляра DPVS в сетевом пространстве имён.

Сначала создайте новое сетевое пространство имён, например, «dpvsns».

/usr/sbin/ip netns add dpvsns

Затем переместите порты NIC для этого экземпляра DPVS в только что созданное сетевое пространство имён.

/usr/sbin/ip link set eth1 netns dpvsns
/usr/sbin/ip link set eth2 netns dpvsns
/usr/sbin/ip link set eth3 netns dpvsns

Наконец, запустите DPVS и все связанные с ним процессы (например, keepalived, маршрутизирующий демон) в сетевом пространстве имён.

/usr/sbin/ip netns exec dpvsns ./bin/dpvs -c /etc/dpvs2.conf -p /var/run/dpvs2.pid -x /var/run/dpvs2.ipc -- --file-prefix=dpvs2 -a 0000:cb:00.1 -a 0000:ca:00.0 -a 0000:ca:00.1 -l 12-20 --main-lcore 12
/usr/sbin/ip netns exec dpvsns ./bin/keepalived -D --pid=/var/run/keepalived2.pid --vrrp_pid=/var/run/vrrp2.pid --checkers_pid=/var/run/checkers2.pid -f etc/keepalived/keepalived2.conf
/usr/sbin/ip netns exec dpvsns /usr/sbin/bird -f -c /etc/bird2.conf -s /var/run/bird2/bird.ctl
...

Для повышения производительности мы можем включить режим нескольких kthread при развёртывании нескольких экземпляров DPVS на сервере. В этом режиме каждый порт KNI является... Отладка DPVS

Если DPVS работает не так, как ожидается, рассмотрите следующие решения для отладки, перечисленные в порядке от простого к сложному.

  • Включите больше логов.
  • Проведите анализ захвата пакетов.
  • Используйте отладку исходного кода с помощью gdb или подобного инструмента.

Мы не будем подробно рассматривать отладку на основе исходного кода, поскольку она ничем не отличается от отладки других пользовательских программ. Просто включите флаг DEBUG, определённый в src/Makefile, перекомпилируйте DPVS и пошагово отлаживайте его с помощью gdb. Это самое базовое и эффективное решение для отладки, хотя оно требует некоторых знаний об исходном коде DPVS и навыков отладки.

Отладка с использованием логов

Во-первых, по умолчанию DPVS запускается с уровнем журнала WARNING. Вы можете изменить его в /etc/dpvs.conf и перезагрузить DPVS с помощью команды kill -SIGHUP. DPVS поддерживает 8 уровней журналов:

  • EMERG
  • ALERT
  • CRIT
  • ERR
  • WARNING
  • NOTICE
  • INFO
  • DEBUG

Использование более низких уровней журнала, таких как «INFO» или «DEBUG», может помочь найти больше информации о вашей проблеме.

Во-вторых, некоторые модули поддерживают более подробную отладочную информацию, которую можно включить при компиляции DPVS. Модульные параметры отладки доступны в config.mk, некоторые из них перечислены ниже. Измените значение на «y» и перекомпилируйте DPVS, если вы хотите отладить модуль.

- CONFIG_DPVS_IPVS_DEBUG    # для отладки переадресации ipvs
- CONFIG_RECORD_BIG_LOOP    # для настройки производительности
- CONFIG_TIMER_MEASURE      # для отладки точности таймера
- CONFIG_TIMER_DEBUG        # для отладки таймеров dpvs
- CONFIG_MSG_DEBUG          # для отладки lcore msg и ipc dpvs
- CONFIG_DPVS_MBUF_DEBUG    # для отладки mbuf
- CONFIG_DPVS_NEIGH_DEBUG   # для отладки модуля соседа
- CONFIG_NDISC_DEBUG        # для отладки модуля ndisc
- CONFIG_DPVS_SAPOOL_DEBUG  # для отладки модуля sapool
- CONFIG_SYNPROXY_DEBUG     # для отладки syn-proxy
- CONFIG_DPVS_MP_DEBUG      # для отладки пула памяти
- ... ...

Обратите внимание, что логи могут сильно влиять на производительность. Рекомендуется отключить журналы отладки в производственных средах.

Захват пакетов и Tcpdump

Поскольку DPVS управляется драйвером PMD DPDK и обходит ядро, традиционные инструменты захвата пакетов, такие как tcpdump и wireshark, не могут работать напрямую с DPVS. DPVS поддерживает два механизма захвата пакетов: forward-to-kni и dpdk-pdump.

Обратите внимание: оба механизма захвата пакетов сильно влияют на производительность. Не включайте их в рабочих средах!

Для объяснения этих двух механизмов мы используем следующий тестовый пример.

# cat pkt-cap.sh 
#!/bin/bash

./bin/dpvs &
sleep 40                                                          # wait for DPVS up

./bin/dpip addr add 192.168.88.12/24 dev dpdk0                    # Host IP address
./bin/dpip addr add 192.168.88.100/32 dev dpdk0                   # VIP

./bin/ipvsadm -A -t 192.168.88.100:80 -s mh
./bin/ipvsadm -a -t 192.168.88.100:80 -r 192.168.88.15:80 -b      # FNAT mode
./bin/ipvsadm -Pt 192.168.88.100:80 -z 192.168.88.241 -F dpdk0    # Local IP address

После успешного выполнения скрипта проверьте конфигурации.

$ ./bin/dpip addr show -s
inet 192.168.88.12/24 scope global dpdk0
     valid_lft forever preferred_lft forever
inet 192.168.88.100/32 scope global dpdk0
     valid_lft forever preferred_lft forever
inet 192.168.88.241/32 scope global dpdk0
     valid_lft forever preferred_lft forever sa_used 0 sa_free 1032176 sa_miss 0
$ ./bin/dpip route show
inet 192.168.88.12/32 via 0.0.0.0 src 0.0.0.0 dev dpdk0 mtu 1500 tos 0 scope host metric 0 proto auto 
inet 192.168.88.100/32 via 0.0.0.0 src 0.0.0.0 dev dpdk0 mtu 1500 tos 0 scope host metric 0 proto auto 
inet 192.168.88.241/32 via 0.0.0.0 src 0.0.0.0 dev dpdk0 mtu 1500 tos 0 scope host metric 0 proto auto 
inet 192.168.88.0/24 via 0.0.0.0 src 192.168.88.12 dev dpdk0 mtu 1500 tos 0 scope link metric 0 proto auto 
$ ./bin/ipvsadm -ln
IP Virtual Server version 0.0.0 (size=0)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port
``` Наконец, мы можем проверить файлы pcap с захваченными пакетами с помощью `tcpdump` или `wireshark`.

```bash
$ tcpdump -nn -r /tmp/icmp.pcap 
чтение из файла /tmp/icmp.pcap, тип ссылки EN10MB (Ethernet)
18:21:01.327633 IP 192.168.88.15 > 192.168.88.12: ICMP эхо-запрос, идентификатор 35422, последовательность 1, длина 64
18:21:01.327679 IP 192.168.88.12 > 192.168.88.15: ICMP эхо-ответ, идентификатор 35422, последовательность 1, длина 64
$ tcpdump -nn -r /tmp/tcp.pcap 
чтение из файла /tmp/tcp.pcap, тип ссылки EN10MB (Ethernet)
18:21:22.572153 IP 192.168.88.15.53186 > 192.168.88.100.80: флаги [S], последовательность 889492797, окно 29200, опции [mss 1460,nop,nop,sackOK,nop,wscale 9], длина 0
18:21:22.572203 IP 192.168.88.241.1028 > 192.168.88.15.80: флаги [S], последовательность 3216285976, окно 29200, опции [exp-cfc2,mss 1460,nop,nop,sackOK,nop,wscale 9], длина 0
18:21:22.572243 IP 192.168.88.15.80 > 192.168.88.241.1028: флаги [S.], последовательность 1294831393, подтверждение 3216285977, окно 29200, опции [mss 1460,nop,nop,sackOK,nop,wscale 9], длина 0
18:21:22.572248 IP 192.168.88.100.80 > 192.168.88.15.53186: флаги [S.], последовательность 1294831393, подтверждение 889492798, окно 29200, опции [mss 1452,nop,nop,sackOK,nop,wscale 9], длина 0
18:21:22.572286 IP 192.168.88.15.53186 > 192.168.88.100.80: флаги [.], подтверждение 1, окно 58, длина 0
18:21:22.572288 IP 192.168.88.241.1028 > 192.168.88.15.80: флаги [.], подтверждение 1, окно 58, опции [exp-cfc2], длина 0
18:21:22.572339 IP 192.168.88.15.53186 > 192.168.88.100.80: флаги [P.], последовательность 1:79, подтверждение 1, окно 58, длина 78
18:21:22.572340 IP 192.168.88.241.1028 > 192.168.88.15.80: флаги [P.], последовательность 1:79, подтверждение 1, окно 58, опции [exp-cfc2], длина 78
18:21:22.572384 IP 192.168.88.15.80 > 192.168.88.241.1028: флаги [.], подтверждение 79, окно 58, длина 0
18:21:22.572385 IP 192.168.88.100.80 > 192.168.88.15.53186: флаги [.], подтверждение 79, окно 58, длина 0
18:21:22.572452 IP 192.168.88.15.80 > 192.168.88.241.1028: флаги [P.], последовательность 1:273, подтверждение 79, окно 58, длина 272
18:21:22.572454 IP 192.168.88.100.80 > 192.168.88.15.53186: флаги [P.], последовательность 1:273, подтверждение 79, окно 58, длина 272
18:21:22.572481 IP 192.168.88.15.53186 > 192.168.88.100.80: флаги [.], подтверждение 273, окно 60, длина 0
18:21:22.572482 IP 192.168.88.241.1028 > 192.168.88.15.80: флаги [.], подтверждение 273, окно 60, длина 0
18:21:22.572556 IP 192.168.88.15.53186 > 192.168.88.100.80: флаги [F.], последовательность 79, подтверждение 273, окно 60, длина 0
18:21:22.572557 IP 192.168.88.241.1028 > 192.168.88.15.80: флаги [F.], последовательность 79, подтверждение 273, окно 60, длина 0
18:21:22.572590 IP 192.168.88.15.80 > 192.168.88.241.1028: флаги [F.], последовательность 273, подтверждение 80, окно 58, длина 0
18:21:22.572591 IP 192.168.88.100.80 > 192.168.88.15.53186: флаги [F.], последовательность 273, подтверждение 80, окно 58, длина 0
18:21:22.572619 IP 192.168.88.15.53186 > 192.168.88.100.80: флаги [.], подтверждение 274, окно 60, длина 0
18:21:22.572620 IP 192.168.88.241.1028 > 192.168.88.15.80: флаги [.], подтверждение 274, окно 60, длина 0

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/mirrors-dpvs.git
git@api.gitlife.ru:oschina-mirror/mirrors-dpvs.git
oschina-mirror
mirrors-dpvs
mirrors-dpvs
master