apic_mapping: Creating L3P with implicit ES uses two IPs on ES

Bug #1522554 reported by Robert Kukura
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Group Based Policy
Fix Released
High
Amit Bose

Bug Description

While investigating https://bugs.launchpad.net/group-based-policy/+bug/1509458, I discovered that GroupPolicyDbPlugin._set_ess_for_l3p() gets called six times during creation of an L3Policy with an implicit ExternalSegment, and that two different IP addresses get passed to it for the same L3Policy. Only one IP address on the ExternalSegment should be needed (with NAT enabled). Its not clear if the extra address is being leaked or returned to the pool.

The following log with extra temporary log statements added shows the six _set_ess_for_l3p() calls, there callers, and the args passed:

2015-12-02 13:59:48,887 INFO [gbpservice.neutron.db.grouppolicy.group_policy_mapping_db] create_l3_policy() calling _set_ess_for_l3p()
2015-12-02 13:59:48,888 INFO [gbpservice.neutron.db.grouppolicy.group_policy_db] _set_ess_for_l3p - l3p_db: <gbpservice.neutron.db.grouppolicy.group_policy_mapping_db.L3PolicyMapping[object at 7c47690] {tenant_id='test-tenant', id='0fc541a0-6c04-4013-b8f4-8a3e7071dd07', type='mapping', name=u'l3p1', description=u'', ip_version=4, ip_pool=u'10.0.0.0/8', subnet_prefix_length=24, shared=False}>, es_dict: {}
2015-12-02 13:59:48,902 INFO [gbpservice.neutron.db.grouppolicy.group_policy_mapping_db] update_l3_policy() calling _set_ess_for_l3p()
2015-12-02 13:59:48,903 INFO [gbpservice.neutron.db.grouppolicy.group_policy_db] _set_ess_for_l3p - l3p_db: <gbpservice.neutron.db.grouppolicy.group_policy_mapping_db.L3PolicyMapping[object at 7b60750] {tenant_id=u'test-tenant', id=u'0fc541a0-6c04-4013-b8f4-8a3e7071dd07', type=u'mapping', name=u'l3p1', description=u'', ip_version=4, ip_pool=u'10.0.0.0/8', subnet_prefix_length=24, shared=False}>, es_dict: {u'e195b652-ed62-42f5-9810-8340bda908a5': []}
2015-12-02 13:59:48,967 WARNING [neutron.notifiers.nova] Authenticating to nova using nova_admin_* options is deprecated. This should be done using an auth plugin, like password
2015-12-02 13:59:49,105 INFO [neutron.callbacks.manager] Notify callbacks for port, after_create
2015-12-02 13:59:49,105 INFO [neutron.callbacks.manager] Calling callback neutron.db.l3_dvrscheduler_db._notify_l3_agent_new_port
2015-12-02 13:59:49,169 WARNING [neutron.scheduler.l3_agent_scheduler] No active L3 agents
2015-12-02 13:59:49,188 INFO [gbpservice.neutron.services.grouppolicy.drivers.cisco.apic.apic_mapping] update_l3_policy_postcommit() calling _plug_l3p_to_es()
2015-12-02 13:59:49,188 INFO [gbpservice.neutron.services.grouppolicy.drivers.cisco.apic.apic_mapping] _plug_l3p_to_es() calling set_external_fixed_ips()
2015-12-02 13:59:49,188 INFO [gbpservice.neutron.services.grouppolicy.group_policy_context] set_external_fixed_ips() calling _update_ess_for_l3p()
2015-12-02 13:59:49,190 INFO [gbpservice.neutron.db.grouppolicy.group_policy_mapping_db] _update_ess_for_l3p() calling _set_ess_for_l3p()
2015-12-02 13:59:49,190 INFO [gbpservice.neutron.db.grouppolicy.group_policy_db] _set_ess_for_l3p - l3p_db: <gbpservice.neutron.db.grouppolicy.group_policy_mapping_db.L3PolicyMapping[object at 7fbf9d0] {tenant_id=u'test-tenant', id=u'0fc541a0-6c04-4013-b8f4-8a3e7071dd07', type=u'mapping', name=u'l3p1', description=u'', ip_version=4, ip_pool=u'10.0.0.0/8', subnet_prefix_length=24, shared=False}>, es_dict: {u'e195b652-ed62-42f5-9810-8340bda908a5': [u'169.254.0.2']}
2015-12-02 13:59:49,197 INFO [gbpservice.neutron.services.grouppolicy.drivers.cisco.apic.apic_mapping] _plug_l3p_to_es() calling _plug_l3p_to_es()
2015-12-02 13:59:49,197 INFO [gbpservice.neutron.services.grouppolicy.drivers.cisco.apic.apic_mapping] _plug_l3p_to_es() calling set_external_fixed_ips()
2015-12-02 13:59:49,197 INFO [gbpservice.neutron.services.grouppolicy.group_policy_context] set_external_fixed_ips() calling _update_ess_for_l3p()
2015-12-02 13:59:49,199 INFO [gbpservice.neutron.db.grouppolicy.group_policy_mapping_db] _update_ess_for_l3p() calling _set_ess_for_l3p()
2015-12-02 13:59:49,199 INFO [gbpservice.neutron.db.grouppolicy.group_policy_db] _set_ess_for_l3p - l3p_db: <gbpservice.neutron.db.grouppolicy.group_policy_mapping_db.L3PolicyMapping[object at 7fbf9d0] {tenant_id=u'test-tenant', id=u'0fc541a0-6c04-4013-b8f4-8a3e7071dd07', type=u'mapping', name=u'l3p1', description=u'', ip_version=4, ip_pool=u'10.0.0.0/8', subnet_prefix_length=24, shared=False}>, es_dict: {u'e195b652-ed62-42f5-9810-8340bda908a5': [u'169.254.0.2']}
2015-12-02 13:59:49,242 WARNING [neutron.notifiers.nova] Authenticating to nova using nova_admin_* options is deprecated. This should be done using an auth plugin, like password
2015-12-02 13:59:49,375 INFO [neutron.callbacks.manager] Notify callbacks for port, after_create
2015-12-02 13:59:49,375 INFO [neutron.callbacks.manager] Calling callback neutron.db.l3_dvrscheduler_db._notify_l3_agent_new_port
2015-12-02 13:59:49,439 WARNING [neutron.scheduler.l3_agent_scheduler] No active L3 agents
2015-12-02 13:59:49,458 INFO [gbpservice.neutron.services.grouppolicy.drivers.cisco.apic.apic_mapping] create_l3_policy_postcommit() calling _plug_l3p_to_es()
2015-12-02 13:59:49,458 INFO [gbpservice.neutron.services.grouppolicy.drivers.cisco.apic.apic_mapping] _plug_l3p_to_es() calling set_external_fixed_ips()
2015-12-02 13:59:49,458 INFO [gbpservice.neutron.services.grouppolicy.group_policy_context] set_external_fixed_ips() calling _update_ess_for_l3p()
2015-12-02 13:59:49,460 INFO [gbpservice.neutron.db.grouppolicy.group_policy_mapping_db] _update_ess_for_l3p() calling _set_ess_for_l3p()
2015-12-02 13:59:49,460 INFO [gbpservice.neutron.db.grouppolicy.group_policy_db] _set_ess_for_l3p - l3p_db: <gbpservice.neutron.db.grouppolicy.group_policy_mapping_db.L3PolicyMapping[object at 873f210] {tenant_id=u'test-tenant', id=u'0fc541a0-6c04-4013-b8f4-8a3e7071dd07', type=u'mapping', name=u'l3p1', description=u'', ip_version=4, ip_pool=u'10.0.0.0/8', subnet_prefix_length=24, shared=False}>, es_dict: {u'e195b652-ed62-42f5-9810-8340bda908a5': [u'169.254.0.3']}
2015-12-02 13:59:49,466 INFO [gbpservice.neutron.services.grouppolicy.drivers.cisco.apic.apic_mapping] _plug_l3p_to_es() calling _plug_l3p_to_es()
2015-12-02 13:59:49,466 INFO [gbpservice.neutron.services.grouppolicy.drivers.cisco.apic.apic_mapping] _plug_l3p_to_es() calling set_external_fixed_ips()
2015-12-02 13:59:49,467 INFO [gbpservice.neutron.services.grouppolicy.group_policy_context] set_external_fixed_ips() calling _update_ess_for_l3p()
2015-12-02 13:59:49,468 INFO [gbpservice.neutron.db.grouppolicy.group_policy_mapping_db] _update_ess_for_l3p() calling _set_ess_for_l3p()
2015-12-02 13:59:49,468 INFO [gbpservice.neutron.db.grouppolicy.group_policy_db] _set_ess_for_l3p - l3p_db: <gbpservice.neutron.db.grouppolicy.group_policy_mapping_db.L3PolicyMapping[object at 873f210] {tenant_id=u'test-tenant', id=u'0fc541a0-6c04-4013-b8f4-8a3e7071dd07', type=u'mapping', name=u'l3p1', description=u'', ip_version=4, ip_pool=u'10.0.0.0/8', subnet_prefix_length=24, shared=False}>, es_dict: {u'e195b652-ed62-42f5-9810-8340bda908a5': [u'169.254.0.3']}

