Skip to content

Commit

Permalink
OpenStack: Complete what we need for QoS support in our driver
Browse files Browse the repository at this point in the history
Sorry, these are more required plumbing changes that I missed in projectcalico#9811 and projectcalico#9856.

Also a key fix to query bandwidth limit and packet rate rules directly, instead of via the policy, as the policy object does not really have a 'rules' attribute.

After these, I've verified that I can execute the QoS workflow in https://docs.openstack.org/neutron/latest/admin/config-qos.html#user-workflow.
  • Loading branch information
nelljerram committed Feb 20, 2025
1 parent 0286a80 commit 22457c5
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 25 deletions.
2 changes: 2 additions & 0 deletions networking-calico/networking_calico/plugins/calico/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ def __init__(self):
cfg.CONF.set_override('type_drivers', ['local', 'flat'], group='ml2')
LOG.info("Forcing ML2 tenant_network_types to 'local'")
cfg.CONF.set_override('tenant_network_types', ['local'], group='ml2')
LOG.info("Forcing ML2 extension_drivers to 'qos'")
cfg.CONF.set_override('extension_drivers', ['qos'], group='ml2')

# This is a bit of a hack to get the models_v2.Port attributes setup in such
# a way as to avoid tracebacks in the neutron-server log.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,32 +318,38 @@ def add_port_qos(self, port, context):

qos_policy_id = port.get('qos_policy_id')
if qos_policy_id:
qos_policy = context.session.query(
qos_models.QosPolicy
rules = context.session.query(
qos_models.QosBandwidthLimitRule
).filter_by(
id=qos_policy_id
).first()
if qos_policy:
for r in qos_policy['rules']:
if r['type'] == "bandwidth_limit":
direction = r.get('direction', 'egress')
if r['max_kbps'] != 0:
if direction == "egress":
qos['egressBandwidth'] = r['max_kbps'] * 1000
else:
qos['ingressBandwidth'] = r['max_kbps'] * 1000
if r['max_burst_kbps'] != 0:
if direction == "egress":
qos['egressBurst'] = r['max_burst_kbps'] * 1000
else:
qos['ingressBurst'] = r['max_burst_kbps'] * 1000
elif r['type'] == "packet_rate_limit":
direction = r.get('direction', 'egress')
if r['max_kpps'] != 0:
if direction == "egress":
qos['egressPacketRate'] = r['max_kpps'] * 1000
else:
qos['ingressPacketRate'] = r['max_kpps'] * 1000
qos_policy_id=qos_policy_id
)
for r in rules:
LOG.debug("BW rule = %r", r)
direction = r.get('direction', 'egress')
if r['max_kbps'] != 0:
if direction == "egress":
qos['egressBandwidth'] = r['max_kbps'] * 1000
else:
qos['ingressBandwidth'] = r['max_kbps'] * 1000
if r['max_burst_kbps'] != 0:
if direction == "egress":
qos['egressBurst'] = r['max_burst_kbps'] * 1000
else:
qos['ingressBurst'] = r['max_burst_kbps'] * 1000

rules = context.session.query(
qos_models.QosPacketRateLimitRule
).filter_by(
qos_policy_id=qos_policy_id
)
for r in rules:
LOG.debug("PR rule = %r", r)
direction = r.get('direction', 'egress')
if r['max_kpps'] != 0:
if direction == "egress":
qos['egressPacketRate'] = r['max_kpps'] * 1000
else:
qos['ingressPacketRate'] = r['max_kpps'] * 1000

if cfg.CONF.calico.max_ingress_connections_per_port != 0:
qos['ingressMaxConnections'] = cfg.CONF.calico.max_ingress_connections_per_port
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@
from networking_calico.plugins.ml2.drivers.calico.endpoints import \
WorkloadEndpointSyncer
from networking_calico.plugins.ml2.drivers.calico.policy import PolicySyncer
from networking_calico.plugins.ml2.drivers.calico.qos_driver import register \
as register_qos_driver
from networking_calico.plugins.ml2.drivers.calico.status import StatusWatcher
from networking_calico.plugins.ml2.drivers.calico.subnets import SubnetSyncer

Expand Down Expand Up @@ -195,6 +197,7 @@ def __init__(self):
'tap',
{'port_filter': True,
'mac_address': '00:61:fe:ed:ca:fe'})
register_qos_driver()
# Lock to prevent concurrent initialisation.
self._init_lock = Semaphore()
# Generally initialize attributes to nil values. They get initialized
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2025 Tigera, Inc. All rights reserved.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from networking_calico.compat import log

from neutron_lib import constants
from neutron_lib.api.definitions import portbindings
from neutron_lib.db import constants as db_consts
from neutron_lib.services.qos import base
from neutron_lib.services.qos import constants as qos_consts


LOG = log.getLogger(__name__)

DRIVER = None

SUPPORTED_RULES = {
qos_consts.RULE_TYPE_BANDWIDTH_LIMIT: {
qos_consts.MAX_KBPS: {
'type:range': [0, db_consts.DB_INTEGER_MAX_VALUE]},
qos_consts.MAX_BURST: {
'type:range': [0, db_consts.DB_INTEGER_MAX_VALUE]},
qos_consts.DIRECTION: {
'type:values': constants.VALID_DIRECTIONS}
},
qos_consts.RULE_TYPE_PACKET_RATE_LIMIT: {
qos_consts.MAX_KPPS: {
'type:range': [0, db_consts.DB_INTEGER_MAX_VALUE]},
qos_consts.MAX_BURST_KPPS: {
'type:range': [0, 0]},
qos_consts.DIRECTION: {
'type:values': constants.VALID_DIRECTIONS}
},
}


class CalicoQoSDriver(base.DriverBase):

@staticmethod
def create():
return CalicoQoSDriver(
name='calico',
vif_types=[portbindings.VIF_TYPE_TAP],
vnic_types=[portbindings.VNIC_NORMAL],
supported_rules=SUPPORTED_RULES,
requires_rpc_notifications=False)


def register():
"""Register the driver."""
global DRIVER
if not DRIVER:
DRIVER = CalicoQoSDriver.create()
LOG.debug('Calico QoS driver registered')

0 comments on commit 22457c5

Please sign in to comment.