ovn 配置逻辑路由器实现三层转发

2023-05-16

本文使用ovn搭建一个三层转发的环境,拓扑图如下

image.png

两个虚拟交换机ls1和ls2,端口ip网段分别为 10.10.10.0/24和 10.10.20.0/24。
虚拟交换机上分别连接两个vm(使用namespace模拟),使用dhclient动态获取ip。
一个虚拟路由器lr1,连接两个虚拟交换机ls1和ls2,实现跨网段通信。

值得注意的是,这里的逻辑路由器不同于neutron中的分布式路由器,虽然ovn逻辑路由器也是分布式的,但它只是一个逻辑上的,不存在实体,而是靠流表实现转发,neutron中的分布式路由器会在每个节点上使用namespace模拟路由器。

创建ls和lr

//创建两个虚拟交换机 ls1 和 ls2
ovn-nbctl ls-add ls1
ovn-nbctl ls-add ls2
//创建一个虚拟路由器 lr1
ovn-nbctl lr-add lr1

//在虚拟路由器上添加端口,用来连接虚拟交换机 ls1
ovn-nbctl lrp-add lr1 lr1-ls1 00:00:00:00:00:01 10.10.10.1/24

//在虚拟交换机 ls1 添加端口,用来连接虚拟路由器 lr1
ovn-nbctl lsp-add ls1 ls1-lr1
//端口类型必须为 router
ovn-nbctl lsp-set-type ls1-lr1 router
//设置地址,必须和 lr1-ls1 的一致
ovn-nbctl lsp-set-addresses ls1-lr1 00:00:00:00:00:01
//指定 router-port
ovn-nbctl lsp-set-options ls1-lr1 router-port=lr1-ls1

//在虚拟路由器上添加端口,用来连接虚拟交换机 ls2
ovn-nbctl lrp-add lr1 lr1-ls2 00:00:00:00:00:02 10.10.20.1/24

//在虚拟交换机 ls2 添加端口,用来连接虚拟路由器 lr1
ovn-nbctl lsp-add ls2 ls2-lr1
//端口类型必须为 router
ovn-nbctl lsp-set-type ls2-lr1 router
//设置地址,必须和 lr1-ls2 的一致
ovn-nbctl lsp-set-addresses ls2-lr1 00:00:00:00:00:02
//指定 router-port
ovn-nbctl lsp-set-options ls2-lr1 router-port=lr1-ls2

查看当前配置

# ovn-nbctl show
switch bf0d3638-0395-4dc8-acba-15ef0d9e6992 (ls2)
    port ls2-lr1
        type: router
        addresses: ["00:00:00:00:00:02"]
        router-port: lr1-ls2
switch 3c3a2c91-5415-411a-89c2-bbccdd400cd4 (ls1)
    port ls1-lr1
        type: router
        addresses: ["00:00:00:00:00:01"]
        router-port: lr1-ls1
router c92da6ff-54f3-45c9-b459-0725263f2ecc (lr1)
    port lr1-ls1
        mac: "00:00:00:00:00:01"
        networks: ["10.10.10.1/24"]
    port lr1-ls2
        mac: "00:00:00:00:00:02"
        networks: ["10.10.20.1/24"]

添加vm对应的端口

//在虚拟交换机 ls1 上添加两个端口,指定 mac 和 ip(10.10.10.0/24网段),用来连接vm
ovn-nbctl lsp-add ls1 ls1-vm1
ovn-nbctl lsp-set-addresses ls1-vm1 "00:00:00:00:00:03 10.10.10.2"
ovn-nbctl lsp-set-port-security ls1-vm1 "00:00:00:00:00:03 10.10.10.2"

ovn-nbctl lsp-add ls1 ls1-vm2
ovn-nbctl lsp-set-addresses ls1-vm2 "00:00:00:00:00:04 10.10.10.3"
ovn-nbctl lsp-set-port-security ls1-vm2 "00:00:00:00:00:04 10.10.10.3"

//在虚拟交换机 ls2 上添加两个端口,指定 mac 和 ip(10.10.20.0/24网段),用来连接vm
ovn-nbctl lsp-add ls2 ls2-vm1
ovn-nbctl lsp-set-addresses ls2-vm1 "00:00:00:00:00:03 10.10.20.2"
ovn-nbctl lsp-set-port-security ls2-vm1 "00:00:00:00:00:03 10.10.20.2"

ovn-nbctl lsp-add ls2 ls2-vm2
ovn-nbctl lsp-set-addresses ls2-vm2 "00:00:00:00:00:04 10.10.20.3"
ovn-nbctl lsp-set-port-security ls2-vm2 "00:00:00:00:00:04 10.10.20.3"

查看当前配置

//这里注意,ls1和ls2上的端口的ip是不同网段的,但是mac地址是可以重复的。
# ovn-nbctl show
switch bf0d3638-0395-4dc8-acba-15ef0d9e6992 (ls2)
    port ls2-vm2
        addresses: ["00:00:00:00:00:04 10.10.20.3"]
    port ls2-vm1
        addresses: ["00:00:00:00:00:03 10.10.20.2"]
    port ls2-lr1
        type: router
        addresses: ["00:00:00:00:00:02"]
        router-port: lr1-ls2
switch 3c3a2c91-5415-411a-89c2-bbccdd400cd4 (ls1)
    port ls1-lr1
        type: router
        addresses: ["00:00:00:00:00:01"]
        router-port: lr1-ls1
    port ls1-vm2
        addresses: ["00:00:00:00:00:04 10.10.10.3"]
    port ls1-vm1
        addresses: ["00:00:00:00:00:03 10.10.10.2"]
router c92da6ff-54f3-45c9-b459-0725263f2ecc (lr1)
    port lr1-ls1
        mac: "00:00:00:00:00:01"
        networks: ["10.10.10.1/24"]
    port lr1-ls2
        mac: "00:00:00:00:00:02"
        networks: ["10.10.20.1/24"]

创建dhcp选项,并绑定到logical switch port,以便vm可以申请ip地址

//创建 dhcp 选项,网段为 10.10.10.0/24
ovn-nbctl dhcp-options-create 10.10.10.0/24
//查看刚创建的 dhcp 选项UUID
ovn-nbctl dhcp-options-list
//通过 UUID 设置此 dhcp 选项的其他参数
ovn-nbctl dhcp-options-set-options 025a611c-c6ae-4f1e-8903-293620759a42 \
server_id=10.10.10.1 server_mac=00:00:00:00:00:01 lease_time=3600 router=10.10.10.1

//设置 logical_switch_port 的 dhcp 字段,指向上面创建的 dhcp 选项
ovn-nbctl lsp-set-dhcpv4-options ls1-vm1 025a611c-c6ae-4f1e-8903-293620759a42
ovn-nbctl lsp-get-dhcpv4-options ls1-vm1

ovn-nbctl lsp-set-dhcpv4-options ls1-vm2 025a611c-c6ae-4f1e-8903-293620759a42
ovn-nbctl lsp-get-dhcpv4-options ls1-vm2

//创建 dhcp 选项,网段为 10.10.20.0/24
ovn-nbctl dhcp-options-create 10.10.20.0/24
//查看刚创建的 dhcp 选项UUID
ovn-nbctl dhcp-options-list
//通过 UUID 设置此 dhcp 选项的其他参数
ovn-nbctl dhcp-options-set-options 6e278b8c-2d6f-4a5d-8256-a91d9770bcb9 \
server_id=10.10.20.1 server_mac=00:00:00:00:00:02 lease_time=3600 router=10.10.20.1

//设置 logical_switch_port 的 dhcp 字段,指向上面创建的 dhcp 选项
ovn-nbctl lsp-set-dhcpv4-options ls2-vm1 6e278b8c-2d6f-4a5d-8256-a91d9770bcb9
ovn-nbctl lsp-get-dhcpv4-options ls2-vm1
 
ovn-nbctl lsp-set-dhcpv4-options ls2-vm2 6e278b8c-2d6f-4a5d-8256-a91d9770bcb9
ovn-nbctl lsp-get-dhcpv4-options ls2-vm2

查看dhcp选项

# ovn-nbctl list dhcp_options
_uuid               : 6e278b8c-2d6f-4a5d-8256-a91d9770bcb9
cidr                : "10.10.20.0/24"
external_ids        : {}
options             : {lease_time="3600", router="10.10.20.1", server_id="10.10.20.1", server_mac="00:00:00:00:00:02"}

_uuid               : 025a611c-c6ae-4f1e-8903-293620759a42
cidr                : "10.10.10.0/24"
external_ids        : {}
options             : {lease_time="3600", router="10.10.10.1", server_id="10.10.10.1", server_mac="00:00:00:00:00:01"}