I suspect the redundant _set_ess_for_l3p() calls, and the two different IP addresses, may be occurring because the implicit_policy driver is updating the L3P with the ES during its create_l3_policy_postcommit() by doing an update_l3_policy(), and this results in the apic_mapping driver's update_l3_policy_postcommit() running for the L3P before it's create_l3_policy_postcommit() runs. The apic_mapping driver's create_l3_policy_postcommit() needs to avoid processing the ES if it has already been processed by the driver's update_l3_policy_postcommit().

This bug addresses the two _set_ess_for_l3p() calls to which different IP addresses are initially passed. I'll file a separate bug regarding the redundant 2nd call to _set_ess_for_l3p() with each IP address.

Changed in group-based-policy:
milestone: none → liberty-1
Revision history for this message
Amit Bose (bose) wrote :

> the implicit_policy driver is updating the L3P with the ES during its create_l3_policy_postcommit() by doing an update_l3_policy(), and this results in the apic_mapping driver's update_l3_policy_postcommit() running for the L3P before it's create_l3_policy_postcommit() runs.

This behavior of the implicit policy driver seems incorrect to me, for example an "update" call is made to the backend driver before a "create" call for a resource. Besides, it affects all backend drivers, including the resource-mapping driver. So instead of working around it in every backend driver, I'm proposing to fix it in implicit-policy driver by doing following in L3PolicyContext.set_external_segment()

