#!/usr/bin/python /usr/bin/plcsh
-# $Id$
import os
import socket
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:
+ logger.log("net: restarting openvswitch")
+ rc = os.system("service openvswitch restart")
+ rc = os.system("service openvswitch status")
+ if rc!=0:
+ logger.log("net: failed to restart openvswitch")
+ return False
+ return True
+
def InitInterfaces(logger, plc, data, root="", files_only=False, program="NodeManager"):
global version
failedToGetSettings = False
# NOTE: GetInterfaces/NodeNetworks does not necessarily order the interfaces
- # returned. Because 'interface'is decremented as each interface is processed,
+ # returned. Because 'interface' is decremented as each interface is processed,
# by the time is_primary=True (primary) interface is reached, the device
# "eth%s" % interface, is not eth0. But, something like eth-4, or eth-12.
# This code sorts the interfaces, placing is_primary=True interfaces first.
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)
if orig_ifname:
logger.verbose('net:InitInterfaces orig_ifname = %s' % orig_ifname)
- details = {}
- details['ONBOOT']='yes'
- details['USERCTL']='no'
- if interface['mac']:
- details['HWADDR'] = interface['mac']
+ details = prepDetails(interface, hostname)
+
if interface['is_primary']:
- details['PRIMARY']='yes'
-
- if interface['method'] == "static":
- details['BOOTPROTO'] = "static"
- details['IPADDR'] = interface['ip']
- 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']:
- details['DNS2'] = interface['dns2']
-
- elif interface['method'] == "dhcp":
- details['BOOTPROTO'] = "dhcp"
- details['PERSISTENT_DHCLIENT'] = "yes"
- if interface['hostname']:
- details['DHCP_HOSTNAME'] = interface['hostname']
- else:
- details['DHCP_HOSTNAME'] = hostname
- if not interface['is_primary']:
- details['DHCLIENTARGS'] = "-R subnet-mask"
+ gateway = interface['gateway']
if 'interface_tag_ids' in interface:
version = 4.3
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'):
+ details[settingname]=setting['value']
+ # IPv6 support on IPv4 interface
+ elif settingname in ('IPV6ADDR','IPV6_DEFAULTGW','IPV6ADDR_SECONDARIES'):
details[settingname]=setting['value']
+ details['IPV6INIT']='yes'
# wireless settings
elif settingname in \
[ "MODE", "ESSID", "NW", "FREQ", "CHANNEL", "SENS", "RATE",
"IWCONFIG", "IWPRIV" ] :
details [settingname] = setting['value']
details ['TYPE']='Wireless'
+ # 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 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)
+
+ logger.log('net:InitInterfaces: Adding %s %s' % (bridgeType, bridgeName))
+ bridgeDetails = prepDetails(interface)
+ 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:
ifname = details['IFNAME']
logger.log("net:InitInterfaces WARNING: possibly blowing away %s configuration"%ifname)
devices_map[ifname] = details
device_id += 1
+ logger.log('net:InitInterfaces: Device map: %r' % devices_map)
m = modprobe.Modprobe()
try:
m.input("%s/etc/modprobe.conf" % root)
lo = "ifcfg-lo"
if lo in ifcfgs: ifcfgs.remove(lo)
- # remove known devices from icfgs list
+ # remove known devices from ifcfgs list
for (dev, details) in devices_map.iteritems():
ifcfg = 'ifcfg-'+dev
if ifcfg in ifcfgs: ifcfgs.remove(ifcfg)
# Process ifcfg-$dev changes / additions
newdevs = []
+ table = 10
for (dev, details) in devices_map.iteritems():
(fd, tmpnam) = tempfile.mkstemp(dir=sysconfig)
f = os.fdopen(fd, "w")
# print the configuration values
for (key, val) in details.iteritems():
if key not in ('IFNAME','ALIAS','CFGOPTIONS','DRIVER','GATEWAY'):
- f.write('%s=%s\n' % (key, val))
+ f.write('%s="%s"\n' % (key, val))
# print the configuration specific option values (if any)
if 'CFGOPTIONS' in details:
src_route_changed = False
if ('PRIMARY' not in details and 'GATEWAY' in details and
details['GATEWAY'] != ''):
- i = len(dev) - 1
- while dev[i - 1].isdigit():
- i -= 1
- table = 10 + int(dev[i:])
+ table += 1
(fd, rule_tmpnam) = tempfile.mkstemp(dir=sysconfig)
os.write(fd, "from %s lookup %d\n" % (details['IPADDR'], table))
os.close(fd)
# 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.
+#
+def prepDetails(interface, hostname=''):
+ details = {}
+ details['ONBOOT'] = 'yes'
+ details['USERCTL'] = 'no'
+ if interface['mac']:
+ details['HWADDR'] = interface['mac']
+ if interface['is_primary']:
+ details['PRIMARY'] = 'yes'
+
+ if interface['method'] == "static":
+ details['BOOTPROTO'] = "static"
+ details['IPADDR'] = interface['ip']
+ details['NETMASK'] = interface['netmask']
+ details['GATEWAY'] = interface['gateway']
+ if interface['is_primary']:
+ if interface['dns1']:
+ details['DNS1'] = interface['dns1']
+ if interface['dns2']:
+ details['DNS2'] = interface['dns2']
+
+ elif interface['method'] == "dhcp":
+ details['BOOTPROTO'] = "dhcp"
+ details['PERSISTENT_DHCLIENT'] = "yes"
+ if interface['hostname']:
+ details['DHCP_HOSTNAME'] = interface['hostname']
+ else:
+ details['DHCP_HOSTNAME'] = hostname
+ if not interface['is_primary']:
+ details['DHCLIENTARGS'] = "-R subnet-mask"
+
+ return details
+
+##
+# 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' ]:
+ if key in details:
+ del details[key]
+ return details
+
if __name__ == "__main__":
import optparse
import sys