import tempfile
import errno
import struct
+import re
import sioc
import modprobe
global version
version = 4.3
+def ovs_check(logger):
+ """ Return True if openvswitch is running, False otherwise. Try restarting
+ it once.
+ """
+ rc = os.system("service openvswitch status")
+ if rc == 0:
+ return True
+ logger.log("net: restarting openvswitch")
+ rc = os.system("service openvswitch restart")
+ rc = os.system("service openvswitch status")
+ if rc == 0:
+ return True
+ logger.log("net: failed to restart openvswitch")
+ return False
+
def InitInterfaces(logger, plc, data, root="", files_only=False, program="NodeManager"):
global version
interfaces.sort( compare_by('is_primary') )
interfaces.reverse()
+ # The names of the bridge devices
+ bridgeDevices = []
+
for interface in interfaces:
logger.verbose('net:InitInterfaces interface %d: %r'%(device_id,interface))
logger.verbose('net:InitInterfaces macs = %r' % macs)
details = prepDetails(interface, hostname)
+ if interface['is_primary']:
+ gateway = interface['gateway']
+
if 'interface_tag_ids' in interface:
version = 4.3
interface_tag_ids = "interface_tag_ids"
for setting in settings:
settingname = setting[name_key].upper()
- if settingname in ('IFNAME','ALIAS','CFGOPTIONS','DRIVER'):
+ if ((settingname in ('IFNAME','ALIAS','CFGOPTIONS','DRIVER','VLAN','TYPE','DEVICETYPE')) or \
+ (re.search('^IPADDR[0-9]+$|^NETMASK[0-9]+$', settingname))):
+ # TD: Added match for secondary IPv4 configuration.
details[settingname]=setting['value']
+ # IPv6 support on IPv4 interface
+ elif settingname in ('IPV6ADDR','IPV6_DEFAULTGW','IPV6ADDR_SECONDARIES', 'IPV6_AUTOCONF'):
+ # TD: Added IPV6_AUTOCONF.
+ details[settingname]=setting['value']
+ details['IPV6INIT']='yes'
# wireless settings
elif settingname in \
[ "MODE", "ESSID", "NW", "FREQ", "CHANNEL", "SENS", "RATE",
# Bridge setting
elif settingname in [ 'BRIDGE' ]:
details['BRIDGE'] = setting['value']
+ elif settingname in [ 'OVS_BRIDGE' ]:
+ # If openvswitch isn't running, then we'll lose network
+ # connectivity when we reconfigure eth0.
+ if ovs_check(logger):
+ details['OVS_BRIDGE'] = setting['value']
+ details['TYPE'] = "OVSPort"
+ details['DEVICETYPE'] = "ovs"
+ else:
+ logger.log("net:InitInterfaces ERROR: OVS_BRIDGE specified, yet ovs is not running")
else:
logger.log("net:InitInterfaces WARNING: ignored setting named %s"%setting[name_key])
else:
logger.log("net:InitInterfaces WARNING: interface alias (%s) not matched to an interface"% details['ALIAS'])
device_id -= 1
- elif 'BRIDGE' in details:
- #The bridge inherits the mac of the first attached interface.
- if 'IFNAME' in details:
- ifname = details['IFNAME']
- device_id -= 1
- elif orig_ifname:
- ifname = orig_ifname
- device_id -= 1
- logger.log('net:InitInterfaces: Bridge detected. Adding %s to devices_map' % ifname)
+ elif ('BRIDGE' in details or 'OVS_BRIDGE' in details) and 'IFNAME' in details:
+ # The bridge inherits the mac of the first attached interface.
+ ifname = details['IFNAME']
+ device_id -= 1
+ if 'BRIDGE' in details:
+ bridgeName = details['BRIDGE']
+ bridgeType = 'Bridge'
+ else:
+ bridgeName = details['OVS_BRIDGE']
+ bridgeType = 'OVSBridge'
+
+ logger.log('net:InitInterfaces: %s detected. Adding %s to devices_map' % (bridgeType, ifname))
devices_map[ifname] = removeBridgedIfaceDetails(details)
- bridgeName = details['BRIDGE']
- logger.log('net:InitInterfaces: Adding bridge %s' % bridgeName)
+ logger.log('net:InitInterfaces: Adding %s %s' % (bridgeType, bridgeName))
bridgeDetails = prepDetails(interface)
- bridgeDetails['TYPE'] = 'Bridge'
+
+ # TD: Add configuration for secondary IPv4 and IPv6 addresses to the bridge.
+ if len(interface[interface_tag_ids]) > 0:
+ try:
+ if version == 4.3:
+ settings = plc.GetInterfaceTags({interface_tag_id:interface[interface_tag_ids]})
+ else:
+ settings = plc.GetNodeNetworkSettings({interface_tag_id:interface[interface_tag_ids]})
+ except:
+ logger.log("net:InitInterfaces FATAL: failed call GetInterfaceTags({'interface_tag_id':{%s})"% \
+ interface[interface_tag_ids])
+ failedToGetSettings = True
+ continue # on to the next interface
+
+ for setting in settings:
+ settingname = setting[name_key].upper()
+ if (re.search('^IPADDR[0-9]+$|^NETMASK[0-9]+$', settingname)):
+ # TD: Added match for secondary IPv4 configuration.
+ bridgeDetails[settingname]=setting['value']
+ # IPv6 support on IPv4 interface
+ elif settingname in ('IPV6ADDR','IPV6_DEFAULTGW','IPV6ADDR_SECONDARIES', 'IPV6_AUTOCONF'):
+ # TD: Added IPV6_AUTOCONF.
+ bridgeDetails[settingname]=setting['value']
+ bridgeDetails['IPV6INIT']='yes'
+
+ bridgeDevices.append(bridgeName)
+ bridgeDetails['TYPE'] = bridgeType
+ if bridgeType == 'OVSBridge':
+ bridgeDetails['DEVICETYPE'] = 'ovs'
+ if bridgeDetails['BOOTPROTO'] == 'dhcp':
+ del bridgeDetails['BOOTPROTO']
+ bridgeDetails['OVSBOOTPROTO'] = 'dhcp'
+ bridgeDetails['OVSDHCPINTERFACES'] = ifname
devices_map[bridgeName] = bridgeDetails
else:
if 'IFNAME' in details:
# handle those correctly
if getvar("SLAVE") == 'yes': continue
+ # Delay bringing up any bridge devices
+ if dev in bridgeDevices: continue
+
if not files_only:
logger.verbose('net:InitInterfaces bringing up %s' % dev)
os.system("/sbin/ifup %s" % dev)
+ # Bring up the bridge devices
+ for bridge in bridgeDevices:
+ if not files_only and bridge in newdevs:
+ logger.verbose('net:InitInterfaces bringing up bridge %s' % bridge)
+ os.system("/sbin/ifup %s" % bridge)
+
##
# Prepare the interface details.
#
details = {}
details['ONBOOT'] = 'yes'
details['USERCTL'] = 'no'
+ # attempt to work around issues seen starting with f23
+ details['NM_CONTROLLED'] = 'no'
if interface['mac']:
details['HWADDR'] = interface['mac']
if interface['is_primary']:
details['NETMASK'] = interface['netmask']
details['GATEWAY'] = interface['gateway']
if interface['is_primary']:
- gateway = interface['gateway']
if interface['dns1']:
details['DNS1'] = interface['dns1']
if interface['dns2']:
# Remove duplicate entry from the bridged interface's configuration file.
#
def removeBridgedIfaceDetails(details):
- for key in [ 'PRIMARY', 'PERSISTENT_DHCLIENT', 'DHCLIENTARGS', 'DHCP_HOSTNAME',
- 'BOOTPROTO', 'IPADDR', 'NETMASK', 'GATEWAY', 'DNS1', 'DNS2' ]:
+ # TD: Also added secondary IPv4 keys and IPv6 keys to the keys to be removed.
+ allKeys = [ 'PRIMARY', 'PERSISTENT_DHCLIENT', 'DHCLIENTARGS', 'DHCP_HOSTNAME',
+ 'BOOTPROTO', 'IPADDR', 'NETMASK', 'GATEWAY', 'DNS1', 'DNS2',
+ 'IPV6ADDR', 'IPV6_DEFAULTGW', 'IPV6ADDR_SECONDARIES',
+ 'IPV6_AUTOCONF', 'IPV6INIT' ]
+ for i in range(1, 256):
+ allKeys.append('IPADDR' + str(i))
+ allKeys.append('NETMASK' + str(i))
+
+ for key in allKeys:
if key in details:
del details[key]
+
+ # TD: Also turn off IPv6
+ details['IPV6INIT'] = 'no'
+ details['IPV6_AUTOCONF'] = 'no'
+
return details
if __name__ == "__main__":
parser.add_option("-p", "--program", action="store", type="string",
dest="program", default="plnet")
(options, args) = parser.parse_args()
- options.root = ''
- options.verbose = True
if len(args) != 1 or options.root is None:
print sys.argv
print >>sys.stderr, "Missing root or node_id"