使用namespace模拟vm,并动态申请ip

//在 master 节点上,创建两个namespace,用来模拟两个vm,使用 "iface-id" 指定
//这两个vm属于 ls1
ip netns add vm1
ovs-vsctl add-port br-int vm1 -- set interface vm1 type=internal
ip link set vm1 address 00:00:00:00:00:03
ip link set vm1 netns vm1
ovs-vsctl set Interface vm1 external_ids:iface-id=ls1-vm1
//申请 ip
ip netns exec vm1 dhclient vm1
ip netns exec vm1 ip addr show vm1
ip netns exec vm1 ip route show

ip netns add vm2
ovs-vsctl add-port br-int vm2 -- set interface vm2 type=internal
ip link set vm2 address 00:00:00:00:00:04
ip link set vm2 netns vm2
ovs-vsctl set Interface vm2 external_ids:iface-id=ls1-vm2
//申请 ip
ip netns exec vm2 dhclient vm2
ip netns exec vm2 ip addr show vm2
ip netns exec vm2 ip route show

//在 node1 节点上,创建两个namespace,用来模拟两个vm,使用 "iface-id" 指定这两个vm属于 ls2
ip netns add vm1
ovs-vsctl add-port br-int vm1 -- set interface vm1 type=internal
ip link set vm1 address 00:00:00:00:00:03
ip link set vm1 netns vm1
ovs-vsctl set Interface vm1 external_ids:iface-id=ls2-vm1
//申请 ip
ip netns exec vm1 dhclient vm1
ip netns exec vm1 ip addr show vm1
ip netns exec vm1 ip route show

ip netns add vm2
ovs-vsctl add-port br-int vm2 -- set interface vm2 type=internal
ip link set vm2 address 00:00:00:00:00:04
ip link set vm2 netns vm2
ovs-vsctl set Interface vm2 external_ids:iface-id=ls2-vm2
//申请 ip
ip netns exec vm2 dhclient vm2
ip netns exec vm2 ip addr show vm2
ip netns exec vm2 ip route show

# ip netns exec vm1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
64: vm1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether 00:00:00:00:00:03 brd ff:ff:ff:ff:ff:ff
    inet 10.10.10.2/24 brd 10.10.10.255 scope global dynamic vm1
       valid_lft 3484sec preferred_lft 3484sec
    inet6 fe80::200:ff:fe00:3/64 scope link
       valid_lft forever preferred_lft forever
//ping网段
# ip netns exec vm1 ping 10.10.10.1
PING 10.10.10.1 (10.10.10.1) 56(84) bytes of data.
64 bytes from 10.10.10.1: icmp_seq=1 ttl=254 time=1.78 ms
^C
--- 10.10.10.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.776/1.776/1.776/0.000 ms
//ping同网段的vm2
# ip netns exec vm1 ping 10.10.10.3
PING 10.10.10.3 (10.10.10.3) 56(84) bytes of data.
64 bytes from 10.10.10.3: icmp_seq=1 ttl=64 time=1.29 ms
^C
--- 10.10.10.3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.287/1.287/1.287/0.000 ms

//ping跨网段的网关
# ip netns exec vm1 ping 10.10.20.1
PING 10.10.20.1 (10.10.20.1) 56(84) bytes of data.
64 bytes from 10.10.20.1: icmp_seq=1 ttl=254 time=0.785 ms
^C
--- 10.10.20.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.785/0.785/0.785/0.000 ms

//ping跨网段的vm1
# ip netns exec vm1 ping 10.10.20.2
PING 10.10.20.2 (10.10.20.2) 56(84) bytes of data.
64 bytes from 10.10.20.2: icmp_seq=1 ttl=63 time=7.60 ms
^C
--- 10.10.20.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 7.601/7.601/7.601/0.000 ms

//ping跨网段的vm2
# ip netns exec vm1 ping 10.10.20.3
PING 10.10.20.3 (10.10.20.3) 56(84) bytes of data.
64 bytes from 10.10.20.3: icmp_seq=1 ttl=63 time=6.65 ms
^C
--- 10.10.20.3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 6.649/6.649/6.649/0.000 ms

查看sbdb的logical flow信息

