Chapter 13. Configure Bridge Mappings
This chapter describes how to configure bridge mappings in Red Hat OpenStack Platform.
13.1. What are bridge mappings used for?
Bridge mappings allow provider network traffic to reach the physical network. Traffic leaves the provider network from the router’s qg-xxx interface and arrives at br-int. A patch port between br-int and br-ex then allows the traffic to pass through the bridge of the provider network and out to the physical network.
13.1.1. Configure bridge mappings
Below is an example of a patch-peer between br-int and br-ex:
int-br-ex <-> phy-br-ex
This connection is configured in the bridge_mappings setting. For example:
bridge_mappings = physnet1:br-ex,physnet2:br-ex2
If the bridge_mapping entry is missing, no network connection exists, and communication to physical networks will not work.
This configuration’s first entry creates a connection between br-int and br-ex using patch peer cable. The second entry creates a patch peer for br-ex2.
13.1.2. Configure the controller node
The bridge_mappings configuration must correlate with that of the network_vlan_ranges option on the controller node. For the example given above, the controller node is configured as follows:
network_vlan_ranges = physnet1:10:20,physnet2:21:25
These values create the provider networks that represent the corresponding external networks; the external networks are then connected to the tenant networks via router interfaces. As a result, it is necessary to configure bridge_mappings on the network node on which the router is scheduled. This means that the router traffic is able to egress using the correct physical network, as represented by the provider network (for example: physnet1).
13.1.3. Traffic flow
In addition to creating the connection, this setting also configures the OVS flow in br-int and br-ex to allow the network traffic to traverse to and from the external network. Each external network is represented by an internal VLAN id, which is tagged to the router’s qg-xxx port. When a packet reaches phy-br-ex, the br-ex port strips the VLAN tag and moves the packet to the physical interface and then to the external network. The return packet from external network arrives on br-ex and is moved to br-int using phy-br-ex <→ int-br-ex. When the packet reaches int-br-ex, another flow in br-int adds internal vlan tag to the packet. This allows the packet to be accepted by qg-xxx.
13.2. Maintaining Bridge Mappings
After removing any mappings, a subsequent patch-port cleanup is required. This action ensures that the bridge configuration is cleared of erroneous entries, with two options available for performing this task:
- Manual port cleanup - requires careful removal of the superfluous ports. No outage is required to network connectivity.
- Automated port cleanup using neutron-ovs-cleanup - performs an automated cleanup, but requires an outage, and requires that the necessary mappings be re-added. Choose this option if you don’t mind having an outage to network connectivity.
Examples are given below for each of these two options:
13.2.1. Manual port cleanup
The manual port cleanup process removes unneeded ports, and doesn’t require a system outage. You can identify these ports by their naming convention: in br-$external_bridge they are named as "phy-"$external_bridge and in br-int they are named "int-"
$external_bridge.
This example procedure removes a bridge from bridge_mappings, and cleans up the corresponding ports. 1. Edit openvswitch_agent.ini and remove the entry for physnet2:br-ex2 from bridge_mappings:
bridge_mappings = physnet1:br-ex,physnet2:br-ex2
Remove the entry for physnet2:br-ex2. The resulting bridge_mappings resembles this:
bridge_mappings = physnet1:br-ex
2. Use ovs-vsctl to remove the patch ports associated with the removed physnet2:br-ex2 entry:
# ovs-vsctl del-port br-ex2 phy-br-ex2 # ovs-vsctl del-port br-int int-br-ex2
If the entire bridge_mappings entry is removed or commented out, cleanup commands will need to be run for each entry,
3. Restart neutron-openvswitch-agent:
# service neutron-openvswitch-agent restart
13.2.2. Automated port cleanup using ‘neutron-ovs-cleanup’
This action is performed using the neutron-ovs-cleanup command combined with the --ovs_all_ports flag. Restart the neutron services or the entire node to then restore the bridges back to their normal working state. This process requires a total networking outage.
The neutron-ovs-cleanup command unplugs all ports (instances, qdhcp/qrouter, among others) from all OVS bridges. Using the flag --ovs_all_ports results in removing all ports from br-int, cleaning up tunnel ends from br-tun, and patch ports from bridge to bridge. In addition, the physical interfaces (such as eth0, eth1) are removed from the bridges (such as br-ex, br-ex2). This will result in lost connectivity to instances until the ports are manually re-added using ovs-vsctl:
# ovs-vsctl add-port br-ex eth1
13.2.2.1. Example usage of neutron-ovs-cleanup:
1. Make a backup of your bridge_mapping entries as found in openvswitch_agent.ini.
2. Run neutron-ovs-cleanup with the --ovs_all_ports flag. Note that this step will result in a total networking outage.
# /usr/bin/neutron-ovs-cleanup --config-file /etc/neutron/plugins/ml2/openvswitch_agent.ini --log-file /var/log/neutron/ovs-cleanup.log --ovs_all_ports
3. Restart these OpenStack Networking services:
# systemctl restart neutron-openvswitch-agent # systemctl restart neutron-l3-agent.service # systemctl restart neutron-dhcp-agent.service
4. Restore connectivity by re-adding the bridge_mapping entries to openvswitch_agent.ini.
5. Restart the neutron-openvswitch-agent service:
# systemctl restart neutron-openvswitch-agent
When the OVS agent restarts, it doesn’t touch any connections which are not present in bridge_mappings. So if you have br-int connected to br-ex2, and br-ex2 has some flows on it, removing it from the bridge_mappings configuration (or commenting it out entirely) won’t disconnect the two bridges, no matter what you do (whether restarting the service, or the node).
13.3. VLAN-Aware Instances
13.3.1. Overview
Instances can now send and receive VLAN-tagged traffic over a single vNIC. This ability is particularly useful for NFV applications (VNFs) that expect VLAN-tagged traffic, allowing multiple customers/services to be served by a single vNIC.
For example, the tenant data network can use VLANs, or tunneling (VXLAN/GRE) segmentation, while the instances will see the traffic tagged with VLAN IDs. As a result, network packets are tagged just before they are injected to the instance; they don’t need to be tagged throughout the entire network.
To implement this, start by creating a parent port and attaching it to an existing neutron network. Doing so will add a trunk connection to the parent port you created. Next, create subports. These subports are the ports that connect VLANs to instances, thereby allowing connectivity to the trunk. Within the instance operating system, you need to create a sub-interface that tags traffic for the VLAN associated with the subport.
13.3.2. Review the Trunk Plugin
In a director-based deployment, the trunk plugin is turned on by default. You can review the configuration on the controller nodes:
1.On the controller node, confirm that the trunk
plugin is enabled in /etc/neutron/neutron.conf. For example:
service_plugins=router,qos,trunk
13.3.3. Create a Trunk Connection
1. Identify the network that requires the trunk port connection. This would be the network that will contain the instance that requires access to the trunked VLANs. In this example, this is the public network:
openstack network list +--------------------------------------+---------+--------------------------------------+ | ID | Name | Subnets | +--------------------------------------+---------+--------------------------------------+ | 82845092-4701-4004-add7-838837837621 | private | 434c7982-cd96-4c41-a8c9-b93adbdcb197 | | 8d8bc6d6-5b28-4e00-b99e-157516ff0050 | public | 3fd811b4-c104-44b5-8ff8-7a86af5e332c | +--------------------------------------+---------+--------------------------------------+
2. Create the parent trunk port, and attach it to the network that the instance will be connected to. In this example, a neutron port named parent-trunk-port
is created on the public network. This trunk will be considered the parent port, as you can use it to create subports.
openstack port create --network public parent-trunk-port +-----------------------+-----------------------------------------------------------------------------+ | Field | Value | +-----------------------+-----------------------------------------------------------------------------+ | admin_state_up | UP | | allowed_address_pairs | | | binding_host_id | | | binding_profile | | | binding_vif_details | | | binding_vif_type | unbound | | binding_vnic_type | normal | | created_at | 2016-10-20T02:02:33Z | | description | | | device_id | | | device_owner | | | extra_dhcp_opts | | | fixed_ips | ip_address='172.24.4.230', subnet_id='dc608964-9af3-4fed-9f06-6d3844fb9b9b' | | headers | | | id | 20b6fdf8-0d43-475a-a0f1-ec8f757a4a39 | | mac_address | fa:16:3e:33:c4:75 | | name | parent-trunk-port | | network_id | 871a6bd8-4193-45d7-a300-dcb2420e7cc3 | | project_id | 745d33000ac74d30a77539f8920555e7 | | project_id | 745d33000ac74d30a77539f8920555e7 | | revision_number | 4 | | security_groups | 59e2af18-93c6-4201-861b-19a8a8b79b23 | | status | DOWN | | updated_at | 2016-10-20T02:02:33Z | +-----------------------+-----------------------------------------------------------------------------+
4. Create a trunk using the port you just created. In this example the trunk is named parent-trunk
.
openstack network trunk create --parent-port parent-trunk-port parent-trunk +-----------------+--------------------------------------+ | Field | Value | +-----------------+--------------------------------------+ | admin_state_up | UP | | created_at | 2016-10-20T02:05:17Z | | description | | | id | 0e4263e2-5761-4cf6-ab6d-b22884a0fa88 | | name | parent-trunk | | port_id | 20b6fdf8-0d43-475a-a0f1-ec8f757a4a39 | | revision_number | 1 | | status | DOWN | | sub_ports | | | tenant_id | 745d33000ac74d30a77539f8920555e7 | | updated_at | 2016-10-20T02:05:17Z | +-----------------+--------------------------------------+
5. View the trunk connection:
openstack network trunk list +--------------------------------------+--------------+--------------------------------------+-------------+ | ID | Name | Parent Port | Description | +--------------------------------------+--------------+--------------------------------------+-------------+ | 0e4263e2-5761-4cf6-ab6d-b22884a0fa88 | parent-trunk | 20b6fdf8-0d43-475a-a0f1-ec8f757a4a39 | | +--------------------------------------+--------------+--------------------------------------+-------------+
- View the details of the trunk connection:
openstack network trunk show parent-trunk +-----------------+--------------------------------------+ | Field | Value | +-----------------+--------------------------------------+ | admin_state_up | UP | | created_at | 2016-10-20T02:05:17Z | | description | | | id | 0e4263e2-5761-4cf6-ab6d-b22884a0fa88 | | name | parent-trunk | | port_id | 20b6fdf8-0d43-475a-a0f1-ec8f757a4a39 | | revision_number | 1 | | status | DOWN | | sub_ports | | | tenant_id | 745d33000ac74d30a77539f8920555e7 | | updated_at | 2016-10-20T02:05:17Z | +-----------------+--------------------------------------+
13.3.4. Add Subports to the Trunk
1. Create a neutron port. This port will be used as a subport connection to the trunk. You must also specify the MAC address that was assigned to the parent port:
openstack port create --network private --mac-address fa:16:3e:33:c4:75 subport-trunk-port +-----------------------+--------------------------------------------------------------------------+ | Field | Value | +-----------------------+--------------------------------------------------------------------------+ | admin_state_up | UP | | allowed_address_pairs | | | binding_host_id | | | binding_profile | | | binding_vif_details | | | binding_vif_type | unbound | | binding_vnic_type | normal | | created_at | 2016-10-20T02:08:14Z | | description | | | device_id | | | device_owner | | | extra_dhcp_opts | | | fixed_ips | ip_address='10.0.0.11', subnet_id='1a299780-56df-4c0b-a4c0-c5a612cef2e8' | | headers | | | id | 479d742e-dd00-4c24-8dd6-b7297fab3ee9 | | mac_address | fa:16:3e:33:c4:75 | | name | subport-trunk-port | | network_id | 3fe6b758-8613-4b17-901e-9ba30a7c4b51 | | project_id | 745d33000ac74d30a77539f8920555e7 | | project_id | 745d33000ac74d30a77539f8920555e7 | | revision_number | 4 | | security_groups | 59e2af18-93c6-4201-861b-19a8a8b79b23 | | status | DOWN | | updated_at | 2016-10-20T02:08:15Z | +-----------------------+--------------------------------------------------------------------------+
If you receive the error HttpException: Conflict
, confirm that you are creating the subport on a different network to the one that has the parent trunk port. This example uses the public
network for the parent trunk port, and private
for the subport.
2. Associate the port with the trunk (parent-trunk
), and specify the VLAN ID (55
):
openstack network trunk set --subport port=subport-trunk-port,segmentation-type=vlan,segmentation-id=55 parent-trunk
13.4. Configure an Instance to use a Trunk
The instance operating system must be configured to use the MAC address that neutron assigned to the subport. You can also configure the subport to use a specific MAC address during the subport creation step.
1. Review the configuration of your network trunk:
$ openstack network trunk list +--------------------------------------+--------------+--------------------------------------+-------------+ | ID | Name | Parent Port | Description | +--------------------------------------+--------------+--------------------------------------+-------------+ | 0e4263e2-5761-4cf6-ab6d-b22884a0fa88 | parent-trunk | 20b6fdf8-0d43-475a-a0f1-ec8f757a4a39 | | +--------------------------------------+--------------+--------------------------------------+-------------+ $ openstack network trunk show parent-trunk +-----------------+------------------------------------------------------------------------------------------------+ | Field | Value | +-----------------+------------------------------------------------------------------------------------------------+ | admin_state_up | UP | | created_at | 2016-10-20T02:05:17Z | | description | | | id | 0e4263e2-5761-4cf6-ab6d-b22884a0fa88 | | name | parent-trunk | | port_id | 20b6fdf8-0d43-475a-a0f1-ec8f757a4a39 | | revision_number | 2 | | status | DOWN | | sub_ports | port_id='479d742e-dd00-4c24-8dd6-b7297fab3ee9', segmentation_id='55', segmentation_type='vlan' | | tenant_id | 745d33000ac74d30a77539f8920555e7 | | updated_at | 2016-10-20T02:10:06Z | +-----------------+------------------------------------------------------------------------------------------------+
2. Create an instance that uses the parent port id
as its vNIC:
nova boot --image cirros --flavor m1.tiny testInstance --security-groups default --key-name sshaccess --nic port-id=20b6fdf8-0d43-475a-a0f1-ec8f757a4a39 +--------------------------------------+-----------------------------------------------+ | Property | Value | +--------------------------------------+-----------------------------------------------+ | OS-DCF:diskConfig | MANUAL | | OS-EXT-AZ:availability_zone | | | OS-EXT-SRV-ATTR:host | - | | OS-EXT-SRV-ATTR:hostname | testinstance | | OS-EXT-SRV-ATTR:hypervisor_hostname | - | | OS-EXT-SRV-ATTR:instance_name | | | OS-EXT-SRV-ATTR:kernel_id | | | OS-EXT-SRV-ATTR:launch_index | 0 | | OS-EXT-SRV-ATTR:ramdisk_id | | | OS-EXT-SRV-ATTR:reservation_id | r-juqco0el | | OS-EXT-SRV-ATTR:root_device_name | - | | OS-EXT-SRV-ATTR:user_data | - | | OS-EXT-STS:power_state | 0 | | OS-EXT-STS:task_state | scheduling | | OS-EXT-STS:vm_state | building | | OS-SRV-USG:launched_at | - | | OS-SRV-USG:terminated_at | - | | accessIPv4 | | | accessIPv6 | | | adminPass | uMyL8PnZRBwQ | | config_drive | | | created | 2016-10-20T03:02:51Z | | description | - | | flavor | m1.tiny (1) | | hostId | | | host_status | | | id | 88b7aede-1305-4d91-a180-67e7eac8b70d | | image | cirros (568372f7-15df-4e61-a05f-10954f79a3c4) | | key_name | sshaccess | | locked | False | | metadata | {} | | name | testInstance | | os-extended-volumes:volumes_attached | [] | | progress | 0 | | security_groups | default | | status | BUILD | | tags | [] | | tenant_id | 745d33000ac74d30a77539f8920555e7 | | updated | 2016-10-20T03:02:51Z | | user_id | 8c4aea738d774967b4ef388eb41fef5e | +--------------------------------------+-----------------------------------------------+