@@ -342,7 +342,7 @@ def update_port_postcommit(self, context):
342
342
state changes that it does not know or care about.
343
343
"""
344
344
port = context .current
345
- network = context .network . current
345
+ segment = context .top_bound_segment
346
346
if self ._is_port_bound (port ):
347
347
binding_profile = port ['binding:profile' ]
348
348
local_link_information = binding_profile .get (
@@ -359,7 +359,7 @@ def update_port_postcommit(self, context):
359
359
return
360
360
# If binding has already succeeded, we should have valid links
361
361
# at this point, but check just in case.
362
- if not self ._is_link_valid (port , network ):
362
+ if not self ._is_link_valid (port , segment ):
363
363
return
364
364
is_802_3ad = self ._is_802_3ad (port )
365
365
for link in local_link_information :
@@ -371,7 +371,7 @@ def update_port_postcommit(self, context):
371
371
ngs_mac_address = switch_id )
372
372
373
373
# If segmentation ID is None, set vlan 1
374
- segmentation_id = network .get ('provider:segmentation_id' ) or 1
374
+ segmentation_id = segment .get (api . SEGMENTATION_ID ) or 1
375
375
trunk_details = port .get ('trunk_details' , {})
376
376
LOG .debug ("Putting switch port %(switch_port)s on "
377
377
"%(switch_info)s in vlan %(segmentation_id)s" ,
@@ -411,10 +411,10 @@ def update_port_postcommit(self, context):
411
411
GENERIC_SWITCH_ENTITY )
412
412
elif self ._is_port_bound (context .original ):
413
413
# The port has been unbound. This will cause the local link
414
- # information to be lost, so remove the port from the network on
414
+ # information to be lost, so remove the port from the segment on
415
415
# the switch now while we have the required information.
416
- self ._unplug_port_from_network (context .original ,
417
- context .network . current )
416
+ self ._unplug_port_from_segment (context .original ,
417
+ context .original_top_bound_segment )
418
418
419
419
def delete_port_precommit (self , context ):
420
420
"""Delete resources of a port.
@@ -443,7 +443,7 @@ def delete_port_postcommit(self, context):
443
443
444
444
port = context .current
445
445
if self ._is_port_bound (port ):
446
- self ._unplug_port_from_network (port , context .network . current )
446
+ self ._unplug_port_from_segment (port , context .top_bound_segment )
447
447
448
448
def _is_vlan_translation_required (self , trunk_details ):
449
449
"""Check if vlan translation is required to configure specific trunk.
@@ -500,34 +500,50 @@ def bind_port(self, context):
500
500
# For more info please read docstring.
501
501
502
502
port = context .current
503
- network = context .network .current
504
503
binding_profile = port ['binding:profile' ]
505
504
local_link_information = binding_profile .get ('local_link_information' )
506
505
507
506
if self ._is_port_supported (port ) and local_link_information :
507
+ # Filter segments where port is already assigned to subnet(s)
508
+ subnets = []
509
+ for fixed_ip in port .get ('fixed_ips' , []):
510
+ subnet_id = fixed_ip .get ('subnet_id' )
511
+ if subnet_id :
512
+ subnets .append (context ._plugin .get_subnet (
513
+ context .plugin_context ,
514
+ subnet_id ))
515
+ segments = []
516
+ if len (subnets ) > 0 :
517
+ for segment in context .segments_to_bind :
518
+ for subnet in subnets :
519
+ segment_id = subnet .get ('segment_id' )
520
+ if segment_id is None or segment_id == segment [api .ID ]:
521
+ segments .append (segment )
522
+ else :
523
+ segments = context .segments_to_bind
524
+
508
525
# NOTE(jamesdenton): If any link of the port is invalid, none
509
526
# of the links should be processed.
510
- if not self ._is_link_valid (port , network ):
527
+ if not self ._is_link_valid (port , segments [ 0 ] ):
511
528
return
512
529
513
- segments = context .segments_to_bind
514
530
context .set_binding (segments [0 ][api .ID ],
515
531
portbindings .VIF_TYPE_OTHER , {})
516
532
517
533
provisioning_blocks .add_provisioning_component (
518
534
context ._plugin_context , port ['id' ], resources .PORT ,
519
535
GENERIC_SWITCH_ENTITY )
520
536
521
- def _is_link_valid (self , port , network ):
522
- """Return whether a link references valid switch and physnet .
537
+ def _is_link_valid (self , port , segment ):
538
+ """Return whether a link references valid switch and segment .
523
539
524
540
If the local link information refers to a switch that is not
525
541
known to NGS or the switch is not associated with the respective
526
542
physnet, the port will not be processed and no exception will
527
543
be raised.
528
544
529
545
:param port: The port to check
530
- :param network: the network mapped to physnet
546
+ :param segment: The segment to check against
531
547
:returns: Whether the link refers to a configured switch and/or switch
532
548
is associated with physnet
533
549
"""
@@ -550,9 +566,9 @@ def _is_link_valid(self, port, network):
550
566
'device' : switch_info })
551
567
return False
552
568
553
- physnet = network [ 'provider:physical_network' ]
569
+ physnet = segment . get ( api . PHYSICAL_NETWORK )
554
570
switch_physnets = switch ._get_physical_networks ()
555
- segmentation_id = network .get ('provider:segmentation_id' ) or 1
571
+ segmentation_id = segment .get (api . SEGMENTATION_ID ) or 1
556
572
557
573
if switch_physnets and physnet not in switch_physnets :
558
574
LOG .error ("Cannot bind port %(port)s as device %(device)s "
@@ -616,15 +632,15 @@ def _is_802_3ad(port):
616
632
return False
617
633
return local_group_information .get ('bond_mode' ) in ['4' , '802.3ad' ]
618
634
619
- def _unplug_port_from_network (self , port , network ):
620
- """Unplug a port from a network .
635
+ def _unplug_port_from_segment (self , port , segment ):
636
+ """Unplug a port from a segment .
621
637
622
638
If the configuration required to unplug the port is not present
623
639
(e.g. local link information), the port will not be unplugged and no
624
640
exception will be raised.
625
641
626
642
:param port: The port to unplug
627
- :param network : The network from which to unplug the port
643
+ :param segment : The segment from which to unplug the port
628
644
"""
629
645
binding_profile = port ['binding:profile' ]
630
646
local_link_information = binding_profile .get ('local_link_information' )
@@ -642,7 +658,7 @@ def _unplug_port_from_network(self, port, network):
642
658
continue
643
659
port_id = link .get ('port_id' )
644
660
# If segmentation ID is None, set vlan 1
645
- segmentation_id = network .get ('provider:segmentation_id' ) or 1
661
+ segmentation_id = segment .get (api . SEGMENTATION_ID ) or 1
646
662
LOG .debug ("Unplugging port %(port)s on %(switch_info)s from vlan: "
647
663
"%(segmentation_id)s" ,
648
664
{'port' : port_id , 'switch_info' : switch_info ,
@@ -656,12 +672,13 @@ def _unplug_port_from_network(self, port, network):
656
672
LOG .error ("Failed to unplug port %(port_id)s "
657
673
"on device: %(switch)s from network %(net_id)s "
658
674
"reason: %(exc)s" ,
659
- {'port_id' : port ['id' ], 'net_id' : network ['id' ],
675
+ {'port_id' : port ['id' ],
676
+ 'net_id' : segment ['network_id' ],
660
677
'switch' : switch_info , 'exc' : e })
661
678
raise e
662
679
LOG .info ('Port %(port_id)s has been unplugged from network '
663
680
'%(net_id)s on device %(device)s' ,
664
- {'port_id' : port ['id' ], 'net_id' : network [ 'id ' ],
681
+ {'port_id' : port ['id' ], 'net_id' : segment [ 'network_id ' ],
665
682
'device' : switch_info })
666
683
667
684
def _get_devices_by_physnet (self , physnet ):
0 commit comments