diff --git a/neutron/agent/linux/bridge_lib.py b/neutron/agent/linux/bridge_lib.py index 625ae94..a9d5976 100644 --- a/neutron/agent/linux/bridge_lib.py +++ b/neutron/agent/linux/bridge_lib.py @@ -50,32 +50,6 @@ class BridgeDevice(ip_lib.IPDevice): ip_wrapper = ip_lib.IPWrapper(self.namespace) return ip_wrapper.netns.execute(cmd, run_as_root=True) - def _sysctl(self, cmd): - """execute() doesn't return the exit status of the command it runs, - it returns stdout and stderr. Setting check_exit_code=True will cause - it to raise a RuntimeError if the exit status of the command is - non-zero, which in sysctl's case is an error. So we're normalizing - that into zero (success) and one (failure) here to mimic what - "echo $?" in a shell would be. - - This is all because sysctl is too verbose and prints the value you - just set on success, unlike most other utilities that print nothing. - - execute() will have dumped a message to the logs with the actual - output on failure, so it's not lost, and we don't need to print it - here. - """ - cmd = ['sysctl', '-w'] + cmd - ip_wrapper = ip_lib.IPWrapper(self.namespace) - try: - ip_wrapper.netns.execute(cmd, run_as_root=True, - check_exit_code=True) - except RuntimeError: - LOG.exception(_LE("Failed running %s"), cmd) - return 1 - - return 0 - @classmethod def addbr(cls, name, namespace=None): bridge = cls(name, namespace) @@ -107,10 +81,6 @@ class BridgeDevice(ip_lib.IPDevice): def disable_stp(self): return self._brctl(['stp', self.name, 'off']) - def disable_ipv6(self): - cmd = 'net.ipv6.conf.%s.disable_ipv6=1' % self.name - return self._sysctl([cmd]) - def owns_interface(self, interface): return os.path.exists( BRIDGE_INTERFACE_FS % {'bridge': self.name, diff --git a/neutron/agent/linux/interface.py b/neutron/agent/linux/interface.py index 551074f..ea564ae 100644 --- a/neutron/agent/linux/interface.py +++ b/neutron/agent/linux/interface.py @@ -318,6 +318,7 @@ class OVSInterfaceDriver(LinuxInterfaceDriver): root_dev, ns_dev = ip.add_veth(tap_name, device_name, namespace2=namespace) + root_dev.disable_ipv6() else: ns_dev = ip.device(device_name) @@ -386,6 +387,7 @@ class IVSInterfaceDriver(LinuxInterfaceDriver): tap_name = self._get_tap_name(device_name, prefix) root_dev, ns_dev = ip.add_veth(tap_name, device_name) + root_dev.disable_ipv6() self._ivs_add_port(tap_name, port_id, mac_address) @@ -433,6 +435,7 @@ class BridgeInterfaceDriver(LinuxInterfaceDriver): # Create ns_veth in a namespace if one is configured. root_veth, ns_veth = ip.add_veth(tap_name, device_name, namespace2=namespace) + root_veth.disable_ipv6() ns_veth.link.set_address(mac_address) if self.conf.network_device_mtu: diff --git a/neutron/agent/linux/ip_lib.py b/neutron/agent/linux/ip_lib.py index 336c3f4..cf2a708 100644 --- a/neutron/agent/linux/ip_lib.py +++ b/neutron/agent/linux/ip_lib.py @@ -208,6 +208,12 @@ class IPWrapper(SubProcessBase): if self.namespace: device.link.set_netns(self.namespace) + def add_vlan(self, name, physical_interface, vlan_id): + cmd = ['add', 'link', physical_interface, 'name', name, + 'type', 'vlan', 'id', vlan_id] + self._as_root([], 'link', cmd) + return IPDevice(name, namespace=self.namespace) + def add_vxlan(self, name, vni, group=None, dev=None, ttl=None, tos=None, local=None, port=None, proxy=False): cmd = ['add', name, 'type', 'vxlan', 'id', vni] @@ -229,7 +235,7 @@ class IPWrapper(SubProcessBase): elif port: raise exceptions.NetworkVxlanPortRangeError(vxlan_range=port) self._as_root([], 'link', cmd) - return (IPDevice(name, namespace=self.namespace)) + return IPDevice(name, namespace=self.namespace) @classmethod def get_namespaces(cls): @@ -304,6 +310,36 @@ class IPDevice(SubProcessBase): LOG.exception(_LE("Failed deleting egress connection state of" " floatingip %s"), ip_str) + def _sysctl(self, cmd): + """execute() doesn't return the exit status of the command it runs, + it returns stdout and stderr. Setting check_exit_code=True will cause + it to raise a RuntimeError if the exit status of the command is + non-zero, which in sysctl's case is an error. So we're normalizing + that into zero (success) and one (failure) here to mimic what + "echo $?" in a shell would be. + + This is all because sysctl is too verbose and prints the value you + just set on success, unlike most other utilities that print nothing. + + execute() will have dumped a message to the logs with the actual + output on failure, so it's not lost, and we don't need to print it + here. + """ + cmd = ['sysctl', '-w'] + cmd + ip_wrapper = IPWrapper(self.namespace) + try: + ip_wrapper.netns.execute(cmd, run_as_root=True, + check_exit_code=True) + except RuntimeError: + LOG.exception(_LE("Failed running %s"), cmd) + return 1 + + return 0 + + def disable_ipv6(self): + sysctl_name = re.sub(r'\.', '/', self.name) + cmd = 'net.ipv6.conf.%s.disable_ipv6=1' % sysctl_name + return self._sysctl([cmd]) class IpCommandBase(object): COMMAND = '' diff --git a/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py b/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py index ee95c2e..45c2300 100644 --- a/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py +++ b/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py @@ -244,14 +244,10 @@ class LinuxBridgeManager(object): "%(physical_interface)s", {'interface': interface, 'vlan_id': vlan_id, 'physical_interface': physical_interface}) - if utils.execute(['ip', 'link', 'add', 'link', - physical_interface, - 'name', interface, 'type', 'vlan', 'id', - vlan_id], run_as_root=True): - return - if utils.execute(['ip', 'link', 'set', - interface, 'up'], run_as_root=True): - return + int_vlan = self.ip.add_vlan(interface, physical_interface, + vlan_id) + int_vlan.disable_ipv6() + int_vlan.link.set_up() LOG.debug("Done creating subinterface %s", interface) return interface @@ -285,6 +281,7 @@ class LinuxBridgeManager(object): "VNI %s because it is in use by another " "interface."), segmentation_id) return None + int_vxlan.disable_ipv6() int_vxlan.link.set_up() LOG.debug("Done creating vxlan interface %s", interface) return interface