# Quantum Open vSwtich plugin
# ---------------------------

# Save trace setting
XTRACE=$(set +o | grep xtrace)
set +o xtrace

source $TOP_DIR/lib/quantum_plugins/ovs_base

function quantum_plugin_create_nova_conf() {
    NOVA_VIF_DRIVER=${NOVA_VIF_DRIVER:-"nova.virt.libvirt.vif.LibvirtHybridOVSBridgeDriver"}
    if [ "$VIRT_DRIVER" = 'xenserver' ]; then
        iniset $NOVA_CONF DEFAULT xenapi_vif_driver nova.virt.xenapi.vif.XenAPIOpenVswitchDriver
        iniset $NOVA_CONF DEFAULT xenapi_ovs_integration_bridge $FLAT_NETWORK_BRIDGE
    fi
}

function quantum_plugin_install_agent_packages() {
    _quantum_ovs_base_install_agent_packages
}

function quantum_plugin_configure_common() {
    Q_PLUGIN_CONF_PATH=etc/quantum/plugins/openvswitch
    Q_PLUGIN_CONF_FILENAME=ovs_quantum_plugin.ini
    Q_DB_NAME="ovs_quantum"
    Q_PLUGIN_CLASS="quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2"
}

function quantum_plugin_configure_debug_command() {
    _quantum_ovs_base_configure_debug_command
}

function quantum_plugin_configure_dhcp_agent() {
    :
}

function quantum_plugin_configure_l3_agent() {
    _quantum_ovs_base_configure_l3_agent
}

function quantum_plugin_configure_plugin_agent() {
    # Setup integration bridge
    OVS_BRIDGE=${OVS_BRIDGE:-br-int}
    _quantum_ovs_base_setup_bridge $OVS_BRIDGE

    # Setup agent for tunneling
    if [[ "$OVS_ENABLE_TUNNELING" = "True" ]]; then
        # Verify tunnels are supported
        # REVISIT - also check kernel module support for GRE and patch ports
        OVS_VERSION=`ovs-vsctl --version | head -n 1 | awk '{print $4;}'`
        if [ $OVS_VERSION \< "1.4" ] && ! is_service_enabled q-svc ; then
            echo "You are running OVS version $OVS_VERSION."
            echo "OVS 1.4+ is required for tunneling between multiple hosts."
            exit 1
        fi
        iniset /$Q_PLUGIN_CONF_FILE OVS enable_tunneling True
        iniset /$Q_PLUGIN_CONF_FILE OVS local_ip $HOST_IP
    fi

    # Setup physical network bridge mappings.  Override
    # ``OVS_VLAN_RANGES`` and ``OVS_BRIDGE_MAPPINGS`` in ``localrc`` for more
    # complex physical network configurations.
    if [[ "$OVS_BRIDGE_MAPPINGS" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$OVS_PHYSICAL_BRIDGE" != "" ]]; then
        OVS_BRIDGE_MAPPINGS=$PHYSICAL_NETWORK:$OVS_PHYSICAL_BRIDGE

        # Configure bridge manually with physical interface as port for multi-node
        sudo ovs-vsctl --no-wait -- --may-exist add-br $OVS_PHYSICAL_BRIDGE
    fi
    if [[ "$OVS_BRIDGE_MAPPINGS" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE OVS bridge_mappings $OVS_BRIDGE_MAPPINGS
    fi
    AGENT_BINARY="$QUANTUM_DIR/bin/quantum-openvswitch-agent"

    if [ "$VIRT_DRIVER" = 'xenserver' ]; then
        # Nova will always be installed along with quantum for a domU
        # devstack install, so it should be safe to rely on nova.conf
        # for xenapi configuration.
        Q_RR_DOM0_COMMAND="$QUANTUM_DIR/bin/quantum-rootwrap-dom0 $NOVA_CONF"
        # Under XS/XCP, the ovs agent needs to target the dom0
        # integration bridge.  This is enabled by using a root wrapper
        # that executes commands on dom0 via a XenAPI plugin.
        iniset /$Q_PLUGIN_CONF_FILE AGENT root_helper "$Q_RR_DOM0_COMMAND"

        # FLAT_NETWORK_BRIDGE is the dom0 integration bridge.  To
        # ensure the bridge lacks direct connectivity, set
        # VM_VLAN=-1;VM_DEV=invalid in localrc
        iniset /$Q_PLUGIN_CONF_FILE OVS integration_bridge $FLAT_NETWORK_BRIDGE

        # The ovs agent needs to ensure that the ports associated with
        # a given network share the same local vlan tag.  On
        # single-node XS/XCP, this requires monitoring both the dom0
        # bridge, where VM's are attached, and the domU bridge, where
        # dhcp servers are attached.
        if is_service_enabled q-dhcp; then
            iniset /$Q_PLUGIN_CONF_FILE OVS domu_integration_bridge $OVS_BRIDGE
            # DomU will use the regular rootwrap
            iniset /$Q_PLUGIN_CONF_FILE AGENT domu_root_helper "$Q_RR_COMMAND"
            # Plug the vm interface into the domU integration bridge.
            sudo ip addr flush dev $GUEST_INTERFACE_DEFAULT
            sudo ip link set $OVS_BRIDGE up
            # Assign the VM IP only if it has been set explicitly
            if [[ "$VM_IP" != "" ]]; then
                sudo ip addr add $VM_IP dev $OVS_BRIDGE
            fi
            sudo ovs-vsctl add-port $OVS_BRIDGE $GUEST_INTERFACE_DEFAULT
        fi
    fi
}

function quantum_plugin_configure_service() {
    if [[ "$ENABLE_TENANT_TUNNELS" = "True" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE OVS tenant_network_type gre
        iniset /$Q_PLUGIN_CONF_FILE OVS tunnel_id_ranges $TENANT_TUNNEL_RANGES
    elif [[ "$ENABLE_TENANT_VLANS" = "True" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE OVS tenant_network_type vlan
    else
        echo "WARNING - The openvswitch plugin is using local tenant networks, with no connectivity between hosts."
    fi

    # Override ``OVS_VLAN_RANGES`` and ``OVS_BRIDGE_MAPPINGS`` in ``localrc``
    # for more complex physical network configurations.
    if [[ "$OVS_VLAN_RANGES" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]]; then
        OVS_VLAN_RANGES=$PHYSICAL_NETWORK
        if [[ "$TENANT_VLAN_RANGE" != "" ]]; then
            OVS_VLAN_RANGES=$OVS_VLAN_RANGES:$TENANT_VLAN_RANGE
        fi
    fi
    if [[ "$OVS_VLAN_RANGES" != "" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE OVS network_vlan_ranges $OVS_VLAN_RANGES
    fi

    # Enable tunnel networks if selected
    if [[ $OVS_ENABLE_TUNNELING = "True" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE OVS enable_tunneling True
    fi
}

function quantum_plugin_setup_interface_driver() {
    local conf_file=$1
    iniset $conf_file DEFAULT interface_driver quantum.agent.linux.interface.OVSInterfaceDriver
}

# Restore xtrace
$XTRACE
