OpenStack Neutron Floating Ip

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску


TL;DR

Краткий список команд

Как трафик попадает из внешнего мира на VM в OpenStack

Этот документ описывает как трафик из внешнего мира доходит до виртуальных машин в OpenStack (один из возможных вариантов реализации).

Описание окружения

Окружение с установленным OpenStack состоит из 3 Control Nodes и они же совмещают роль Network Node, и одной Compute Node (минимально-возможное количество)
Для получения трафика из-вне используется интерфейс с именем floating (имя может быть выбрано произвольно)


Исследование пути трафика

В окружении (для простоты) запущен один единственный инстанс, у которого Floating IP 10.72.10.124 os server list

+--------------------------------------+--------------------------+--------+----------------------------------------+------------+--------------------+
| ID                                   | Name                     | Status | Networks                               | Image      | Flavor             |
+--------------------------------------+--------------------------+--------+----------------------------------------+------------+--------------------+
| 795dc7f8-15b4-4b5d-9f8d-c40f178467f7 | test-cirros-vm-on-nvme-1 | ACTIVE | lb-mgmt-net=10.255.4.184, 10.72.10.124 | Cirros-5.1 | m1.nano.vm-on-nvme |
+--------------------------------------+--------------------------+--------+----------------------------------------+------------+--------------------+

Сеть для floating Ips (10.72.10.0/24) настроена на маршрутизаторе в Vlan 729, и этот Vlan приходит в интерфейс с именем floating на каждой из Controller/Network nodes
Шлюзом для Floating сети выступает внешний по отношению к OpenStack маршрутизатор.

С тестового ноутбука до виртуальной машины маршрут выглядит так:

Keys:  Help   Display mode   Restart statistics   Order of fields   quit
Packets               Pings
 Host             Loss%   Snt   Last   Avg  Best  Wrst StDev
 1. 192.168.33.1  0.0%     6    2.0   1.7   1.5   2.0   0.2
 2. 10.72.10.124  0.0%     5    2.2   2.1   1.7   2.4   0.3

Определени через какую Network (Control/Network) ноду пойдет трафик

