@staticmethod
    @utils.synchronized('lock_bridge', external=True)
    def ensure_bridge(bridge, interface, net_attrs=None, gateway=True,
                      filtering=True):
        if not device_exists(bridge):
            LOG.debug('Starting Bridge %s', bridge)
            out, err = _execute('brctl', 'addbr', bridge,
                                check_exit_code=False, run_as_root=True)
            if (err and err != "device %s already exists; can't create "
                               "bridge with the same name\n" % (bridge)):
                msg = _('Failed to add bridge: %s') % err
                raise exception.NovaException(msg)

            _execute('brctl', 'setfd', bridge, 0, run_as_root=True)
            # _execute('brctl setageing %s 10' % bridge, run_as_root=True)
            _execute('brctl', 'stp', bridge, 'off', run_as_root=True)
            _execute('ip', 'link', 'set', bridge, 'up', run_as_root=True)

        if interface:
            LOG.debug('Adding interface %(interface)s to bridge %(bridge)s',
                      {'interface': interface, 'bridge': bridge})
            out, err = _execute('brctl', 'addif', bridge, interface,
                                check_exit_code=False, run_as_root=True)
            if (err and err != "device %s is already a member of a bridge; "
                     "can't enslave it to bridge %s.\n" % (interface, bridge)):
                msg = _('Failed to add interface: %s') % err
                raise exception.NovaException(msg)

            # NOTE(apmelton): Linux bridge's default behavior is to use the
            # lowest mac of all plugged interfaces. This isn't a problem when
            # it is first created and the only interface is the bridged
            # interface. But, as instance interfaces are plugged, there is a
            # chance for the mac to change. So, set it here so that it won't
            # change in the future.
            if not CONF.fake_network:
                interface_addrs = netifaces.ifaddresses(interface)
                interface_mac = interface_addrs[netifaces.AF_LINK][0]['addr']
                _execute('ip', 'link', 'set', bridge, 'address', interface_mac,
                         run_as_root=True)

            out, err = _execute('ip', 'link', 'set', interface, 'up',
                                check_exit_code=False, run_as_root=True)

            # NOTE(vish): This will break if there is already an ip on the
            #             interface, so we move any ips to the bridge
            # NOTE(danms): We also need to copy routes to the bridge so as
            #              not to break existing connectivity on the interface
            old_routes = []
            out, err = _execute('ip', 'route', 'show', 'dev', interface)
            for line in out.split('\n'):
                fields = line.split()
                if fields and 'via' in fields:
                    old_routes.append(fields)
                    _execute('ip', 'route', 'del', *fields,
                             run_as_root=True)
            out, err = _execute('ip', 'addr', 'show', 'dev', interface,
                                'scope', 'global')
            for line in out.split('\n'):
                fields = line.split()
                if fields and fields[0] == 'inet':
                    if fields[-2] in ('secondary', 'dynamic', ):
                        params = fields[1:-2]
                    else:
                        params = fields[1:-1]
                    _execute(*_ip_bridge_cmd('del', params, fields[-1]),
                             run_as_root=True, check_exit_code=[0, 2, 254])
                    _execute(*_ip_bridge_cmd('add', params, bridge),
                             run_as_root=True, check_exit_code=[0, 2, 254])
            for fields in old_routes:
                _execute('ip', 'route', 'add', *fields,
                         run_as_root=True)

        if filtering:
            # Don't forward traffic unless we were told to be a gateway
            ipv4_filter = iptables_manager.ipv4['filter']
            if gateway:
                for rule in get_gateway_rules(bridge):
                    ipv4_filter.add_rule(*rule)
            else:
                ipv4_filter.add_rule('FORWARD',
                                     ('--in-interface %s -j %s'
                                      % (bridge, CONF.iptables_drop_action)))
                ipv4_filter.add_rule('FORWARD',
                                     ('--out-interface %s -j %s'
                                      % (bridge, CONF.iptables_drop_action)))
Create a bridge unless it already exists.
dataset/ETHPy150Open openstack/nova/nova/network/linux_net.py/LinuxBridgeInterfaceDriver.ensure_bridge