如何实现OpenStack STT隧道(by quqi99)

作者:张华  发表于:2016-05-21
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明

( http://blog.csdn.net/quqi99 )

代码

VMWare NSX使用OVS STT隧道,OVS是支持STT隧道,但是Neutron还不支持。所以我rebase了社区一个废弃很久的代码想测试一下TSO/GSO对其的影响(冲突很多,改动还有点大,代码见附件)。

机器

从内网找了机器两台,一台机器网卡两块,一块万兆网络用于走STT流量,一块千兆网卡用于外网流量。

node1, duduo.seg, controller node

  • eth0: 10.230.56.15,   1000Mb/s,  br-ex
  • eth6: 10.230.56.21,  10000Mb/s, out-off-band management
  • eth7: 192.168.122.3, 10000Mb/s, br-phy

node2, voltorb.seg, compute node

  • eth0: 10.230.56.14,   1000Mb/s, out-off-band management
  • eth4: 192.168.122.2, 10000Mb/s, br-phy

Devstack

sudo mkdir -p /bak/openstack && sudo chown -R ubuntu:root /bak/
sudo mkdir -p /opt/stack && sudo chown -R ubuntu:root /opt/stack
cd /bak/openstack/ && git clone https://github.com/openstack-dev/devstack.git

这两台机器位于内网,故当要下载东西时需要临时添加代理(export http_proxy=http://squid.internal:3128 && export https_proxy=http://squid.internal:3128),下载完毕应立即取消代理(unset http_proxy && uset https_proxy)。所以./stack.sh需运行两遍,一遍加代理运行访问互联网下载完该下载的东西,第二遍设置去掉代理(一定要去掉代理,不然openstack代理中的http访问全会出一些与此不相关的错)及设置OFFLINE=True后再运行一遍。

locarc文件内容如下,注意点见黑体注释。

#OFFLINE=True
#unset http_proxy
#unset https_proxy
PUBLIC_INTERFACE=eth7         #计算节点改为eth4
HOST_IP=192.168.122.3         #计算节点改为192.168.122.2
SERVICE_HOST=$HOST_IP         #计算节点改为192.168.122.3
DEST=/bak/openstack
sudo apt-get install openvswitch-switch qemu-kvm libvirt-bin
sudo virsh net-destroy default #两机器由MaaS申请,MaaS与Qemu都用了网段192.168.122.0/24冲突了影响路由造成会两机器网络不通
sudo ovs-vsctl -- --may-exist add-br br-phy #先建好br-phy,避免devstack创建网桥时将IP从eth7移到br-phy造成网络混乱
#sudo ovs-vsctl -- --may-exist add-port br-phy eth7 -- set interface eth7 type=internal
#使用type=internal时路由在eth7上会造成"ovs-ofctl dump-flows br-phy“命令失败
sudo ovs-vsctl -- --may-exist add-port br-phy eth7
sudo ifconfig eth7 0.0.0.0 up
sudo ifconfig br-phy 192.168.122.3/24
sleep 5

#ENABLED_SERVICES=n-cpu,rabbit,neutron,q-agt
ENABLED_SERVICES=rabbit,mysql,key,g-api,g-reg
ENABLED_SERVICES+=,n-api,n-crt,n-obj,n-cpu,n-cond,n-sch,n-cauth,n-novnc
ENABLED_SERVICES+=,q-svc,q-agt,q-dhcp,q-l3,q-meta,neutron
Q_USE_ROOTWRAP=True
Q_USE_ROOTWRAP_DAEMON=False
NOVA_VNC_ENABLED=True
Q_ML2_TENANT_NETWORK_TYPE=flat,vlan,gre,vxlan
Q_ML2_PLUGIN_TYPE_DRIVERS=flat,vlan,gre,vxlan

#我们没有使用provider network(即flat, vlan物理网络)去自动创建网络,我们将手工创建,所以需要修改devstack代码
#Q_USE_PROVIDER_NETWORKING=True
#FIXED_RANGE="10.230.56.100/24"
#NETWORK_GATEWAY=10.230.56.1
#PROVIDER_PROVIDER_SUBNET_NAMESUBNET_NAME="provider_net"
#PROVIDER_NETWORK_TYPE="flat"
GIT_BASE="https://git.openstack.org"     #因为两台机器在内网中需要添加http_proxy代理

MYSQL_HOST=$SERVICE_HOST
RABBIT_HOST=$SERVICE_HOST
RABBIT_HEARTBEAT_TIMEOUT_THRESHOLD=120   #此参数和kombu_reconnect_delay=3.0一样重要是否rabbitmq连接总断开
GLANCE_HOSTPORT=$SERVICE_HOST:9292
Q_HOST=$SERVICE_HOST

FIXED_RANGE=10.0.1.0/24
#113 -- 118, http://jodies.de/ipcalc
FLOATING_RANGE=10.230.56.0/24
Q_FLOATING_ALLOCATION_POOL=start=10.230.56.100,end=10.230.56.155
PUBLIC_NETWORK_GATEWAY=10.230.56.1
NETWORK_GATEWAY=10.0.1.1
#若只有一块网卡,公网网络可与管理网络设置一致,可添加:Q_USE_PROVIDERNET_FOR_PUBLIC=True && PUBLIC_BRIDGE=br-phy
PUBLIC_BRIDGE=br-ex
# sudo ovs-vsctl -- --may-exist add-port br-ex eth0 -- set interface eth0 type=internal  #事后采用type=internal添加不影响已有网络
OVS_PHYSICAL_BRIDGE=br-phy
OVS_BRIDGE_MAPPINGS=physnet1:br-phy
IP_VERSION=4
DATABASE_USER=root
DATABASE_PASSWORD=password
ADMIN_PASSWORD=password
SERVICE_PASSWORD=password
RABBIT_PASSWORD=password
SERVICE_TOKEN=ADMIN
LOGFILE=$DEST/logs/stack.log
ENABLE_DEBUG_LOG_LEVEL=False
SYSLOG=False
VERBOSE=True
SCREEN_LOGDIR=$DEST/logs
LOG_COLOR=False
Q_USE_DEBUG_COMMAND=False
APACHE_ENABLED_SERVICES+=keystone
KEYSTONE_TOKEN_FORMAT=uuid
USE_SSL=False
disable_service tls-proxy
IMAGE_URLS="https://cloud-images.ubuntu.com/trusty/current/trusty-server-cloudimg-amd64-disk1.img"
DOWNLOAD_DEFAULT_IMAGES=False
#IPSEC_PACKAGE=strongswan

# Neutron Agent configuration
Q_USE_NAMESPACE=True
Q_ALLOW_OVERLAPPING_IP=True
# Neutron ML2 configuration
Q_PLUGIN=ml2
#Q_DVR_MODE=dvr_snat
Q_DVR_MODE=legacy
# VLAN
ENABLE_TENANT_VLANS=True
ML2_VLAN_RANGES=physnet1:1000:2999,physnet2:1000:2999
# GRE
ENABLE_TENANT_TUNNELS=True
TENANT_TUNNEL_RANGE=1000:2000
Q_ML2_PLUGIN_VXLAN_TYPE_OPTIONS=(vni_ranges=1000:2000)

# Avanced ML2 configuration
Q_AGENT=openvswitch
Q_ML2_PLUGIN_MECHANISM_DRIVERS=openvswitch,l2population

因为我不想devstack去创建网络(我想手工创建),我也不想devstack修改我已经创建好的br-phy网卡,所以需要定制devstack代码:

[email protected]:/bak/openstack/devstack$ git diff
diff --git a/lib/neutron-legacy b/lib/neutron-legacy
index 383944f..4bba78b 100644
--- a/lib/neutron-legacy
+++ b/lib/neutron-legacy
@@ -658,7 +658,7 @@ function _move_neutron_addresses_route {
 function cleanup_mutnauq {

     if [[ -n "$OVS_PHYSICAL_BRIDGE" ]]; then
-        _move_neutron_addresses_route "$OVS_PHYSICAL_BRIDGE" "$PUBLIC_INTERFACE" False True "inet"
+        #_move_neutron_addresses_route "$OVS_PHYSICAL_BRIDGE" "$PUBLIC_INTERFACE" False True "inet"

         if [[ $(ip -f inet6 a s dev "$OVS_PHYSICAL_BRIDGE" | grep -c ‘global‘) != 0 ]]; then
             # ip(8) wants the prefix length when deleting
diff --git a/lib/neutron_plugins/services/l3 b/lib/neutron_plugins/services/l3
index a5a6c81..855a0f8 100644
--- a/lib/neutron_plugins/services/l3
+++ b/lib/neutron_plugins/services/l3
@@ -102,7 +102,7 @@ function _configure_neutron_l3_agent {

     neutron_plugin_configure_l3_agent

-    _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" True False "inet"
+    #_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"
diff --git a/stack.sh b/stack.sh
index 21f7f35..e248d06 100755
--- a/stack.sh
+++ b/stack.sh
@@ -1249,7 +1249,7 @@ fi
 # Once neutron agents are started setup initial network elements
 if is_service_enabled q-svc && [[ "$NEUTRON_CREATE_INITIAL_NETWORKS" == "True" ]]; then
     echo_summary "Creating initial neutron network elements"
-    create_neutron_initial_network
+#    create_neutron_initial_network
     setup_neutron_debug
 fi

升级stt代码与数据库

cd ../neutron && patch -p1 < stt.diff
sudo python setup.py develop   #生成STT_TYPE_Driver
screen -x stack
$ grep ‘stt‘ /etc/neutron/plugins/ml2/ml2_conf.ini
tenant_network_types = flat,vlan,gre,vxlan,stt
type_drivers = flat,vlan,gre,vxlan,stt
[agent]
tunnel_types = stt

下列方法升级数据库后在screen中重启neutron-server与neutron-ovs-agent两个服务

#http://docs.openstack.org/developer/neutron/devref/alembic_migrations.html
neutron-db-manage current --verbose
neutron-db-manage upgrade heads

创建网络 & 测试步骤

export OS_USERNAME=admin
export OS_PASSWORD=password
export OS_TENANT_NAME=demo
export OS_AUTH_URL=http://192.168.122.3:5000/v2.0
export OS_AUTH_STRATEGY=keystone

neutron net-create net-stt --provider:network_type stt --provider:segmentation_id 1012
neutron subnet-create --allocation-pool start=10.0.1.22,end=10.0.1.122 --gateway 10.0.1.1 net-stt 10.0.1.0/24 --enable_dhcp=True --name subnet-stt

neutron net-create public -- --router:external=True --provider:network_type flat --provider:physical_network physnet1
neutron subnet-create --allocation-pool start=10.230.56.102,end=10.230.56.126 --gateway 10.230.56.1 public 10.230.56.100/24 --enable_dhcp=False --name public-subnet

neutron router-create router1
EXT_NET_ID=$(neutron net-list |grep ‘ public ‘ |awk ‘{print $2}‘)
ROUTER_ID=$(neutron router-list |grep ‘ router1 ‘ |awk ‘{print $2}‘)
SUBNET_ID=$(neutron subnet-list |grep ‘10.0.1.0/24‘ |awk ‘{print $2}‘)
neutron router-interface-add $ROUTER_ID $SUBNET_ID
neutron router-gateway-set $ROUTER_ID $EXT_NET_ID

sudo rabbitmqctl status
neutron agent-list
nova service-disable duduo nova-compute
nova service-list
glance image-list
nova flavor-list
neutron net-list
nova boot --flavor 2 --image trusty-server-cloudimg-amd64-disk1 --nic net-id=92d70323-f3f8-439f-97c6-6fe7fa12c262 i1

遇到的问题

1, 如果很多openstack服务中出现错误”MessagingTimeout: Timed out waiting for a reply to message ID“,且如果rabbitmq日志中出现了”Missed heartbeats from client, timeout: 60s”,可以修改/etc/neutron/neutron.conf, /etc/nova/nova.conf, /etc/glance/glance-api.conf等所有配置文件为如下内容,然后重启所有服务

[oslo_messaging_rabbit]
kombu_reconnect_delay=3.0
heartbeat_timeout_threshold=120

2, 如果eth7以 type=internal模式加入网桥会造成"sudo ovs-ofctl dump-flows br-phy"命令无法执行。

[email protected]:/bak/openstack/devstack$ sudo ovs-ofctl dump-flows br-phy
ovs-ofctl: br-phy: failed to connect to socket (Connection reset by peer)
[email protected]:/bak/openstack/devstack$ sudo ovs-vsctl del-port br-phy eth7
[email protected]:/bak/openstack/devstack$ sudo ovs-ofctl dump-flows br-phy
NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=11533.961s, table=0, n_packets=20103, n_bytes=6910304, idle_age=3, priority=0 actions=NORMAL
[email protected]:/bak/openstack/devstack$ sudo ovs-ofctl dump-flows br-phy
NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=11584.170s, table=0, n_packets=20125, n_bytes=6912276, idle_age=0, priority=0 actions=NORMAL
[email protected]:/bak/openstack/devstack$ sudo ovs-vsctl del-port br-phy eth7
[email protected]:/bak/openstack/devstack$ sudo ovs-vsctl -- --may-exist add-port br-phy eth7 -- set interface eth7 type=internal
[email protected]:/bak/openstack/devstack$ sudo ovs-ofctl dump-flows br-phy
ovs-ofctl: br-phy: failed to connect to socket (Connection reset by peer)

3, 执行命令“sudo apt-get install openvswitch-switch qemu-kvm libvirt-bin“后创建的virbr0与MaaS的网段都是192.168.122.0/24会造成两物理机网络不通

[email protected]:/bak/openstack/devstack$ sudo brctl show 
bridge name bridge id STP enabled interfaces
virbr0 8000.525400e658db yes virbr0-nic
[email protected]:/bak/openstack/devstack$ sudo virsh net-destroy default

4, 创建虚机时调度那一块出现ERROR,多半是要将RetryFilter移除。

5, 创建虚机时无法从glance获取镜像报错”,Neutron也报一些“Connection timed out”的错,原因是内网机器下载使用了http_proxy,需要移除代理。

2016-05-20 12:16:24.074 444 ERROR nova.compute.manager [instance: efc19b8b-aeb5-4b49-ba89-4ba6b0696d34] HTTPException:    ERROR: The requested URL could not be retrieved    ERROR The requested URL could not be retrieved     The following error was encountered while trying to retrieve the URL: http://192.168.122.3:9292/v1/images/b868b12f-0bf2-4b04-bead-03f9c5c52bb6   Connection to 192.168.122.3 failed.   The system returned: (110) Connection timed out  The remote host or network may be down. Please try the request again.  Your cache administrator is webmaster.       Generated Fri, 20 May 2016 12:16:24 GMT by shuppet.canonical.com (squid/2.7.STABLE7)    (HTTP N/A)

NeutronClientException: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" CONTENT="text/html; charset=utf-8"> <title>ERROR: The requested URL could not be retrieved</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=ERR_CONNECT_FAIL> <div id="titles"> <h1>ERROR</h1> <h2>The requested URL could not be retrieved</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="http://192.168.122.3:9696/v2.0/extensions.json">http://192.168.122.3:9696/v2.0/extensions.json</a></p>  <blockquote id="error"> <p><b>Connection to 192.168.122.3 failed.</b></p> </blockquote>  <p id="sysmsg">The system returned: <i>(110) Connection timed out</i></p>  <p>The remote host or network may be down. Please try the request again.</p>  <p>Your cache administrator is <a href="mailto:webmaster%W">webmaster</a>.</p>  <br> </div>  <hr> <div id="footer"> <p>Generated Fri, 20 May 2016 12:16:23 GMT by shuppet.canonical.com (squid/2.7.STABLE7)</p> <!-- ERR_CONNECT_FAIL --> </div> </body></html> 
Removing descriptor: 18

6, OVS STT在某些kernel版本上无法创建网卡,此问题还未解决

neutron-server.log
2016-05-20 14:37:17.068 25813 ERROR neutron.plugins.ml2.drivers.openvswitch.agent.ovs_neutron_agent [req-e7932a08-657c-48c9-a797-649e3019375b - -] Failed to set-up stt tunnel port to 192.168.122.3

/var/log/openvswitch/ovs-vswitchd.log
2016-05-20T14:37:16.941Z|00051|dpif|WARN|[email protected]: failed to add stt-c0a87a03 as port: Address family not supported by protocol

Neutron STT ML2 Type Driver Code

diff --git a/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD b/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD
index cf26eb1..6a75db4 100644
--- a/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD
+++ b/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD
@@ -1 +1 @@
-30107ab6a3ee
+3abed5b82c57
diff --git a/neutron/db/migration/alembic_migrations/versions/newton/contract/3abed5b82c57_add_stt_type_driver.py b/neutron/db/migration/alembic_migrations/versions/newton/contract/3abed5b82c57_add_stt_type_driver.py
new file mode 100644
index 0000000..c305f6c
--- /dev/null
+++ b/neutron/db/migration/alembic_migrations/versions/newton/contract/3abed5b82c57_add_stt_type_driver.py
@@ -0,0 +1,49 @@
+# Copyright 2015 OpenStack Foundation
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+#
+
+"""add_stt_type_driver
+
+Revision ID: 3abed5b82c57
+Revises: 30107ab6a3ee
+Create Date: 2016-05-19 12:52:40.546353
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = ‘3abed5b82c57‘
+down_revision = ‘30107ab6a3ee‘
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+    op.create_table(
+        ‘ml2_stt_allocations‘,
+        sa.Column(‘stt_context_id‘, sa.Integer(),
+                  autoincrement=False, nullable=False),
+        sa.Column(‘allocated‘, sa.Boolean(),
+                  server_default=sa.sql.false(), nullable=False),
+        sa.PrimaryKeyConstraint(‘stt_context_id‘),
+    )
+    op.create_index(op.f(‘ix_ml2_stt_allocations_allocated‘),
+                    ‘ml2_stt_allocations‘, [‘allocated‘], unique=False)
+    op.create_table(
+        ‘ml2_stt_endpoints‘,
+        sa.Column(‘ip_address‘, sa.String(length=64), nullable=False),
+        sa.Column(‘host‘, sa.String(length=255), nullable=True),
+        sa.PrimaryKeyConstraint(‘ip_address‘),
+        sa.UniqueConstraint(‘host‘, name=‘unique_ml2_stt_endpoints0host‘),
+    )
diff --git a/neutron/db/migration/models/head.py b/neutron/db/migration/models/head.py
index 6112dbf..2b336ac 100644
--- a/neutron/db/migration/models/head.py
+++ b/neutron/db/migration/models/head.py
@@ -54,6 +54,7 @@ from neutron.ipam.drivers.neutrondb_ipam import db_models  # noqa
 from neutron.plugins.ml2.drivers import type_flat  # noqa
 from neutron.plugins.ml2.drivers import type_geneve  # noqa
 from neutron.plugins.ml2.drivers import type_gre  # noqa
+from neutron.plugins.ml2.drivers import type_stt  # noqa
 from neutron.plugins.ml2.drivers import type_vlan  # noqa
 from neutron.plugins.ml2.drivers import type_vxlan  # noqa
 from neutron.plugins.ml2 import models  # noqa
diff --git a/neutron/plugins/common/constants.py b/neutron/plugins/common/constants.py
index 4b38514..2a6ced1 100644
--- a/neutron/plugins/common/constants.py
+++ b/neutron/plugins/common/constants.py
@@ -69,6 +69,7 @@ TYPE_GENEVE = ‘geneve‘
 TYPE_GRE = ‘gre‘
 TYPE_LOCAL = ‘local‘
 TYPE_VXLAN = ‘vxlan‘
+TYPE_STT = ‘stt‘
 TYPE_VLAN = ‘vlan‘
 TYPE_NONE = ‘none‘

@@ -86,6 +87,10 @@ MAX_GENEVE_VNI = 2 ** 24 - 1
 MIN_GRE_ID = 1
 MAX_GRE_ID = 2 ** 32 - 1

+# For STT Tunnel
+MIN_STT_CONTEXT_ID = 1
+MAX_STT_CONTEXT_ID = 2 ** 64 - 1
+
 # For VXLAN Tunnel
 MIN_VXLAN_VNI = 1
 MAX_VXLAN_VNI = 2 ** 24 - 1
@@ -95,3 +100,6 @@ VXLAN_UDP_PORT = 4789
 GENEVE_ENCAP_MIN_OVERHEAD = 50
 GRE_ENCAP_OVERHEAD = 42
 VXLAN_ENCAP_OVERHEAD = 50
+# NOTE(arosen): STT does not need an ENCAP_OVERHEAD as it‘s TCP based
+# thus L2 fragmentation will not come into play. The packets will be
+# sized to the systems configured MTU.
diff --git a/neutron/plugins/ml2/config.py b/neutron/plugins/ml2/config.py
index 4e2e43d..f85a9f5 100644
--- a/neutron/plugins/ml2/config.py
+++ b/neutron/plugins/ml2/config.py
@@ -19,7 +19,8 @@ from neutron._i18n import _

 ml2_opts = [
     cfg.ListOpt(‘type_drivers‘,
-                default=[‘local‘, ‘flat‘, ‘vlan‘, ‘gre‘, ‘vxlan‘, ‘geneve‘],
+                default=[‘local‘, ‘flat‘, ‘vlan‘, ‘gre‘, ‘vxlan‘, ‘stt‘,
+                         ‘geneve‘],
                 help=_("List of network type driver entrypoints to be loaded "
                        "from the neutron.ml2.type_drivers namespace.")),
     cfg.ListOpt(‘tenant_network_types‘,
diff --git a/neutron/plugins/ml2/drivers/openvswitch/agent/common/constants.py b/neutron/plugins/ml2/drivers/openvswitch/agent/common/constants.py
index 96903d3..b996f39 100644
--- a/neutron/plugins/ml2/drivers/openvswitch/agent/common/constants.py
+++ b/neutron/plugins/ml2/drivers/openvswitch/agent/common/constants.py
@@ -33,7 +33,7 @@ NONEXISTENT_PEER = ‘nonexistent-peer‘

 # The different types of tunnels
 TUNNEL_NETWORK_TYPES = [p_const.TYPE_GRE, p_const.TYPE_VXLAN,
-                        p_const.TYPE_GENEVE]
+                        p_const.TYPE_GENEVE, p_const.TYPE_STT]

 ### OpenFlow table IDs

@@ -75,6 +75,7 @@ DVR_PROCESS = 1
 PATCH_LV_TO_TUN = 2
 GRE_TUN_TO_LV = 3
 VXLAN_TUN_TO_LV = 4
+STT_TUN_TO_LV = 5
 GENEVE_TUN_TO_LV = 6

 DVR_NOT_LEARN = 9
@@ -98,7 +99,8 @@ ARP_REPLY = ‘0x2‘
 # Map tunnel types to tables number
 TUN_TABLE = {p_const.TYPE_GRE: GRE_TUN_TO_LV,
              p_const.TYPE_VXLAN: VXLAN_TUN_TO_LV,
-             p_const.TYPE_GENEVE: GENEVE_TUN_TO_LV}
+             p_const.TYPE_GENEVE: GENEVE_TUN_TO_LV,
+             p_const.TYPE_STT: STT_TUN_TO_LV}

 # The default respawn interval for the ovsdb monitor
diff --git a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py
index 93fbc19..41d4976 100644
--- a/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py
+++ b/neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py
@@ -367,6 +367,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
     def _reset_tunnel_ofports(self):
         self.tun_br_ofports = {p_const.TYPE_GENEVE: {},
                                p_const.TYPE_GRE: {},
+                               p_const.TYPE_STT: {},
                                p_const.TYPE_VXLAN: {}}

     def setup_rpc(self):
@@ -629,7 +630,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,

         :param net_uuid: the uuid of the network associated with this vlan.
         :param network_type: the network type (‘gre‘, ‘vxlan‘, ‘vlan‘, ‘flat‘,
-                                               ‘local‘, ‘geneve‘)
+                                               ‘local‘, ‘stt‘, ‘geneve‘)
         :param physical_network: the physical network for ‘vlan‘ or ‘flat‘
         :param segmentation_id: the VID for ‘vlan‘ or tunnel ID for ‘tunnel‘
         ‘‘‘
@@ -2110,7 +2111,7 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
         if (self.enable_distributed_routing and self.enable_tunneling
             and not self.l2_pop):

-            raise ValueError(_("DVR deployments for VXLAN/GRE/Geneve "
+            raise ValueError(_("DVR deployments for VXLAN/GRE/STT/Geneve "
                                "underlays require L2-pop to be enabled, "
                                "in both the Agent and Server side."))

diff --git a/neutron/plugins/ml2/drivers/type_stt.py b/neutron/plugins/ml2/drivers/type_stt.py
new file mode 100644
index 0000000..27b8e9a
--- /dev/null
+++ b/neutron/plugins/ml2/drivers/type_stt.py
@@ -0,0 +1,142 @@
+# Copyright (c) 2015 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from oslo_config import cfg
+from oslo_log import log
+from six import moves
+import sqlalchemy as sa
+from sqlalchemy import sql
+
+from neutron.common import exceptions as n_exc
+from neutron.db import api as db_api
+from neutron.db import model_base
+from neutron.i18n import _LE
+from neutron.plugins.common import constants as p_const
+from neutron.plugins.ml2.drivers import type_tunnel
+
+LOG = log.getLogger(__name__)
+
+stt_opts = [
+    cfg.ListOpt(‘context_id_ranges‘,
+                default=[‘1000:3000‘],
+                help=_("Comma-separated list of "
+                       "<context_id_min>:<context_id_max> tuples "
+                       "enumerating ranges of STT Context IDs that are "
+                       "available for tenant network allocation"))
+]
+
+cfg.CONF.register_opts(stt_opts, "ml2_type_stt")
+
+
+class SttAllocation(model_base.BASEV2):
+
+    __tablename__ = ‘ml2_stt_allocations‘
+
+    stt_context_id = sa.Column(sa.Integer, nullable=False, primary_key=True,
+                               autoincrement=False)
+    allocated = sa.Column(sa.Boolean, nullable=False, default=False,
+                          server_default=sql.false(), index=True)
+
+
+class SttEndpoints(model_base.BASEV2):
+    """Represents tunnel endpoint in RPC mode."""
+
+    __tablename__ = ‘ml2_stt_endpoints‘
+    __table_args__ = (
+        sa.UniqueConstraint(‘host‘,
+                            name=‘unique_ml2_stt_endpoints0host‘),
+        model_base.BASEV2.__table_args__
+    )
+    ip_address = sa.Column(sa.String(64), primary_key=True)
+    host = sa.Column(sa.String(255), nullable=True)
+
+    def __repr__(self):
+        return "<SttTunnelEndpoint(%s)>" % self.ip_address
+
+
+class SttTypeDriver(type_tunnel.EndpointTunnelTypeDriver):
+
+    def __init__(self):
+        super(SttTypeDriver, self).__init__(SttAllocation,
+                                            SttEndpoints)
+
+    def get_type(self):
+        return p_const.TYPE_STT
+
+    def initialize(self):
+        try:
+            self._initialize(cfg.CONF.ml2_type_stt.context_id_ranges)
+        except n_exc.NetworkTunnelRangeError:
+            LOG.exception(_LE("Failed to parse context_id_ranges. "
+                              "Service terminated!"))
+            raise SystemExit()
+
+    def sync_allocations(self):
+        # FIXME(arosen) - refactor out duplicate code from type_vxlan driver.
+
+        # determine current configured allocatable context_ids
+        stt_context_ids = set()
+        for tun_min, tun_max in self.tunnel_ranges:
+            if tun_max + 1 - tun_min > p_const.MAX_STT_CONTEXT_ID:
+                LOG.error(_LE("Skipping unreasonable STT VNI range "
+                              "%(tun_min)s:%(tun_max)s"),
+                          {‘tun_min‘: tun_min, ‘tun_max‘: tun_max})
+            else:
+                stt_context_ids |= set(moves.range(tun_min, tun_max + 1))
+
+        session = db_api.get_session()
+        with session.begin(subtransactions=True):
+            # remove from table unallocated tunnels not currently allocatable
+            # fetch results as list via all() because we‘ll be iterating
+            # through them twice
+            allocs = (session.query(SttAllocation).
+                      with_lockmode("update").all())
+            # collect all context_ids present in db
+            existing_context_ids = set(alloc.stt_context_id
+                                       for alloc in allocs)
+            # collect those context_ids that needs to be deleted from db
+            context_ids_to_remove = [
+                alloc.stt_context_id for alloc in allocs
+                if (alloc.stt_context_id not in stt_context_ids and
+                    not alloc.allocated)]
+            # Immediately delete context_ids in chunks. This leaves no work for
+            # flush at the end of transaction
+            bulk_size = 100
+            chunked_context_ids = (
+                context_ids_to_remove[i:i + bulk_size]
+                for i in range(0, len(context_ids_to_remove), bulk_size))
+            for context_id_list in chunked_context_ids:
+                if context_id_list:
+                    session.query(SttAllocation).filter(
+                        SttAllocation.stt_context_id.in_(context_id_list)).delete(
+                            synchronize_session=False)
+            # collect context_ids that need to be added
+            context_ids = list(stt_context_ids - existing_context_ids)
+            chunked_context_ids = (context_ids[i:i + bulk_size] for i in
+                            range(0, len(context_ids), bulk_size))
+            for context_id_list in chunked_context_ids:
+                bulk = [{‘stt_context_id‘: context_id, ‘allocated‘: False}
+                        for context_id in context_id_list]
+                session.execute(SttAllocation.__table__.insert(), bulk)
+
+    def get_endpoints(self):
+        """Get every stt endpoints from database."""
+        stt_endpoints = self._get_endpoints()
+        return [{‘ip_address‘: stt_endpoint.ip_address,
+                 ‘host‘: stt_endpoint.host}
+                for stt_endpoint in stt_endpoints]
+
+    def add_endpoint(self, ip, host):
+        return self._add_endpoint(ip, host)
diff --git a/setup.cfg b/setup.cfg
index 5479a7c..7098b9d 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -91,6 +91,7 @@ neutron.ml2.type_drivers =
     geneve = neutron.plugins.ml2.drivers.type_geneve:GeneveTypeDriver
     gre = neutron.plugins.ml2.drivers.type_gre:GreTypeDriver
     vxlan = neutron.plugins.ml2.drivers.type_vxlan:VxlanTypeDriver
+    stt = neutron.plugins.ml2.drivers.type_stt:SttTypeDriver
 neutron.ml2.mechanism_drivers =
     logger = neutron.tests.unit.plugins.ml2.drivers.mechanism_logger:LoggerMechanismDriver
     test = neutron.tests.unit.plugins.ml2.drivers.mechanism_test:TestMechanismDriver
时间: 2024-10-16 21:54:28

如何实现OpenStack STT隧道(by quqi99)的相关文章

关于OpenStack的学习路线及相关资源汇总

首先我们想学习openstack,那么openstack是什么?能干什么?涉及的初衷是什么?由什么来组成?刚接触openstack,说openstack不是一个软件,而是由多个组件进行组合,这是一个更深层次的理解,当我们看到dashboard的时候,我们或许对openstack感觉有一点感性认识了.dashboard可以理解为openstack与用户交流的一个窗口,而dashboard对于真正的使用者来讲,它的功能上面有一定的局限性.而对于初学者通过它,可能会对openstack有一定的了解.o

[转] OpenStack IPSec VPNaaS

OpenStack IPSec VPNaaS ( by quqi99 ) 作者:张华  发表于:2013-08-03版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 http://blog.csdn.net/quqi99 ) 今天想review一下社区IPSec VNPaaS Driver的代码,所以系统看了一下这背后的知识.笔记如下: 什么是VPN VPN可以通过在L2或L3层建立一条逻辑链路让广域网上多个内网能够相互访问(我的理解,VPN除了让广域网的内

docker容器网络通信原理分析

概述 自从docker容器出现以来,容器的网络通信就一直是大家关注的焦点,也是生产环境的迫切需求.而容器的网络通信又可以分为两大方面:单主机容器上的相互通信和跨主机的容器相互通信.而本文将分别针对这两方面,对容器的通信原理进行简单的分析,帮助大家更好地使用docker. docker单主机容器通信 基于对net namespace的控制,docker可以为在容器创建隔离的网络环境,在隔离的网络环境下,容器具有完全独立的网络栈,与宿主机隔离,也可以使容器共享主机或者其他容器的网络命名空间,基本可以

Docker容器学习梳理--容器间网络通信设置(Pipework和Open vSwitch)

自从Docker容器出现以来,容器的网络通信就一直是被关注的焦点,也是生产环境的迫切需求.容器的网络通信又可以分为两大方面:单主机容器上的相互通信,和跨主机的容器相互通信.下面将分别针对这两方面,对容器的通信原理进行简单的分析,帮助大家更好地使用docker.前面已经在Docker容器学习梳理--基础知识(2)这一篇中详细介绍了Docker的网络配置以及pipework工具. docker单主机容器通信 基于对net namespace的控制,docker可以为在容器创建隔离的网络环境,在隔离的

一篇文章为你图解Kubernetes网络通信原理

本文来自51cto因出现文章被删除提示,为避免丢失将其复制备查 Kubernetes对集群内部的网络进行了重新抽象,以实现整个集群网络扁平化.我们可以理解网络模型时,可以完全抽离物理节点去理解,我们用图说话,先有基本印象. 名词解释 1.网络的命名空间:Linux在网络栈中引入网络命名空间,将独立的网络协议栈隔离到不同的命令空间中,彼此间无法通信;docker利用这一特性,实现不容器间的网络隔离. 2.Veth设备对:也叫虚拟网络接口对.Veth设备对的引入是为了实现在不同网络命名空间的通信.

调试OpenStack时遇到的主要问题(by quqi99)

作者:张华  发表于:2014-11-09版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 ( http://blog.csdn.net/quqi99 ) 今天想debug一下nova-compute进程, 用devstack迅速安装之后, kill掉nova-compute进程,然后修改nova/cmd/__init__.py文件的“eventlet.monkey_patch(os=False)”为“eventlet.monkey_patch(all=Fa

玩转OpenStack网络Neutron(4)--网络隧道技术 VXALN &amp; GRE

欢迎转载,转载请保留原作者信息 欢迎交流学习,共同进步! 作者:颜海峰 个人博客:http://yanheven.github.io 微博:海峰_云计算 http://weibo.com/344736086 网络隧道技术介绍 计算节点配置 Open vSwitch 使用 VXLAN 网络 网络节点配置 Open vSwitch 使用 VXLAN 网络 配置 Neutron 使用 VXLAN Type Driver 配置 VXLAN 编号范围 查看 Neutron 网络的 VNI 指定 VNI 创

openstack使用openvswitch实现vxlan组网

 openstack使用openvswitch实现vxlan openstack环境: 1 版本:ocata 2 系统:ubuntu16.04.2 3 控制节点 1个 + 计算节点 1个 4 控制节点网卡为ens33,ip = 172.171.5.200 ens34 manual模式 无IP 一 下载openswitch controller : apt-get install  neutron-openvswitch-agent compute : apt-get install neutro

Debian Customer PPA RFC (by quqi99)

作者:张华  发表于:2016-01-13版权声明:能够随意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 ( http://blog.csdn.net/quqi99 ) Precondition a, sudo apt install gnupg pbuilder ubuntu-dev-tools bzr-builddeb apt-file debhelper dh-systemd openstack-pkg-tools b, GPG keyscp -r /home/hu