@@ -405,6 +405,15 @@ def set_bridge_alias_using_phy_nic_name(bridge_name, nic_name):
405405def get_bridge_phy_nic_name_from_alias (bridge_name ):
406406 return shell .call ("ip link show %s | awk '/alias/{ print $NF; exit }'" % bridge_name ).strip ()
407407
408+ def get_bridge_alias_related_slave (bridge_name ):
409+ phy_nic_alias = get_bridge_phy_nic_name_from_alias (bridge_name )
410+ slaves = shell .call ("bridge link show | grep 'master %s'"
411+ " | awk '{print $2}' | sed 's/://' | sed 's/@.*$//'" % bridge_name ).strip ().split ('\n ' )
412+ for slave in slaves :
413+ if slave .startswith (phy_nic_alias ):
414+ return slave
415+ return None
416+
408417def get_total_disk_size (dir_path ):
409418 stat = os .statvfs (dir_path )
410419 return stat .f_blocks * stat .f_frsize
@@ -1432,6 +1441,20 @@ def delete_bridge(bridge_name):
14321441 shell .run ("ip link set %s down" % bridge_name )
14331442 shell .run ("brctl delbr %s" % bridge_name )
14341443
1444+ def check_bridge_with_interface (vlan_interface , expected_bridge_name ):
1445+ bridge_name = find_bridge_having_physical_interface (vlan_interface )
1446+ if bridge_name and bridge_name != expected_bridge_name :
1447+ raise Exception ('failed to check vlan interface[%s], it has been occupied by bridge[%s]'
1448+ % (vlan_interface , bridge_name ))
1449+
1450+ def update_bridge_interface_configuration (old_interface , new_interface , bridge_name , l2_network_uuid ):
1451+ check_bridge_with_interface (old_interface , bridge_name )
1452+ ip_link_set_net_device_nomaster (old_interface )
1453+ ip_link_set_net_device_master (new_interface , bridge_name )
1454+ set_bridge_alias_using_phy_nic_name (bridge_name , new_interface )
1455+ set_device_uuid_alias (new_interface , l2_network_uuid )
1456+
1457+
14351458def find_bridge_having_physical_interface (ifname ):
14361459 if is_bridge_slave (ifname ):
14371460 br_name = shell .call ("cat /sys/class/net/%s/master/uevent | grep 'INTERFACE' | awk -F '=' '{printf $2}'" % ifname )
@@ -1476,6 +1499,14 @@ def ip_link_set_net_device_master(net_device, master):
14761499 if not actual_result or actual_result != master :
14771500 raise Exception ("set net device[%s] master to [%s] failed, try again now" % (net_device , master ))
14781501
1502+ @retry (times = 2 , sleep_time = 1 )
1503+ def ip_link_set_net_device_nomaster (net_device ):
1504+ shell .call ("ip link set %s nomaster" % net_device )
1505+ # Double check, because sometimes the master might not be removed successfully
1506+ actual_result = shell .call ("cat /sys/class/net/%s/master/uevent | grep 'INTERFACE'" % net_device , exception = False ).strip ('\n ' )
1507+ if actual_result :
1508+ raise Exception ("set net device[%s] nomaster failed, try again now" % net_device )
1509+
14791510def delete_novlan_bridge (bridge_name , interface , move_route = True ):
14801511 if not is_network_device_existing (bridge_name ):
14811512 logger .debug ("can not find bridge %s" % bridge_name )
@@ -1546,30 +1577,40 @@ def modify_device_state_in_networkmanager(device_name, state):
15461577 # MAC address.
15471578 shell .call ("ip link set %s address `cat /sys/class/net/%s/address`" % (bridge_name , interface ))
15481579
1549- if not move_route :
1550- return
1580+ if move_route :
1581+ move_dev_route (interface , bridge_name )
1582+
1583+
1584+ def move_dev_route (src_dev , dest_dev ):
1585+ """
1586+ Move IP address and routes from one network device (src_dev) to another (dest_dev).
15511587
1552- out = shell .call ('ip addr show dev %s | grep "inet "' % interface , exception = False )
1588+ Args:
1589+ - src_dev: The source device from which the IP and routes will be moved.
1590+ - dest_dev: The destination device to which the IP and routes will be moved.
1591+ """
1592+ # Check if the source device has an IP address set
1593+ out = shell .call ('ip addr show dev %s | grep "inet "' % src_dev , exception = False )
15531594 if not out :
1554- logger .debug ("Interface %s doesn't set ip address yet . No need to move route. " % interface )
1595+ logger .debug ("Source device %s doesn't have an IP address set . No need to move routes. " % src_dev )
15551596 return
15561597
1557- #record old routes
1598+ # Record old routes associated with the source device
15581599 routes = []
1559- r_out = shell .call ("ip route show dev %s | grep via | sed 's/onlink//g'" % interface )
1600+ r_out = shell .call ("ip route show dev %s | grep via | sed 's/onlink//g'" % src_dev )
15601601 for line in r_out .split ('\n ' ):
15611602 if line != "" :
15621603 routes .append (line )
15631604 shell .call ('ip route del %s' % line )
15641605
1565- #mv ip on interface to bridge
1606+ # Move IP address from the source device to the destination device
15661607 ip = out .strip ().split ()[1 ]
1567- shell .call ('ip addr del %s dev %s' % (ip , interface ))
1568- r_out = shell .call ('ip addr show dev %s | grep "inet %s"' % (bridge_name , ip ), exception = False )
1608+ shell .call ('ip addr del %s dev %s' % (ip , src_dev ))
1609+ r_out = shell .call ('ip addr show dev %s | grep "inet %s"' % (dest_dev , ip ), exception = False )
15691610 if not r_out :
1570- shell .call ('ip addr add %s dev %s' % (ip , bridge_name ))
1611+ shell .call ('ip addr add %s dev %s' % (ip , dest_dev ))
15711612
1572- #restore routes on bridge
1613+ # Restore routes on the destination device
15731614 for r in routes :
15741615 shell .call ('ip route add %s' % r )
15751616
@@ -2405,6 +2446,37 @@ def get_nics_by_cidr(cidr):
24052446
24062447 return nics
24072448
2449+ def get_vxlan_details (vxlan_interface ):
2450+ cmd = shell .ShellCmd ("ip -d link show dev {name}" .format (name = vxlan_interface ))
2451+ cmd (is_exception = False )
2452+ if cmd .return_code == 0 :
2453+ for line in cmd .stdout .split ("\n " ):
2454+ if "vxlan id" in line :
2455+ vtep_ip = line .split ("local " )[1 ].split (" " )[0 ]
2456+ dst_port = line .split ("dstport " )[1 ].split (" " )[0 ]
2457+ return vtep_ip , dst_port
2458+ return None , None
2459+
2460+
2461+ def change_vxlan_interface (old_vni , new_vni ):
2462+ old_vxlan = "vxlan" + str (old_vni )
2463+ vtep_ip , dst_port = get_vxlan_details (old_vxlan )
2464+ if not vtep_ip or not dst_port :
2465+ raise Exception ("Failed to get details for VXLAN interface: {}" .format (old_vxlan ))
2466+ new_vxlan = "vxlan" + str (new_vni )
2467+ create_vxlan_interface (new_vni , vtep_ip , dst_port )
2468+ cmd = shell .ShellCmd ("ip link set %s address `cat /sys/class/net/%s/address`" % (new_vxlan , old_vxlan ))
2469+ cmd (is_exception = False )
2470+ cmd = shell .ShellCmd ("ip link set {name} down" .format (name = old_vxlan ))
2471+ cmd (is_exception = False )
2472+ cmd = shell .ShellCmd ("ip link set {name} up" .format (name = new_vxlan ))
2473+ cmd (is_exception = False )
2474+ if cmd .return_code != 0 :
2475+ raise Exception ("Failed to set new VXLAN interface up: {}" .format (new_vxlan ))
2476+
2477+ logger .debug ("Successfully changed VXLAN interface from {old} to {new}." .format (old = old_vxlan , new = new_vxlan ))
2478+
2479+
24082480def create_vxlan_interface (vni , vtepIp ,dstport ):
24092481 vni = str (vni )
24102482 cmd = shell .ShellCmd ("ip -d -o link show dev {name} | grep -w {ip} " .format (** {"name" : "vxlan" + vni , "ip" : vtepIp }))
0 commit comments