Skip to content

Commit

Permalink
Option2: First set IP address, sleep for a while, and check
Browse files Browse the repository at this point in the history
if interface is activated thro nmcli. Retry for few times,
until it succeeds or times out.
  • Loading branch information
sudhar-krishnakumar committed Oct 25, 2024
1 parent 4073e16 commit 57ef4c8
Showing 1 changed file with 80 additions and 24 deletions.
104 changes: 80 additions & 24 deletions ipu-plugin/pkg/ipuplugin/lifecycleservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"net"
"os"
"strings"
"time"

"github.com/intel/ipu-opi-plugins/ipu-plugin/pkg/p4rtclient"
"github.com/intel/ipu-opi-plugins/ipu-plugin/pkg/types"
Expand Down Expand Up @@ -99,7 +100,7 @@ func (fs *FileSystemHandlerImpl) GetVendor(iface string) ([]byte, error) {

type ExecutableHandler interface {
validate() bool
nmcliSetup(link netlink.Link) error
nmcliSetupIpAddress(link netlink.Link, ipStr string, ipAddr *netlink.Addr) error
}

type ExecutableHandlerImpl struct{}
Expand Down Expand Up @@ -196,28 +197,87 @@ func getCommPf(mode string, linkList []netlink.Link) (netlink.Link, error) {
/*
It can take time for network-manager's state for each interface, to become
activated, when IP address is set, which can cause the IP address to not stick.
Removing the host-acc comm channel interface out of network-manager's mgmt.
TODO: Currently we only support nmcli/NetworkManager daemon combination(RHEL),
this api can be extended for other distros that use different CLI/systemd-networkd.
Note: Below approach...does not work...bcos if there was no conn info
in NM database...then it wont get activated...on the contrary...when IP addr add..
is run..for a managed interface...NM..adds it to its database...shows up in nmcli.
So Step1-> trying to check for activated..does not work..if conn info does not pre-exist.
It seems...first Doing ip addr add..will trigger NM to add info to its DB..
and then make it activated.
*/
func (e *ExecutableHandlerImpl) nmcliSetup(link netlink.Link) error {
func (e *ExecutableHandlerImpl) nmcliSetupIpAddress(link netlink.Link, ipStr string, ipAddr *netlink.Addr) error {
var runCmd string
var err error
var output string
maxRetries := 8
retryInterval := 10 * time.Second
intfActivated := false
ipAddrSet := false
intfName := link.Attrs().Name
output, err := utils.ExecuteScript(`nmcli general status`)
if err == nil {
output, err = utils.ExecuteScript(`nmcli device set ` + intfName + ` managed no`)
if err != nil {
log.Errorf("nmcli err->%v, output->%v\n", err, output)
return fmt.Errorf("nmcli err->%v, output->%v\n", err, output)
ipWithMask := ipStr + "/24"

for cnt := 0; cnt < maxRetries; cnt++ {
if err = networkHandler.AddrAdd(link, ipAddr); err != nil {
//Note::Can error if address already set, ignoring for now.
log.Errorf("AddrAdd err ->%v, for ip->%v\n", err, ipAddr)
}
} else {
log.Infof("network manager not running, skipping nmcli, err->%v\n", err)
addrList, err := networkHandler.AddrList(link, netlink.FAMILY_V4)
if err == nil {
ipAddrList := fmt.Sprintf("AddrList->%v\n", addrList)
if strings.Contains(ipAddrList, ipStr) {
log.Infof("AddrList->%v, contains expected IP->%v\n", ipAddrList, ipStr)
ipAddrSet = true
goto sleep
}
log.Errorf("AddrList->%v, does not contain expected IP->%v\n", ipAddrList, ipStr)
} else {
log.Errorf("AddrList err ->%v\n", err)
}
sleep:
if ipAddrSet && intfActivated {
break
}
if intfActivated != true {
time.Sleep(retryInterval)
output, err = utils.ExecuteScript(`nmcli general status`)
if err == nil {
runCmd = fmt.Sprintf(`nmcli -g GENERAL.STATE con show "%s" | grep activated`, intfName)
output, err = utils.ExecuteScript(runCmd)
output = strings.TrimSuffix(output, "\n")
if (output != "activated") || (err != nil) {
log.Errorf("nmcli err ->%v, output->%v, for cmd->%v\n", err, output, runCmd)
// no such connection profile
if strings.Contains(err.Error(), "no such connection profile") {
runCmd = fmt.Sprintf(`nmcli connection add type ethernet ifname "%s" con-name "%s" \
ip4 "%s"`, intfName, intfName, ipWithMask)
_, err = utils.ExecuteScript(runCmd)
if err != nil {
log.Errorf("nmcli err->%v, for cmd->%v\n", err, runCmd)
goto retry
} else {
log.Infof("nmcli cmd->%v, passed\n", runCmd)
}
}
goto retry
} else {
log.Infof("nmcli interface->%v activated\n", intfName)
intfActivated = true
}
} else {
log.Infof("network manager not running, err->%v, output-%v\n", err, output)
goto retry
}
}
retry:
log.Infof("nmcliSetIPAddress: Retry attempt cnt->%v:\n", cnt)
}
output, err = utils.ExecuteScript(`ip link set ` + intfName + ` up`)
if err != nil {
log.Errorf("ip link set err->%v, output->%v\n", err, output)
return fmt.Errorf("ip link set err->%v, output->%v\n", err, output)
if ipAddrSet && intfActivated {
log.Infof("nmcliSetIPAddress: successful->%v, for interface->%v\n", ipStr, intfName)
return nil
}
return nil
log.Errorf("nmcliSetIP: error->%v, setting IP for->%v, ipAddrSet->%v, intfActivated->%v\n", err, intfName, ipAddrSet, intfActivated)
return fmt.Errorf("nmcliSetIP: error->%v, setting IP for->%v, ipAddrSet->%v, intfActivated->%v\n", err, intfName, ipAddrSet, intfActivated)
}

func setIP(link netlink.Link, ip string) error {
Expand All @@ -230,11 +290,6 @@ func setIP(link netlink.Link, ip string) error {

if len(list) == 0 {

if err = executableHandler.nmcliSetup(link); err != nil {
log.Errorf("setIP: err->%v from nmcliSetup\n", err)
return fmt.Errorf("setIP: err->%v from nmcliSetup", err)
}

ipAddr := net.ParseIP(ip)

if ipAddr.To4() == nil {
Expand All @@ -245,10 +300,11 @@ func setIP(link netlink.Link, ip string) error {
// Set the IP address on PF
addr := &netlink.Addr{IPNet: &net.IPNet{IP: ipAddr, Mask: net.CIDRMask(24, 32)}}

if err = networkHandler.AddrAdd(link, addr); err != nil {
log.Errorf("setIP: unable to add address: %v\n", err)
return fmt.Errorf("unable to add address: %v", err)
if err = executableHandler.nmcliSetupIpAddress(link, ip, addr); err != nil {
log.Errorf("setIP: err->%v from nmcliSetup\n", err)
return fmt.Errorf("setIP: err->%v from nmcliSetup", err)
}

} else {
log.Errorf("address already set. Unset ip address for interface %s and run again\n", link.Attrs().Name)
return fmt.Errorf("address already set. Unset ip address for interface %s and run again", link.Attrs().Name)
Expand Down

0 comments on commit 57ef4c8

Please sign in to comment.