diff --git a/packaging/openstack-neutron/0109-Add-status_changed-notification-for-some-components.patch b/packaging/openstack-neutron/0109-Add-status_changed-notification-for-some-components.patch new file mode 100644 index 0000000..662778b --- /dev/null +++ b/packaging/openstack-neutron/0109-Add-status_changed-notification-for-some-components.patch @@ -0,0 +1,225 @@ +From 05799039082848c3bbae36e9e8b3e89536ec0ced Mon Sep 17 00:00:00 2001 +From: Hunt Xu +Date: Thu, 25 May 2017 18:58:04 +0800 +Subject: [PATCH 109/118] Add status_changed notification for some components + +Supported components: + * Firewall + * Loadbalancer Pool + * Loadbalancer VIP + * Loadbalancer Member + * Loadbalancer Health Monitor + * VPN Service + * IPsec Site Connection + * Port used for PPTP VPN + +Fixes: redmine #10220 + +Signed-off-by: Hunt Xu +--- + neutron/db/loadbalancer/loadbalancer_db.py | 2 + + neutron/db/vpn/vpn_db.py | 4 + + neutron/notifiers/eayun.py | 93 ++++++++++++++++++++++ + neutron/services/firewall/fwaas_plugin.py | 2 + + .../drivers/common/agent_driver_base.py | 2 + + 5 files changed, 103 insertions(+) + create mode 100644 neutron/notifiers/eayun.py + +diff --git a/neutron/db/loadbalancer/loadbalancer_db.py b/neutron/db/loadbalancer/loadbalancer_db.py +index 061735b24..9598a1233 100644 +--- a/neutron/db/loadbalancer/loadbalancer_db.py ++++ b/neutron/db/loadbalancer/loadbalancer_db.py +@@ -28,6 +28,7 @@ from neutron.db import servicetype_db as st_db + from neutron.extensions import loadbalancer + from neutron.extensions import loadbalancer_l7 + from neutron import manager ++from neutron.notifiers.eayun import eayun_notify + from neutron.openstack.common import excutils + from neutron.openstack.common import jsonutils + from neutron.openstack.common import log as logging +@@ -243,6 +244,7 @@ class LoadBalancerPluginDb(loadbalancer.LoadBalancerPluginBase, + def _core_plugin(self): + return manager.NeutronManager.get_plugin() + ++ @eayun_notify('LB_MEMBER', Member) + def update_status(self, context, model, id, status, + status_description=None): + with context.session.begin(subtransactions=True): +diff --git a/neutron/db/vpn/vpn_db.py b/neutron/db/vpn/vpn_db.py +index d50d4bd6f..6034bbc3a 100644 +--- a/neutron/db/vpn/vpn_db.py ++++ b/neutron/db/vpn/vpn_db.py +@@ -30,6 +30,7 @@ from neutron.db import servicetype_db as st_db + from neutron.db.vpn import vpn_validator + from neutron.extensions import vpnaas + from neutron import manager ++from neutron.notifiers.eayun import eayun_notify + from neutron.openstack.common import excutils + from neutron.openstack.common import log as logging + from neutron.openstack.common import uuidutils +@@ -805,6 +806,7 @@ class VPNPluginRpcDbMixin(): + l3_agent_db.RouterL3AgentBinding.l3_agent_id == agent.id) + return query + ++ @eayun_notify(constants.VPN) + def update_status_by_agent(self, context, service_status_info_list): + """Updating vpnservice and vpnconnection status. + +@@ -842,6 +844,7 @@ class VPNPluginRpcDbMixin(): + context, conn_id, conn['status'], + conn['updated_pending_status']) + ++ @eayun_notify('PPTP') + def set_vpnservice_status(self, context, vpnservice_id, status): + with context.session.begin(subtransactions=True): + try: +@@ -851,6 +854,7 @@ class VPNPluginRpcDbMixin(): + LOG.warn(_('vpnservice %s in db is already deleted'), + vpnservice_db['id']) + ++ @eayun_notify('PPTP_ports') + def update_pptp_status_by_agent( + self, context, host, + pptp_processes_status, credentials, updated_ports, +diff --git a/neutron/notifiers/eayun.py b/neutron/notifiers/eayun.py +new file mode 100644 +index 000000000..5c09c4774 +--- /dev/null ++++ b/neutron/notifiers/eayun.py +@@ -0,0 +1,93 @@ ++from neutron.common import rpc as n_rpc ++from neutron.common import constants as n_constants ++from neutron.plugins.common import constants ++ ++ ++class Notifier(object): ++ ++ def __init__(self): ++ self._notifier = n_rpc.get_notifier('eayun') ++ ++ def status_changed(self, context, resource, resource_id, status): ++ self._notifier.info( ++ context, resource + '.status.changed', ++ {resource: {'id': resource_id, 'status': status}}) ++ ++ ++_notifier = Notifier() ++ ++ ++def eayun_notify(service, obj_model=None): ++ def handle_func(func): ++ def handle_firewall( ++ fw_rpc_callback, context, firewall_id, status, **kwargs ++ ): ++ ret = func( ++ fw_rpc_callback, context, firewall_id, status, **kwargs) ++ _notifier.status_changed(context, 'firewall', firewall_id, status) ++ return ret ++ ++ def handle_ipsec_vpns( ++ vpn_plugin, context, service_status_info_list ++ ): ++ func(vpn_plugin, context, service_status_info_list) ++ for vpnservice in service_status_info_list: ++ _notifier.status_changed( ++ context, 'vpnservice', ++ vpnservice['id'], vpnservice['status']) ++ for conn_id, conn in vpnservice[ ++ 'ipsec_site_connections' ++ ].items(): ++ _notifier.status_changed( ++ context, 'ipsec_site_connection', ++ conn_id, conn['status']) ++ ++ def handle_loadbalancer( ++ lb_rpc_callback, context, obj_type, obj_id, status ++ ): ++ func(lb_rpc_callback, context, obj_type, obj_id, status) ++ if obj_type != 'member': ++ _notifier.status_changed(context, obj_type, obj_id, status) ++ ++ def handle_lb_member( ++ lb_plugin, context, model, obj_id, status, **kwargs ++ ): ++ func(lb_plugin, context, model, obj_id, status, **kwargs) ++ if issubclass(model, obj_model): ++ _notifier.status_changed(context, 'member', obj_id, status) ++ ++ def handle_pptp_vpn( ++ vpn_plugin, context, vpnservice_id, status ++ ): ++ func(vpn_plugin, context, vpnservice_id, status) ++ _notifier.status_changed( ++ context, 'vpnservice', vpnservice_id, status) ++ ++ def handle_pptp_ports( ++ vpn_plugin, context, host, pptp_processes_status, ++ credentials, updated_ports, provider ++ ): ++ func(vpn_plugin, context, host, pptp_processes_status, ++ credentials, updated_ports, provider) ++ for port_id, status in updated_ports.iteritems(): ++ port_status = n_constants.PORT_STATUS_DOWN ++ if status: ++ port_status = n_constants.PORT_STATUS_ACTIVE ++ _notifier.status_changed( ++ context, 'pptp_port', port_id, port_status) ++ ++ if service == constants.FIREWALL: ++ return handle_firewall ++ elif service == constants.VPN: ++ return handle_ipsec_vpns ++ elif service == constants.LOADBALANCER: ++ return handle_loadbalancer ++ elif service == 'LB_MEMBER': ++ return handle_lb_member ++ elif service == 'PPTP': ++ return handle_pptp_vpn ++ elif service == 'PPTP_ports': ++ return handle_pptp_ports ++ else: ++ raise NotImplementedError ++ return handle_func +diff --git a/neutron/services/firewall/fwaas_plugin.py b/neutron/services/firewall/fwaas_plugin.py +index 4d7aaf833..e99a46f20 100644 +--- a/neutron/services/firewall/fwaas_plugin.py ++++ b/neutron/services/firewall/fwaas_plugin.py +@@ -24,6 +24,7 @@ from neutron.db.firewall import firewall_db + from neutron.db.firewall import targetrouters_db + from neutron.extensions import firewall as fw_ext + from neutron.extensions.firewall_target_routers import FW_TARGET_ROUTERS ++from neutron.notifiers.eayun import eayun_notify + from neutron.openstack.common import log as logging + from neutron.plugins.common import constants as const + +@@ -38,6 +39,7 @@ class FirewallCallbacks(n_rpc.RpcCallback): + super(FirewallCallbacks, self).__init__() + self.plugin = plugin + ++ @eayun_notify(const.FIREWALL) + def set_firewall_status(self, context, firewall_id, status, **kwargs): + """Agent uses this to set a firewall's status.""" + LOG.debug(_("set_firewall_status() called")) +diff --git a/neutron/services/loadbalancer/drivers/common/agent_driver_base.py b/neutron/services/loadbalancer/drivers/common/agent_driver_base.py +index 5c24f30c3..dd1028eb9 100644 +--- a/neutron/services/loadbalancer/drivers/common/agent_driver_base.py ++++ b/neutron/services/loadbalancer/drivers/common/agent_driver_base.py +@@ -25,6 +25,7 @@ from neutron.db import agents_db + from neutron.db.loadbalancer import loadbalancer_db + from neutron.extensions import lbaas_agentscheduler + from neutron.extensions import portbindings ++from neutron.notifiers.eayun import eayun_notify + from neutron.openstack.common import importutils + from neutron.openstack.common import log as logging + from neutron.plugins.common import constants +@@ -158,6 +159,7 @@ class LoadBalancerCallbacks(n_rpc.RpcCallback): + if hm.status in constants.ACTIVE_PENDING_STATUSES: + hm.status = constants.ACTIVE + ++ @eayun_notify(constants.LOADBALANCER) + def update_status(self, context, obj_type, obj_id, status): + model_mapping = { + 'pool': loadbalancer_db.Pool, +-- +2.13.3 + diff --git a/packaging/openstack-neutron/0110-FWaaS-apply-firewall-rules-to-router-ingress-traffic.patch b/packaging/openstack-neutron/0110-FWaaS-apply-firewall-rules-to-router-ingress-traffic.patch new file mode 100644 index 0000000..35a0619 --- /dev/null +++ b/packaging/openstack-neutron/0110-FWaaS-apply-firewall-rules-to-router-ingress-traffic.patch @@ -0,0 +1,51 @@ +From b4e776a67ec88c72b18d91ef6680aa9809751c5e Mon Sep 17 00:00:00 2001 +From: Hunt Xu +Date: Tue, 6 Jun 2017 11:33:04 +0800 +Subject: [PATCH 110/118] FWaaS: apply firewall rules to router ingress traffic + +Fixes: redmine #10238 + +Signed-off-by: Hunt Xu +--- + neutron/services/firewall/drivers/linux/iptables_fwaas.py | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/neutron/services/firewall/drivers/linux/iptables_fwaas.py b/neutron/services/firewall/drivers/linux/iptables_fwaas.py +index b7d3a67f1..18e5fec6f 100644 +--- a/neutron/services/firewall/drivers/linux/iptables_fwaas.py ++++ b/neutron/services/firewall/drivers/linux/iptables_fwaas.py +@@ -39,6 +39,7 @@ IP_VER_TAG = {IPV4: 'v4', + IPV6: 'v6'} + + INTERNAL_DEV_PREFIX = 'qr-' ++EXTERNAL_DEV_PREFIX = 'qg-' + SNAT_INT_DEV_PREFIX = 'sg-' + ROUTER_2_FIP_DEV_PREFIX = 'rfp-' + +@@ -265,6 +266,11 @@ class IptablesFwaasDriver(fwaas_base.FwaasDriverBase): + if_prefix, bname, chain_name)] + self._add_rules_to_chain(ipt_mgr, + ver, 'FORWARD', jump_rule) ++ if direction == INGRESS_DIRECTION: ++ jump_rule = ['-i %s+ -j %s-%s' % ( ++ EXTERNAL_DEV_PREFIX, bname, chain_name)] ++ self._add_rules_to_chain( ++ ipt_mgr, ver, 'INPUT', jump_rule) + + #jump to DROP_ALL policy + chain_name = iptables_manager.get_chain_name(FWAAS_DEFAULT_CHAIN) +@@ -278,6 +284,11 @@ class IptablesFwaasDriver(fwaas_base.FwaasDriverBase): + self._add_rules_to_chain(ipt_mgr, IPV4, 'FORWARD', jump_rule) + self._add_rules_to_chain(ipt_mgr, IPV6, 'FORWARD', jump_rule) + ++ jump_rule = [ ++ '-i %s+ -j %s-%s' % (EXTERNAL_DEV_PREFIX, bname, chain_name)] ++ self._add_rules_to_chain(ipt_mgr, IPV4, 'INPUT', jump_rule) ++ self._add_rules_to_chain(ipt_mgr, IPV6, 'INPUT', jump_rule) ++ + def _convert_fwaas_to_iptables_rule(self, rule): + action = rule.get('action') == 'allow' and 'ACCEPT' or 'DROP' + args = [self._protocol_arg(rule.get('protocol')), +-- +2.13.3 + diff --git a/packaging/openstack-neutron/0111-FWaaS-support-some-more-protocols-in-FW-rules.patch b/packaging/openstack-neutron/0111-FWaaS-support-some-more-protocols-in-FW-rules.patch new file mode 100644 index 0000000..acd1930 --- /dev/null +++ b/packaging/openstack-neutron/0111-FWaaS-support-some-more-protocols-in-FW-rules.patch @@ -0,0 +1,65 @@ +From d26e41e4c070e0dd687bd960aaae893959b62c5b Mon Sep 17 00:00:00 2001 +From: Hunt Xu +Date: Tue, 6 Jun 2017 16:59:29 +0800 +Subject: [PATCH 111/118] FWaaS: support some more protocols in FW rules + +* GRE (47) +* ESP (50) +* AH (51) +* SCTP (132) + +Fixes: redmine #10240 + +Signed-off-by: Hunt Xu +--- + neutron/extensions/firewall.py | 4 +++- + neutron/plugins/common/constants.py | 4 ++++ + neutron/services/firewall/drivers/linux/iptables_fwaas.py | 2 +- + 3 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/neutron/extensions/firewall.py b/neutron/extensions/firewall.py +index eb038147e..02ac56078 100644 +--- a/neutron/extensions/firewall.py ++++ b/neutron/extensions/firewall.py +@@ -151,7 +151,9 @@ class FirewallRuleConflict(qexception.Conflict): + "another tenant %(tenant_id)s") + + +-fw_valid_protocol_values = [None, constants.TCP, constants.UDP, constants.ICMP] ++fw_valid_protocol_values = [None, constants.TCP, constants.UDP, constants.ICMP ++ constants.SCTP, constants.GRE, ++ constants.ESP, constants.AH] + fw_valid_action_values = [constants.FWAAS_ALLOW, constants.FWAAS_DENY] + + +diff --git a/neutron/plugins/common/constants.py b/neutron/plugins/common/constants.py +index 5e435ace7..110addb4d 100644 +--- a/neutron/plugins/common/constants.py ++++ b/neutron/plugins/common/constants.py +@@ -72,6 +72,10 @@ FWAAS_DENY = "deny" + TCP = "tcp" + UDP = "udp" + ICMP = "icmp" ++SCTP = "sctp" ++GRE = "gre" ++ESP = "esp" ++AH = "ah" + + # Network Type constants + TYPE_FLAT = 'flat' +diff --git a/neutron/services/firewall/drivers/linux/iptables_fwaas.py b/neutron/services/firewall/drivers/linux/iptables_fwaas.py +index b7d3a67f1..bae0c7ef6 100644 +--- a/neutron/services/firewall/drivers/linux/iptables_fwaas.py ++++ b/neutron/services/firewall/drivers/linux/iptables_fwaas.py +@@ -311,7 +311,7 @@ class IptablesFwaasDriver(fwaas_base.FwaasDriverBase): + return '' + + def _port_arg(self, direction, protocol, port): +- if not (protocol in ['udp', 'tcp'] and port): ++ if not (protocol in ['udp', 'tcp', 'sctp'] and port): + return '' + return '--%s %s' % (direction, port) + +-- +2.13.3 + diff --git a/packaging/openstack-neutron/0112-Fix-firewall-port-range-compare-error.patch b/packaging/openstack-neutron/0112-Fix-firewall-port-range-compare-error.patch new file mode 100644 index 0000000..95e85e9 --- /dev/null +++ b/packaging/openstack-neutron/0112-Fix-firewall-port-range-compare-error.patch @@ -0,0 +1,30 @@ +From f64cbcf2ae1e8ad96f99203945b87c8505ab489e Mon Sep 17 00:00:00 2001 +From: "cheng.tang" +Date: Wed, 7 Jun 2017 16:33:25 +0800 +Subject: [PATCH 112/118] Fix firewall port range compare error + +Fixes: redmine #10246 + +Signed-off-by: cheng.tang +Signed-off-by: Hunt Xu +--- + neutron/extensions/firewall.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/neutron/extensions/firewall.py b/neutron/extensions/firewall.py +index 02ac56078..e6e13db42 100644 +--- a/neutron/extensions/firewall.py ++++ b/neutron/extensions/firewall.py +@@ -206,7 +206,8 @@ def _validate_port_range(data, key_specs=None): + msg = _("Invalid port '%s'") % p + LOG.debug(msg) + return msg +- if len(ports) > 2 or ports[0] > ports[-1]: ++ ++ if len(ports) > 2 or int(ports[0]) > int(ports[-1]): + msg = _("Invalid port range '%s'") % ports + return msg + +-- +2.13.3 + diff --git a/packaging/openstack-neutron/0113-metering-properly-do-data-filtering-within-some-APIs.patch b/packaging/openstack-neutron/0113-metering-properly-do-data-filtering-within-some-APIs.patch new file mode 100644 index 0000000..1dcd1cb --- /dev/null +++ b/packaging/openstack-neutron/0113-metering-properly-do-data-filtering-within-some-APIs.patch @@ -0,0 +1,74 @@ +From d22988095ec094f9981d05bb5801874e9a5c7709 Mon Sep 17 00:00:00 2001 +From: Hunt Xu +Date: Wed, 14 Jun 2017 12:19:09 +0800 +Subject: [PATCH 113/118] metering: properly do data filtering within some APIs + +This prevents getting and sending unrelated data to metering agents. + +Fixes: redmine #10261 + +Signed-off-by: Hunt Xu +--- + neutron/db/metering/metering_db.py | 1 + + neutron/services/metering/metering_plugin.py | 11 +++++------ + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/neutron/db/metering/metering_db.py b/neutron/db/metering/metering_db.py +index adef1af6b..94d5d3ddc 100644 +--- a/neutron/db/metering/metering_db.py ++++ b/neutron/db/metering/metering_db.py +@@ -188,6 +188,7 @@ class MeteringDbMixin(metering.MeteringPluginBase, + raise metering.MeteringLabelRuleNotFound(rule_id=rule_id) + + context.session.delete(rule) ++ return rule + + def _get_metering_rules_dict(self, metering_label): + rules = [] +diff --git a/neutron/services/metering/metering_plugin.py b/neutron/services/metering/metering_plugin.py +index 6abb29708..cd4c564db 100644 +--- a/neutron/services/metering/metering_plugin.py ++++ b/neutron/services/metering/metering_plugin.py +@@ -42,7 +42,7 @@ class MeteringPlugin(metering_db.MeteringDbMixin, + context, metering_label) + + data = metering_db.MeteringDbMixin.get_sync_data_metering( +- self, context) ++ self, context, label['id']) + self.meter_rpc.add_metering_label(context, data) + + return label +@@ -62,7 +62,7 @@ class MeteringPlugin(metering_db.MeteringDbMixin, + context, metering_label_rule) + + data = metering_db.MeteringDbMixin.get_sync_data_metering( +- self, context) ++ self, context, rule['metering_label_id']) + self.meter_rpc.update_metering_label_rules(context, data) + + return rule +@@ -71,18 +71,17 @@ class MeteringPlugin(metering_db.MeteringDbMixin, + rule = super(MeteringPlugin, self).delete_metering_label_rule( + context, rule_id) + ++ label_id = rule['metering_label_id'] + data = metering_db.MeteringDbMixin.get_sync_data_metering( +- self, context) ++ self, context, label_id) + self.meter_rpc.update_metering_label_rules(context, data) + +- return rule +- + def create_es_metering_label(self, context, es_metering_label): + label = super(MeteringPlugin, self).create_es_metering_label( + context, es_metering_label) + + data = es_metering_db.EsMeteringDbMixin.get_sync_data_metering( +- self, context) ++ self, context, label_id=label['id']) + self.meter_rpc.add_es_metering_label(context, data) + + return label +-- +2.13.3 + diff --git a/packaging/openstack-neutron/0114-Loadbalancer-enable-a-created-free-port-to-be-used-b.patch b/packaging/openstack-neutron/0114-Loadbalancer-enable-a-created-free-port-to-be-used-b.patch new file mode 100644 index 0000000..bc43252 --- /dev/null +++ b/packaging/openstack-neutron/0114-Loadbalancer-enable-a-created-free-port-to-be-used-b.patch @@ -0,0 +1,125 @@ +From 6182b24aef2a650a96e16b9fe35fb4fec0714384 Mon Sep 17 00:00:00 2001 +From: Hunt Xu +Date: Fri, 16 Jun 2017 18:25:32 +0800 +Subject: [PATCH 114/118] Loadbalancer: enable a created free port to be used + by new VIP + +With this commit, when creating a new loadbalancer VIP, an exsiting free +Neutron port can be used as the VIP port. +(Port is specified using subnet_id and ip_address.) + +Fixes: redmine #10286 + +Signed-off-by: Hunt Xu +--- + neutron/db/loadbalancer/loadbalancer_db.py | 65 ++++++++++++++++-------------- + neutron/extensions/loadbalancer.py | 4 ++ + 2 files changed, 39 insertions(+), 30 deletions(-) + +diff --git a/neutron/db/loadbalancer/loadbalancer_db.py b/neutron/db/loadbalancer/loadbalancer_db.py +index 3decaef83..d21ae2c6d 100644 +--- a/neutron/db/loadbalancer/loadbalancer_db.py ++++ b/neutron/db/loadbalancer/loadbalancer_db.py +@@ -423,49 +423,54 @@ class LoadBalancerPluginDb(loadbalancer.LoadBalancerPluginBase, + sess_qry = context.session.query(SessionPersistence) + sess_qry.filter_by(vip_id=vip_id).delete() + +- def _vip_port_has_exist(self, context, vip_db, ip_addr): +- port_filter = {'fixed_ips': {'ip_address': [ip_addr]}} ++ def _get_vip_port(self, context, vip_db, fixed_ip): ++ port_filter = {'fixed_ips': {'ip_address': [fixed_ip['ip_address']], ++ 'subnet_id': [fixed_ip['subnet_id']]}} + + ports = self._core_plugin.get_ports(context, filters=port_filter) + if ports: +- # verify port id has exist in VIP +- vips = self.get_vips(context, +- filters={'port_id': [ports[0]['id']]}) +- if vips: +- # verify vip listen on different L4 port +- for vip in vips: +- if vip_db.protocol_port == vip['protocol_port']: +- raise loadbalancer.ProtocolPortInUse( +- proto_port=vip['protocol_port'], vip=vip['id']) +- return ports[0] ++ port = ports[0] ++ port_id = port['id'] ++ device_owner = port['device_owner'] ++ ++ # port is free or port is owned by neutron:LOADBALANCER ++ valid_device_owners = ['', 'neutron:' + constants.LOADBALANCER] ++ if device_owner not in valid_device_owners: ++ raise loadbalancer.PortNotOwnedByLB(port_id=port_id) ++ ++ # verify vip listen on different L4 port ++ vips = self.get_vips(context, filters={'port_id': [port_id]}) ++ for vip in vips: ++ if vip_db.protocol_port == vip['protocol_port']: ++ raise loadbalancer.ProtocolPortInUse( ++ proto_port=vip['protocol_port'], vip=vip['id']) ++ return port + return None + + def _create_port_for_vip(self, context, vip_db, subnet_id, ip_address): + # resolve subnet and create port + subnet = self._core_plugin.get_subnet(context, subnet_id) + fixed_ip = {'subnet_id': subnet['id']} +- need_create_port = True ++ port = None + + if ip_address and ip_address != attributes.ATTR_NOT_SPECIFIED: + fixed_ip['ip_address'] = ip_address +- # check if vip port has exist +- port = self._vip_port_has_exist(context, vip_db, ip_address) +- if port: +- need_create_port = False +- +- port_data = { +- 'tenant_id': vip_db.tenant_id, +- 'name': 'vip-' + vip_db.id, +- 'network_id': subnet['network_id'], +- 'mac_address': attributes.ATTR_NOT_SPECIFIED, +- 'admin_state_up': False, +- 'device_id': '', +- 'device_owner': '', +- 'fixed_ips': [fixed_ip] +- } +- +- if need_create_port: ++ # Use an existing port if no confliction ++ port = self._get_vip_port(context, vip_db, fixed_ip) ++ ++ if not port: ++ port_data = { ++ 'tenant_id': vip_db.tenant_id, ++ 'name': 'vip-' + vip_db.id, ++ 'network_id': subnet['network_id'], ++ 'mac_address': attributes.ATTR_NOT_SPECIFIED, ++ 'admin_state_up': False, ++ 'device_id': '', ++ 'device_owner': '', ++ 'fixed_ips': [fixed_ip] ++ } + port = self._core_plugin.create_port(context, {'port': port_data}) ++ + vip_db.port_id = port['id'] + # explicitly sync session with db + context.session.flush() +diff --git a/neutron/extensions/loadbalancer.py b/neutron/extensions/loadbalancer.py +index 5f3589681..cc170d266 100644 +--- a/neutron/extensions/loadbalancer.py ++++ b/neutron/extensions/loadbalancer.py +@@ -113,6 +113,10 @@ class ProtocolPortInUse(qexception.BadRequest): + message = _("VIP %(vip)s has bound to the protocol port %(proto_port)s") + + ++class PortNotOwnedByLB(qexception.BadRequest): ++ message = _("Port %(port_id)s not owned by LOADBALANCER.") ++ ++ + class PoolNotBoundToAgent(qexception.BadRequest): + message = _("Pool %(pool)s has not bound to agent %(agent)s") + +-- +2.13.3 + diff --git a/packaging/openstack-neutron/0115-Fix-exception-message-format-error.patch b/packaging/openstack-neutron/0115-Fix-exception-message-format-error.patch new file mode 100644 index 0000000..845dd59 --- /dev/null +++ b/packaging/openstack-neutron/0115-Fix-exception-message-format-error.patch @@ -0,0 +1,51 @@ +From ac5cd299fe4c8552ff9f92d669227813a0b2bcde Mon Sep 17 00:00:00 2001 +From: "cheng.tang" +Date: Mon, 26 Jun 2017 16:12:01 +0800 +Subject: [PATCH 115/118] Fix exception message format error + +Fixes: redmine #10312 +Signed-off-by: Hunt Xu +--- + neutron/extensions/loadbalancer_l7.py | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/neutron/extensions/loadbalancer_l7.py b/neutron/extensions/loadbalancer_l7.py +index 7f92c9d0b..92f5a77fa 100644 +--- a/neutron/extensions/loadbalancer_l7.py ++++ b/neutron/extensions/loadbalancer_l7.py +@@ -39,7 +39,7 @@ class L7policyInUse(qexception.BadRequest): + + class L7policyActionKeyValueNotSupport(qexception.BadRequest): + message = _("L7policy action %(l7policy_action)s with key %(l7policy_key)s" +- "and value %(l7policy_value)s does not support") ++ " and value %(l7policy_value)s does not support") + + + class L7ruleNotFound(qexception.NotFound): +@@ -51,7 +51,7 @@ class L7ruleInUse(qexception.NotFound): + + + class L7ruleTypeKeyValueNotSupport(qexception.BadRequest): +- message = _("L7rule type %(l7rule_type)s with key %(l7rule_key)s" ++ message = _("L7rule type %(l7rule_type)s with key %(l7rule_key)s " + "and value %(l7rule_value)s dose not support") + + +@@ -61,12 +61,12 @@ class L7ruleCompareTypeValueNotSupport(qexception.BadRequest): + + + class L7policyRuleAssociationExists(qexception.BadRequest): +- message = _("L7policy %(policy_id)s is already associated" ++ message = _("L7policy %(policy_id)s is already associated " + "with L7rule %(rule_id)s") + + + class L7policyRuleAssociationNotFound(qexception.NotFound): +- message = _("L7policy %(policy_id)s is not associated" ++ message = _("L7policy %(policy_id)s is not associated " + "with L7rule %(rule_id)s") + + +-- +2.13.3 + diff --git a/packaging/openstack-neutron/0116-Add-monitor-address-and-port-for-lbaas-member.patch b/packaging/openstack-neutron/0116-Add-monitor-address-and-port-for-lbaas-member.patch new file mode 100644 index 0000000..e8082ce --- /dev/null +++ b/packaging/openstack-neutron/0116-Add-monitor-address-and-port-for-lbaas-member.patch @@ -0,0 +1,152 @@ +From 35f487ba73d7bcb98e6d975ccbaae41537a43d54 Mon Sep 17 00:00:00 2001 +From: "cheng.tang" +Date: Thu, 4 May 2017 14:19:01 +0800 +Subject: [PATCH 116/118] Add monitor address and port for lbaas member + +This allow lbaas member health check different +IP and Port tuple + +Fixes: redmine #9977 + +Signed-off-by: cheng.tang +Signed-off-by: Hunt Xu +--- + neutron/db/loadbalancer/loadbalancer_db.py | 6 +++ + ...tor_address_and_port_column_for_lbaas_member.py | 45 ++++++++++++++++++++++ + .../db/migration/alembic_migrations/versions/HEAD | 2 +- + neutron/extensions/loadbalancer.py | 11 +++++- + .../services/loadbalancer/drivers/haproxy/cfg.py | 6 +++ + 5 files changed, 68 insertions(+), 2 deletions(-) + create mode 100644 neutron/db/migration/alembic_migrations/versions/0ffcc7f9a449_add_monitor_address_and_port_column_for_lbaas_member.py + +diff --git a/neutron/db/loadbalancer/loadbalancer_db.py b/neutron/db/loadbalancer/loadbalancer_db.py +index 061735b24..a96187b39 100644 +--- a/neutron/db/loadbalancer/loadbalancer_db.py ++++ b/neutron/db/loadbalancer/loadbalancer_db.py +@@ -108,6 +108,8 @@ class Member(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant, + weight = sa.Column(sa.Integer, nullable=False) + admin_state_up = sa.Column(sa.Boolean(), nullable=False) + priority = sa.Column(sa.Integer, nullable=False, default=256) ++ monitor_address = sa.Column(sa.String(64), nullable=True) ++ monitor_port = sa.Column(sa.Integer, nullable=True) + + + class Pool(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant, +@@ -778,6 +780,8 @@ class LoadBalancerPluginDb(loadbalancer.LoadBalancerPluginBase, + 'weight': member['weight'], + 'admin_state_up': member['admin_state_up'], + 'priority': member['priority'], ++ 'monitor_address': member['monitor_address'], ++ 'monitor_port': member['monitor_port'], + 'status': member['status'], + 'status_description': member['status_description']} + +@@ -797,6 +801,8 @@ class LoadBalancerPluginDb(loadbalancer.LoadBalancerPluginBase, + address=v['address'], + protocol_port=v['protocol_port'], + weight=v['weight'], ++ monitor_address=v['monitor_address'], ++ monitor_port=v['monitor_port'], + admin_state_up=v['admin_state_up'], + status=constants.PENDING_CREATE) + if attributes.is_attr_set(v['priority']): +diff --git a/neutron/db/migration/alembic_migrations/versions/0ffcc7f9a449_add_monitor_address_and_port_column_for_lbaas_member.py b/neutron/db/migration/alembic_migrations/versions/0ffcc7f9a449_add_monitor_address_and_port_column_for_lbaas_member.py +new file mode 100644 +index 000000000..bb7197c57 +--- /dev/null ++++ b/neutron/db/migration/alembic_migrations/versions/0ffcc7f9a449_add_monitor_address_and_port_column_for_lbaas_member.py +@@ -0,0 +1,45 @@ ++# Copyright 2017 OpenStack Foundation ++# ++# 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. ++# ++ ++"""add priority column for lbaas member table ++ ++Revision ID: 0ffcc7f9a449 ++Revises: 7dc5a7c3d759 ++Create Date: 2017-05-11 23:57:10.409817 ++ ++""" ++ ++# revision identifiers, used by Alembic. ++revision = '0ffcc7f9a449' ++down_revision = '7dc5a7c3d759' ++ ++from alembic import op ++import sqlalchemy as sa ++ ++ ++def upgrade(): ++ op.add_column( ++ 'members', ++ sa.Column('monitor_address', sa.String(64), nullable=True) ++ ) ++ op.add_column( ++ 'members', ++ sa.Column('monitor_port', sa.Integer, nullable=True) ++ ) ++ ++ ++def downgrade(): ++ op.drop_column('members', 'monitor_address') ++ op.drop_column('members', 'monitor_port') +diff --git a/neutron/db/migration/alembic_migrations/versions/HEAD b/neutron/db/migration/alembic_migrations/versions/HEAD +index 81eed9065..a2117f3c1 100644 +--- a/neutron/db/migration/alembic_migrations/versions/HEAD ++++ b/neutron/db/migration/alembic_migrations/versions/HEAD +@@ -1 +1 @@ +-7dc5a7c3d759 ++0ffcc7f9a449 +diff --git a/neutron/extensions/loadbalancer.py b/neutron/extensions/loadbalancer.py +index 3c6ecb8ff..7db9841c6 100644 +--- a/neutron/extensions/loadbalancer.py ++++ b/neutron/extensions/loadbalancer.py +@@ -260,7 +260,16 @@ RESOURCE_ATTRIBUTE_MAP = { + 'status': {'allow_post': False, 'allow_put': False, + 'is_visible': True}, + 'status_description': {'allow_post': False, 'allow_put': False, +- 'is_visible': True} ++ 'is_visible': True}, ++ 'monitor_address': {'allow_post': True, 'allow_put': True, ++ 'validate': {'type:ip_address_or_none': None}, ++ 'default': None, ++ 'is_visible': True}, ++ 'monitor_port': {'allow_post': True, 'allow_put': True, ++ 'validate': {'type:range_or_none': [1, 65535]}, ++ 'default': None, ++ 'convert_to': attr.convert_to_int_if_not_none, ++ 'is_visible': True} + }, + 'health_monitors': { + 'id': {'allow_post': False, 'allow_put': False, +diff --git a/neutron/services/loadbalancer/drivers/haproxy/cfg.py b/neutron/services/loadbalancer/drivers/haproxy/cfg.py +index ca9899ce7..cecac69b8 100644 +--- a/neutron/services/loadbalancer/drivers/haproxy/cfg.py ++++ b/neutron/services/loadbalancer/drivers/haproxy/cfg.py +@@ -285,6 +285,12 @@ def _build_backend(config): + if need_server_id: + server += ' id %d' % _get_acl_member_id(member['id']) + ++ # add health check address and port opt ++ if member['monitor_address'] is not None: ++ server += ' addr %s' % member['monitor_address'] ++ if member['monitor_port'] is not None: ++ server += ' port %s' % member['monitor_port'] ++ + if _has_http_cookie_persistence(config): + server += ' cookie %d' % config['members'].index(member) + member_opts.append(server) +-- +2.13.3 + diff --git a/packaging/openstack-neutron/0117-Fix-exception-error-when-l7rule-delete.patch b/packaging/openstack-neutron/0117-Fix-exception-error-when-l7rule-delete.patch new file mode 100644 index 0000000..db61682 --- /dev/null +++ b/packaging/openstack-neutron/0117-Fix-exception-error-when-l7rule-delete.patch @@ -0,0 +1,29 @@ +From c9dc08807c7dd61fb9e6e3a143648307ab9cc851 Mon Sep 17 00:00:00 2001 +From: "cheng.tang" +Date: Thu, 29 Jun 2017 13:01:28 +0800 +Subject: [PATCH 117/118] Fix exception error when l7rule delete + +Fixes: redmine #10380 + +Signed-off-by: cheng.tang +Signed-off-by: Hunt Xu +--- + neutron/extensions/loadbalancer_l7.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/neutron/extensions/loadbalancer_l7.py b/neutron/extensions/loadbalancer_l7.py +index 7f92c9d0b..d0a00fb67 100644 +--- a/neutron/extensions/loadbalancer_l7.py ++++ b/neutron/extensions/loadbalancer_l7.py +@@ -46,7 +46,7 @@ class L7ruleNotFound(qexception.NotFound): + message = _("L7rule %(l7rule_id)s could not be found") + + +-class L7ruleInUse(qexception.NotFound): ++class L7ruleInUse(qexception.InUse): + message = _("L7rule %(l7rule_id)s still in use") + + +-- +2.13.3 + diff --git a/packaging/openstack-neutron/0118-Port-don-t-check-max-fixed_ips-quota-for-dhcp-agent-.patch b/packaging/openstack-neutron/0118-Port-don-t-check-max-fixed_ips-quota-for-dhcp-agent-.patch new file mode 100644 index 0000000..22040c9 --- /dev/null +++ b/packaging/openstack-neutron/0118-Port-don-t-check-max-fixed_ips-quota-for-dhcp-agent-.patch @@ -0,0 +1,222 @@ +From 9c722b0cb6dc7e1a32729c55585ba388fec370d8 Mon Sep 17 00:00:00 2001 +From: Hunt Xu +Date: Tue, 4 Jul 2017 14:03:37 +0800 +Subject: [PATCH 118/118] Port: don't check max fixed_ips quota for dhcp-agent + callbacks + +DHCP ports may have more fixed_ips than the normal quota value set by +max_fixed_ips_per_port. This commit skips the check when port is created +or updated by the dhcp-agent. + +Fixes: redmine #10437 + +Signed-off-by: Hunt Xu +--- + neutron/api/rpc/handlers/dhcp_rpc.py | 12 ++++++++---- + neutron/db/db_base_plugin_v2.py | 38 ++++++++++++++++++++++++------------ + neutron/plugins/ml2/plugin.py | 12 +++++++----- + 3 files changed, 40 insertions(+), 22 deletions(-) + +diff --git a/neutron/api/rpc/handlers/dhcp_rpc.py b/neutron/api/rpc/handlers/dhcp_rpc.py +index 56016be70..045233844 100644 +--- a/neutron/api/rpc/handlers/dhcp_rpc.py ++++ b/neutron/api/rpc/handlers/dhcp_rpc.py +@@ -58,9 +58,11 @@ class DhcpRpcCallback(n_rpc.RpcCallback): + """Perform port operations taking care of concurrency issues.""" + try: + if action == 'create_port': +- return plugin.create_port(context, port) ++ return plugin.create_port(context, port, ++ check_fixed_ips_amount=False) + elif action == 'update_port': +- return plugin.update_port(context, port['id'], port['port']) ++ return plugin.update_port(context, port['id'], port['port'], ++ check_fixed_ips_amount=False) + else: + msg = _('Unrecognized action') + raise n_exc.Invalid(message=msg) +@@ -172,7 +174,8 @@ class DhcpRpcCallback(n_rpc.RpcCallback): + [dict(subnet_id=s) for s in dhcp_enabled_subnet_ids]) + + retval = plugin.update_port(context, port['id'], +- dict(port=port)) ++ dict(port=port), ++ check_fixed_ips_amount=False) + + except n_exc.NotFound as e: + LOG.warning(e) +@@ -247,7 +250,8 @@ class DhcpRpcCallback(n_rpc.RpcCallback): + if fixed_ips[i]['subnet_id'] == subnet_id: + del fixed_ips[i] + break +- plugin.update_port(context, port['id'], dict(port=port)) ++ plugin.update_port(context, port['id'], dict(port=port), ++ check_fixed_ips_amount=False) + + def update_lease_expiration(self, context, **kwargs): + """Release the fixed_ip associated the subnet on a port.""" +diff --git a/neutron/db/db_base_plugin_v2.py b/neutron/db/db_base_plugin_v2.py +index 9582efed3..f213438cc 100644 +--- a/neutron/db/db_base_plugin_v2.py ++++ b/neutron/db/db_base_plugin_v2.py +@@ -394,7 +394,8 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2, + return True + return False + +- def _test_fixed_ips_for_port(self, context, network_id, fixed_ips): ++ def _test_fixed_ips_for_port(self, context, network_id, fixed_ips, ++ check_fixed_ips_amount=True): + """Test fixed IPs for port. + + Check that configured subnets are valid prior to allocating any +@@ -454,7 +455,10 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2, + 'ip_address': fixed['ip_address']}) + else: + fixed_ip_set.append({'subnet_id': subnet_id}) +- if len(fixed_ip_set) > cfg.CONF.max_fixed_ips_per_port: ++ if ( ++ check_fixed_ips_amount and ++ len(fixed_ip_set) > cfg.CONF.max_fixed_ips_per_port ++ ): + msg = _('Exceeded maximim amount of fixed ips per port') + raise n_exc.InvalidInput(error_message=msg) + return fixed_ip_set +@@ -480,14 +484,17 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2, + return ips + + def _update_ips_for_port(self, context, network_id, port_id, original_ips, +- new_ips): ++ new_ips, check_fixed_ips_amount=True): + """Add or remove IPs from the port.""" + ips = [] + # These ips are still on the port and haven't been removed + prev_ips = [] + + # the new_ips contain all of the fixed_ips that are to be updated +- if len(new_ips) > cfg.CONF.max_fixed_ips_per_port: ++ if ( ++ check_fixed_ips_amount and ++ len(new_ips) > cfg.CONF.max_fixed_ips_per_port ++ ): + msg = _('Exceeded maximim amount of fixed ips per port') + raise n_exc.InvalidInput(error_message=msg) + +@@ -501,7 +508,9 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2, + prev_ips.append(original_ip) + + # Check if the IP's to add are OK +- to_add = self._test_fixed_ips_for_port(context, network_id, new_ips) ++ to_add = self._test_fixed_ips_for_port( ++ context, network_id, new_ips, ++ check_fixed_ips_amount=check_fixed_ips_amount) + for ip in original_ips: + LOG.debug(_("Port update. Hold %s"), ip) + NeutronDbPluginV2._delete_ip_allocation(context, +@@ -514,7 +523,8 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2, + ips = self._allocate_fixed_ips(context, to_add) + return ips, prev_ips + +- def _allocate_ips_for_port(self, context, port): ++ def _allocate_ips_for_port(self, context, port, ++ check_fixed_ips_amount=True): + """Allocate IP addresses for the port. + + If port['fixed_ips'] is set to 'ATTR_NOT_SPECIFIED', allocate IP +@@ -526,9 +536,9 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2, + + fixed_configured = p['fixed_ips'] is not attributes.ATTR_NOT_SPECIFIED + if fixed_configured: +- configured_ips = self._test_fixed_ips_for_port(context, +- p["network_id"], +- p['fixed_ips']) ++ configured_ips = self._test_fixed_ips_for_port( ++ context, p["network_id"], p['fixed_ips'], ++ check_fixed_ips_amount=check_fixed_ips_amount) + ips = self._allocate_fixed_ips(context, configured_ips) + else: + filter = {'network_id': [p['network_id']]} +@@ -1290,7 +1300,7 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2, + def create_port_bulk(self, context, ports): + return self._create_bulk('port', context, ports) + +- def create_port(self, context, port): ++ def create_port(self, context, port, check_fixed_ips_amount=True): + p = port['port'] + port_id = p.get('id') or uuidutils.generate_uuid() + network_id = p['network_id'] +@@ -1338,7 +1348,8 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2, + context.session.add(db_port) + + # Update the IP's for the port +- ips = self._allocate_ips_for_port(context, port) ++ ips = self._allocate_ips_for_port( ++ context, port, check_fixed_ips_amount=check_fixed_ips_amount) + if ips: + for ip in ips: + ip_address = ip['ip_address'] +@@ -1348,7 +1359,7 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2, + + return self._make_port_dict(db_port, process_extensions=False) + +- def update_port(self, context, id, port): ++ def update_port(self, context, id, port, check_fixed_ips_amount=True): + p = port['port'] + + changed_ips = False +@@ -1378,7 +1389,8 @@ class NeutronDbPluginV2(neutron_plugin_base_v2.NeutronPluginBaseV2, + original = self._make_port_dict(port, process_extensions=False) + added_ips, prev_ips = self._update_ips_for_port( + context, port["network_id"], id, original["fixed_ips"], +- p['fixed_ips']) ++ p['fixed_ips'], ++ check_fixed_ips_amount=check_fixed_ips_amount) + + # Update ips if necessary + for ip in added_ips: +diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py +index d1b411cde..9d37c871e 100644 +--- a/neutron/plugins/ml2/plugin.py ++++ b/neutron/plugins/ml2/plugin.py +@@ -778,7 +778,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, + # the fact that an error occurred. + LOG.error(_("mechanism_manager.delete_subnet_postcommit failed")) + +- def create_port(self, context, port): ++ def create_port(self, context, port, check_fixed_ips_amount=True): + attrs = port['port'] + attrs['status'] = const.PORT_STATUS_DOWN + +@@ -787,7 +787,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, + self._ensure_default_security_group_on_port(context, port) + sgids = self._get_security_groups_on_port(context, port) + dhcp_opts = port['port'].get(edo_ext.EXTRADHCPOPTS, []) +- result = super(Ml2Plugin, self).create_port(context, port) ++ result = super(Ml2Plugin, self).create_port( ++ context, port, check_fixed_ips_amount=check_fixed_ips_amount) + self.extension_manager.process_create_port(session, attrs, result) + self._process_port_create_security_group(context, result, sgids) + network = self.get_network(context, result['network_id']) +@@ -829,7 +830,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, + self.delete_port(context, result['id']) + return bound_context._port + +- def update_port(self, context, id, port): ++ def update_port(self, context, id, port, check_fixed_ips_amount=True): + attrs = port['port'] + need_port_update_notify = False + +@@ -845,8 +846,9 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, + if not port_db: + raise exc.PortNotFound(port_id=id) + original_port = self._make_port_dict(port_db) +- updated_port = super(Ml2Plugin, self).update_port(context, id, +- port) ++ updated_port = super(Ml2Plugin, self).update_port( ++ context, id, port, ++ check_fixed_ips_amount=check_fixed_ips_amount) + self.extension_manager.process_update_port(session, attrs, + original_port) + if addr_pair.ADDRESS_PAIRS in port['port']: +-- +2.13.3 + diff --git a/packaging/openstack-neutron/0119-EW-DVR-fix-issues-related-to-hosted-ports.patch b/packaging/openstack-neutron/0119-EW-DVR-fix-issues-related-to-hosted-ports.patch new file mode 100644 index 0000000..dc7439c --- /dev/null +++ b/packaging/openstack-neutron/0119-EW-DVR-fix-issues-related-to-hosted-ports.patch @@ -0,0 +1,52 @@ +From a35c490e92ae06c43aa7255de17005833db122bf Mon Sep 17 00:00:00 2001 +From: Hunt Xu +Date: Thu, 13 Jul 2017 13:50:53 +0800 +Subject: [PATCH] EW DVR: fix issues related to hosted ports + +Hosted ports may not be ready when configuring rules. With this commit a +chance is given for the rules of hosted ports to be re-configured during +the next sync upon such case. + +This commit also fix a minor issue when deleting OpenFlow rules of +removed hosted ports. + +Fixes: 56cf4bd93 ("openvswitch-agent: implement EW DVR using OpenFlow rules") +Fixes: redmine #10558 + +Signed-off-by: Hunt Xu +--- + neutron/plugins/openvswitch/agent/openflow_ew_dvr_agent.py | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/neutron/plugins/openvswitch/agent/openflow_ew_dvr_agent.py b/neutron/plugins/openvswitch/agent/openflow_ew_dvr_agent.py +index 1dfce3c15..87056a50a 100644 +--- a/neutron/plugins/openvswitch/agent/openflow_ew_dvr_agent.py ++++ b/neutron/plugins/openvswitch/agent/openflow_ew_dvr_agent.py +@@ -232,8 +232,14 @@ class OFEWDVRAgent(object): + dl_dst=gateway_mac, proto='ip', ip_dst=port['ip']) + + def _add_flows_to_hosted_port(self, port, gateway_mac): ++ if port['host'] != self.host: ++ LOG.debug("Port %s is not hosted by this agent.", port['name']) ++ return + port_ofno = self.int_br.get_port_ofport(port['name']) +- if port_ofno == INVALID_OFPORT or port['host'] != self.host: ++ if port_ofno == INVALID_OFPORT: ++ LOG.warning("Port %s is not ready.", port['name']) ++ # Setting port['host'] to None for next sync. ++ port['host'] = None + return + actions = "strip_vlan,mod_dl_src:%s,dec_ttl,output:%s" % ( + gateway_mac, port_ofno) +@@ -289,7 +295,7 @@ class OFEWDVRAgent(object): + + old_port = old_subnet['ports'].pop(port_id) + if self._port_moved_out_of_host(old_port, port): +- self._del_flows_to_hosted_port(port) ++ self._del_flows_to_hosted_port(old_port) + elif self._port_moved_into_host(old_port, port): + self._add_flows_to_hosted_port(port, gateway_mac) + +-- +2.13.3 + diff --git a/packaging/openstack-neutron/openstack-neutron.spec b/packaging/openstack-neutron/openstack-neutron.spec index b29b0f8..c06c682 100644 --- a/packaging/openstack-neutron/openstack-neutron.spec +++ b/packaging/openstack-neutron/openstack-neutron.spec @@ -4,7 +4,7 @@ Name: openstack-neutron Version: 2014.2 -Release: 34%{?dist_eayunstack} +Release: 35%{?dist_eayunstack} Provides: openstack-quantum = %{version}-%{release} Obsoletes: openstack-quantum < 2013.2-0.4.b3 Summary: OpenStack Networking Service @@ -151,6 +151,17 @@ Patch0105: 0105-es-metering-fix-port-selection-when-tcp_port-is-spec.patch Patch0106: 0106-Optimize-haproxy-driver-port_to_pool_id-dict.patch Patch0107: 0107-OpenFlow-EW-DVR-be-more-torelant-when-syncing-dvr-po.patch Patch0108: 0108-Add-check-if-extra-actions-params-is-correct.patch +Patch0109: 0109-Add-status_changed-notification-for-some-components.patch +Patch0110: 0110-FWaaS-apply-firewall-rules-to-router-ingress-traffic.patch +Patch0111: 0111-FWaaS-support-some-more-protocols-in-FW-rules.patch +Patch0112: 0112-Fix-firewall-port-range-compare-error.patch +Patch0113: 0113-metering-properly-do-data-filtering-within-some-APIs.patch +Patch0114: 0114-Loadbalancer-enable-a-created-free-port-to-be-used-b.patch +Patch0115: 0115-Fix-exception-message-format-error.patch +Patch0116: 0116-Add-monitor-address-and-port-for-lbaas-member.patch +Patch0117: 0117-Fix-exception-error-when-l7rule-delete.patch +Patch0118: 0118-Port-don-t-check-max-fixed_ips-quota-for-dhcp-agent-.patch +Patch0119: 0119-EW-DVR-fix-issues-related-to-hosted-ports.patch BuildArch: noarch @@ -737,6 +748,17 @@ IPSec. %patch0106 -p1 %patch0107 -p1 %patch0108 -p1 +%patch0109 -p1 +%patch0110 -p1 +%patch0111 -p1 +%patch0112 -p1 +%patch0113 -p1 +%patch0114 -p1 +%patch0115 -p1 +%patch0116 -p1 +%patch0117 -p1 +%patch0118 -p1 +%patch0119 -p1 find neutron -name \*.py -exec sed -i '/\/usr\/bin\/env python/{d;q}' {} + @@ -1198,6 +1220,19 @@ exit 0 %changelog +* Wed Jul 19 2017 Xu Meihong 2014.2-35.eayunstack.dev +- add patch 0109 from github pull request #100 (redmine#10220) +- add patch 0110 from github pull request #101 (redmine#10238) +- add patch 0111 from github pull request #102 (redmine#10240) +- add patch 0112 from github pull request #103 (redmine#10246) +- add patch 0113 from github pull request #105 (redmine#10261) +- add patch 0114 from github pull request #106 (redmine#10286) +- add patch 0115 from github pull request #107 (redmine#10312) +- add patch 0116 from github pull request #95 (redmine#9977) +- add patch 0117 from github pull request #109 (redmine#10380) +- add patch 0118 from github pull request #110 (redmine#10437) +- add patch 0119 from github pull request #113 (redmine#10558) + * Thu Jun 01 2017 Xu Meihong 2014.2-34.eayunstack.dev - add patch 0108 from github pull request #99 (redmine#10217)