* Don't call GroupPolicyPlugin.update_l3_policy(); instead, update the DB to add an association between the L3Policy and 'default' external-segment
* As before, update the L3PolicyContext with 'default' external-segment ID

Doing this will ensure that before the create post-commit of the backend drivers is called, both the context and DB will be set up in a way that would be the same as when the create L3Policy request referred to 'default' external segment.

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to group-based-policy (master)

Fix proposed to branch: master
Review: https://review.openstack.org/253664

Changed in group-based-policy:
status: New → In Progress
Revision history for this message
Robert Kukura (rkukura) wrote :

I think your suggestion makes sense, and also makes implicit ESes work more similarly to implicit L2Ps and implicit L3Ps. I'm not sure why update_l3_policy() was used for implicit ESes in the first place.

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to group-based-policy (master)

Reviewed: https://review.openstack.org/253664
Committed: https://git.openstack.org/cgit/openstack/group-based-policy/commit/?id=46a121339ffee90154cfc900a8991735746a4c11
Submitter: Jenkins
Branch: master

commit 46a121339ffee90154cfc900a8991735746a4c11
Author: Amit Bose <email address hidden>
Date: Fri Dec 4 11:30:16 2015 -0800

    Avoid allocating multiple router gateway IPs

    When an L3Policy is implicitly associated with the
    'default' external-segment, multiple IP addresses
    get allocated for the gateway port. This happens
    because update-postcommit is called before
    create-postcommit during the creation of L3Policy.
    This change avoids the update-postcommit;
    instead we set things up in the DB and request
    context in a way so that create-postcommit behaves
    as if the 'default' external-segment was specified
    as part of the create request.

    Closes-Bug: 1522554

    Change-Id: Iebea8cf315d2ed7acbf4994940ccd57a93133475
    Signed-off-by: Amit Bose <email address hidden>

Changed in group-based-policy:
status: In Progress → Fix Released
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to group-based-policy (stable/kilo)

Fix proposed to branch: stable/kilo
Review: https://review.openstack.org/254418

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to group-based-policy (stable/juno)

Fix proposed to branch: stable/juno
Review: https://review.openstack.org/254419

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to group-based-policy (stable/kilo)

Reviewed: https://review.openstack.org/254418
Committed: https://git.openstack.org/cgit/openstack/group-based-policy/commit/?id=2b370862fa835977bfb109899928503c2f6c4fad
Submitter: Jenkins
Branch: stable/kilo

commit 2b370862fa835977bfb109899928503c2f6c4fad
Author: Amit Bose <email address hidden>
Date: Fri Dec 4 11:30:16 2015 -0800

    Avoid allocating multiple router gateway IPs

    When an L3Policy is implicitly associated with the
    'default' external-segment, multiple IP addresses
    get allocated for the gateway port. This happens
    because update-postcommit is called before
    create-postcommit during the creation of L3Policy.
    This change avoids the update-postcommit;
    instead we set things up in the DB and request
    context in a way so that create-postcommit behaves
    as if the 'default' external-segment was specified
    as part of the create request.

    Closes-Bug: 1522554

    Change-Id: Iebea8cf315d2ed7acbf4994940ccd57a93133475
    Signed-off-by: Amit Bose <email address hidden>
    (cherry picked from commit 46a121339ffee90154cfc900a8991735746a4c11)

tags: added: in-stable-kilo
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to group-based-policy (stable/juno)

Reviewed: https://review.openstack.org/254419
Committed: https://git.openstack.org/cgit/openstack/group-based-policy/commit/?id=2a6aa3d23a462069f892f21ea5d382067bbcbd13
Submitter: Jenkins
Branch: stable/juno

commit 2a6aa3d23a462069f892f21ea5d382067bbcbd13
Author: Amit Bose <email address hidden>
Date: Fri Dec 4 11:30:16 2015 -0800

    Avoid allocating multiple router gateway IPs

    When an L3Policy is implicitly associated with the
    'default' external-segment, multiple IP addresses
    get allocated for the gateway port. This happens
    because update-postcommit is called before
    create-postcommit during the creation of L3Policy.
    This change avoids the update-postcommit;
    instead we set things up in the DB and request
    context in a way so that create-postcommit behaves
    as if the 'default' external-segment was specified
    as part of the create request.

    Closes-Bug: 1522554

    Change-Id: Iebea8cf315d2ed7acbf4994940ccd57a93133475
    Signed-off-by: Amit Bose <email address hidden>
    (cherry picked from commit 46a121339ffee90154cfc900a8991735746a4c11)
    (cherry picked from commit 2b370862fa835977bfb109899928503c2f6c4fad)

tags: added: in-stable-juno
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.