# ovn-sbctl lflow-list
Datapath: "lr1" (971c4f82-1d3e-402c-b511-be9a412983f1)  Pipeline: ingress
  table=0 (lr_in_admission    ), priority=100  , match=(vlan.present || eth.src[40]), action=(drop;)
  table=0 (lr_in_admission    ), priority=50   , match=(eth.dst == 00:00:00:00:00:01 && inport == "lr1-ls1"), action=(xreg0[0..47] = 00:00:00:00:00:01; next;)
  table=0 (lr_in_admission    ), priority=50   , match=(eth.dst == 00:00:00:00:00:02 && inport == "lr1-ls2"), action=(xreg0[0..47] = 00:00:00:00:00:02; next;)
  table=0 (lr_in_admission    ), priority=50   , match=(eth.mcast && inport == "lr1-ls1"), action=(xreg0[0..47] = 00:00:00:00:00:01; next;)
  table=0 (lr_in_admission    ), priority=50   , match=(eth.mcast && inport == "lr1-ls2"), action=(xreg0[0..47] = 00:00:00:00:00:02; next;)
  table=1 (lr_in_lookup_neighbor), priority=100  , match=(arp.op == 2), action=(reg9[2] = lookup_arp(inport, arp.spa, arp.sha); next;)
  table=1 (lr_in_lookup_neighbor), priority=100  , match=(inport == "lr1-ls1" && arp.spa == 10.10.10.0/24 && arp.op == 1), action=(reg9[2] = lookup_arp(inport, arp.spa, arp.sha); next;)
  table=1 (lr_in_lookup_neighbor), priority=100  , match=(inport == "lr1-ls2" && arp.spa == 10.10.20.0/24 && arp.op == 1), action=(reg9[2] = lookup_arp(inport, arp.spa, arp.sha); next;)
  table=1 (lr_in_lookup_neighbor), priority=100  , match=(nd_na), action=(reg9[2] = lookup_nd(inport, nd.target, nd.tll); next;)
  table=1 (lr_in_lookup_neighbor), priority=100  , match=(nd_ns), action=(reg9[2] = lookup_nd(inport, ip6.src, nd.sll); next;)
  table=1 (lr_in_lookup_neighbor), priority=0    , match=(1), action=(reg9[2] = 1; next;)
  table=2 (lr_in_learn_neighbor), priority=100  , match=(reg9[2] == 1), action=(next;)
  table=2 (lr_in_learn_neighbor), priority=90   , match=(arp), action=(put_arp(inport, arp.spa, arp.sha); next;)
  table=2 (lr_in_learn_neighbor), priority=90   , match=(nd_na), action=(put_nd(inport, nd.target, nd.tll); next;)
  table=2 (lr_in_learn_neighbor), priority=90   , match=(nd_ns), action=(put_nd(inport, ip6.src, nd.sll); next;)
  table=3 (lr_in_ip_input     ), priority=100  , match=(ip4.src == {10.10.10.1, 10.10.10.255} && reg9[0] == 0), action=(drop;)
  table=3 (lr_in_ip_input     ), priority=100  , match=(ip4.src == {10.10.20.1, 10.10.20.255} && reg9[0] == 0), action=(drop;)
  table=3 (lr_in_ip_input     ), priority=100  , match=(ip4.src_mcast ||ip4.src == 255.255.255.255 || ip4.src == 127.0.0.0/8 || ip4.dst == 127.0.0.0/8 || ip4.src == 0.0.0.0/8 || ip4.dst == 0.0.0.0/8), action=(drop;)
  table=3 (lr_in_ip_input     ), priority=100  , match=(ip6.dst == fe80::200:ff:fe00:1 && udp.src == 547 && udp.dst == 546), action=(reg0 = 0; handle_dhcpv6_reply;)
  table=3 (lr_in_ip_input     ), priority=100  , match=(ip6.dst == fe80::200:ff:fe00:2 && udp.src == 547 && udp.dst == 546), action=(reg0 = 0; handle_dhcpv6_reply;)
  table=3 (lr_in_ip_input     ), priority=90   , match=(inport == "lr1-ls1" && arp.op == 1 && arp.tpa == 10.10.10.1 && arp.spa == 10.10.10.0/24), action=(eth.dst = eth.src; eth.src = xreg0[0..47]; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = xreg0[0..47]; arp.tpa = arp.spa; arp.spa = 10.10.10.1; outport = inport; flags.loopback = 1; output;)
  table=3 (lr_in_ip_input     ), priority=90   , match=(inport == "lr1-ls1" && ip6.dst == {fe80::200:ff:fe00:1, ff02::1:ff00:1} && nd_ns && nd.target == fe80::200:ff:fe00:1), action=(nd_na_router { eth.src = xreg0[0..47]; ip6.src = fe80::200:ff:fe00:1; nd.target = fe80::200:ff:fe00:1; nd.tll = xreg0[0..47]; outport = inport; flags.loopback = 1; output; };)
  table=3 (lr_in_ip_input     ), priority=90   , match=(inport == "lr1-ls2" && arp.op == 1 && arp.tpa == 10.10.20.1 && arp.spa == 10.10.20.0/24), action=(eth.dst = eth.src; eth.src = xreg0[0..47]; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = xreg0[0..47]; arp.tpa = arp.spa; arp.spa = 10.10.20.1; outport = inport; flags.loopback = 1; output;)
  table=3 (lr_in_ip_input     ), priority=90   , match=(inport == "lr1-ls2" && ip6.dst == {fe80::200:ff:fe00:2, ff02::1:ff00:2} && nd_ns && nd.target == fe80::200:ff:fe00:2), action=(nd_na_router { eth.src = xreg0[0..47]; ip6.src = fe80::200:ff:fe00:2; nd.target = fe80::200:ff:fe00:2; nd.tll = xreg0[0..47]; outport = inport; flags.loopback = 1; output; };)
  table=3 (lr_in_ip_input     ), priority=90   , match=(ip4.dst == 10.10.10.1 && icmp4.type == 8 && icmp4.code == 0), action=(ip4.dst <-> ip4.src; ip.ttl = 255; icmp4.type = 0; flags.loopback = 1; next; )
  table=3 (lr_in_ip_input     ), priority=90   , match=(ip4.dst == 10.10.20.1 && icmp4.type == 8 && icmp4.code == 0), action=(ip4.dst <-> ip4.src; ip.ttl = 255; icmp4.type = 0; flags.loopback = 1; next; )
  table=3 (lr_in_ip_input     ), priority=90   , match=(ip6.dst == fe80::200:ff:fe00:1 && icmp6.type == 128 && icmp6.code == 0), action=(ip6.dst <-> ip6.src; ip.ttl = 255; icmp6.type = 129; flags.loopback = 1; next; )
  table=3 (lr_in_ip_input     ), priority=90   , match=(ip6.dst == fe80::200:ff:fe00:2 && icmp6.type == 128 && icmp6.code == 0), action=(ip6.dst <-> ip6.src; ip.ttl = 255; icmp6.type = 129; flags.loopback = 1; next; )
  table=3 (lr_in_ip_input     ), priority=85   , match=(arp || nd), action=(drop;)
  table=3 (lr_in_ip_input     ), priority=84   , match=(nd_rs || nd_ra), action=(next;)
  table=3 (lr_in_ip_input     ), priority=83   , match=(ip6.mcast_rsvd), action=(drop;)
  table=3 (lr_in_ip_input     ), priority=82   , match=(ip4.mcast || ip6.mcast), action=(drop;)
  table=3 (lr_in_ip_input     ), priority=80   , match=(ip4 && ip4.dst == 10.10.10.1 && !ip.later_frag && sctp), action=(sctp_abort {eth.dst <-> eth.src; ip4.dst <-> ip4.src; next; };)
  table=3 (lr_in_ip_input     ), priority=80   , match=(ip4 && ip4.dst == 10.10.10.1 && !ip.later_frag && tcp), action=(tcp_reset {eth.dst <-> eth.src; ip4.dst <-> ip4.src; next; };)
  table=3 (lr_in_ip_input     ), priority=80   , match=(ip4 && ip4.dst == 10.10.10.1 && !ip.later_frag && udp), action=(icmp4 {eth.dst <-> eth.src; ip4.dst <-> ip4.src; ip.ttl = 255; icmp4.type = 3; icmp4.code = 3; next; };)
  table=3 (lr_in_ip_input     ), priority=80   , match=(ip4 && ip4.dst == 10.10.20.1 && !ip.later_frag && sctp), action=(sctp_abort {eth.dst <-> eth.src; ip4.dst <-> ip4.src; next; };)
  table=3 (lr_in_ip_input     ), priority=80   , match=(ip4 && ip4.dst == 10.10.20.1 && !ip.later_frag && tcp), action=(tcp_reset {eth.dst <-> eth.src; ip4.dst <-> ip4.src; next; };)
  table=3 (lr_in_ip_input     ), priority=80   , match=(ip4 && ip4.dst == 10.10.20.1 && !ip.later_frag && udp), action=(icmp4 {eth.dst <-> eth.src; ip4.dst <-> ip4.src; ip.ttl = 255; icmp4.type = 3; icmp4.code = 3; next; };)
  table=3 (lr_in_ip_input     ), priority=80   , match=(ip6 && ip6.dst == fe80::200:ff:fe00:1 && !ip.later_frag && sctp), action=(sctp_abort {eth.dst <-> eth.src; ip6.dst <-> ip6.src; next; };)
  table=3 (lr_in_ip_input     ), priority=80   , match=(ip6 && ip6.dst == fe80::200:ff:fe00:1 && !ip.later_frag && tcp), action=(tcp_reset {eth.dst <-> eth.src; ip6.dst <-> ip6.src; next; };)
  table=3 (lr_in_ip_input     ), priority=80   , match=(ip6 && ip6.dst == fe80::200:ff:fe00:1 && !ip.later_frag && udp), action=(icmp6 {eth.dst <-> eth.src; ip6.dst <-> ip6.src; ip.ttl = 255; icmp6.type = 1; icmp6.code = 4; next; };)
  table=3 (lr_in_ip_input     ), priority=80   , match=(ip6 && ip6.dst == fe80::200:ff:fe00:2 && !ip.later_frag && sctp), action=(sctp_abort {eth.dst <-> eth.src; ip6.dst <-> ip6.src; next; };)
  table=3 (lr_in_ip_input     ), priority=80   , match=(ip6 && ip6.dst == fe80::200:ff:fe00:2 && !ip.later_frag && tcp), action=(tcp_reset {eth.dst <-> eth.src; ip6.dst <-> ip6.src; next; };)
  table=3 (lr_in_ip_input     ), priority=80   , match=(ip6 && ip6.dst == fe80::200:ff:fe00:2 && !ip.later_frag && udp), action=(icmp6 {eth.dst <-> eth.src; ip6.dst <-> ip6.src; ip.ttl = 255; icmp6.type = 1; icmp6.code = 4; next; };)
  table=3 (lr_in_ip_input     ), priority=70   , match=(ip4 && ip4.dst == 10.10.10.1 && !ip.later_frag), action=(icmp4 {eth.dst <-> eth.src; ip4.dst <-> ip4.src; ip.ttl = 255; icmp4.type = 3; icmp4.code = 2; next; };)
  table=3 (lr_in_ip_input     ), priority=70   , match=(ip4 && ip4.dst == 10.10.20.1 && !ip.later_frag), action=(icmp4 {eth.dst <-> eth.src; ip4.dst <-> ip4.src; ip.ttl = 255; icmp4.type = 3; icmp4.code = 2; next; };)
  table=3 (lr_in_ip_input     ), priority=70   , match=(ip6 && ip6.dst == fe80::200:ff:fe00:1 && !ip.later_frag), action=(icmp6 {eth.dst <-> eth.src; ip6.dst <-> ip6.src; ip.ttl = 255; icmp6.type = 1; icmp6.code = 3; next; };)
  table=3 (lr_in_ip_input     ), priority=70   , match=(ip6 && ip6.dst == fe80::200:ff:fe00:2 && !ip.later_frag), action=(icmp6 {eth.dst <-> eth.src; ip6.dst <-> ip6.src; ip.ttl = 255; icmp6.type = 1; icmp6.code = 3; next; };)
  table=3 (lr_in_ip_input     ), priority=60   , match=(ip4.dst == {10.10.10.1}), action=(drop;)
  table=3 (lr_in_ip_input     ), priority=60   , match=(ip4.dst == {10.10.20.1}), action=(drop;)
  table=3 (lr_in_ip_input     ), priority=60   , match=(ip6.dst == {fe80::200:ff:fe00:1}), action=(drop;)
  table=3 (lr_in_ip_input     ), priority=60   , match=(ip6.dst == {fe80::200:ff:fe00:2}), action=(drop;)
  table=3 (lr_in_ip_input     ), priority=50   , match=(eth.bcast), action=(drop;)
  table=3 (lr_in_ip_input     ), priority=40   , match=(inport == "lr1-ls1" && ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst <-> eth.src; icmp4.type = 11; /* Time exceeded */ icmp4.code = 0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src = 10.10.10.1; ip.ttl = 255; next; };)
  table=3 (lr_in_ip_input     ), priority=40   , match=(inport == "lr1-ls2" && ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst <-> eth.src; icmp4.type = 11; /* Time exceeded */ icmp4.code = 0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src = 10.10.20.1; ip.ttl = 255; next; };)
  table=3 (lr_in_ip_input     ), priority=30   , match=(ip4 && ip.ttl == {0, 1}), action=(drop;)
  table=3 (lr_in_ip_input     ), priority=0    , match=(1), action=(next;)
  table=4 (lr_in_defrag       ), priority=0    , match=(1), action=(next;)
  table=5 (lr_in_unsnat       ), priority=0    , match=(1), action=(next;)
  table=6 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
  table=7 (lr_in_ecmp_stateful), priority=0    , match=(1), action=(next;)
  table=8 (lr_in_nd_ra_options), priority=0    , match=(1), action=(next;)
  table=9 (lr_in_nd_ra_response), priority=0    , match=(1), action=(next;)
  table=10(lr_in_ip_routing   ), priority=550  , match=(nd_rs || nd_ra), action=(drop;)
  table=10(lr_in_ip_routing   ), priority=129  , match=(inport == "lr1-ls1" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[0..15] = 0; xxreg0 = ip6.dst; xxreg1 = fe80::200:ff:fe00:1; eth.src = 00:00:00:00:00:01; outport = "lr1-ls1"; flags.loopback = 1; next;)
  table=10(lr_in_ip_routing   ), priority=129  , match=(inport == "lr1-ls2" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[0..15] = 0; xxreg0 = ip6.dst; xxreg1 = fe80::200:ff:fe00:2; eth.src = 00:00:00:00:00:02; outport = "lr1-ls2"; flags.loopback = 1; next;)
  table=10(lr_in_ip_routing   ), priority=49   , match=(ip4.dst == 10.10.10.0/24), action=(ip.ttl--; reg8[0..15] = 0; reg0 = ip4.dst; reg1 = 10.10.10.1; eth.src = 00:00:00:00:00:01; outport = "lr1-ls1"; flags.loopback = 1; next;)
  table=10(lr_in_ip_routing   ), priority=49   , match=(ip4.dst == 10.10.20.0/24), action=(ip.ttl--; reg8[0..15] = 0; reg0 = ip4.dst; reg1 = 10.10.20.1; eth.src = 00:00:00:00:00:02; outport = "lr1-ls2"; flags.loopback = 1; next;)
  table=11(lr_in_ip_routing_ecmp), priority=150  , match=(reg8[0..15] == 0), action=(next;)
  table=12(lr_in_policy       ), priority=0    , match=(1), action=(reg8[0..15] = 0; next;)
  table=13(lr_in_policy_ecmp  ), priority=150  , match=(reg8[0..15] == 0), action=(next;)
  table=14(lr_in_arp_resolve  ), priority=500  , match=(ip4.mcast || ip6.mcast), action=(next;)
  table=14(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr1-ls1" && reg0 == 10.10.10.2), action=(eth.dst = 00:00:00:00:00:03; next;)
  table=14(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr1-ls1" && reg0 == 10.10.10.3), action=(eth.dst = 00:00:00:00:00:04; next;)
  table=14(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr1-ls2" && reg0 == 10.10.20.2), action=(eth.dst = 00:00:00:00:00:03; next;)
  table=14(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr1-ls2" && reg0 == 10.10.20.3), action=(eth.dst = 00:00:00:00:00:04; next;)
  table=14(lr_in_arp_resolve  ), priority=0    , match=(ip4), action=(get_arp(outport, reg0); next;)
  table=14(lr_in_arp_resolve  ), priority=0    , match=(ip6), action=(get_nd(outport, xxreg0); next;)
  table=15(lr_in_chk_pkt_len  ), priority=0    , match=(1), action=(next;)
  table=16(lr_in_larger_pkts  ), priority=0    , match=(1), action=(next;)
  table=17(lr_in_gw_redirect  ), priority=0    , match=(1), action=(next;)
  table=18(lr_in_arp_request  ), priority=100  , match=(eth.dst == 00:00:00:00:00:00 && ip4), action=(arp { eth.dst = ff:ff:ff:ff:ff:ff; arp.spa = reg1; arp.tpa = reg0; arp.op = 1; output; };)
  table=18(lr_in_arp_request  ), priority=100  , match=(eth.dst == 00:00:00:00:00:00 && ip6), action=(nd_ns { nd.target = xxreg0; output; };)
  table=18(lr_in_arp_request  ), priority=0    , match=(1), action=(output;)
Datapath: "lr1" (971c4f82-1d3e-402c-b511-be9a412983f1)  Pipeline: egress
  table=0 (lr_out_undnat      ), priority=0    , match=(1), action=(next;)
  table=1 (lr_out_snat        ), priority=120  , match=(nd_ns), action=(next;)
  table=1 (lr_out_snat        ), priority=0    , match=(1), action=(next;)
  table=2 (lr_out_egr_loop    ), priority=0    , match=(1), action=(next;)
  table=3 (lr_out_delivery    ), priority=100  , match=(outport == "lr1-ls1"), action=(output;)
  table=3 (lr_out_delivery    ), priority=100  , match=(outport == "lr1-ls2"), action=(output;)
Datapath: "ls1" (919643ab-44c5-4368-b6ff-f701093af973)  Pipeline: ingress
  table=0 (ls_in_port_sec_l2  ), priority=100  , match=(eth.src[40]), action=(drop;)
  table=0 (ls_in_port_sec_l2  ), priority=100  , match=(vlan.present), action=(drop;)
  table=0 (ls_in_port_sec_l2  ), priority=50   , match=(inport == "ls1-lr1"), action=(next;)
  table=0 (ls_in_port_sec_l2  ), priority=50   , match=(inport == "ls1-vm1" && eth.src == {00:00:00:00:00:03}), action=(next;)
  table=0 (ls_in_port_sec_l2  ), priority=50   , match=(inport == "ls1-vm2" && eth.src == {00:00:00:00:00:04}), action=(next;)
  table=1 (ls_in_port_sec_ip  ), priority=90   , match=(inport == "ls1-vm1" && eth.src == 00:00:00:00:00:03 && ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 67), action=(next;)
  table=1 (ls_in_port_sec_ip  ), priority=90   , match=(inport == "ls1-vm1" && eth.src == 00:00:00:00:00:03 && ip4.src == {10.10.10.2}), action=(next;)
  table=1 (ls_in_port_sec_ip  ), priority=90   , match=(inport == "ls1-vm2" && eth.src == 00:00:00:00:00:04 && ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 67), action=(next;)
  table=1 (ls_in_port_sec_ip  ), priority=90   , match=(inport == "ls1-vm2" && eth.src == 00:00:00:00:00:04 && ip4.src == {10.10.10.3}), action=(next;)
  table=1 (ls_in_port_sec_ip  ), priority=80   , match=(inport == "ls1-vm1" && eth.src == 00:00:00:00:00:03 && ip), action=(drop;)
  table=1 (ls_in_port_sec_ip  ), priority=80   , match=(inport == "ls1-vm2" && eth.src == 00:00:00:00:00:04 && ip), action=(drop;)
  table=1 (ls_in_port_sec_ip  ), priority=0    , match=(1), action=(next;)
  table=2 (ls_in_port_sec_nd  ), priority=90   , match=(inport == "ls1-vm1" && eth.src == 00:00:00:00:00:03 && arp.sha == 00:00:00:00:00:03 && arp.spa == {10.10.10.2}), action=(next;)
  table=2 (ls_in_port_sec_nd  ), priority=90   , match=(inport == "ls1-vm2" && eth.src == 00:00:00:00:00:04 && arp.sha == 00:00:00:00:00:04 && arp.spa == {10.10.10.3}), action=(next;)
  table=2 (ls_in_port_sec_nd  ), priority=80   , match=(inport == "ls1-vm1" && (arp || nd)), action=(drop;)
  table=2 (ls_in_port_sec_nd  ), priority=80   , match=(inport == "ls1-vm2" && (arp || nd)), action=(drop;)
  table=2 (ls_in_port_sec_nd  ), priority=0    , match=(1), action=(next;)
  table=3 (ls_in_lookup_fdb   ), priority=0    , match=(1), action=(next;)
  table=4 (ls_in_put_fdb      ), priority=0    , match=(1), action=(next;)
  table=5 (ls_in_pre_acl      ), priority=110  , match=(eth.dst == $svc_monitor_mac), action=(next;)
  table=5 (ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
  table=6 (ls_in_pre_lb       ), priority=110  , match=(eth.dst == $svc_monitor_mac), action=(next;)
  table=6 (ls_in_pre_lb       ), priority=110  , match=(ip && inport == "ls1-lr1"), action=(next;)
  table=6 (ls_in_pre_lb       ), priority=110  , match=(nd || nd_rs || nd_ra || mldv1 || mldv2), action=(next;)
  table=6 (ls_in_pre_lb       ), priority=0    , match=(1), action=(next;)
  table=7 (ls_in_pre_stateful ), priority=100  , match=(reg0[0] == 1), action=(ct_next;)
  table=7 (ls_in_pre_stateful ), priority=0    , match=(1), action=(next;)
  table=8 (ls_in_acl_hint     ), priority=0    , match=(1), action=(next;)
  table=9 (ls_in_acl          ), priority=34000, match=(eth.dst == $svc_monitor_mac), action=(next;)
  table=9 (ls_in_acl          ), priority=0    , match=(1), action=(next;)
  table=10(ls_in_qos_mark     ), priority=0    , match=(1), action=(next;)
  table=11(ls_in_qos_meter    ), priority=0    , match=(1), action=(next;)
  table=12(ls_in_lb           ), priority=0    , match=(1), action=(next;)
  table=13(ls_in_stateful     ), priority=100  , match=(reg0[1] == 1), action=(ct_commit { ct_label.blocked = 0; }; next;)
  table=13(ls_in_stateful     ), priority=100  , match=(reg0[2] == 1 && ip4 && sctp), action=(reg1 = ip4.dst; reg2[0..15] = sctp.dst; ct_lb;)
  table=13(ls_in_stateful     ), priority=100  , match=(reg0[2] == 1 && ip4 && tcp), action=(reg1 = ip4.dst; reg2[0..15] = tcp.dst; ct_lb;)
  table=13(ls_in_stateful     ), priority=100  , match=(reg0[2] == 1 && ip4 && udp), action=(reg1 = ip4.dst; reg2[0..15] = udp.dst; ct_lb;)
  table=13(ls_in_stateful     ), priority=100  , match=(reg0[2] == 1 && ip6 && sctp), action=(xxreg1 = ip6.dst; reg2[0..15] = sctp.dst; ct_lb;)
  table=13(ls_in_stateful     ), priority=100  , match=(reg0[2] == 1 && ip6 && tcp), action=(xxreg1 = ip6.dst; reg2[0..15] = tcp.dst; ct_lb;)
  table=13(ls_in_stateful     ), priority=100  , match=(reg0[2] == 1 && ip6 && udp), action=(xxreg1 = ip6.dst; reg2[0..15] = udp.dst; ct_lb;)
  table=13(ls_in_stateful     ), priority=0    , match=(1), action=(next;)
  table=14(ls_in_pre_hairpin  ), priority=0    , match=(1), action=(next;)
  table=15(ls_in_nat_hairpin  ), priority=0    , match=(1), action=(next;)
  table=16(ls_in_hairpin      ), priority=0    , match=(1), action=(next;)
  table=17(ls_in_arp_rsp      ), priority=100  , match=(arp.tpa == 10.10.10.2 && arp.op == 1 && inport == "ls1-vm1"), action=(next;)
  table=17(ls_in_arp_rsp      ), priority=100  , match=(arp.tpa == 10.10.10.3 && arp.op == 1 && inport == "ls1-vm2"), action=(next;)
  table=17(ls_in_arp_rsp      ), priority=50   , match=(arp.tpa == 10.10.10.2 && arp.op == 1), action=(eth.dst = eth.src; eth.src = 00:00:00:00:00:03; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = 00:00:00:00:00:03; arp.tpa = arp.spa; arp.spa = 10.10.10.2; outport = inport; flags.loopback = 1; output;)
  table=17(ls_in_arp_rsp      ), priority=50   , match=(arp.tpa == 10.10.10.3 && arp.op == 1), action=(eth.dst = eth.src; eth.src = 00:00:00:00:00:04; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = 00:00:00:00:00:04; arp.tpa = arp.spa; arp.spa = 10.10.10.3; outport = inport; flags.loopback = 1; output;)
  table=17(ls_in_arp_rsp      ), priority=0    , match=(1), action=(next;)
  table=18(ls_in_dhcp_options ), priority=100  , match=(inport == "ls1-vm1" && eth.src == 00:00:00:00:00:03 && ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 67), action=(reg0[3] = put_dhcp_opts(offerip = 10.10.10.2, lease_time = 3600, netmask = 255.255.255.0, router = 10.10.10.1, server_id = 10.10.10.1); next;)
  table=18(ls_in_dhcp_options ), priority=100  , match=(inport == "ls1-vm1" && eth.src == 00:00:00:00:00:03 && ip4.src == 10.10.10.2 && ip4.dst == {10.10.10.1, 255.255.255.255} && udp.src == 68 && udp.dst == 67), action=(reg0[3] = put_dhcp_opts(offerip = 10.10.10.2, lease_time = 3600, netmask = 255.255.255.0, router = 10.10.10.1, server_id = 10.10.10.1); next;)
  table=18(ls_in_dhcp_options ), priority=100  , match=(inport == "ls1-vm2" && eth.src == 00:00:00:00:00:04 && ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 67), action=(reg0[3] = put_dhcp_opts(offerip = 10.10.10.3, lease_time = 3600, netmask = 255.255.255.0, router = 10.10.10.1, server_id = 10.10.10.1); next;)
  table=18(ls_in_dhcp_options ), priority=100  , match=(inport == "ls1-vm2" && eth.src == 00:00:00:00:00:04 && ip4.src == 10.10.10.3 && ip4.dst == {10.10.10.1, 255.255.255.255} && udp.src == 68 && udp.dst == 67), action=(reg0[3] = put_dhcp_opts(offerip = 10.10.10.3, lease_time = 3600, netmask = 255.255.255.0, router = 10.10.10.1, server_id = 10.10.10.1); next;)
  table=18(ls_in_dhcp_options ), priority=0    , match=(1), action=(next;)
  table=19(ls_in_dhcp_response), priority=100  , match=(inport == "ls1-vm1" && eth.src == 00:00:00:00:00:03 && ip4 && udp.src == 68 && udp.dst == 67 && reg0[3]), action=(eth.dst = eth.src; eth.src = 00:00:00:00:00:01; ip4.src = 10.10.10.1; udp.src = 67; udp.dst = 68; outport = inport; flags.loopback = 1; output;)
  table=19(ls_in_dhcp_response), priority=100  , match=(inport == "ls1-vm2" && eth.src == 00:00:00:00:00:04 && ip4 && udp.src == 68 && udp.dst == 67 && reg0[3]), action=(eth.dst = eth.src; eth.src = 00:00:00:00:00:01; ip4.src = 10.10.10.1; udp.src = 67; udp.dst = 68; outport = inport; flags.loopback = 1; output;)
  table=19(ls_in_dhcp_response), priority=0    , match=(1), action=(next;)
  table=20(ls_in_dns_lookup   ), priority=0    , match=(1), action=(next;)
  table=21(ls_in_dns_response ), priority=0    , match=(1), action=(next;)
  table=22(ls_in_external_port), priority=0    , match=(1), action=(next;)
  table=23(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == $svc_monitor_mac), action=(handle_svc_check(inport);)
  table=23(ls_in_l2_lkup      ), priority=80   , match=(flags[1] == 0 && arp.op == 1 && arp.tpa == { 10.10.10.1}), action=(clone {outport = "ls1-lr1"; output; }; outport = "_MC_flood_l2"; output;)
  table=23(ls_in_l2_lkup      ), priority=80   , match=(flags[1] == 0 && nd_ns && nd.target == { fe80::200:ff:fe00:1}), action=(clone {outport = "ls1-lr1"; output; }; outport = "_MC_flood_l2"; output;)
  table=23(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:00:01} && (arp.op == 1 || nd_ns)), action=(outport = "_MC_flood_l2"; output;)
  table=23(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), action=(outport = "_MC_flood"; output;)
  table=23(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 00:00:00:00:00:01), action=(outport = "ls1-lr1"; output;)
  table=23(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 00:00:00:00:00:03), action=(outport = "ls1-vm1"; output;)
  table=23(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 00:00:00:00:00:04), action=(outport = "ls1-vm2"; output;)
  table=23(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = get_fdb(eth.dst); next;)
  table=24(ls_in_l2_unknown   ), priority=50   , match=(outport == "none"), action=(drop;)
  table=24(ls_in_l2_unknown   ), priority=0    , match=(1), action=(output;)
Datapath: "ls1" (919643ab-44c5-4368-b6ff-f701093af973)  Pipeline: egress
  table=0 (ls_out_pre_lb      ), priority=110  , match=(eth.src == $svc_monitor_mac), action=(next;)
  table=0 (ls_out_pre_lb      ), priority=110  , match=(ip && outport == "ls1-lr1"), action=(next;)
  table=0 (ls_out_pre_lb      ), priority=110  , match=(nd || nd_rs || nd_ra || mldv1 || mldv2), action=(next;)
  table=0 (ls_out_pre_lb      ), priority=0    , match=(1), action=(next;)
  table=1 (ls_out_pre_acl     ), priority=110  , match=(eth.src == $svc_monitor_mac), action=(next;)
  table=1 (ls_out_pre_acl     ), priority=0    , match=(1), action=(next;)
  table=2 (ls_out_pre_stateful), priority=100  , match=(reg0[0] == 1), action=(ct_next;)
  table=2 (ls_out_pre_stateful), priority=0    , match=(1), action=(next;)
  table=3 (ls_out_lb          ), priority=0    , match=(1), action=(next;)
  table=4 (ls_out_acl_hint    ), priority=0    , match=(1), action=(next;)
  table=5 (ls_out_acl         ), priority=34000, match=(eth.src == $svc_monitor_mac), action=(next;)
  table=5 (ls_out_acl         ), priority=34000, match=(outport == "ls1-vm1" && eth.src == 00:00:00:00:00:01 && ip4.src == 10.10.10.1 && udp && udp.src == 67 && udp.dst == 68), action=(next;)
  table=5 (ls_out_acl         ), priority=34000, match=(outport == "ls1-vm2" && eth.src == 00:00:00:00:00:01 && ip4.src == 10.10.10.1 && udp && udp.src == 67 && udp.dst == 68), action=(next;)
  table=5 (ls_out_acl         ), priority=0    , match=(1), action=(next;)
  table=6 (ls_out_qos_mark    ), priority=0    , match=(1), action=(next;)
  table=7 (ls_out_qos_meter   ), priority=0    , match=(1), action=(next;)
  table=8 (ls_out_stateful    ), priority=100  , match=(reg0[1] == 1), action=(ct_commit { ct_label.blocked = 0; }; next;)
  table=8 (ls_out_stateful    ), priority=100  , match=(reg0[2] == 1), action=(ct_lb;)
  table=8 (ls_out_stateful    ), priority=0    , match=(1), action=(next;)
  table=9 (ls_out_port_sec_ip ), priority=90   , match=(outport == "ls1-vm1" && eth.dst == 00:00:00:00:00:03 && ip4.dst == {255.255.255.255, 224.0.0.0/4, 10.10.10.2}), action=(next;)
  table=9 (ls_out_port_sec_ip ), priority=90   , match=(outport == "ls1-vm2" && eth.dst == 00:00:00:00:00:04 && ip4.dst == {255.255.255.255, 224.0.0.0/4, 10.10.10.3}), action=(next;)
  table=9 (ls_out_port_sec_ip ), priority=80   , match=(outport == "ls1-vm1" && eth.dst == 00:00:00:00:00:03 && ip), action=(drop;)
  table=9 (ls_out_port_sec_ip ), priority=80   , match=(outport == "ls1-vm2" && eth.dst == 00:00:00:00:00:04 && ip), action=(drop;)
  table=9 (ls_out_port_sec_ip ), priority=0    , match=(1), action=(next;)
  table=10(ls_out_port_sec_l2 ), priority=100  , match=(eth.mcast), action=(output;)
  table=10(ls_out_port_sec_l2 ), priority=50   , match=(outport == "ls1-lr1"), action=(output;)
  table=10(ls_out_port_sec_l2 ), priority=50   , match=(outport == "ls1-vm1" && eth.dst == {00:00:00:00:00:03}), action=(output;)
  table=10(ls_out_port_sec_l2 ), priority=50   , match=(outport == "ls1-vm2" && eth.dst == {00:00:00:00:00:04}), action=(output;)
Datapath: "ls2" (15665d7c-8d79-469c-8202-1a5d626ff297)  Pipeline: ingress
  table=0 (ls_in_port_sec_l2  ), priority=100  , match=(eth.src[40]), action=(drop;)
  table=0 (ls_in_port_sec_l2  ), priority=100  , match=(vlan.present), action=(drop;)
  table=0 (ls_in_port_sec_l2  ), priority=50   , match=(inport == "ls2-lr1"), action=(next;)
  table=0 (ls_in_port_sec_l2  ), priority=50   , match=(inport == "ls2-vm1" && eth.src == {00:00:00:00:00:03}), action=(next;)
  table=0 (ls_in_port_sec_l2  ), priority=50   , match=(inport == "ls2-vm2" && eth.src == {00:00:00:00:00:04}), action=(next;)
  table=1 (ls_in_port_sec_ip  ), priority=90   , match=(inport == "ls2-vm1" && eth.src == 00:00:00:00:00:03 && ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 67), action=(next;)
  table=1 (ls_in_port_sec_ip  ), priority=90   , match=(inport == "ls2-vm1" && eth.src == 00:00:00:00:00:03 && ip4.src == {10.10.20.2}), action=(next;)
  table=1 (ls_in_port_sec_ip  ), priority=90   , match=(inport == "ls2-vm2" && eth.src == 00:00:00:00:00:04 && ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 67), action=(next;)
  table=1 (ls_in_port_sec_ip  ), priority=90   , match=(inport == "ls2-vm2" && eth.src == 00:00:00:00:00:04 && ip4.src == {10.10.20.3}), action=(next;)
  table=1 (ls_in_port_sec_ip  ), priority=80   , match=(inport == "ls2-vm1" && eth.src == 00:00:00:00:00:03 && ip), action=(drop;)
  table=1 (ls_in_port_sec_ip  ), priority=80   , match=(inport == "ls2-vm2" && eth.src == 00:00:00:00:00:04 && ip), action=(drop;)
  table=1 (ls_in_port_sec_ip  ), priority=0    , match=(1), action=(next;)
  table=2 (ls_in_port_sec_nd  ), priority=90   , match=(inport == "ls2-vm1" && eth.src == 00:00:00:00:00:03 && arp.sha == 00:00:00:00:00:03 && arp.spa == {10.10.20.2}), action=(next;)
  table=2 (ls_in_port_sec_nd  ), priority=90   , match=(inport == "ls2-vm2" && eth.src == 00:00:00:00:00:04 && arp.sha == 00:00:00:00:00:04 && arp.spa == {10.10.20.3}), action=(next;)
  table=2 (ls_in_port_sec_nd  ), priority=80   , match=(inport == "ls2-vm1" && (arp || nd)), action=(drop;)
  table=2 (ls_in_port_sec_nd  ), priority=80   , match=(inport == "ls2-vm2" && (arp || nd)), action=(drop;)
  table=2 (ls_in_port_sec_nd  ), priority=0    , match=(1), action=(next;)
  table=3 (ls_in_lookup_fdb   ), priority=0    , match=(1), action=(next;)
  table=4 (ls_in_put_fdb      ), priority=0    , match=(1), action=(next;)
  table=5 (ls_in_pre_acl      ), priority=110  , match=(eth.dst == $svc_monitor_mac), action=(next;)
  table=5 (ls_in_pre_acl      ), priority=0    , match=(1), action=(next;)
  table=6 (ls_in_pre_lb       ), priority=110  , match=(eth.dst == $svc_monitor_mac), action=(next;)
  table=6 (ls_in_pre_lb       ), priority=110  , match=(ip && inport == "ls2-lr1"), action=(next;)
  table=6 (ls_in_pre_lb       ), priority=110  , match=(nd || nd_rs || nd_ra || mldv1 || mldv2), action=(next;)
  table=6 (ls_in_pre_lb       ), priority=0    , match=(1), action=(next;)
  table=7 (ls_in_pre_stateful ), priority=100  , match=(reg0[0] == 1), action=(ct_next;)
  table=7 (ls_in_pre_stateful ), priority=0    , match=(1), action=(next;)
  table=8 (ls_in_acl_hint     ), priority=0    , match=(1), action=(next;)
  table=9 (ls_in_acl          ), priority=34000, match=(eth.dst == $svc_monitor_mac), action=(next;)
  table=9 (ls_in_acl          ), priority=0    , match=(1), action=(next;)
  table=10(ls_in_qos_mark     ), priority=0    , match=(1), action=(next;)
  table=11(ls_in_qos_meter    ), priority=0    , match=(1), action=(next;)
  table=12(ls_in_lb           ), priority=0    , match=(1), action=(next;)
  table=13(ls_in_stateful     ), priority=100  , match=(reg0[1] == 1), action=(ct_commit { ct_label.blocked = 0; }; next;)
  table=13(ls_in_stateful     ), priority=100  , match=(reg0[2] == 1 && ip4 && sctp), action=(reg1 = ip4.dst; reg2[0..15] = sctp.dst; ct_lb;)
  table=13(ls_in_stateful     ), priority=100  , match=(reg0[2] == 1 && ip4 && tcp), action=(reg1 = ip4.dst; reg2[0..15] = tcp.dst; ct_lb;)
  table=13(ls_in_stateful     ), priority=100  , match=(reg0[2] == 1 && ip4 && udp), action=(reg1 = ip4.dst; reg2[0..15] = udp.dst; ct_lb;)
  table=13(ls_in_stateful     ), priority=100  , match=(reg0[2] == 1 && ip6 && sctp), action=(xxreg1 = ip6.dst; reg2[0..15] = sctp.dst; ct_lb;)
  table=13(ls_in_stateful     ), priority=100  , match=(reg0[2] == 1 && ip6 && tcp), action=(xxreg1 = ip6.dst; reg2[0..15] = tcp.dst; ct_lb;)
  table=13(ls_in_stateful     ), priority=100  , match=(reg0[2] == 1 && ip6 && udp), action=(xxreg1 = ip6.dst; reg2[0..15] = udp.dst; ct_lb;)
  table=13(ls_in_stateful     ), priority=0    , match=(1), action=(next;)
  table=14(ls_in_pre_hairpin  ), priority=0    , match=(1), action=(next;)
  table=15(ls_in_nat_hairpin  ), priority=0    , match=(1), action=(next;)
  table=16(ls_in_hairpin      ), priority=0    , match=(1), action=(next;)
  table=17(ls_in_arp_rsp      ), priority=100  , match=(arp.tpa == 10.10.20.2 && arp.op == 1 && inport == "ls2-vm1"), action=(next;)
  table=17(ls_in_arp_rsp      ), priority=100  , match=(arp.tpa == 10.10.20.3 && arp.op == 1 && inport == "ls2-vm2"), action=(next;)
  table=17(ls_in_arp_rsp      ), priority=50   , match=(arp.tpa == 10.10.20.2 && arp.op == 1), action=(eth.dst = eth.src; eth.src = 00:00:00:00:00:03; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = 00:00:00:00:00:03; arp.tpa = arp.spa; arp.spa = 10.10.20.2; outport = inport; flags.loopback = 1; output;)
  table=17(ls_in_arp_rsp      ), priority=50   , match=(arp.tpa == 10.10.20.3 && arp.op == 1), action=(eth.dst = eth.src; eth.src = 00:00:00:00:00:04; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = 00:00:00:00:00:04; arp.tpa = arp.spa; arp.spa = 10.10.20.3; outport = inport; flags.loopback = 1; output;)
  table=17(ls_in_arp_rsp      ), priority=0    , match=(1), action=(next;)
  table=18(ls_in_dhcp_options ), priority=100  , match=(inport == "ls2-vm1" && eth.src == 00:00:00:00:00:03 && ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 67), action=(reg0[3] = put_dhcp_opts(offerip = 10.10.20.2, lease_time = 3600, netmask = 255.255.255.0, router = 10.10.20.1, server_id = 10.10.20.1); next;)
  table=18(ls_in_dhcp_options ), priority=100  , match=(inport == "ls2-vm1" && eth.src == 00:00:00:00:00:03 && ip4.src == 10.10.20.2 && ip4.dst == {10.10.20.1, 255.255.255.255} && udp.src == 68 && udp.dst == 67), action=(reg0[3] = put_dhcp_opts(offerip = 10.10.20.2, lease_time = 3600, netmask = 255.255.255.0, router = 10.10.20.1, server_id = 10.10.20.1); next;)
  table=18(ls_in_dhcp_options ), priority=100  , match=(inport == "ls2-vm2" && eth.src == 00:00:00:00:00:04 && ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 67), action=(reg0[3] = put_dhcp_opts(offerip = 10.10.20.3, lease_time = 3600, netmask = 255.255.255.0, router = 10.10.20.1, server_id = 10.10.20.1); next;)
  table=18(ls_in_dhcp_options ), priority=100  , match=(inport == "ls2-vm2" && eth.src == 00:00:00:00:00:04 && ip4.src == 10.10.20.3 && ip4.dst == {10.10.20.1, 255.255.255.255} && udp.src == 68 && udp.dst == 67), action=(reg0[3] = put_dhcp_opts(offerip = 10.10.20.3, lease_time = 3600, netmask = 255.255.255.0, router = 10.10.20.1, server_id = 10.10.20.1); next;)
  table=18(ls_in_dhcp_options ), priority=0    , match=(1), action=(next;)
  table=19(ls_in_dhcp_response), priority=100  , match=(inport == "ls2-vm1" && eth.src == 00:00:00:00:00:03 && ip4 && udp.src == 68 && udp.dst == 67 && reg0[3]), action=(eth.dst = eth.src; eth.src = 00:00:00:00:00:02; ip4.src = 10.10.20.1; udp.src = 67; udp.dst = 68; outport = inport; flags.loopback = 1; output;)
  table=19(ls_in_dhcp_response), priority=100  , match=(inport == "ls2-vm2" && eth.src == 00:00:00:00:00:04 && ip4 && udp.src == 68 && udp.dst == 67 && reg0[3]), action=(eth.dst = eth.src; eth.src = 00:00:00:00:00:02; ip4.src = 10.10.20.1; udp.src = 67; udp.dst = 68; outport = inport; flags.loopback = 1; output;)
  table=19(ls_in_dhcp_response), priority=0    , match=(1), action=(next;)
  table=20(ls_in_dns_lookup   ), priority=0    , match=(1), action=(next;)
  table=21(ls_in_dns_response ), priority=0    , match=(1), action=(next;)
  table=22(ls_in_external_port), priority=0    , match=(1), action=(next;)
  table=23(ls_in_l2_lkup      ), priority=110  , match=(eth.dst == $svc_monitor_mac), action=(handle_svc_check(inport);)
  table=23(ls_in_l2_lkup      ), priority=80   , match=(flags[1] == 0 && arp.op == 1 && arp.tpa == { 10.10.20.1}), action=(clone {outport = "ls2-lr1"; output; }; outport = "_MC_flood_l2"; output;)
  table=23(ls_in_l2_lkup      ), priority=80   , match=(flags[1] == 0 && nd_ns && nd.target == { fe80::200:ff:fe00:2}), action=(clone {outport = "ls2-lr1"; output; }; outport = "_MC_flood_l2"; output;)
  table=23(ls_in_l2_lkup      ), priority=75   , match=(eth.src == {00:00:00:00:00:02} && (arp.op == 1 || nd_ns)), action=(outport = "_MC_flood_l2"; output;)
  table=23(ls_in_l2_lkup      ), priority=70   , match=(eth.mcast), action=(outport = "_MC_flood"; output;)
  table=23(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 00:00:00:00:00:02), action=(outport = "ls2-lr1"; output;)
  table=23(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 00:00:00:00:00:03), action=(outport = "ls2-vm1"; output;)
  table=23(ls_in_l2_lkup      ), priority=50   , match=(eth.dst == 00:00:00:00:00:04), action=(outport = "ls2-vm2"; output;)
  table=23(ls_in_l2_lkup      ), priority=0    , match=(1), action=(outport = get_fdb(eth.dst); next;)
  table=24(ls_in_l2_unknown   ), priority=50   , match=(outport == "none"), action=(drop;)
  table=24(ls_in_l2_unknown   ), priority=0    , match=(1), action=(output;)
Datapath: "ls2" (15665d7c-8d79-469c-8202-1a5d626ff297)  Pipeline: egress
  table=0 (ls_out_pre_lb      ), priority=110  , match=(eth.src == $svc_monitor_mac), action=(next;)
  table=0 (ls_out_pre_lb      ), priority=110  , match=(ip && outport == "ls2-lr1"), action=(next;)
  table=0 (ls_out_pre_lb      ), priority=110  , match=(nd || nd_rs || nd_ra || mldv1 || mldv2), action=(next;)
  table=0 (ls_out_pre_lb      ), priority=0    , match=(1), action=(next;)
  table=1 (ls_out_pre_acl     ), priority=110  , match=(eth.src == $svc_monitor_mac), action=(next;)
  table=1 (ls_out_pre_acl     ), priority=0    , match=(1), action=(next;)
  table=2 (ls_out_pre_stateful), priority=100  , match=(reg0[0] == 1), action=(ct_next;)
  table=2 (ls_out_pre_stateful), priority=0    , match=(1), action=(next;)
  table=3 (ls_out_lb          ), priority=0    , match=(1), action=(next;)
  table=4 (ls_out_acl_hint    ), priority=0    , match=(1), action=(next;)
  table=5 (ls_out_acl         ), priority=34000, match=(eth.src == $svc_monitor_mac), action=(next;)
  table=5 (ls_out_acl         ), priority=34000, match=(outport == "ls2-vm1" && eth.src == 00:00:00:00:00:02 && ip4.src == 10.10.20.1 && udp && udp.src == 67 && udp.dst == 68), action=(next;)
  table=5 (ls_out_acl         ), priority=34000, match=(outport == "ls2-vm2" && eth.src == 00:00:00:00:00:02 && ip4.src == 10.10.20.1 && udp && udp.src == 67 && udp.dst == 68), action=(next;)
  table=5 (ls_out_acl         ), priority=0    , match=(1), action=(next;)
  table=6 (ls_out_qos_mark    ), priority=0    , match=(1), action=(next;)
  table=7 (ls_out_qos_meter   ), priority=0    , match=(1), action=(next;)
  table=8 (ls_out_stateful    ), priority=100  , match=(reg0[1] == 1), action=(ct_commit { ct_label.blocked = 0; }; next;)
  table=8 (ls_out_stateful    ), priority=100  , match=(reg0[2] == 1), action=(ct_lb;)
  table=8 (ls_out_stateful    ), priority=0    , match=(1), action=(next;)
  table=9 (ls_out_port_sec_ip ), priority=90   , match=(outport == "ls2-vm1" && eth.dst == 00:00:00:00:00:03 && ip4.dst == {255.255.255.255, 224.0.0.0/4, 10.10.20.2}), action=(next;)
  table=9 (ls_out_port_sec_ip ), priority=90   , match=(outport == "ls2-vm2" && eth.dst == 00:00:00:00:00:04 && ip4.dst == {255.255.255.255, 224.0.0.0/4, 10.10.20.3}), action=(next;)
  table=9 (ls_out_port_sec_ip ), priority=80   , match=(outport == "ls2-vm1" && eth.dst == 00:00:00:00:00:03 && ip), action=(drop;)
  table=9 (ls_out_port_sec_ip ), priority=80   , match=(outport == "ls2-vm2" && eth.dst == 00:00:00:00:00:04 && ip), action=(drop;)
  table=9 (ls_out_port_sec_ip ), priority=0    , match=(1), action=(next;)
  table=10(ls_out_port_sec_l2 ), priority=100  , match=(eth.mcast), action=(output;)
  table=10(ls_out_port_sec_l2 ), priority=50   , match=(outport == "ls2-lr1"), action=(output;)
  table=10(ls_out_port_sec_l2 ), priority=50   , match=(outport == "ls2-vm1" && eth.dst == {00:00:00:00:00:03}), action=(output;)
  table=10(ls_out_port_sec_l2 ), priori

也可参考:ovn 配置逻辑路由器实现三层转发 - 简书 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ovn 配置逻辑路由器实现三层转发 的相关文章

  • Testing ovn manually based on LXD (by quqi99)

    作者 xff1a 张华 发表于 xff1a 2022 05 27 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 准备两个LXD容器 lxc list 43 43 43 43
  • ovn-central raft HA (by quqi99)

    作者 xff1a 张华 发表于 xff1a 2022 10 12 版权声明 xff1a 可以任意转载 xff0c 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 What s raft RAFT https raft git
  • 《OVN Logical Flows and ovn-trace》翻译

    在本篇文章中 xff0c 我将解释什么是Logical Flow以及如何使用ovn trace去更好地理解它们 同时 xff0c 我也会用一些例子来解释 xff0c 为什么使用Logical Flow这种抽象模型能让新特性的添加变得出乎意料
  • OVN简介

    三 OVN入门 3 1 OVN简介 Open vSwitch xff08 OVS xff09 是一款开源的 虚拟交换机 xff0c 控制协议方面它不但支持OpenFlow的所有特性而且扩展了部分OpenFlow的功能 xff1b Overl
  • OVN – OVN OpenStack(二)

    OpenStack networking ovn 项目为Neutron提供了一个基于ML2的OVN插件 xff0c 它使用OVN组件代替了各种Neutron的Python agent xff0c 也不再使用 RabbitMQ xff0c 而
  • OVN-软件定义网络(一)

    前言 测试环境是用github上开源代码搭建 编译完成后进行如下操作 环境配置 控制节点 创建逻辑交换机 ovn nbctl db 61 unix run openvswitch ovnnb db sock ls add ly ls 在逻辑
  • OVN入门

    参考链接 如何借助 OVN 来提高 OVS 在云计算环境中的性能 OVN简介 Open vSwitch Documentation OVSDB介绍及在OpenDaylight中的调用 OpenDaylight即将迈入 七年之痒 xff1f
  • openstack/ovn环境,虚拟机连接外网设置

    当使用OVN来做为neutron的后端 xff0c 来实现SDN方案时 xff0c 我们也会需要虚拟机连接外网 xff0c 本文记录操作方法 xff1a 环境 xff1a pike版本 xff0c 创建好net1 xff0c 子网subne
  • ovn 配置逻辑路由器实现三层转发

    本文使用ovn搭建一个三层转发的环境 xff0c 拓扑图如下 image png 两个虚拟交换机ls1和ls2 xff0c 端口ip网段分别为 10 10 10 0 24和 10 10 20 0 24 虚拟交换机上分别连接两个vm 使用na
  • ovn 通过网关虚拟路由器连接外部网络

    本文实验如何通过ovn的网关逻辑路由器将ovn网络连接到外部网络 前面讲过ovn的逻辑路由器是分布式的 xff0c 这意味着它没有绑定到某个节点上 xff0c 而是存在于所有节点上的 xff0c 同时它是通过每个节点的openflow流表来
  • ovn-northd 源码分析

    ovn northd是ovn中的核心后台进程 xff0c 主要负责将ovn的高层配置转换成供ovn controller后台进程使用的逻辑配置 xff0c 更详细的说就是它将ovn northbound数据库中传统意义上的逻辑网络配置转换成
  • OpenvSwitch 的 Open Virtual Network(OVN)项目

    几天前 xff08 1 月 13 日 xff09 xff0c OpenvSwitch 团队正式宣布了 OVN xff08 Open Virtual Network xff09 项目 xff0c 参考 Open Virtual Network
  • 【kubernetes/k8s概念】kube-ovn架构和部署安装

    Kube OVN是一款由灵雀云自主研发的开源企业级云原生Kubernetes容器网络编排系统 xff0c 它通过将OpenStack领域成熟的网络功能平移到Kubernetes xff0c 极大增强了Kubernetes容器网络的安全性 可
  • 【kubernetes/k8s概念】OVN NorthBound DB 及 ovn-nbctl 命令

    OVN 北向数据库 xff08 OVN Northbound DB xff09 是 OVN 和 CMS 之间的接口 xff0c Northbound DB 的数据几乎都是由 CMS 产生的 xff0c ovn northd 监听这个数据库的
  • 【kubernetes/k8s概念】OVN SouthBound DB 及 ovn-sbctl 命令

    OVN 南向数据库 xff08 OVN Southbound DB xff09 xff0c 南向数据库是系统的中心 xff0c 客户端是上层的 ovn northd 和下层运行在每一个传输节点的 ovn controller 南向数据库包括
  • OVN 简介

    文章目录 OVN 介绍OVN的架构OVN 应用OVN 信息流配置数据状态信息 Chassis 设置逻辑网络 OVN 介绍 Open vSwitch xff08 OVS xff09 是一款开源的 虚拟交换机 xff0c 控制协议方面它不但支持
  • OVN 流表基础 -- 基于 kubeOVN (一)

    文章目录 Kubectl ko 工具分析Nbctl SbctlTrace Ovn 流表MatchActionRegisterTable 介绍Logical Switch DatapathsLogical Router Datapaths K
  • OVS和OVN 2.8新功能

    OVS和OVN 2 8新功能 本文最初整理在我的github上SDN Learning notes 本文翻译自ovs官方文档 本文档主要是关于2017年8月底发布的Open vSwitch 2 8中添加的内容 xff0c 重点介绍OVN中的
  • OVN实验----L3互通

    概述 在L2互通基础上 xff0c 完成跨网段互访 物理拓扑 如上一个实验OVN实验 L2互通 逻辑拓扑 按照上个实验OVN实验 L2互通 的操作方式 xff0c 再配置一组容器blue xff0c 网段192 168 2 0 24 配置完
  • Testing ovn manually based on LXD (by quqi99)

    作者 张华 发表于 2022 05 27 版权声明 可以任意转载 转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 准备两个LXD容器 lxc list NAME STATE IPV4 IPV6 TYPE SNAPSHOTS

随机推荐