On Wed, Mar 9, 2016 at 1:32 PM, Ryan Moats <rmo...@us.ibm.com> wrote:
>
>
>
> "dev" <dev-boun...@openvswitch.org> wrote on 03/09/2016 03:12:07 PM:
>
> > From: Russell Bryant <russ...@ovn.org>
> > To: ovs dev <dev@openvswitch.org>
> > Date: 03/09/2016 03:12 PM
> > Subject: [ovs-dev] [RFC] OVN northbound address sets
> > Sent by: "dev" <dev-boun...@openvswitch.org>
> >
> > I'd like to propose a new feature for the OVN northbound database.  If
we
> > reach some consensus, I will implement it.
> >
> > Overview:
> >
> > One use case for OVN ACLs includes matching on a set of IP addresses.  A
> > simple example:
> >
> >     inport == "lport1" && ip.src == {10.0.0.1, 10.0.0.3, 10.0.7}
> >
> > This is only 3 addresses, but it could easily be hundreds of addresses.
> >
> > I'd like to add a new table to OVN_Northbound called something like
> > "Address_Set".
> >
> > +        "Address_Set": {
> > +            "columns": {
> > +                "name": {"type": "string"},
> > +                "addresses": {"type": {"key": "string",
> > +                                       "min": 0,
> > +                                       "max": "unlimited"}}},
> > +            "indexes": [["name"]],
> > +            "isRoot": false},
> >
> > I'd also like to be able to refer to an address set by name in an ACL
> > match.  I'm not sure about the syntax, but as an example:
> >
> >     inport == "lport1" && ip.src == address_set("my-set")
> >
> >
> > More context:
> >
> > OpenStack Neutron (the networking API for OpenStack) has a feature
called
> > "security groups", which were inspired by security groups for EC2.  The
> > default security group policy is:
> >
> > +--------------------------------------+---------
> > +----------------------------------------------------------------------+
> > | id                                   | name    | security_group_rules
> >                                             |
> > +--------------------------------------+---------
> > +----------------------------------------------------------------------+
> > | 8db9f44c-fa02-4184-b77f-e59a6fb94acd | default | egress, IPv4
> >                                             |
> > |                                      |         | egress, IPv6
> >                                             |
> > |                                      |         | ingress, IPv4,
> > remote_group_id: 8db9f44c-fa02-4184-b77f-e59a6fb94acd |
> > |                                      |         | ingress, IPv6,
> > remote_group_id: 8db9f44c-fa02-4184-b77f-e59a6fb94acd |
> > +--------------------------------------+---------
> > +----------------------------------------------------------------------+
> >
> > This translates to:
> >
> > * Allow all outbound IPv4 and IPv6 traffic from the VM.
> > * Allow all inbound IPv4 and IPv6 traffic that originated from other
> ports
> > that have this same security group assigned to them.
> > * Otherwise, drop traffic by default.
> >
> > Implementation of "remote_group_id" requires matching on the set of IP
> > addresses for all ports using this security group.
> >
> > There is a lot of flexibility with OVN ACLs.  The approach currently
used
> > by the Neutron plugin is to create an OVN ACL for each security group
> rule
> > on a port.  The ACLs for a given port with this "default" policy might
be
> > something like:
> >
> > from-lport  1002 (inport == "5155d5f6-4f1d-4ce2-81a5-60320f412040" &&
> ip4)
> > allow-related
> > from-lport  1002 (inport == "5155d5f6-4f1d-4ce2-81a5-60320f412040" &&
> ip6)
> > allow-related
> >   to-lport  1002 (outport == "5155d5f6-4f1d-4ce2-81a5-60320f412040" &&
> ip4
> > && (ip4.src == 10.0.0.10 || ip4.src == 10.0.0.9)) allow-related
> >   to-lport  1002 (outport == "5155d5f6-4f1d-4ce2-81a5-60320f412040" &&
> ip6
> > && (ip6.src == fd73:4054:de17:0:f816:3eff:fe5b:5a77 || ip6.src ==
> > fd73:4054:de17:0:f816:3eff:fe68:53d4)) allow-related
> >
> > This becomes much more painful as the number of ports increases.  Given
> 500
> > ports that have both IPv4 and IPv6 addresses, we'll have 1000 ACLs, each
> > with 999 IP addresses listed in them.  Adding the last address would be
> > harmless, though.  When port 501 gets created, we have to go update the
> set
> > of IP addresses in the 1000 existing ACL rows.
> >
> > We could cut this down somewhat by having a single ACL row for this rule
> on
> > each logical switch.  There are some downsides to this.  First, we still
> > have to maintain that large set of IP addresses in multiple places (one
> per
> > logical switch).  Second, the current ACL-per-port+rule breakdown is
> fairly
> > convenient.  It may also be beneficial if we want to trace a conntrack
> > entry back to the OVN ACL, and then back to the exact port+rule that
> > allowed it to be created.
> >
> > If we had this address set functionality, we could maintain address sets
> > for security groups that use the "remote_group_id" functionality.  As
> ports
> > get added/removed, we would only update the address set and we could
> leave
> > all of the existing ACLs alone.  This would help greatly with one of the
> > bottlenecks we currently have in the OpenStack Neutron plugin.
> >
> > As for implementation, one way to do this is leave it entirely as a
> > northbound DB thing and have ovn-northd translate it into the full set
of
> > addresses in logical flows.
> >
> > An additional step could be to add the same "address set" functionality
> to
> > logical flows to reduce the amount of data expressed in logical flows.
> In
> > that case, I suppose the "Address_Set" table would be identical to the
> one
> > in OVN_Northbound.
> >
> > Thoughts?
>
> IMHO, the scaling arguments for having address sets in the NB db apply
> equally to the SB db, so it makes sense to me to carry this all the way
> through and expand it to the full set of addresses in ovn-controller.
>
> Ryan (regXboi)
>
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev

Russell,

This is a great idea!! Just like what ipset has helped for iptables.

And I agree with the "additional step" (as pointed out by Ryan) that we
should enable this for SB lflow, considering the scaling problem of
lflow_run() we are already facing.

With this approach, the expanded physical flows on each hypervisor will
still be O(N) for a given port in a group with N ports, but it should have
huge improvement for performance along the path: neutron -> nb -> sb ->
ovn-controller.

For the downside #1, I wonder why not just have a global address set table
(maybe one for NB and one for SB) instead of one per logical switch?
Security-group needs to be enforced across logical switches anyway.

For the downside #2, I tend to disagree. It seems more clean for
networking-ovn to add/delete addresses to/from a set when attached/detached
to/from a sec-group without worrying about ACL refreshes. And the flow is
clear so I think it is still straightforward for trouble shooting.

Let me know if you need a hand to work together with you on this :)

P.S.

To further solve the O(N) problem on hypervisor, we can utilize the tunnel
metadata to carry group-id, so that we will need only O(1) physical flows
on each hypervisor. But there will be 2 limitations with the tunnel:
1. It won't work in bridged networks where there is no tunnel.
2. It is straightforward to represent a group-id in tunnel metadata, but
sometimes a port can belong to more than one groups, which is not easy to
be encoded in tunnel header, and even harder for matching by openflow rules.
In these 2 cases it can fallback to the address set approach. I will post a
separate thread to describe the end-to-end design for the tunnel metadata
idea (seems not urgent though, now that we have the address set solution).

--
Best regards,
Han
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to