Adding support for OVS Hybrid binding
Allows the OVS binding script to recognize if it has to do hybrid binding or not and operate accordingly. Closes-Bug: #1535828 Change-Id: I7c7d7b115b546c136a07880bc568662558dbc950
This commit is contained in:
parent
b822c22c8f
commit
cc05a7b903
@ -19,9 +19,11 @@ import pyroute2
|
||||
|
||||
from kuryr.common import config
|
||||
from kuryr.common import exceptions
|
||||
from kuryr import utils
|
||||
|
||||
|
||||
CONTAINER_VETH_POSTFIX = '_c'
|
||||
VETH_PREFIX = 'tap'
|
||||
CONTAINER_VETH_PREFIX = 't_c'
|
||||
BINDING_SUBCOMMAND = 'bind'
|
||||
DOWN = 'DOWN'
|
||||
FALLBACK_VIF_TYPE = 'unbound'
|
||||
@ -32,8 +34,8 @@ KIND_VETH = 'veth'
|
||||
MAC_ADDRESS_KEY = 'mac_address'
|
||||
SUBNET_ID_KEY = 'subnet_id'
|
||||
UNBINDING_SUBCOMMAND = 'unbind'
|
||||
VETH_POSTFIX = '-veth'
|
||||
VIF_TYPE_KEY = 'binding:vif_type'
|
||||
VIF_DETAILS_KEY = 'binding:vif_details'
|
||||
|
||||
_IPDB_CACHE = None
|
||||
_IPROUTE_CACHE = None
|
||||
@ -113,8 +115,8 @@ def port_bind(endpoint_id, neutron_port, neutron_subnets):
|
||||
"""
|
||||
ip = get_ipdb()
|
||||
|
||||
ifname = endpoint_id[:8] + VETH_POSTFIX
|
||||
peer_name = ifname + CONTAINER_VETH_POSTFIX
|
||||
ifname = VETH_PREFIX + endpoint_id[:8]
|
||||
peer_name = CONTAINER_VETH_PREFIX + ifname
|
||||
subnets_dict = {subnet['id']: subnet for subnet in neutron_subnets}
|
||||
|
||||
try:
|
||||
@ -143,6 +145,7 @@ def port_bind(endpoint_id, neutron_port, neutron_subnets):
|
||||
'Could not configure the veth endpoint for the container.')
|
||||
|
||||
vif_type = neutron_port.get(VIF_TYPE_KEY, FALLBACK_VIF_TYPE)
|
||||
vif_details = utils.string_mappings(neutron_port.get(VIF_DETAILS_KEY))
|
||||
binding_exec_path = os.path.join(config.CONF.bindir, vif_type)
|
||||
port_id = neutron_port['id']
|
||||
network_id = neutron_port['network_id']
|
||||
@ -151,7 +154,7 @@ def port_bind(endpoint_id, neutron_port, neutron_subnets):
|
||||
try:
|
||||
stdout, stderr = processutils.execute(
|
||||
binding_exec_path, BINDING_SUBCOMMAND, port_id, ifname,
|
||||
endpoint_id, mac_address, network_id, tenant_id,
|
||||
endpoint_id, mac_address, network_id, tenant_id, vif_details,
|
||||
run_as_root=True)
|
||||
except processutils.ProcessExecutionError:
|
||||
with excutils.save_and_reraise_exception():
|
||||
@ -171,13 +174,14 @@ def port_unbind(endpoint_id, neutron_port):
|
||||
"""
|
||||
|
||||
vif_type = neutron_port.get(VIF_TYPE_KEY, FALLBACK_VIF_TYPE)
|
||||
vif_details = utils.string_mappings(neutron_port.get(VIF_DETAILS_KEY))
|
||||
unbinding_exec_path = os.path.join(config.CONF.bindir, vif_type)
|
||||
ifname = endpoint_id[:8] + VETH_POSTFIX
|
||||
ifname = VETH_PREFIX + endpoint_id[:8]
|
||||
port_id = neutron_port['id']
|
||||
mac_address = neutron_port['mac_address']
|
||||
stdout, stderr = processutils.execute(
|
||||
unbinding_exec_path, UNBINDING_SUBCOMMAND, port_id, ifname,
|
||||
endpoint_id, mac_address, run_as_root=True)
|
||||
endpoint_id, mac_address, vif_details, run_as_root=True)
|
||||
try:
|
||||
cleanup_veth(ifname)
|
||||
except pyroute2.netlink.NetlinkError:
|
||||
|
@ -47,7 +47,7 @@ class TestKuryrJoinFailures(base.TestKuryrFailures):
|
||||
fake_ifname = 'fake-veth'
|
||||
fake_binding_response = (
|
||||
fake_ifname,
|
||||
fake_ifname + binding.CONTAINER_VETH_POSTFIX,
|
||||
binding.CONTAINER_VETH_PREFIX + fake_ifname,
|
||||
('fake stdout', '')
|
||||
)
|
||||
self.mox.StubOutWithMock(binding, 'port_bind')
|
||||
|
@ -167,3 +167,11 @@ def make_net_name(netid, tags=True):
|
||||
if tags:
|
||||
return const.NET_NAME_PREFIX + netid[:8]
|
||||
return netid
|
||||
|
||||
|
||||
def string_mappings(mapping_list):
|
||||
"""Make a string out of the mapping list"""
|
||||
details = ''
|
||||
if mapping_list:
|
||||
details = '"' + str(mapping_list) + '"'
|
||||
return details
|
||||
|
@ -12,42 +12,98 @@
|
||||
# under the License.
|
||||
|
||||
INT_BRIDGE="br-int"
|
||||
HYBRID_PLUG="'ovs_hybrid_plug': True"
|
||||
|
||||
OPERATION=$1
|
||||
PORT=$2
|
||||
VETH=$3
|
||||
CONTAINER_UUID=$4
|
||||
MAC_ADDRESS=$5
|
||||
|
||||
|
||||
bind_port() {
|
||||
ovs_bind_port() {
|
||||
echo "plugging veth $VETH (Neutron port $PORT)..."
|
||||
sudo ovs-vsctl -- --may-exist add-port $INT_BRIDGE $VETH -- \
|
||||
ovs-vsctl -- --may-exist add-port $INT_BRIDGE $VETH -- \
|
||||
set interface $VETH external_ids:attached-mac=$MAC_ADDRESS \
|
||||
external_ids:iface-id=$PORT external_ids:vm-uuid=$CONTAINER_UUID \
|
||||
external_ids:iface-status=active external_ids:owner=kuryr
|
||||
}
|
||||
|
||||
unbind_port() {
|
||||
echo "unplugging veth $PORT..."
|
||||
PORT=`sudo ovs-vsctl --data=bare --no-heading --columns=name \
|
||||
find interface external_ids:iface-id=$PORT \
|
||||
external_ids:owner=kuryr`
|
||||
if [ -z "$PORT" ]; then
|
||||
ovs_unbind_port() {
|
||||
echo "unplugging port $PORT..."
|
||||
MYPORT=`ovs-vsctl --data=bare --no-heading --columns=name \
|
||||
find interface external_ids:iface-id=$PORT \
|
||||
external_ids:owner=kuryr`
|
||||
if [ -z "$MYPORT" ]; then
|
||||
echo >&2 "Failed to find port $PORT."
|
||||
exit 1
|
||||
fi
|
||||
sudo ovs-vsctl del-port $INT_BRIDGE $PORT
|
||||
ovs-vsctl del-port $INT_BRIDGE $MYPORT
|
||||
}
|
||||
|
||||
ovs_hybrid_bind_port() {
|
||||
echo "... plugging veth $VETH (Neutron port $PORT) ..."
|
||||
# create a linux bridge
|
||||
br_name="qbr"${PORT:0:11}
|
||||
ip link add name $br_name type bridge
|
||||
echo 0 > /sys/devices/virtual/net/$br_name/bridge/forward_delay
|
||||
echo 0 > /sys/devices/virtual/net/$br_name/bridge/stp_state
|
||||
|
||||
# connect the veth outside to linux bridge
|
||||
ip link set $VETH up
|
||||
ip link set dev $VETH master $br_name
|
||||
# create a veth pair to connect linux bridge and the integration bridge
|
||||
veth_lb="qvb"${PORT:0:11}
|
||||
veth_ovs="qvo"${PORT:0:11}
|
||||
ip link add $veth_lb type veth peer name $veth_ovs
|
||||
|
||||
# connect one end to the linux bridge
|
||||
ip link set dev $veth_lb master $br_name
|
||||
ip link set $br_name up
|
||||
|
||||
# connect one end to the ovs integration bridge
|
||||
ovs-vsctl add-port $INT_BRIDGE $veth_ovs -- \
|
||||
set interface $veth_ovs external_ids:attached-mac=$MAC_ADDRESS \
|
||||
external_ids:iface-id=$PORT external_ids:vm-id=$CONTAINER_UUID \
|
||||
external_ids:iface-status=active external_ids:owner=kuryr
|
||||
|
||||
ip link set $veth_lb up
|
||||
ip link set $veth_ovs up
|
||||
}
|
||||
|
||||
ovs_hybrid_unbind_port() {
|
||||
echo "unplugging port $PORT ..."
|
||||
br_name="qbr"${PORT:0:11}
|
||||
veth_lb="qvb"${PORT:0:11}
|
||||
veth_ovs="qvo"${PORT:0:11}
|
||||
|
||||
ip link set dev $veth_lb nomaster
|
||||
ovs-vsctl del-port $veth_ovs
|
||||
ip link delete $veth_lb type veth
|
||||
|
||||
ip link set $br_name down
|
||||
ip link delete $br_name type bridge
|
||||
}
|
||||
|
||||
|
||||
case $OPERATION in
|
||||
"bind")
|
||||
shift
|
||||
bind_port
|
||||
if [ "${7/$HYBRID_PLUG}" = "$7" ]
|
||||
then
|
||||
ovs_bind_port
|
||||
else
|
||||
ovs_hybrid_bind_port
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
"unbind")
|
||||
shift
|
||||
unbind_port
|
||||
if [ "${5/$HYBRID_PLUG}" = "$5" ]
|
||||
then
|
||||
ovs_unbind_port
|
||||
else
|
||||
ovs_hybrid_unbind_port
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
|
Loading…
Reference in New Issue
Block a user