This document presents the current problem with ACLs and the design changes proposed to core OVN as well as the necessary modifications to be made to networking-ovn to improve their usage.
There is basically two problems being addressed in this spec:
1. While in Neutron, a Security Group Rule
is tied to a
Security Group
, in OVN ACLs
are created per port. Therefore,
we’ll typically have many more ACLs than Security Group Rules, resulting
in a performance hit as the number of ports grows.
2. An ACL in OVN is applied to a Logical Switch
. As a result,
networking-ovn
has to figure out which Logical Switches to apply the
generated ACLs per each Security Rule.
Let’s highlight both problems with an example:
When we implement the above scenario in OVN, this is what we’ll get:
And this is how, for example, the ACL match fields for the default Neutron Security Group would look like:
outport == <port1_uuid> && ip4 && ip4.src == $as_ip4_<sg1_uuid>
outport == <port2_uuid> && ip4 && ip4.src == $as_ip4_<sg1_uuid>
outport == <port3_uuid> && ip4 && ip4.src == $as_ip4_<sg1_uuid>
...
outport == <port300_uuid> && ip4 && ip4.src == $as_ip4_<sg1_uuid>
As you can see, all of them look the same except for the outport field which
is clearly redundant and makes the NB database grow a lot at scale.
Also, networking-ovn
had to figure out for each rule in SG1 which Logical
Switches it had to apply the ACLs on (NA, NB and NC). This can be really costly
when the number of networks and port grows.
In the OpenStack context, we’ll be facing this scenario most of the time where the majority of the ACLs will look the same except for the outport/inport fields in the match column. It would make sense to be able to substitute all those ACLs by a single one which references all the ports affected by that SG rule:
outport == @port_group1 && ip4 && ip4.src == $port_group1_ip4
There’s a series of patches in Core OVN that will enable us to achieve this optimization:
https://github.com/openvswitch/ovs/commit/3d2848bafa93a2b483a4504c5de801454671dccf https://github.com/openvswitch/ovs/commit/1beb60afd25a64f1779903b22b37ed3d9956d47c https://github.com/openvswitch/ovs/commit/689829d53612a573f810271a01561f7b0948c8c8
In summary, these patches are:
In the OpenStack integration driver, the following changes are required to accomplish this optimization:
external_ids
column.-def acl_direction(r, port):
+def acl_direction(r):
if r['direction'] == 'ingress':
portdir = 'outport'
else:
portdir = 'inport'
- return '%s == "%s"' % (portdir, port['id'])
+ return '%s == "@%s"' % (portdir, utils.ovn_name(r['security_group_id'])
As a bonus, we are tackling the race conditions that could happen in Address_Sets right now when we’re deleting and creating a port at the same time. This is thanks to the fact that the Address_Sets in the SB table are generated automatically by ovn-northd from the Port_Group contents and Port Group is referencing actual Logical Switch Ports. More info at: https://bugs.launchpad.net/networking-ovn/+bug/1611852
Port_Group
table, keep the old
behavior(Address Sets) for backwards compatibility.We should eventually remove the backwards compatibility and migration path. At that point we should require OVS >= 2.10 from networking-ovn.
When a port doesn’t belong to any Security Group and port security is enabled,
we, by default, drop all the traffic to/from that port. In order to implement
this through Port Groups, we’ll create a special Port Group with a fixed name
(neutron_pg_drop
) which holds the ACLs to drop all the traffic.
This PG will be created automatically when we first need it, avoiding the need to create it beforehand or during deployment.
Except where otherwise noted, this document is licensed under Creative Commons Attribution 3.0 License. See all OpenStack Legal Documents.