From e108ac6bdf80f646d1663ad7dd063e6988c111d3 Mon Sep 17 00:00:00 2001 From: LIU Yulong Date: Wed, 16 Jan 2019 18:48:19 +0800 Subject: [PATCH] Add port forwarding floating IP QoS Port forwarding floating IPs QoS should be limited under the binding QoS policy. So this patch extends the l3-agent fip-qos agent extension floating IP list with the port forwarding related IPs. Change-Id: Iddabfabafc0803edd1e4ac0893dc188f1907234a Closes-Bug: #1796925 --- neutron/agent/l3/extensions/qos/fip.py | 3 ++- neutron/agent/l3/router_info.py | 4 ++++ neutron/services/portforwarding/pf_plugin.py | 18 ++++++++++++++---- neutron/tests/common/l3_test_common.py | 14 ++++++++++++++ .../extensions/qos/test_fip_qos_extension.py | 17 +++++++++++++++++ neutron/tests/functional/agent/l3/framework.py | 3 +++ ...rt-forwarding-fip-qos-f808d6b4826fb849.yaml | 7 +++++++ 7 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 releasenotes/notes/add-port-forwarding-fip-qos-f808d6b4826fb849.yaml diff --git a/neutron/agent/l3/extensions/qos/fip.py b/neutron/agent/l3/extensions/qos/fip.py index 1ea8e9812d9..e9b6d6f96f7 100644 --- a/neutron/agent/l3/extensions/qos/fip.py +++ b/neutron/agent/l3/extensions/qos/fip.py @@ -248,7 +248,8 @@ class FipQosAgentExtension(qos_base.L3QosAgentExtensionBase, "for router: %s", router_info.router_id) return - floating_ips = router_info.get_floating_ips() + floating_ips = (router_info.get_floating_ips() + + router_info.get_port_forwarding_fips()) current_fips = self.fip_qos_map.router_floating_ips.get( router_info.router_id, set()) new_fips = set() diff --git a/neutron/agent/l3/router_info.py b/neutron/agent/l3/router_info.py index 308e011954f..03a2d15b356 100644 --- a/neutron/agent/l3/router_info.py +++ b/neutron/agent/l3/router_info.py @@ -166,6 +166,10 @@ class RouterInfo(object): """Filter Floating IPs to be hosted on this agent.""" return self.router.get(lib_constants.FLOATINGIP_KEY, []) + def get_port_forwarding_fips(self): + """Get router port forwarding floating IPs.""" + return self.router.get('_pf_floatingips', []) + def floating_forward_rules(self, fip): fixed_ip = fip['fixed_ip_address'] floating_ip = fip['floating_ip_address'] diff --git a/neutron/services/portforwarding/pf_plugin.py b/neutron/services/portforwarding/pf_plugin.py index b52ec6358de..31c8bc2ee7c 100644 --- a/neutron/services/portforwarding/pf_plugin.py +++ b/neutron/services/portforwarding/pf_plugin.py @@ -47,6 +47,9 @@ from neutron.services.portforwarding.common import exceptions as pf_exc LOG = logging.getLogger(__name__) +# Move to neutron-lib someday. +PORT_FORWARDING_FLOATINGIP_KEY = '_pf_floatingips' + def make_result_with_fields(f): @functools.wraps(f) @@ -511,18 +514,25 @@ class PortForwardingPlugin(fip_pf.PortForwardingPluginBase): router_ids = [router.get('id') for router in routers] router_pf_fip_set = collections.defaultdict(set) fip_pfs = collections.defaultdict(set) - router_fip = collections.defaultdict(set) + router_fip_ids = collections.defaultdict(set) item_pf_fields = pf.PortForwarding.get_port_forwarding_obj_by_routers( context, router_ids) for router_id, fip_addr, pf_id, fip_id in item_pf_fields: router_pf_fip_set[router_id].add(utils.ip_to_cidr(fip_addr, 32)) fip_pfs[fip_id].add(pf_id) - router_fip[router_id].add(fip_id) + router_fip_ids[router_id].add(fip_id) for router in routers: - if router['id'] in router_fip: + if router['id'] in router_fip_ids: router['port_forwardings_fip_set'] = router_pf_fip_set[ router['id']] - router['fip_managed_by_port_forwardings'] = router_fip[ + router['fip_managed_by_port_forwardings'] = router_fip_ids[ router['id']] + + router_pf_fips_info = router.get( + PORT_FORWARDING_FLOATINGIP_KEY, []) + for fip_id in router_fip_ids[router['id']]: + fip = self.l3_plugin.get_floatingip(context, fip_id) + router_pf_fips_info.append(fip) + router[PORT_FORWARDING_FLOATINGIP_KEY] = router_pf_fips_info diff --git a/neutron/tests/common/l3_test_common.py b/neutron/tests/common/l3_test_common.py index ce7a1ae2c1c..6e51340aaf1 100644 --- a/neutron/tests/common/l3_test_common.py +++ b/neutron/tests/common/l3_test_common.py @@ -59,6 +59,7 @@ def prepare_router_data(ip_version=lib_constants.IP_VERSION_4, extra_routes=False, dual_stack=False, enable_gw=True, v6_ext_gw_with_sub=True, snat_bound_fip=False, + enable_pf_floating_ip=False, **kwargs): fixed_ips = [] subnets = [] @@ -143,6 +144,19 @@ def prepare_router_data(ip_version=lib_constants.IP_VERSION_4, router_fips.append(fip) router[lib_constants.FLOATINGIP_KEY] = router_fips + pf_fips = [] + if enable_pf_floating_ip: + fip = {'id': _uuid(), + 'port_id': _uuid(), + 'status': 'DOWN', + 'floating_ip_address': '19.4.4.4', + 'fixed_ip_address': '10.0.0.3'} + qos_policy_id = kwargs.get(qos_consts.QOS_POLICY_ID) + if qos_policy_id: + fip[qos_consts.QOS_POLICY_ID] = qos_policy_id + pf_fips.append(fip) + router['_pf_floatingips'] = pf_fips + router_append_interface(router, count=num_internal_ports, ip_version=ip_version, dual_stack=dual_stack) if enable_ha: diff --git a/neutron/tests/functional/agent/l3/extensions/qos/test_fip_qos_extension.py b/neutron/tests/functional/agent/l3/extensions/qos/test_fip_qos_extension.py index 68d185ecaf0..8e4afbb8a2e 100644 --- a/neutron/tests/functional/agent/l3/extensions/qos/test_fip_qos_extension.py +++ b/neutron/tests/functional/agent/l3/extensions/qos/test_fip_qos_extension.py @@ -174,6 +174,23 @@ class TestL3AgentFipQosExtension(L3AgentFipQoSExtensionTestFramework): self._test_centralized_routers(enable_ha=True, ingress=False, egress=True) + def _test_router_with_pf_fips_qos(self, enable_ha): + router_info = self.generate_router_info( + enable_ha=enable_ha, + enable_pf_floating_ip=True, + qos_policy_id=TEST_POLICY_ID1) + ri = self.manage_router(self.agent, router_info) + self._assert_bandwidth_limit_rule_is_set( + ri, '19.4.4.4', self.test_bw_limit_rule_1) + self._assert_bandwidth_limit_rule_is_set( + ri, '19.4.4.4', self.test_bw_limit_rule_2) + + def test_ha_router_with_pf_fips_qos(self): + self._test_router_with_pf_fips_qos(enable_ha=True) + + def test_legacy_router_with_pf_fips_qos(self): + self._test_router_with_pf_fips_qos(enable_ha=False) + class TestL3AgentFipQosExtensionDVR( test_dvr_router.TestDvrRouter, diff --git a/neutron/tests/functional/agent/l3/framework.py b/neutron/tests/functional/agent/l3/framework.py index 7292eab7d50..9828851a132 100644 --- a/neutron/tests/functional/agent/l3/framework.py +++ b/neutron/tests/functional/agent/l3/framework.py @@ -109,6 +109,7 @@ class L3AgentTestFramework(base.BaseSudoTestCase): enable_fip=True, enable_snat=True, num_internal_ports=1, dual_stack=False, v6_ext_gw_with_sub=True, + enable_pf_floating_ip=False, qos_policy_id=None): if ip_version == constants.IP_VERSION_6 and not dual_stack: enable_snat = False @@ -125,6 +126,8 @@ class L3AgentTestFramework(base.BaseSudoTestCase): dual_stack=dual_stack, v6_ext_gw_with_sub=( v6_ext_gw_with_sub), + enable_pf_floating_ip=( + enable_pf_floating_ip), qos_policy_id=qos_policy_id) def _test_conntrack_disassociate_fip(self, ha): diff --git a/releasenotes/notes/add-port-forwarding-fip-qos-f808d6b4826fb849.yaml b/releasenotes/notes/add-port-forwarding-fip-qos-f808d6b4826fb849.yaml new file mode 100644 index 00000000000..d43aafe2b8d --- /dev/null +++ b/releasenotes/notes/add-port-forwarding-fip-qos-f808d6b4826fb849.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + L3 agent supports QoS bandwidth limit functionality for port + forwarding floating IPs now. If floating IP has binding QoS + policy (with bandwidth limit rules), the traffic bandwidth + will be limited.