Из маршрута можно сделать следующие выводы:

  • так как 192.168.33.1 -это адрес шлюза по-умолчанию для ноутбука с которого делается трассировка маршрута, а адрес VM 10.72.10.124 уже следующий в трассировке, то можно предположить что этот маршрутизатор и выступает шлюзом для floating сеть 10.72.10.0/24
  • Если это утверждение верно, то изучив таблицу arp-записей на маршрутизаторе, возможно узнать мак-адрес VM (точнее, мак-адрес с которого уходит трафик от этой VM, этот адрес будет отличаться от того который можно посмотреть командой ip link show на самой VM.



В реальной жизни в окружении клиента доступа на роутеры и коммутаторы может не быть и тогда единственный способ понять через какую Compute/Network ноду идет трафик - это использовать tcpdump

Просмотр таблицы arp на маршрутизаторе

В качестве маршрутизатора в этом (тестовом!) окружении выступает устройство Mikrotik RB4011iGS+5HacQ2HnD (RouterOS 7.4)
(это не типичная инсталляция, для других случаев маршрутизатор скорее всего окажется другого производителя)



Просматриваем таблицу arp-записей (с поиском по ip=10.72.10.124)

[admin@RB4011iGS+5HacQ2HnD] > /ip/arp/print where address=10.72.10.124

Flags: D, P - PUBLISHED; C - COMPLETE
Columns: ADDRESS, MAC-ADDRESS, INTERFACE
#    ADDRESS       MAC-ADDRESS        INTERFACE
0 DC 10.72.10.124  FA:16:3E:40:32:D5  bridge-mosk-vlan-729-ch-os-fl

Из этого вывода можно видеть что

  • мак-адрес хоста <cod>10.72.10.124 известен роутеру: FA:16:3E:40:32:D5
  • этот адрес изучен на физическом интерфейсе bridge-mosk-vlan-729-ch-os-fl
  • этот интерфейс (bridge-mosk-vlan-729-ch-os-fl) и является шлюзом для floating сети, на нем назначен первый адрес 10.72.10.1/24 из этого ( 10.72.10.0/24) диапазона

/ip/address/print where interface=bridge-mosk-vlan-729-ch-os-fl

Columns: ADDRESS, NETWORK, INTERFACE
# ADDRESS        NETWORK     INTERFACE
0 10.72.10.1/24  10.72.10.0  bridge-mosk-vlan-729-ch-os-fl



  • Проверить какие еще адреса имеют мак такой же как и у адреса с которого отвечает VM:



[admin@RB4011iGS+5HacQ2HnD] > /ip/arp/print where mac-address=FA:16:3E:40:32:D5

Flags: D, P - PUBLISHED; C - COMPLETE
Columns: ADDRESS, MAC-ADDRESS, INTERFACE
#    ADDRESS       MAC-ADDRESS        INTERFACE
0 DC 10.72.10.124  FA:16:3E:40:32:D5  bridge-mosk-vlan-729-ch-os-fl
1 DC 10.72.10.27   FA:16:3E:40:32:D5  bridge-mosk-vlan-729-ch-os-fl

Тут видно что есть еще один IP с таким же маком - можно предположить что это или еще одна виртуальная машина, которая выходит через тот же роутер, или собственно адрес самого роутера.
В нашем простейшем случае, очевидно что это не может быть адресом виртуальной машины, так как в клауде запущена всего одна виртуальная машина с адресом 10.72.10.124

Note: "О роутерах в OpenStack":

Просмотреть роутеры можно командой openstack router list

+--------------------------------------+------+--------+-------+----------------------------------+-------------+-------+
| ID                                   | Name | Status | State | Project                          | Distributed | HA    |
+--------------------------------------+------+--------+-------+----------------------------------+-------------+-------+
| 54550846-33f2-4954-8649-3233a49cedb4 | r2   | ACTIVE | UP    | 93900840d7804fd2adfe9bfd452263c7 | False       | False |
| 6cf2a3cc-5242-42b5-8c57-3ee78b0d0983 | r1   | ACTIVE | UP    | 10510c89d63d490b967f90511cdc902d | True        | False |
+--------------------------------------+------+--------+-------+----------------------------------+-------------+-------+

А подробно информацию о роутере: openstack router show 54550846-33f2-4954-8649-3233a49cedb4 (вывод команды немного отформатирован для лучшей читаемости)

+-------------------------+-------------------------------------------------------------------
| Field                   | Value                                                             
+-------------------------+-------------------------------------------------------------------
| admin_state_up          | UP                                                                
| availability_zone_hints |                                                                   
| availability_zones      | nova                                                              
| created_at              | 2023-02-27T14:15:39Z                                              
| description             | router_for_nat                                                    
| distributed             | False                                                             
| external_gateway_info   | {"network_id": "5b1a5b04-b5ed-4ced-a097-585f40b0a5fd",
|                            "external_fixed_ips": [
|                               {"subnet_id": "32d92f06-a3c7-42f1-9dbc-0eee02aa47c1", "ip_address": "10.72.10.27"}
|                             ], 
|                             "enable_snat": false} 
| flavor_id               | None                                                              
| ha                      | False                                                             
| id                      | 54550846-33f2-4954-8649-3233a49cedb4                              
| interfaces_info         | [
|                              {"port_id": "e02600f1-cd39-4f1d-b1bc-c619602087b0", 
|                                "ip_address": "10.255.0.1", 
|                                "subnet_id": "4383ea14-91b6-49f9-98fa-8d6993012da2"}
|                             ]
| name                    | r2                                                                
| project_id              | 93900840d7804fd2adfe9bfd452263c7                                  
| revision_number         | 10                                                                
| routes                  |                                                                   
| status                  | ACTIVE                                                            
| tags                    |                                                                   
| updated_at              | 2023-02-28T13:10:28Z                                              
+-------------------------+---------------------------------------

Сам по себе роутер в OpenStack это НЕ виртуальная машина, а network namespace (сущность ядра Linux на Network Node)


Просмотр таблицы коммутации на top-of-rack switch

Зная мак-адрес целевой виртуальной машины, можно определить с какого порта коммутатора "виден" мак (правильно говорить: на каком порту коммутатора был изучен этот мак, но тут и далее я пользуюсь чаще сленговыми терминами)


В этой инсталляции в качестве коммутатора для всех нод используется Cisco Сatalyst WS-C3750E-48PD
Просмотреть с какого порта был изучен мак-адрес можно следующей командой: c3750e-lab#show mac address-table address fa16.3e40.32d5
(Обратите внимания, что формат показа мак-адресов у различных вендоров может отличаться, и следует это учитывать.)

          Mac Address Table
-------------------------------------------

Vlan    Mac Address       Type        Ports
----    -----------       --------    -----
 729    fa16.3e40.32d5    DYNAMIC     Gi1/0/7

Из вывода команды можно видеть что

  • Мак-адрес изучен с 7-го порта (Gi1/0/7)
  • Мак-адерс находится в 729 Vlan (это было понятно еще на роутере по имени интерфейса bridge-mosk-vlan-729-ch-os-fl, так как в его имени содержится информация vlan: 729 os: OpenStack, fl: floatiung network, но в общем случае такой информации не будет, и этот сетап - исключение, так как при настройке заведомо предполагалось упрощение дебага.



Зная номер порта, можно обратится к документации по клауду, и определить какой сервер подключен в какой порт.
(если документация недоступна то можно попробовать определить по тому какие еще мак-адреса присутствуют на порту, в других Vlan)
В этой инсталляции (где документация есть) определяем что в порт подключен к Control/Network Node c адресом 10.72.5.11



Прохождение тарфика внутри Compute Node

В этом сетапе - это нода 10.72.5.11 kaas-node-b4d3a72a-abe6-4dba-9547-30915084c409

Vlan 729 заходит в интерфейс с именем floating

  • это имя дано специально, в общем случае имя может отличаться
  • на этом интерфейсе уже нет никаких тегов - они снимаются раньше, другими словами tcpdump -i floating -n -ee не покажет тегированного трафика,

для данного случая не принципиально как именно снимается тег

  • на этом интерфейсе нет ip адреса
<code>ip addr  show dev floating</code>
7: floating: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master ovs-system state UP group default qlen 1000
    link/ether 52:54:15:ac:ac:16 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::5054:15ff:feac:ac16/64 scope link
       valid_lft forever preferred_lft forever
Note: "floating":

Изначально на этом интерфейсе присутствовал ip адрес - это в целом не мешало работе виртуальных машин, однако они не были доступны с этой ноды (но были доступны из сети).
Это была ошибка конфигурации, в целом назначать адреса на порты бриджа не правильно.


  • Детальная информация по интерфейсу:

ip -d link show dev floating

7: floating: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master ovs-system state UP mode DEFAULT group default qlen 1000
    link/ether 52:54:15:ac:ac:16 brd ff:ff:ff:ff:ff:ff promiscuity 1 minmtu 68 maxmtu 65535
    openvswitch_slave addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535

Тут важно что этот интерфейс включен как порт OpenVSwitch (что видно из строки openvswitch_slave ) и, соответвенно трафик попавший в этот интерфейс попадает в openvswitch

Прохождение трафика внутри OpenVSwitch

OpenVSwitch представляет собой программную реализацию OpenFlow коммутатора, (точнее в пределах одной Linux ноды можно создать несколько независимо работающих OpenFlow коммутаторов)

Note: "OpenVswitch in Docker":

В этой инсталляции процессы openvswitch работают внутри docker-контейнера, по этой причине все команды для работы с openvswitch нужно запускать оттуда:
docker exec -ti 1d8e520565ba ovs-vsctl show
однако для простоты в дальнейшем я буду опускать docker exec ...

Выяснить в какой виртуальный свитч попадает трафик

Выша было выяснено, что трафик уходит в недра OpenVSwitch, однако теперь предстоит выяснить в какой именно виртуальный коммутатора попадает трафик
Для этого просмотрим все виртуальные коммутаторы: ovs-vsctl show Часть вывода команды скрыта, полный вывод см ниже, тут оставлена только значимая часть

    Bridge br-ch-os-fl
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        datapath_type: system
        Port br-ch-os-fl
            Interface br-ch-os-fl
                type: internal
        Port phy-br-ch-os-fl
            Interface phy-br-ch-os-fl
                type: patch
                options: {peer=int-br-ch-os-fl}
        Port floating
            Interface floating

Тут ключевые моменты такие

  • Виртуальный коммутатор br-ch-os-fl, одним из портов (Port floating) которого и является интерфейс Interface floating является тем коммутатором куда попадает трафик
  • Этот коммутатор подключен к контроллеру, is_connected: true
  • Кроме порта через который в него попадает внешний трафик (floating), у него есть еще 2 порта:
    • Port phy-br-ch-os-flЭто порт имеет тип type: internal что означает что он виден в системе и на него можно назначить адрес (прочитать подробнее можно тут: https://arthurchiao.art/blog/ovs-deep-dive-6-internal-port/
    • Port br-ch-os-fl Этот порт имеет тип type: patch и предназначен для соединения нескольких виртуальных коммутаторов между собой, второй конец этого виртуального патч-корда имеет имя int-br-ch-os-fl. В целом, это напоминает работу интерфейса veth

Прохождение трафика через виртуальный коммутатор br-ch-os-fl

Итак, трафик попал в виртуальный коммутатор br-ch-os-fl через физический интерфейс floating
(он же порт коммутатора с таким же именем floating)
В отличии от "классических" коммутаторов, которые осуществляют пересылку пакетов основываясь на изученной таблице мак-адресов,
OpenFlow-коммутаторы (которыми и является виртуальный коммутатор br-ch-os-fl) используют для определения порта назначения OpenFlow-правила
Для просмотра правил в случае OpenVSwitch можно использовать команду ovs-ofctl dump-flows br-ch-os-fl

  • br-ch-os-fl - это имя виртуального коммутатора, которых может быть более чем один на одной Linux-ноде.


Результат работы команды

 cookie=0x2d19cd3395437eb3, duration=691002.184s, table=0, n_packets=106295, n_bytes=10732118, priority=2,in_port="phy-br-ch-os-fl"           actions=resubmit(,1)
 cookie=0x2d19cd3395437eb3, duration=691222.458s, table=0, n_packets=186,    n_bytes=11672,    priority=0                                     actions=NORMAL
 cookie=0x2d19cd3395437eb3, duration=691002.076s, table=0, n_packets=777807, n_bytes=48652600, priority=1                                     actions=resubmit(,3)
 cookie=0x2d19cd3395437eb3, duration=691001.975s, table=1, n_packets=106295, n_bytes=10732118, priority=0                                     actions=resubmit(,2)
 cookie=0x2d19cd3395437eb3, duration=690851.627s, table=2, n_packets=105853, n_bytes=10694426, priority=4,in_port="phy-br-ch-os-fl",dl_vlan=2 actions=strip_vlan,NORMAL
 cookie=0x2d19cd3395437eb3, duration=691001.628s, table=2, n_packets=442,    n_bytes=37692,    priority=2,in_port="phy-br-ch-os-fl"           actions=drop
 cookie=0x2d19cd3395437eb3, duration=690999.407s, table=3, n_packets=0,      n_bytes=0,        priority=2,dl_src=fa:16:3f:0e:d7:45            actions=output:"phy-br-ch-os-fl"
 cookie=0x2d19cd3395437eb3, duration=690999.335s, table=3, n_packets=0,      n_bytes=0,        priority=2,dl_src=fa:16:3f:64:4e:1f            actions=output:"phy-br-ch-os-fl"
 cookie=0x2d19cd3395437eb3, duration=690999.291s, table=3, n_packets=0,      n_bytes=0,        priority=2,dl_src=fa:16:3f:96:cd:a5            actions=output:"phy-br-ch-os-fl"
 cookie=0x2d19cd3395437eb3, duration=690999.111s, table=3, n_packets=0,      n_bytes=0,        priority=2,dl_src=fa:16:3f:a0:1e:1b            actions=output:"phy-br-ch-os-fl"
 cookie=0x2d19cd3395437eb3, duration=690998.887s, table=3, n_packets=0,      n_bytes=0,        priority=2,dl_src=fa:16:3f:f9:d4:00            actions=output:"phy-br-ch-os-fl"
 cookie=0x2d19cd3395437eb3, duration=691001.561s, table=3, n_packets=777807, n_bytes=48652600, priority=1                                     actions=NORMAL

Правила просамтриваются в следующем порядке

  • таблицы по номерам, от меньшего к большему (первая таблица - с номером 0)
  • Правила внутри таблицы просматриваются в порядке приоритетов, от большего к меньшему, первое правило с номером 65535
  • При равном приортете правила просматриваются в том порядке в котором добавлены (c верху вниз)


Для лучшего понимания, отсортируем правила в то порядке в котором они будут работать (с верху вниз, верхнее - первое)

Таблица 0

 cookie=0x2d19cd3395437eb3, duration=691002.184s, table=0, n_packets=106295, n_bytes=10732118, priority=2,in_port="phy-br-ch-os-fl"           actions=resubmit(,1)
 cookie=0x2d19cd3395437eb3, duration=691002.076s, table=0, n_packets=777807, n_bytes=48652600, priority=1                                     actions=resubmit(,3)
 cookie=0x2d19cd3395437eb3, duration=691222.458s, table=0, n_packets=186,    n_bytes=11672,    priority=0                                     actions=NORMAL

Таблица 1

 cookie=0x2d19cd3395437eb3, duration=691001.975s, table=1, n_packets=106295, n_bytes=10732118, priority=0                                     actions=resubmit(,2)

Таблица 2

 cookie=0x2d19cd3395437eb3, duration=690851.627s, table=2, n_packets=105853, n_bytes=10694426, priority=4,in_port="phy-br-ch-os-fl",dl_vlan=2 actions=strip_vlan,NORMAL
 cookie=0x2d19cd3395437eb3, duration=691001.628s, table=2, n_packets=442,    n_bytes=37692,    priority=2,in_port="phy-br-ch-os-fl"           actions=drop

Таблица 3

 cookie=0x2d19cd3395437eb3, duration=690999.407s, table=3, n_packets=0,      n_bytes=0,        priority=2,dl_src=fa:16:3f:0e:d7:45            actions=output:"phy-br-ch-os-fl"
 cookie=0x2d19cd3395437eb3, duration=690999.335s, table=3, n_packets=0,      n_bytes=0,        priority=2,dl_src=fa:16:3f:64:4e:1f            actions=output:"phy-br-ch-os-fl"
 cookie=0x2d19cd3395437eb3, duration=690999.291s, table=3, n_packets=0,      n_bytes=0,        priority=2,dl_src=fa:16:3f:96:cd:a5            actions=output:"phy-br-ch-os-fl"
 cookie=0x2d19cd3395437eb3, duration=690999.111s, table=3, n_packets=0,      n_bytes=0,        priority=2,dl_src=fa:16:3f:a0:1e:1b            actions=output:"phy-br-ch-os-fl"
 cookie=0x2d19cd3395437eb3, duration=690998.887s, table=3, n_packets=0,      n_bytes=0,        priority=2,dl_src=fa:16:3f:f9:d4:00            actions=output:"phy-br-ch-os-fl"
 cookie=0x2d19cd3395437eb3, duration=691001.561s, table=3, n_packets=777807, n_bytes=48652600, priority=1                                     actions=NORMAL

table 0 коммутатора br-ch-os-fl

Правила table 0

table=0, priority=2,in_port="phy-br-ch-os-fl" actions=resubmit(,1)


  • Правило означает: все пакеты с порта phy-br-ch-os-fl, исследуемый трафик в это правило не попадает так как приходит с порта floating
 cookie=0x2d19cd3395437eb3, duration=691002.184s, table=0, n_packets=106295, n_bytes=10732118, priority=2,in_port="phy-br-ch-os-fl"           actions=resubmit(,1)

table=0, priority=1 actions=resubmit(,3)

  • Правило означает: все пакеты (так как не указано никакое условие) и именно оно будет применено к исследуемому трафику, действие в нет - перейти в таблицу 3, это действие описывает actions=resubmit(,3)
cookie=0x2d19cd3395437eb3, duration=691002.076s, table=0, n_packets=777807, n_bytes=48652600, priority=1                                     actions=resubmit(,3)

table=0, priority=0 actions=NORMAL

  • Это правило никогда не сработает, но если по какой-то причине предыдущее правило будет отсутствовать, то это правило заставит сделать коммутацию как классический свитч, используя таблицу ма-адресов.
 cookie=0x2d19cd3395437eb3, duration=691222.458s, table=0, n_packets=186,    n_bytes=11672,    priority=0                                     actions=NORMAL

table 3 коммутатора br-ch-os-fl

Согласно правилу в таблице 0, исследуемый трафик отправлен в таблицу 3
В этой таблице много похожих правил, все они означают что при совпадении мак-адресов отправить пакет в порт phy-br-ch-os-fl
и ни один из мак-адресов не является мак-адресом трафика адресованного виртуальной машине

В случае когда трафик к виртуальной машине идет из-за пределов OpenStack (это и есть рассматриваемый случай), то мак-адресом отправителя таких пакетов будет мак-адрес маршрутизатора,
того интерфейса который смотрит в floating сеть (в этом сетапе это VLAN729)
Просмотреть мак-адрес в случае микротика можно в настройках интерфейса

/interface/bridge/print where name=bridge-mosk-vlan-729-ch-os-fl
Flags: X - disabled, R - running
 9 R name="bridge-mosk-vlan-729-ch-os-fl" mtu=auto actual-mtu=1500 l2mtu=1588 arp=enabled arp-timeout=auto mac-address=00:02:2D:AA:BB:02 protocol-mode=none fast-forward=yes igmp-snooping=no auto-mac=no admin-mac=00:02:2D:AA:BB:02 ageing-time=5m
     vlan-filtering=no dhcp-snooping=no

и тут видно что admin-mac=00:02:2D:AA:BB:02 не совпадает ни с одним из правил (все кроме первого правила спрятаны под спойлер), из чего делаем вывод что отрабатывает только последнее правило.

 cookie=0x2d19cd3395437eb3, duration=690999.407s, table=3, n_packets=0,      n_bytes=0,        priority=2,dl_src=fa:16:3f:0e:d7:45            actions=output:"phy-br-ch-os-fl"

Последнее правило имеет actions=NORMAL, это значит что дальнейшая коммутация будет осуществляться классическим способом, используя таблицу коммутации по мак-адресам,
и значит нужно проверить содержание этой таблицы.

 cookie=0x2d19cd3395437eb3, duration=691001.561s, table=3, n_packets=777807, n_bytes=48652600, priority=1                                     actions=NORMAL

Forwarding Database(таблица мак-адресов) коммутатора br-ch-os-fl

Таблицу Forwarding Database (FDB, таблица мак-адресов) на OpenVSwitch можно просмотреть командой:
ovs-appctl fdb/show br-ch-os-fl

 port  VLAN  MAC                Age
    1     0  6a:7a:ba:bc:8b:26  219
    1     0  d4:ca:6d:7c:a6:5c  199
    1     0  52:54:15:aa:aa:16   24
    1     0  52:54:15:ff:ff:16   23
    1     0  00:02:2d:aa:bb:02    1
    2     0  fa:16:3e:40:32:d5    1

Из этой таблицы видно, что целевой мак (fa:16:3e:40:32:d5) в ней присутствует и изучен с порта номер 2,
а все остальные маки изучены с порта номер 1 (в том числе и мак маршрутизатора, 00:02:2d:aa:bb:02 )

Однако, вывод ovs-vsctl show не дает информации о номерах портов, а только их имена:

    Bridge br-ch-os-fl
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        datapath_type: system
        Port br-ch-os-fl
            Interface br-ch-os-fl
                type: internal
        Port phy-br-ch-os-fl
            Interface phy-br-ch-os-fl
                type: patch
                options: {peer=int-br-ch-os-fl}
        Port floating
            Interface floating

Далее требуется сопоставить номера портов виртуального коммутатора br-ch-os-fl и их имена

Сопоставление номеров и имен портов для виртуального коммутатора br-ch-os-fl

Просмотреть нумерацию портов (внутри одного из многих коммутаторов!) можно командой
ovs-ofctl -OOpenFlow13 show br-ch-os-fl

  • br-ch-os-fl - имя коммутатора, для которого хочется посмотреть порты
OFPT_FEATURES_REPLY (OF1.3) (xid=0x2): dpid:0000ba2f0edece4e
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS GROUP_STATS QUEUE_STATS
OFPST_PORT_DESC reply (OF1.3) (xid=0x3):
 1(floating): addr:52:54:15:ac:ac:16
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max
 2(phy-br-ch-os-fl): addr:96:e8:e7:04:ec:d9
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br-ch-os-fl): addr:ba:2f:0e:de:ce:4e
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (OF1.3) (xid=0x9): frags=normal miss_send_len=0

Из вывода команды видно, что порт номер 2 это порт phy-br-ch-os-fl, который имеет состояние LIVE


из вывода команды ovs-vsctl show (оставлена только значимая часть) можно видеть что порт 2, он же phy-br-ch-os-fl,
имеет тип type: patch, и второй конец "виртуального патч-корда" имеет имя int-br-ch-os-fl (options: {peer=int-br-ch-os-fl})

...
        Port phy-br-ch-os-fl
            Interface phy-br-ch-os-fl
                type: patch
                options: {peer=int-br-ch-os-fl}
...

TODO (открытые вопросы):
Пока не ясно для чего служит

 LOCAL(br-ch-os-fl): addr:ba:2f:0e:de:ce:4e
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max

Этот же интерфейс, с таким же маком (ba:2f:0e:de:ce:4e) и состоянием ( LINK_DOWN) виден в системе:
ip link show dev br-ch-os-fl

77: br-ch-os-fl: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether ba:2f:0e:de:ce:4e brd ff:ff:ff:ff:ff:ff

Определение куда попадает трафик через виртуальный патчк-корд phy-br-ch-os-fl

Для того что бы понть куда трафик попадает через виртуальный патч-корд phy-br-ch-os-fl, нужно вернуться назад к выводу команды ovs-vsctl show
В части вывода, касающейся коммутатора br-int можно видеть, что вторая часть патч-корда (peer=int-br-ch-os-fl) является портом коммутатора br-int

   Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        datapath_type: system
        Port patch-tun
            Interface patch-tun
                type: patch
                options: {peer=patch-int}
        Port qr-e02600f1-cd
            tag: 1
            Interface qr-e02600f1-cd
                type: internal
        Port int-br-ch-os-fl
            Interface int-br-ch-os-fl
                type: patch
                options: {peer=phy-br-ch-os-fl}
        Port qg-aefc8a2e-98
            tag: 2
            Interface qg-aefc8a2e-98
                type: internal
        Port br-int
            Interface br-int
                type: internal
        Port qg-932d2f98-d2
            tag: 2
            Interface qg-932d2f98-d2
                type: internal
        Port o-hm0
            tag: 1
            Interface o-hm0
                type: internal
        Port fg-ecf7bdaf-ff
            tag: 2
            Interface fg-ecf7bdaf-ff
                type: internal

Вот описание порта через который трафик попадет в коммутатор br-int - это (ожидаемо) виртуальный патч-корд, второй конец которого - phy-br-ch-os-fl включен в коммутатор br-ch-os-fl

        Port int-br-ch-os-fl
            Interface int-br-ch-os-fl
                type: patch
                options: {peer=phy-br-ch-os-fl}

Прохождение трафика через виртуальный коммутатор br-int

Как выяснили, трафик попадает в коммутатор br-int через порт int-br-ch-os-fl

        Port int-br-ch-os-fl
            Interface int-br-ch-os-fl
                type: patch
                options: {peer=phy-br-ch-os-fl}

Так-как коммутатор br-int так же являетя OpenFlow коммутатором, то для понимания пути прохождения трафика нужно просмотреть правила OpenFlow
Просмотреть правила можно командой:
ovs-ofctl dump-flows br-int

Полный вывод достаточно большой, скрыт под спойлер, для анализа используем сокращенный вывод.

В целом логика такая же как и при прохождении трафика br-ch-os-fl

Напомню, чтот правила просматриваются по таблицам, сначала таблица 0, потом 1 и т.д, а правила внутри таблицы просматриваются в порядке приоритета, от большего к меньшему
Далее везде используется вывод уже отсортированный для удобства просмотра.
Поля cookie, duration, n_packets n_bytes удалены для удобства, они не влияют на результат работы правила.

table 0 коммутатора br-int

table=0 priority=65535,dl_vlan=4095

Этому правилу (ниже) соответствует трафик с VLAN_ID=4095, рассматриваемый сейчас трафик тэга не имеет, значит правило не срабатывает на него.

table=0   priority=65535,dl_vlan=4095                                                                                                  actions=drop

table=0 priority=200,reg3=0

Это правило (ниже) вызывает у меня затруднение, reg3=0 это обращение к 3-му регистру, но я пока не могу точно сказать как работает это расширение протокола OpenFlow
Судя по всему, это правило следует читать так

Если у пакета регистр3=0 (что касается всех пакетов, так как этот регистр - это внутреннее свойство пакета, а не поле по какому-либо смещению, и не существует за пределами OpenVSwitch), то:

  • set_queue:0,load Установить очередь 0 (TODO: Добавить пояснения)
  • 0x1->NXM_NX_REG3[0] Установить (загрузить в регистр) значение 0x1 в 0 байт регистра 3
  • resubmit(,0) Перенаправить пакет на вход таблицы 0

При повторном прохождении пакета это правило более не срабатывает, так как reg3 не равен более 0, а равен 0x1

table=0   priority=200,reg3=0                                                                                                          actions=set_queue:0,load:0x1->NXM_NX_REG3[0],resubmit(,0)



table=0 priority=5,in_port="int-br-ch-os-fl",dl_dst=fa:16:3f:e0:b7:4b actions=resubmit(,4)

Это правило (ниже) не срабатывает так-как не совпадает мак получателя (мак получателя FA:16:3E:40:32:D5не совпадает с маком fa:16:3f:e0:b7:4b из правила)

table=0   priority=5,in_port="int-br-ch-os-fl",dl_dst=fa:16:3f:e0:b7:4b                                                                actions=resubmit(,4)

Остальные не сработавшие но полностью аналогичные правила спрятаны под спойлер, мак-адреса тоже не совпадают.

table=0 priority=3,in_port="int-br-ch-os-fl",vlan_tci=0x0000/0x1fff actions=mod_vlan_vid:2,resubmit(,60)

Это правило следует читать как

  • Пакеты с порта int-br-ch-os-fl
  • У которых не установлен VlanID

Чуть подробнее остановлюсь на условии vlan_tci=0x0000/0x1fff
Прочитать можно тут: ovs-fields.7.txt


Правило читается так:

  • взять поле vlan_tci (это внутренняя структура у OpenVSwitchи других OpenFlow свитчей, а не поле в пакете!)
  • наложить на него битовую маску 0x1fff (что в двоичной форме соответствует 0001111111111111
  • результат сравнить с 0x0000


Накладывание битовой маски - по сути операция умножения, другим словами это означает что первые три бита в исходном пакет могут быть любыми (после умножения на 0 они будут равны 0),
а остальные должны уже быть равны нулю в исходном пакете (умножение на 1 не изменяет их значения)

В описании поля vlan_tci видно, что первые 3 бита отведены под PCP (Priority Control Point)

        NXM_VLAN_TCI
        <---------->
         3   1   12
       +----+--+----+
       |PCP |P |VID |
       +----+--+----+




Другими словами, это правило означает что

  • Бит присутствия VLAN (CFI, Canonical Format Indicator) должен быть выставлен в 0
  • Поле VLAN ID выставлено в 0 (все биты установлены в 0)
  • значение поля приоритета игнорируетс

В сумме это правило значит "нетэгированный пакет с порта int-br-ch-os-fl" куда и попадает искомый трафик - и он далее передается в таблицу 60 после того как на него будет добавлен тег 2 (mod_vlan_vid:2)

table=0   priority=3,in_port="int-br-ch-os-fl",vlan_tci=0x0000/0x1fff                                                                  actions=mod_vlan_vid:2,resubmit(,60)

table=0 priority=2,in_port="int-br-ch-os-fl" actions=drop

Это правило значит что все что не попало под предыдущее правило (другими словами пакеты с тегом) нужно дропнуть

table=0   priority=2,in_port="int-br-ch-os-fl"                                                                                         actions=drop


table=0 priority=0 actions=resubmit(,60)

Это правило безусловно все остальные пакеты передаст в таблицу 60, не модифицируя их

table=0   priority=0                                                                                                                   actions=resubmit(,60)

table 60 коммутатора br-int

Полный список правил (вывод не содержит не значазих полей)

table=60  priority=100,in_port="o-hm0"                    actions=load:0x3->NXM_NX_REG5[],load:0x1->NXM_NX_REG6[],resubmit(,71)
table=60  priority=100,in_port="qg-aefc8a2e-98"           actions=load:0x6->NXM_NX_REG5[],load:0x2->NXM_NX_REG6[],resubmit(,73)
table=60  priority=100,in_port="qg-932d2f98-d2"           actions=load:0x7->NXM_NX_REG5[],load:0x2->NXM_NX_REG6[],resubmit(,73)
table=60  priority=100,in_port="fg-ecf7bdaf-ff"           actions=load:0x5->NXM_NX_REG5[],load:0x2->NXM_NX_REG6[],resubmit(,73)
table=60  priority=100,in_port="qr-e02600f1-cd"           actions=load:0x4->NXM_NX_REG5[],load:0x1->NXM_NX_REG6[],resubmit(,73)
table=60  priority=90,dl_vlan=1,dl_dst=fa:16:3e:0c:e4:73  actions=load:0x3->NXM_NX_REG5[],load:0x1->NXM_NX_REG6[],strip_vlan,resubmit(,81)
table=60  priority=3                                      actions=NORMAL

Тут видно что все правила, кроме последнего, имеют условия не соответствующие исследуемому трафику - отличия в поле in_port, vlan или мак
Соответственно срабатывает третье правило (actions=NORMAL) и далее для коммутации трафика используется классическаая таблица мак-адресов

Таблица мак-адресов коммутатора br-int

Далее для проверки куда отправить пакет с маком назначения fa:16:3e:40:32:d5 нужно проверить содержимое таблицы коммутации (FDB, Forwarding Database)

ovs-appctl fdb/show br-int

 port  VLAN  MAC                Age
    1     2  52:54:15:aa:aa:16  119
    1     2  52:54:15:ff:ff:16   38
    1     2  00:02:2d:aa:bb:02    0
    5     2  fa:16:3e:40:32:d5    0

Тут видно что мак fa:16:3e:40:32:d5 изучен с порта номер 5
Для того что бы выяснить какой именно порт имеет номер 5, просмотреть номера портов

ovs-ofctl -OOpenFlow13 show br-int

OFPT_FEATURES_REPLY (OF1.3) (xid=0x2): dpid:0000ae845ebd9a43
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS GROUP_STATS QUEUE_STATS
OFPST_PORT_DESC reply (OF1.3) (xid=0x3):
 1(int-br-ch-os-fl): addr:f6:69:e1:c0:39:3c
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max
 2(patch-tun): addr:16:6a:e5:70:65:5c
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max
 3(o-hm0): addr:fa:16:3e:42:68:31
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max
 4(qr-e02600f1-cd): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
 5(qg-aefc8a2e-98): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
 6(fg-deee2f23-09): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
 7(qg-932d2f98-d2): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
 8(tapb9b0014b-e1): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br-int): addr:ae:84:5e:bd:9a:43
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (OF1.3) (xid=0x9): frags=normal miss_send_len=0

Тут видно что номеру 5 соответствует интерфейс qg-aefc8a2e-98

 5(qg-aefc8a2e-98): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max

ovs-vsctl show показывает что

  • это интерфейс типа internal и это означает что он должен быть виден в системе командой ip link show ...
  • этот интерфейс имеет VLAN (tag: 2), что (предположительно) соответствует access port 2, при отправки на этот порт будет снят тег, а при получении - добавлен тег 2
  • тег 2 совпадает с тегом которым тегирован исследуемый трафик
        Port qg-932d2f98-d2
            tag: 2
            Interface qg-932d2f98-d2
                type: internal
</code>
Однако "в лоб" интерфейс в системе не виден <BR>
<code>ip link show dev qg-aefc8a2e-98</code>
<PRE>
Device "qg-aefc8a2e-98" does not exist.

Это связано с тем что он находится внутри network namespace
Дальнейшим прохождением трафика занимается уже не OpenVSwitch, а сетевая подсистема Linux

Note: "Почему Port Down?":

Можно было увидеть: config: PORT_DOWN, state: LINK_DOWN

 5(qg-aefc8a2e-98): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max

Могу предположить что OpenVSWitch не может определить статус интерфейса, если он находится в network namespace отличном от "умолчального" (в терминах Cisco это называется VRF Global)

Прохождение трафика внутри Network Node

Первым делом следует определить в какой именно network namespace помещен интерфейс (qg-aefc8a2e-98 - имя интерфейса и оно же имя порта openvswitch)

Определение Network Namespace в который попадает трафик

ip netns list

qdhcp-bd7e52d9-e09c-4d43-8816-db1be731a761 (id: 50)
fip-5b1a5b04-b5ed-4ced-a097-585f40b0a5fd (id: 29)
snat-6cf2a3cc-5242-42b5-8c57-3ee78b0d0983 (id: 49)
qrouter-6cf2a3cc-5242-42b5-8c57-3ee78b0d0983
qrouter-54550846-33f2-4954-8649-3233a49cedb4 (id: 14)

Для того что бы не перебирать все неймспейсы руками: for NET_NS_NAME in $(ip netns list | awk '{print $1}'); do ip netns exec ${NET_NS_NAME} ip -s -d link show dev qg-aefc8a2e-98 2>/dev/null && echo ${NET_NS_NAME} && break; done

83: qg-aefc8a2e-98: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether fa:16:3e:40:32:d5 brd ff:ff:ff:ff:ff:ff promiscuity 1 minmtu 68 maxmtu 65535
    openvswitch addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
    RX: bytes  packets  errors  dropped overrun mcast
    373294     7318     0       0       0       0
    TX: bytes  packets  errors  dropped carrier collsns
    198624     1955     0       0       0       0

qrouter-54550846-33f2-4954-8649-3233a49cedb4


Из вывода видно, что интерфейс это порт openvswitch,
а искомый Network Namespace - qrouter-54550846-33f2-4954-8649-3233a49cedb4


Note: "В поисках неймспейса":

На самом деле можно было предположить что это какой-то роутер openstack router list

+--------------------------------------+------+--------+-------+----------------------------------+-------------+-------+
| ID                                   | Name | Status | State | Project                          | Distributed | HA    |
+--------------------------------------+------+--------+-------+----------------------------------+-------------+-------+
| 54550846-33f2-4954-8649-3233a49cedb4 | r2   | ACTIVE | UP    | 93900840d7804fd2adfe9bfd452263c7 | False       | False |
...

и тут видно что ID роутера совпадает с именем неймспейса
Конечно когда роутеров много - все может оказаться сложнее


qrouter-54550846-33f2-4954-8649-3233a49cedb4

Далее запускаем шелл (отключив буфферизацию ввода и вывода и исследуем настройки сети внутри неймспейса) ip netns exec qrouter-54550846-33f2-4954-8649-3233a49cedb4 stdbuf -i0 -o0 -e0 bash

Note: "stdbuf": Без отключение буферизации например tcpdump выдает на экран пакеты не сразу, а пачками. Что может сильно мешать дебагу

Причины такого поведения в неймспейсе я пока не исследовал

Просмотрим базовые настойки сетевого стека:

ip -d link show

ip -d link show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0 minmtu 0 maxmtu 0 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
82: qr-e02600f1-cd: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1430 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether fa:16:3e:69:cd:07 brd ff:ff:ff:ff:ff:ff promiscuity 1 minmtu 68 maxmtu 65535
    openvswitch addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
83: qg-aefc8a2e-98: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether fa:16:3e:40:32:d5 brd ff:ff:ff:ff:ff:ff promiscuity 1 minmtu 68 maxmtu 65535
    openvswitch addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535

Из вывода можно увидеть, что тут присутвуют 2 интерфейса, оба являются портами OpenVSwitch:

  • qg-aefc8a2e-98 - интерфейс через который приходит трафик
  • qr-e02600f1-cd - еще один интерфейс, назначение которого пока не известно (но можно предположить что он смотрит во внутреннюю сеть тенанта)

Роутер выглядит как классический, с 1 портом WAN - qg-aefc8a2e-98 и одним портом LAN - qr-e02600f1-cd

ip -d addr show

ip -d addr show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0 minmtu 0 maxmtu 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
82: qr-e02600f1-cd: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1430 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether fa:16:3e:69:cd:07 brd ff:ff:ff:ff:ff:ff promiscuity 1 minmtu 68 maxmtu 65535
    openvswitch numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
    inet 10.255.0.1/16 brd 10.255.255.255 scope global qr-e02600f1-cd
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fe69:cd07/64 scope link
       valid_lft forever preferred_lft forever
83: qg-aefc8a2e-98: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether fa:16:3e:40:32:d5 brd ff:ff:ff:ff:ff:ff promiscuity 1 minmtu 68 maxmtu 65535
    openvswitch numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
    inet 10.72.10.27/24 brd 10.72.10.255 scope global qg-aefc8a2e-98
       valid_lft forever preferred_lft forever
    inet 10.72.10.124/32 brd 10.72.10.124 scope global qg-aefc8a2e-98
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fe40:32d5/64 scope link
       valid_lft forever preferred_lft forever


У роутера 3 IP адреса (за исклбючением lo который я нигде отдельно не описываю)

  • на интерфейсе qg-aefc8a2e-98
    • 10.255.0.1/16 - это адрес на интерфейсе в тенантную сеть и он выступает шлюзом для ВМ в этой сети
  • на интерфейсе qg-aefc8a2e-98
    • 10.72.10.27/24 - Floating IP роутера (кстати зачем он ему?)
    • 10.72.10.124/32 - Floating IP назначеный на ВМ

Так как Floating адрес виртуальной машины назначин на интерфейс qg-aefc8a2e-98, который как рассмотрели выше, средствами OpenVSwitch,
через виртуальные коммутаторы соединен с сетью floating (Vlan729 на физическом коммутаторе), то становится понятно как происходит изучение ARP -
сетевой стек линукса Network Node отвечает на ARP-запросы на адрес 10.72.10.124, что является поведением по-умолчанию.

Никакая "магия" proxy_arp здесь не используется

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

ip route

ip route

default via 10.72.10.1 dev qg-aefc8a2e-98 proto static
10.72.10.0/24 dev qg-aefc8a2e-98 proto kernel scope link src 10.72.10.27
10.255.0.0/16 dev qr-e02600f1-cd proto kernel scope link src 10.255.0.1

Таблица маршрутизации соответствует ожиданиям и максимально проста - по одному маршруту в каждый из сегментов сети, и маршрут по-умолчанию.

arp -n

arp -n

arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
10.255.4.184             ether   fa:16:3e:ea:49:b7   C                     qr-e02600f1-cd
10.72.10.1               ether   00:02:2d:aa:bb:02   C                     qg-aefc8a2e-98

Таблица ARP тоже полностью соответвует ожиданиям - 2 записи, шлюза во внешний мир и виртуальной машины.

ip route get 10.72.10.124

ip route get 10.72.10.124

ip route get 10.72.10.124
local 10.72.10.124 dev lo src 10.72.10.124 uid 0
    cache <local>

Результат соответвует ожиданиям - так как адрес 10.72.10.124 назначен на один из интерфейса маршрутизатора, то трафик адресованный этому адресу (тавтология?) будет обрабатываться как локальный.

iptables-save

iptables-save

*raw

# Generated by iptables-save v1.8.4 on Mon Apr 17 11:54:58 2023
*raw
:PREROUTING ACCEPT [2580:169942]
:OUTPUT ACCEPT [2537:233396]
:neutron-l3-agent-OUTPUT - [0:0]
:neutron-l3-agent-PREROUTING - [0:0]
-A PREROUTING -j neutron-l3-agent-PREROUTING
-A OUTPUT -j neutron-l3-agent-OUTPUT
COMMIT
# Completed on Mon Apr 17 11:54:58 2023
# Generated by iptables-save v1.8.4 on Mon Apr 17 11:54:58 2023

*nat

*nat
:PREROUTING ACCEPT [11:2391]
:INPUT ACCEPT [11:2391]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [2:128]
:neutron-l3-agent-OUTPUT - [0:0]
:neutron-l3-agent-POSTROUTING - [0:0]
:neutron-l3-agent-PREROUTING - [0:0]
:neutron-l3-agent-float-snat - [0:0]
:neutron-l3-agent-snat - [0:0]
:neutron-postrouting-bottom - [0:0]
-A PREROUTING -j neutron-l3-agent-PREROUTING
-A OUTPUT -j neutron-l3-agent-OUTPUT
-A POSTROUTING -j neutron-l3-agent-POSTROUTING
-A POSTROUTING -j neutron-postrouting-bottom
-A neutron-l3-agent-OUTPUT -d 10.72.10.124/32 -j DNAT --to-destination 10.255.4.184
-A neutron-l3-agent-POSTROUTING ! -o qg-aefc8a2e-98 -m conntrack ! --ctstate DNAT -j ACCEPT
-A neutron-l3-agent-PREROUTING -d 169.254.169.254/32 -i qr-+ -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 9697
-A neutron-l3-agent-PREROUTING -d 10.72.10.124/32 -j DNAT --to-destination 10.255.4.184
-A neutron-l3-agent-float-snat -s 10.255.4.184/32 -j SNAT --to-source 10.72.10.124 --random-fully
-A neutron-l3-agent-snat -j neutron-l3-agent-float-snat
-A neutron-l3-agent-snat -m mark ! --mark 0x2/0xffff -m conntrack --ctstate DNAT -j SNAT --to-source 10.72.10.27 --random-fully
-A neutron-postrouting-bottom -m comment --comment "Perform source NAT on outgoing traffic." -j neutron-l3-agent-snat
COMMIT
# Completed on Mon Apr 17 11:54:58 2023
# Generated by iptables-save v1.8.4 on Mon Apr 17 11:54:58 2023

*mangle

:PREROUTING ACCEPT [2580:169942]
:INPUT ACCEPT [12:2739]
:FORWARD ACCEPT [32:4899]
:OUTPUT ACCEPT [2537:233396]
:POSTROUTING ACCEPT [2569:238295]
:neutron-l3-agent-FORWARD - [0:0]
:neutron-l3-agent-INPUT - [0:0]
:neutron-l3-agent-OUTPUT - [0:0]
:neutron-l3-agent-POSTROUTING - [0:0]
:neutron-l3-agent-PREROUTING - [0:0]
:neutron-l3-agent-float-snat - [0:0]
:neutron-l3-agent-floatingip - [0:0]
:neutron-l3-agent-mark - [0:0]
:neutron-l3-agent-scope - [0:0]
-A PREROUTING -j neutron-l3-agent-PREROUTING
-A INPUT -j neutron-l3-agent-INPUT
-A FORWARD -j neutron-l3-agent-FORWARD
-A OUTPUT -j neutron-l3-agent-OUTPUT
-A POSTROUTING -j neutron-l3-agent-POSTROUTING
-A neutron-l3-agent-PREROUTING -j neutron-l3-agent-mark
-A neutron-l3-agent-PREROUTING -j neutron-l3-agent-scope
-A neutron-l3-agent-PREROUTING -m connmark ! --mark 0x0/0xffff0000 -j CONNMARK --restore-mark --nfmask 0xffff0000 --ctmask 0xffff0000
-A neutron-l3-agent-PREROUTING -j neutron-l3-agent-floatingip
-A neutron-l3-agent-PREROUTING -d 169.254.169.254/32 -i qr-+ -p tcp -m tcp --dport 80 -j MARK --set-xmark 0x1/0xffff
-A neutron-l3-agent-float-snat -m connmark --mark 0x0/0xffff0000 -j CONNMARK --save-mark --nfmask 0xffff0000 --ctmask 0xffff0000
-A neutron-l3-agent-mark -i qg-aefc8a2e-98 -j MARK --set-xmark 0x2/0xffff
-A neutron-l3-agent-scope -i qr-e02600f1-cd -j MARK --set-xmark 0x4000000/0xffff0000
-A neutron-l3-agent-scope -i qg-aefc8a2e-98 -j MARK --set-xmark 0x4000000/0xffff0000
COMMIT
# Completed on Mon Apr 17 11:54:58 2023
# Generated by iptables-save v1.8.4 on Mon Apr 17 11:54:58 2023

*filter

:INPUT ACCEPT [12:2739]
:FORWARD ACCEPT [32:4899]
:OUTPUT ACCEPT [2537:233396]
:neutron-filter-top - [0:0]
:neutron-l3-agent-FORWARD - [0:0]
:neutron-l3-agent-INPUT - [0:0]
:neutron-l3-agent-OUTPUT - [0:0]
:neutron-l3-agent-local - [0:0]
:neutron-l3-agent-scope - [0:0]
-A INPUT -j neutron-l3-agent-INPUT
-A FORWARD -j neutron-filter-top
-A FORWARD -j neutron-l3-agent-FORWARD
-A OUTPUT -j neutron-filter-top
-A OUTPUT -j neutron-l3-agent-OUTPUT
-A neutron-filter-top -j neutron-l3-agent-local
-A neutron-l3-agent-FORWARD -j neutron-l3-agent-scope
-A neutron-l3-agent-INPUT -m mark --mark 0x1/0xffff -j ACCEPT
-A neutron-l3-agent-INPUT -p tcp -m tcp --dport 9697 -j DROP
-A neutron-l3-agent-scope -o qr-e02600f1-cd -m mark ! --mark 0x4000000/0xffff0000 -j DROP
-A neutron-l3-agent-scope -o qg-aefc8a2e-98 -m mark ! --mark 0x4000000/0xffff0000 -j DROP
COMMIT
# Completed on Mon Apr 17 11:54:58 2023


Разбор правил IPTABLES

На первый взгляд правил довольно много
Для понимания в каком порядке происходит прохождения пакета - прикрепляю классическую 'iptables-big-picture' (так она и назодится гуглом)
Netfilter-packet-flow.svg.png]

Из этой схемы становится более понятно в каком порядке какие таблицы просматривать.
eBPF/qdisc (шейпера) пропускаем. Считаем что интерфейс не является бриджом (в классическом смысле - Linux Bridge, проверить brctl show, которая показывает что бриджей нет)


Порядок прохождения пакетов

Порядок прохождения пакетов
Имя таблицы Имя Цепочки Примечание
raw PREROUTING

12312 1212

mangle PREROUTING
nat PREROUTING
Принятие решения о маршрутизации
mangle FORWARD
filter FORWARD
mangle POSTROUTING
nat POSTROUTING

Ссылки