Skip to content

Commit

Permalink
controller: set vlan-limit=0
Browse files Browse the repository at this point in the history
This allows L3+ ACLs to match against double tagged vlan traffic on
vlan-passthru switches.

The default in OVS is vlan-limit=1 for backwards compatibility. This
means packets are not "parsed" deeper than one tag level.

This patch sets it to 0, which means "parse as deep as OVS supports".
Right now it's effectively the same as setting it to "2", which is the
maximum number of tag levels that OVS supports right now.

It is already set to 2 in puppet-vswitch that is used in some OpenStack
distributions:

https://opendev.org/openstack/puppet-vswitch/commit/14011d69c18e628a3466fa71db25cefb7adff425

Signed-off-by: Ihar Hrachyshka <ihrachys@redhat.com>
Signed-off-by: Numan Siddique <numans@ovn.org>
  • Loading branch information
booxter authored and numansiddique committed Jul 23, 2021
1 parent 9820cab commit 7e2c892
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 0 deletions.
13 changes: 13 additions & 0 deletions controller/ovn-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,7 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl)
* their interest explicitly. */
ovsdb_idl_add_table(ovs_idl, &ovsrec_table_open_vswitch);
ovsdb_idl_add_column(ovs_idl, &ovsrec_open_vswitch_col_external_ids);
ovsdb_idl_add_column(ovs_idl, &ovsrec_open_vswitch_col_other_config);
ovsdb_idl_add_column(ovs_idl, &ovsrec_open_vswitch_col_bridges);
ovsdb_idl_add_column(ovs_idl, &ovsrec_open_vswitch_col_datapaths);
ovsdb_idl_add_table(ovs_idl, &ovsrec_table_interface);
Expand Down Expand Up @@ -3204,6 +3205,18 @@ main(int argc, char *argv[])
process_br_int(ovs_idl_txn, bridge_table, ovs_table,
&br_int, &br_int_dp);

/* Enable ACL matching for double tagged traffic. */
if (ovs_idl_txn) {
const struct ovsrec_open_vswitch *cfg =
ovsrec_open_vswitch_table_first(ovs_table);
int vlan_limit = smap_get_int(
&cfg->other_config, "vlan-limit", -1);
if (vlan_limit != 0) {
ovsrec_open_vswitch_update_other_config_setkey(
cfg, "vlan-limit", "0");
}
}

if (ovsdb_idl_has_ever_connected(ovnsb_idl_loop.idl) &&
northd_version_match) {

Expand Down
97 changes: 97 additions & 0 deletions tests/ovn.at
Original file line number Diff line number Diff line change
Expand Up @@ -1907,6 +1907,103 @@ AT_CLEANUP

AT_BANNER([OVN end-to-end tests])

OVN_FOR_EACH_NORTHD([
AT_SETUP([ovn -- enables vlan-limit=0])
ovn_start

net_add n
check ovs-vsctl add-br br-phys
ovn_attach n br-phys 192.168.0.1

OVS_WAIT_UNTIL([test x`ovs-vsctl get Open_vSwitch . other_config:vlan-limit | tr -d '""'` = x0])

check ovs-vsctl set Open_vSwitch . other_config:vlan-limit=100
OVS_WAIT_UNTIL([test x`ovs-vsctl get Open_vSwitch . other_config:vlan-limit | tr -d '""'` = x0])

check ovs-vsctl set Open_vSwitch . other_config:vlan-limit=foo
OVS_WAIT_UNTIL([test x`ovs-vsctl get Open_vSwitch . other_config:vlan-limit | tr -d '""'` = x0])

AT_CLEANUP
])

OVN_FOR_EACH_NORTHD([
AT_SETUP([ovn -- allows ACLs to match against vlan-transparent double tagged traffic L3 fields])
ovn_start

for i in 1 2; do
check ovn-nbctl ls-add lsw$i
check ovn-nbctl --wait=sb add Logical-Switch lsw$i other_config vlan-passthru=true

ln_port_name=ln-$i
check ovn-nbctl lsp-add lsw$i $ln_port_name
check ovn-nbctl lsp-set-addresses $ln_port_name unknown
check ovn-nbctl lsp-set-type $ln_port_name localnet
check ovn-nbctl lsp-set-options $ln_port_name network_name=phys
net_add n
done

# two hypervisors, each connected to the same network
for i in 1 2; do
sim_add hv-$i
as hv-$i
ovs-vsctl add-br br-phys
ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
ovn_attach n br-phys 192.168.0.$i
done

check ovs-vsctl add-port br-phys tap
for i in 1 2; do
as hv-$i
check ovs-vsctl add-port br-int vif$i -- set Interface vif$i \
external-ids:iface-id=lp$i options:tx_pcap=vif$i-tx.pcap options:rxq_pcap=vif$i-rx.pcap
check ovn-nbctl lsp-add lsw$i lp$i
check ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 10.0.0.$i"
done
for i in 1 2; do
OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp$i` = xup])
> $i.expected
done

test_tcp_packet() {
local inport=$1 eth_dst=$2 eth_src=$3 ip_dst=$4 ip_src=$5 eout=$6 lout=$7 fail=$8
tag=810000ff
local packet=${eth_dst}${eth_src}${tag}${tag}08004500002800004000ff060000${ip_src}${ip_dst}0001000100000001000000005000ffff00000000
as hv-$inport ovs-appctl netdev-dummy/receive vif$inport $packet
if [[ $fail -eq 0 ]]; then
echo $packet >> ${eout#lp}.expected
fi
}

# first check that acl drop rule works for tagged traffic
for i in 1 2; do
check ovn-nbctl acl-add lsw$i to-lport 1000 'tcp' drop
done
check ovn-nbctl --wait=hv sync

test_tcp_packet 1 f00000000002 f00000000001 0a000002 0a000001 lp2 lp2 1
test_tcp_packet 2 f00000000001 f00000000002 0a000001 0a000002 lp1 lp1 1

for i in 1 2; do
OVN_CHECK_PACKETS_REMOVE_BROADCAST([vif$i-tx.pcap], [$i.expected])
done

# now check that with no rule traffic passes through
for i in 1 2; do
check ovn-nbctl acl-del lsw$i to-lport 1000 'tcp'
check ovn-nbctl acl-add lsw$i to-lport 1000 'tcp' allow-stateless
done
check ovn-nbctl --wait=hv sync

test_tcp_packet 2 f00000000001 f00000000002 0a000001 0a000002 lp1 lp1 0
test_tcp_packet 1 f00000000002 f00000000001 0a000002 0a000001 lp2 lp2 0

for i in 1 2; do
OVN_CHECK_PACKETS_REMOVE_BROADCAST([vif$i-tx.pcap], [$i.expected])
done

AT_CLEANUP
])

# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
OVN_FOR_EACH_NORTHD([
AT_SETUP([3 HVs, 1 LS, 3 lports/HV])
Expand Down

0 comments on commit 7e2c892

Please sign in to comment.