Files
devstack/lib/neutron_plugins/services/l3
Sean Dague 6a008fa74b Change to neutron by default.
nova-net is deprecated, and it's long time to switch to neutron by
default. This patch does that, and has an auto configuration mode that
mostly just works for the basic case.

It does this by assuming that unless the user specifies an interface
for it to manage, that it will not automatically have access to a
physical interface. The floating range is put on br-ex (per normal),
fixed ranges stay on their OVS interfaces.

Because there is no dedicated interface managed by neutron, we add an
iptables rule which allows guests to route out. While somewhat
synthetic, it does provide a working out of the box developer
experience, and is not hugely more synthetic then all the other
interface / route setup we have to do for the system.

You should be able to run this with a local.conf of just

[[local|localrc]]
ADMIN_PASSWORD=pass
DATABASE_PASSWORD=pass
RABBIT_PASSWORD=pass
SERVICE_PASSWORD=pass

And get a working neutron on a single interface box

Documentation will come in subsequent patches, however getting the
code out there and getting feedback is going to help shape this
direction.

Change-Id: I185325a684372e8a2ff25eae974a9a2a2d6277e0
2016-08-04 14:13:30 -04:00

382 lines
19 KiB
Bash

#!/bin/bash
# Subnet IP version
IP_VERSION=${IP_VERSION:-"4+6"}
# Validate IP_VERSION
if [[ $IP_VERSION != "4" ]] && [[ $IP_VERSION != "6" ]] && [[ $IP_VERSION != "4+6" ]]; then
die $LINENO "IP_VERSION must be either 4, 6, or 4+6"
fi
# Specify if the initial private and external networks should be created
NEUTRON_CREATE_INITIAL_NETWORKS=${NEUTRON_CREATE_INITIAL_NETWORKS:-True}
## Provider Network Information
PROVIDER_SUBNET_NAME=${PROVIDER_SUBNET_NAME:-"provider_net"}
IPV6_PROVIDER_SUBNET_NAME=${IPV6_PROVIDER_SUBNET_NAME:-"provider_net_v6"}
IPV6_PROVIDER_FIXED_RANGE=${IPV6_PROVIDER_FIXED_RANGE:-}
IPV6_PROVIDER_NETWORK_GATEWAY=${IPV6_PROVIDER_NETWORK_GATEWAY:-}
PUBLIC_BRIDGE=${PUBLIC_BRIDGE:-br-ex}
PUBLIC_BRIDGE_MTU=${PUBLIC_BRIDGE_MTU:-1500}
# If Q_USE_PUBLIC_VETH=True, create and use a veth pair instead of
# PUBLIC_BRIDGE. This is intended to be used with
# Q_USE_PROVIDERNET_FOR_PUBLIC=True.
Q_USE_PUBLIC_VETH=${Q_USE_PUBLIC_VETH:-False}
Q_PUBLIC_VETH_EX=${Q_PUBLIC_VETH_EX:-veth-pub-ex}
Q_PUBLIC_VETH_INT=${Q_PUBLIC_VETH_INT:-veth-pub-int}
# The next variable is configured by plugin
# e.g. _configure_neutron_l3_agent or lib/neutron_plugins/*
#
# L3 routers exist per tenant
Q_L3_ROUTER_PER_TENANT=${Q_L3_ROUTER_PER_TENANT:-True}
# Use flat providernet for public network
#
# If Q_USE_PROVIDERNET_FOR_PUBLIC=True, use a flat provider network
# for external interface of neutron l3-agent. In that case,
# PUBLIC_PHYSICAL_NETWORK specifies provider:physical_network value
# used for the network. In case of ofagent, you should add the
# corresponding entry to your OFAGENT_PHYSICAL_INTERFACE_MAPPINGS.
# For openvswitch agent, you should add the corresponding entry to
# your OVS_BRIDGE_MAPPINGS.
#
# eg. (ofagent)
# Q_USE_PROVIDERNET_FOR_PUBLIC=True
# Q_USE_PUBLIC_VETH=True
# PUBLIC_PHYSICAL_NETWORK=public
# OFAGENT_PHYSICAL_INTERFACE_MAPPINGS=public:veth-pub-int
#
# eg. (openvswitch agent)
# Q_USE_PROVIDERNET_FOR_PUBLIC=True
# PUBLIC_PHYSICAL_NETWORK=public
# OVS_BRIDGE_MAPPINGS=public:br-ex
Q_USE_PROVIDERNET_FOR_PUBLIC=${Q_USE_PROVIDERNET_FOR_PUBLIC:-False}
PUBLIC_PHYSICAL_NETWORK=${PUBLIC_PHYSICAL_NETWORK:-public}
# Generate 40-bit IPv6 Global ID to comply with RFC 4193
IPV6_GLOBAL_ID=`uuidgen | sed s/-//g | cut -c 23- | sed -e "s/\(..\)\(....\)\(....\)/\1:\2:\3/"`
# IPv6 gateway and subnet defaults, in case they are not customized in localrc
IPV6_RA_MODE=${IPV6_RA_MODE:-slaac}
IPV6_ADDRESS_MODE=${IPV6_ADDRESS_MODE:-slaac}
IPV6_PUBLIC_SUBNET_NAME=${IPV6_PUBLIC_SUBNET_NAME:-ipv6-public-subnet}
IPV6_PRIVATE_SUBNET_NAME=${IPV6_PRIVATE_SUBNET_NAME:-ipv6-private-subnet}
FIXED_RANGE_V6=${FIXED_RANGE_V6:-fd$IPV6_GLOBAL_ID::/64}
IPV6_PRIVATE_NETWORK_GATEWAY=${IPV6_PRIVATE_NETWORK_GATEWAY:-fd$IPV6_GLOBAL_ID::1}
IPV6_PUBLIC_RANGE=${IPV6_PUBLIC_RANGE:-2001:db8::/64}
IPV6_PUBLIC_NETWORK_GATEWAY=${IPV6_PUBLIC_NETWORK_GATEWAY:-2001:db8::2}
IPV6_ROUTER_GW_IP=${IPV6_ROUTER_GW_IP:-2001:db8::1}
# Gateway and subnet defaults, in case they are not customized in localrc
NETWORK_GATEWAY=${NETWORK_GATEWAY:-10.0.0.1}
PUBLIC_NETWORK_GATEWAY=${PUBLIC_NETWORK_GATEWAY:-172.24.4.1}
PRIVATE_SUBNET_NAME=${PRIVATE_SUBNET_NAME:-"private-subnet"}
PUBLIC_SUBNET_NAME=${PUBLIC_SUBNET_NAME:-"public-subnet"}
# Subnetpool defaults
SUBNETPOOL_NAME=${SUBNETPOOL_NAME:-"shared-default-subnetpool"}
SUBNETPOOL_PREFIX_V4=${SUBNETPOOL_PREFIX_V4:-10.0.0.0/8}
SUBNETPOOL_PREFIX_V6=${SUBNETPOOL_PREFIX_V6:-2001:db8:8000::/48}
SUBNETPOOL_SIZE_V4=${SUBNETPOOL_SIZE_V4:-24}
SUBNETPOOL_SIZE_V6=${SUBNETPOOL_SIZE_V6:-64}
function _determine_config_l3 {
local opts="--config-file $NEUTRON_CONF --config-file $Q_L3_CONF_FILE"
echo "$opts"
}
function _configure_neutron_l3_agent {
cp $NEUTRON_DIR/etc/l3_agent.ini.sample $Q_L3_CONF_FILE
iniset $Q_L3_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
iniset $Q_L3_CONF_FILE AGENT root_helper "$Q_RR_COMMAND"
if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then
iniset $Q_L3_CONF_FILE AGENT root_helper_daemon "$Q_RR_DAEMON_COMMAND"
fi
_neutron_setup_interface_driver $Q_L3_CONF_FILE
neutron_plugin_configure_l3_agent $Q_L3_CONF_FILE
# If we've given a PUBLIC_INTERFACE to take over, then we assume
# that we can own the whole thing, and privot it into the OVS
# bridge. If we are not, we're probably on a single interface
# machine, and we just setup NAT so that fixed guests can get out.
if [[ -n "$PUBLIC_INTERFACE" ]]; then
_move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" True False "inet"
if [[ $(ip -f inet6 a s dev "$PUBLIC_INTERFACE" | grep -c 'global') != 0 ]]; then
_move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" False False "inet6"
fi
else
local default_dev=""
default_dev=$(ip route | grep ^default | awk '{print $5}')
sudo iptables -t nat -A POSTROUTING -o $default_dev -s $FLOATING_RANGE -j MASQUERADE
fi
}
# Explicitly set router id in l3 agent configuration
function _neutron_set_router_id {
if [[ "$Q_L3_ROUTER_PER_TENANT" == "False" ]]; then
iniset $Q_L3_CONF_FILE DEFAULT router_id $ROUTER_ID
fi
}
# Get ext_gw_interface depending on value of Q_USE_PUBLIC_VETH
function _neutron_get_ext_gw_interface {
if [[ "$Q_USE_PUBLIC_VETH" == "True" ]]; then
echo $Q_PUBLIC_VETH_EX
else
# Disable in-band as we are going to use local port
# to communicate with VMs
sudo ovs-vsctl set Bridge $PUBLIC_BRIDGE \
other_config:disable-in-band=true
echo $PUBLIC_BRIDGE
fi
}
function create_neutron_initial_network {
local project_id
project_id=$(openstack project list | grep " demo " | get_field 1)
die_if_not_set $LINENO project_id "Failure retrieving project_id for demo"
# Allow drivers that need to create an initial network to do so here
if type -p neutron_plugin_create_initial_network_profile > /dev/null; then
neutron_plugin_create_initial_network_profile $PHYSICAL_NETWORK
fi
if is_provider_network; then
die_if_not_set $LINENO PHYSICAL_NETWORK "You must specify the PHYSICAL_NETWORK"
die_if_not_set $LINENO PROVIDER_NETWORK_TYPE "You must specify the PROVIDER_NETWORK_TYPE"
NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create $PHYSICAL_NETWORK --tenant_id $project_id --provider:network_type $PROVIDER_NETWORK_TYPE --provider:physical_network "$PHYSICAL_NETWORK" ${SEGMENTATION_ID:+--provider:segmentation_id $SEGMENTATION_ID} --shared | grep ' id ' | get_field 2)
die_if_not_set $LINENO NET_ID "Failure creating NET_ID for $PHYSICAL_NETWORK $project_id"
if [[ "$IP_VERSION" =~ 4.* ]]; then
SUBNET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create --tenant_id $project_id --ip_version 4 ${ALLOCATION_POOL:+--allocation-pool $ALLOCATION_POOL} --name $PROVIDER_SUBNET_NAME --gateway $NETWORK_GATEWAY $NET_ID $FIXED_RANGE | grep ' id ' | get_field 2)
die_if_not_set $LINENO SUBNET_ID "Failure creating SUBNET_ID for $PROVIDER_SUBNET_NAME $project_id"
fi
if [[ "$IP_VERSION" =~ .*6 ]]; then
die_if_not_set $LINENO IPV6_PROVIDER_FIXED_RANGE "IPV6_PROVIDER_FIXED_RANGE has not been set, but Q_USE_PROVIDERNET_FOR_PUBLIC is true and IP_VERSION includes 6"
die_if_not_set $LINENO IPV6_PROVIDER_NETWORK_GATEWAY "IPV6_PROVIDER_NETWORK_GATEWAY has not been set, but Q_USE_PROVIDERNET_FOR_PUBLIC is true and IP_VERSION includes 6"
SUBNET_V6_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create --tenant_id $project_id --ip_version 6 --ipv6-address-mode $IPV6_ADDRESS_MODE --gateway $IPV6_PROVIDER_NETWORK_GATEWAY --name $IPV6_PROVIDER_SUBNET_NAME $NET_ID $IPV6_PROVIDER_FIXED_RANGE | grep 'id' | get_field 2)
die_if_not_set $LINENO SUBNET_V6_ID "Failure creating SUBNET_V6_ID for $IPV6_PROVIDER_SUBNET_NAME $project_id"
fi
if [[ $Q_AGENT == "openvswitch" ]]; then
sudo ip link set $OVS_PHYSICAL_BRIDGE up
sudo ip link set br-int up
sudo ip link set $PUBLIC_INTERFACE up
fi
else
NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create --tenant-id $project_id "$PRIVATE_NETWORK_NAME" | grep ' id ' | get_field 2)
die_if_not_set $LINENO NET_ID "Failure creating NET_ID for $PRIVATE_NETWORK_NAME $project_id"
if [[ "$IP_VERSION" =~ 4.* ]]; then
# Create IPv4 private subnet
SUBNET_ID=$(_neutron_create_private_subnet_v4 $project_id)
fi
if [[ "$IP_VERSION" =~ .*6 ]]; then
# Create IPv6 private subnet
IPV6_SUBNET_ID=$(_neutron_create_private_subnet_v6 $project_id)
fi
fi
if is_networking_extension_supported "router" && is_networking_extension_supported "external-net"; then
# Create a router, and add the private subnet as one of its interfaces
if [[ "$Q_L3_ROUTER_PER_TENANT" == "True" ]]; then
# create a tenant-owned router.
ROUTER_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-create --tenant-id $project_id $Q_ROUTER_NAME | grep ' id ' | get_field 2)
die_if_not_set $LINENO ROUTER_ID "Failure creating ROUTER_ID for $project_id $Q_ROUTER_NAME"
else
# Plugin only supports creating a single router, which should be admin owned.
ROUTER_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-create $Q_ROUTER_NAME | grep ' id ' | get_field 2)
die_if_not_set $LINENO ROUTER_ID "Failure creating ROUTER_ID for $Q_ROUTER_NAME"
fi
EXTERNAL_NETWORK_FLAGS="--router:external"
if is_networking_extension_supported "auto-allocated-topology" && is_networking_extension_supported "subnet_allocation"; then
EXTERNAL_NETWORK_FLAGS="$EXTERNAL_NETWORK_FLAGS --is-default"
if [[ "$IP_VERSION" =~ 4.* ]]; then
SUBNETPOOL_V4_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnetpool-create $SUBNETPOOL_NAME --default-prefixlen $SUBNETPOOL_SIZE_V4 --pool-prefix $SUBNETPOOL_PREFIX_V4 --shared --is-default=True | grep ' id ' | get_field 2)
fi
if [[ "$IP_VERSION" =~ .*6 ]]; then
SUBNETPOOL_V6_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnetpool-create $SUBNETPOOL_NAME --default-prefixlen $SUBNETPOOL_SIZE_V6 --pool-prefix $SUBNETPOOL_PREFIX_V6 --shared --is-default=True | grep ' id ' | get_field 2)
fi
fi
# Create an external network, and a subnet. Configure the external network as router gw
if [ "$Q_USE_PROVIDERNET_FOR_PUBLIC" = "True" ]; then
EXT_NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create "$PUBLIC_NETWORK_NAME" -- $EXTERNAL_NETWORK_FLAGS --provider:network_type=flat --provider:physical_network=${PUBLIC_PHYSICAL_NETWORK} | grep ' id ' | get_field 2)
else
EXT_NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create "$PUBLIC_NETWORK_NAME" -- $EXTERNAL_NETWORK_FLAGS | grep ' id ' | get_field 2)
fi
die_if_not_set $LINENO EXT_NET_ID "Failure creating EXT_NET_ID for $PUBLIC_NETWORK_NAME"
if [[ "$IP_VERSION" =~ 4.* ]]; then
# Configure router for IPv4 public access
_neutron_configure_router_v4
fi
if [[ "$IP_VERSION" =~ .*6 ]]; then
# Configure router for IPv6 public access
_neutron_configure_router_v6
fi
fi
}
# Create private IPv4 subnet
function _neutron_create_private_subnet_v4 {
local project_id=$1
local subnet_params="--tenant-id $project_id "
subnet_params+="--ip_version 4 "
subnet_params+="--gateway $NETWORK_GATEWAY "
subnet_params+="--name $PRIVATE_SUBNET_NAME "
subnet_params+="$NET_ID $FIXED_RANGE"
local subnet_id
subnet_id=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep ' id ' | get_field 2)
die_if_not_set $LINENO subnet_id "Failure creating private IPv4 subnet for $project_id"
echo $subnet_id
}
# Create private IPv6 subnet
function _neutron_create_private_subnet_v6 {
local project_id=$1
die_if_not_set $LINENO IPV6_RA_MODE "IPV6 RA Mode not set"
die_if_not_set $LINENO IPV6_ADDRESS_MODE "IPV6 Address Mode not set"
local ipv6_modes="--ipv6-ra-mode $IPV6_RA_MODE --ipv6-address-mode $IPV6_ADDRESS_MODE"
local subnet_params="--tenant-id $project_id "
subnet_params+="--ip_version 6 "
subnet_params+="--gateway $IPV6_PRIVATE_NETWORK_GATEWAY "
subnet_params+="--name $IPV6_PRIVATE_SUBNET_NAME "
subnet_params+="$NET_ID $FIXED_RANGE_V6 $ipv6_modes"
local ipv6_subnet_id
ipv6_subnet_id=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep ' id ' | get_field 2)
die_if_not_set $LINENO ipv6_subnet_id "Failure creating private IPv6 subnet for $project_id"
echo $ipv6_subnet_id
}
# Create public IPv4 subnet
function _neutron_create_public_subnet_v4 {
local subnet_params+="--ip_version 4 "
subnet_params+="${Q_FLOATING_ALLOCATION_POOL:+--allocation-pool $Q_FLOATING_ALLOCATION_POOL} "
subnet_params+="--gateway $PUBLIC_NETWORK_GATEWAY "
subnet_params+="--name $PUBLIC_SUBNET_NAME "
subnet_params+="$EXT_NET_ID $FLOATING_RANGE "
subnet_params+="-- --enable_dhcp=False"
local id_and_ext_gw_ip
id_and_ext_gw_ip=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep -e 'gateway_ip' -e ' id ')
die_if_not_set $LINENO id_and_ext_gw_ip "Failure creating public IPv4 subnet"
echo $id_and_ext_gw_ip
}
# Create public IPv6 subnet
function _neutron_create_public_subnet_v6 {
local subnet_params="--ip_version 6 "
subnet_params+="--gateway $IPV6_PUBLIC_NETWORK_GATEWAY "
subnet_params+="--name $IPV6_PUBLIC_SUBNET_NAME "
subnet_params+="$EXT_NET_ID $IPV6_PUBLIC_RANGE "
subnet_params+="-- --enable_dhcp=False"
local ipv6_id_and_ext_gw_ip
ipv6_id_and_ext_gw_ip=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep -e 'gateway_ip' -e ' id ')
die_if_not_set $LINENO ipv6_id_and_ext_gw_ip "Failure creating an IPv6 public subnet"
echo $ipv6_id_and_ext_gw_ip
}
# Configure neutron router for IPv4 public access
function _neutron_configure_router_v4 {
neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-interface-add $ROUTER_ID $SUBNET_ID
# Create a public subnet on the external network
local id_and_ext_gw_ip
id_and_ext_gw_ip=$(_neutron_create_public_subnet_v4 $EXT_NET_ID)
local ext_gw_ip
ext_gw_ip=$(echo $id_and_ext_gw_ip | get_field 2)
PUB_SUBNET_ID=$(echo $id_and_ext_gw_ip | get_field 5)
# Configure the external network as the default router gateway
neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-gateway-set $ROUTER_ID $EXT_NET_ID
# This logic is specific to using the l3-agent for layer 3
if is_service_enabled q-l3 || is_service_enabled neutron-l3; then
# Configure and enable public bridge
local ext_gw_interface="none"
if is_neutron_ovs_base_plugin; then
ext_gw_interface=$(_neutron_get_ext_gw_interface)
elif [[ "$Q_AGENT" = "linuxbridge" ]]; then
# Search for the brq device the neutron router and network for $FIXED_RANGE
# will be using.
# e.x. brq3592e767-da for NET_ID 3592e767-da66-4bcb-9bec-cdb03cd96102
ext_gw_interface=brq${EXT_NET_ID:0:11}
fi
if [[ "$ext_gw_interface" != "none" ]]; then
local cidr_len=${FLOATING_RANGE#*/}
local testcmd="ip -o link | grep -q $ext_gw_interface"
test_with_retry "$testcmd" "$ext_gw_interface creation failed"
if [[ $(ip addr show dev $ext_gw_interface | grep -c $ext_gw_ip) == 0 && ( $Q_USE_PROVIDERNET_FOR_PUBLIC == "False" || $Q_USE_PUBLIC_VETH == "True" ) ]]; then
sudo ip addr add $ext_gw_ip/$cidr_len dev $ext_gw_interface
sudo ip link set $ext_gw_interface up
fi
ROUTER_GW_IP=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" port-list -c fixed_ips -c device_owner | grep router_gateway | awk -F'ip_address' '{ print $2 }' | cut -f3 -d\" | tr '\n' ' ')
die_if_not_set $LINENO ROUTER_GW_IP "Failure retrieving ROUTER_GW_IP"
sudo ip route replace $FIXED_RANGE via $ROUTER_GW_IP
fi
_neutron_set_router_id
fi
}
# Configure neutron router for IPv6 public access
function _neutron_configure_router_v6 {
neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-interface-add $ROUTER_ID $IPV6_SUBNET_ID
# Create a public subnet on the external network
local ipv6_id_and_ext_gw_ip
ipv6_id_and_ext_gw_ip=$(_neutron_create_public_subnet_v6 $EXT_NET_ID)
local ipv6_ext_gw_ip
ipv6_ext_gw_ip=$(echo $ipv6_id_and_ext_gw_ip | get_field 2)
local ipv6_pub_subnet_id
ipv6_pub_subnet_id=$(echo $ipv6_id_and_ext_gw_ip | get_field 5)
# If the external network has not already been set as the default router
# gateway when configuring an IPv4 public subnet, do so now
if [[ "$IP_VERSION" == "6" ]]; then
neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-gateway-set $ROUTER_ID $EXT_NET_ID
fi
# This logic is specific to using the l3-agent for layer 3
if is_service_enabled q-l3 || is_service_enabled neutron-l3; then
# Ensure IPv6 forwarding is enabled on the host
sudo sysctl -w net.ipv6.conf.all.forwarding=1
# Configure and enable public bridge
# Override global IPV6_ROUTER_GW_IP with the true value from neutron
IPV6_ROUTER_GW_IP=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" port-list -c fixed_ips | grep $ipv6_pub_subnet_id | awk -F'ip_address' '{ print $2 }' | cut -f3 -d\" | tr '\n' ' ')
die_if_not_set $LINENO IPV6_ROUTER_GW_IP "Failure retrieving IPV6_ROUTER_GW_IP"
if is_neutron_ovs_base_plugin; then
local ext_gw_interface
ext_gw_interface=$(_neutron_get_ext_gw_interface)
local ipv6_cidr_len=${IPV6_PUBLIC_RANGE#*/}
# Configure interface for public bridge
sudo ip -6 addr replace $ipv6_ext_gw_ip/$ipv6_cidr_len dev $ext_gw_interface
sudo ip -6 route replace $FIXED_RANGE_V6 via $IPV6_ROUTER_GW_IP dev $ext_gw_interface
fi
_neutron_set_router_id
fi
}
function is_provider_network {
if [ "$Q_USE_PROVIDER_NETWORKING" == "True" ]; then
return 0
fi
return 1
}
function is_networking_extension_supported {
local extension=$1
# TODO(sc68cal) cache this instead of calling every time
EXT_LIST=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" ext-list -c alias -f value)
[[ $EXT_LIST =~ $extension ]] && return 0
}