@@ -19,6 +19,8 @@ import (
19
19
"errors"
20
20
"fmt"
21
21
"net"
22
+ "reflect"
23
+ "sort"
22
24
"strings"
23
25
"time"
24
26
@@ -572,6 +574,55 @@ func (sw *OvsSwitch) DeleteVtep(vtepIP string) error {
572
574
return sw .ovsdbDriver .DeleteVtep (intfName )
573
575
}
574
576
577
+ func (sw * OvsSwitch ) cleanupOldUplinkState (portName string , intfList []string ) (bool , error ) {
578
+ var err error
579
+ var oldUplinkIntf []string
580
+ portCreateReq := true
581
+
582
+ // Check if uplink is already created
583
+ // Case 1: Bonded ports - port name is the uplinkName
584
+ // Case 2: Indiviual port - port name is the interface name
585
+ portPresent := sw .ovsdbDriver .IsPortNamePresent (portName )
586
+ if portPresent {
587
+ /* If port already exists, make sure it has the same member links
588
+ If not, a cleanup is required */
589
+ sort .Strings (intfList )
590
+ oldUplinkIntf = sw .ovsdbDriver .GetInterfacesInPort (portName )
591
+ if reflect .DeepEqual (intfList , oldUplinkIntf ) {
592
+ log .Warnf ("Uplink already part of %s" , sw .bridgeName )
593
+ portCreateReq = false
594
+ } else {
595
+ log .Warnf ("Deleting old uplink bond with intfs: %+v" , oldUplinkIntf )
596
+ err = sw .ovsdbDriver .DeletePortBond (portName , oldUplinkIntf )
597
+ if err == nil {
598
+ portCreateReq = true
599
+ }
600
+ }
601
+ return portCreateReq , err
602
+ }
603
+
604
+ if len (intfList ) == 1 && sw .ovsdbDriver .IsPortNamePresent (intfList [0 ]) {
605
+ // Uplink port already part of switch. No change required.
606
+ log .Debugf ("Uplink intf %s already part of %s" , intfList [0 ], sw .bridgeName )
607
+ return false , nil
608
+ }
609
+
610
+ /* Cleanup any other individual ports that may exist */
611
+ for _ , intf := range intfList {
612
+ if sw .ovsdbDriver .IsIntfNamePresent (intf ) {
613
+ log .Infof ("Deleting old uplink port: %+v" , intf )
614
+ err = sw .ovsdbDriver .DeletePort (intf )
615
+ if err != nil {
616
+ break
617
+ }
618
+ portCreateReq = true
619
+ }
620
+ }
621
+
622
+ // No cleanup done and new port creation required
623
+ return portCreateReq , err
624
+ }
625
+
575
626
// AddUplink adds uplink port(s) to the OVS
576
627
func (sw * OvsSwitch ) AddUplink (uplinkName string , intfList []string ) error {
577
628
var err error
@@ -583,16 +634,23 @@ func (sw *OvsSwitch) AddUplink(uplinkName string, intfList []string) error {
583
634
log .Fatalf ("Can not add uplink to OVS type %s." , sw .netType )
584
635
}
585
636
586
- // Check if port is already part of the OVS and add it
587
- if ! sw .ovsdbDriver .IsPortNamePresent (uplinkName ) {
637
+ createUplink , err := sw .cleanupOldUplinkState (uplinkName , intfList )
638
+ if err != nil {
639
+ log .Errorf ("Could not cleanup previous uplink state" )
640
+ return err
641
+ }
642
+
643
+ if createUplink {
588
644
if len (intfList ) > 1 {
645
+ log .Debugf ("Creating uplink port bond: %s with intf: %+v" , uplinkName , intfList )
589
646
err = sw .ovsdbDriver .CreatePortBond (intfList , uplinkName )
590
647
if err != nil {
591
648
log .Errorf ("Error adding uplink %s to OVS. Err: %v" , intfList , err )
592
649
return err
593
650
}
594
651
uplinkType = ofnet .BondType
595
652
} else {
653
+ log .Debugf ("Creating uplink port: %s" , intfList [0 ])
596
654
// Ask OVSDB driver to add the port as a trunk port
597
655
err = sw .ovsdbDriver .CreatePort (intfList [0 ], "" , uplinkName , 0 , 0 , 0 )
598
656
if err != nil {
@@ -601,14 +659,14 @@ func (sw *OvsSwitch) AddUplink(uplinkName string, intfList []string) error {
601
659
}
602
660
uplinkType = ofnet .PortType
603
661
}
604
- }
605
662
606
- // HACK: When an uplink is added to OVS, it disconnects the controller connection.
607
- // This is a hack to workaround this issue. We wait for the OVS to reconnect
608
- // to the controller.
609
- // Wait for a while for OVS switch to disconnect/connect to ofnet agent
610
- time .Sleep (time .Second )
611
- sw .ofnetAgent .WaitForSwitchConnection ()
663
+ // HACK: When an uplink is added to OVS, it disconnects the controller connection.
664
+ // This is a hack to workaround this issue. We wait for the OVS to reconnect
665
+ // to the controller.
666
+ // Wait for a while for OVS switch to disconnect/connect to ofnet agent
667
+ time .Sleep (time .Second )
668
+ sw .ofnetAgent .WaitForSwitchConnection ()
669
+ }
612
670
613
671
uplinkInfo := ofnet.PortInfo {
614
672
Name : uplinkName ,
@@ -686,16 +744,31 @@ func (sw *OvsSwitch) HandleLinkUpdates(linkUpd ofnet.LinkUpdateInfo) {
686
744
func (sw * OvsSwitch ) RemoveUplinks () error {
687
745
688
746
var err error
747
+
689
748
// some error checking
690
749
if sw .netType != "vlan" {
691
750
log .Fatalf ("Can not remove uplink from OVS type %s." , sw .netType )
692
751
}
752
+
693
753
for intfListObj := range sw .uplinkDb .IterBuffered () {
694
754
intfList := intfListObj .Val .([]string )
695
755
portName := intfListObj .Key
696
- if ! sw .ovsdbDriver .IsPortNamePresent (portName ) {
756
+
757
+ // Remove uplink from agent
758
+ err = sw .ofnetAgent .RemoveUplink (portName )
759
+ if err != nil {
760
+ log .Errorf ("Error removing uplink %s. Err: %v" , portName , err )
761
+ return err
762
+ }
763
+ log .Infof ("Removed uplink %s from ofnet" , portName )
764
+
765
+ isPortPresent := sw .ovsdbDriver .IsPortNamePresent (portName )
766
+ if len (intfList ) == 1 {
767
+ isPortPresent = sw .ovsdbDriver .IsPortNamePresent (intfList [0 ])
768
+ }
769
+ if isPortPresent {
697
770
if len (intfList ) == 1 {
698
- err = sw .ovsdbDriver .DeletePort (portName )
771
+ err = sw .ovsdbDriver .DeletePort (intfList [ 0 ] )
699
772
} else {
700
773
err = sw .ovsdbDriver .DeletePortBond (portName , intfList )
701
774
}
@@ -705,17 +778,11 @@ func (sw *OvsSwitch) RemoveUplinks() error {
705
778
}
706
779
}
707
780
time .Sleep (time .Second )
708
-
709
- // Remove uplink from agent
710
- err = sw .ofnetAgent .RemoveUplink (portName )
711
- if err != nil {
712
- log .Errorf ("Error removing uplink %s. Err: %v" , portName , err )
713
- return err
714
- }
715
781
sw .uplinkDb .Remove (portName )
716
782
717
- log .Infof ("Removed uplink %s from OVS switch %s." , portName , sw .bridgeName )
783
+ log .Infof ("Removed uplink %s(%+v) from OVS switch %s." , portName , intfList , sw .bridgeName )
718
784
}
785
+
719
786
return nil
720
787
}
721
788
0 commit comments