# Neutron Modular Layer 2 plugin
# ------------------------------

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

# Enable this to simply and quickly enable tunneling with ML2.
# Select either 'gre', 'vxlan', or '(gre vxlan)'
Q_ML2_TENANT_NETWORK_TYPE=${Q_ML2_TENANT_NETWORK_TYPE:-"vxlan"}
# This has to be set here since the agent will set this in the config file
if [[ "$Q_ML2_TENANT_NETWORK_TYPE" != "local" ]]; then
    Q_AGENT_EXTRA_AGENT_OPTS+=(tunnel_types=$Q_ML2_TENANT_NETWORK_TYPE)
elif [[ "$ENABLE_TENANT_TUNNELS" == "True" ]]; then
    Q_AGENT_EXTRA_AGENT_OPTS+=(tunnel_types=gre)
fi

# Default openvswitch L2 agent
Q_AGENT=${Q_AGENT:-openvswitch}
source $TOP_DIR/lib/neutron_plugins/${Q_AGENT}_agent

# List of MechanismDrivers to load
Q_ML2_PLUGIN_MECHANISM_DRIVERS=${Q_ML2_PLUGIN_MECHANISM_DRIVERS:-openvswitch,linuxbridge}
# List of Type Drivers to load
Q_ML2_PLUGIN_TYPE_DRIVERS=${Q_ML2_PLUGIN_TYPE_DRIVERS:-local,flat,vlan,gre,vxlan}
# Default GRE TypeDriver options
Q_ML2_PLUGIN_GRE_TYPE_OPTIONS=${Q_ML2_PLUGIN_GRE_TYPE_OPTIONS:-tunnel_id_ranges=$TENANT_TUNNEL_RANGES}
# Default VXLAN TypeDriver options
Q_ML2_PLUGIN_VXLAN_TYPE_OPTIONS=${Q_ML2_PLUGIN_VXLAN_TYPE_OPTIONS:-vni_ranges=1001:2000}
# Default VLAN TypeDriver options
Q_ML2_PLUGIN_VLAN_TYPE_OPTIONS=${Q_ML2_PLUGIN_VLAN_TYPE_OPTIONS:-}

# L3 Plugin to load for ML2
ML2_L3_PLUGIN=${ML2_L3_PLUGIN:-neutron.services.l3_router.l3_router_plugin.L3RouterPlugin}

function populate_ml2_config {
    CONF=$1
    SECTION=$2
    OPTS=$3

    if [ -z "$OPTS" ]; then
        return
    fi
    for I in "${OPTS[@]}"; do
        # Replace the first '=' with ' ' for iniset syntax
        iniset $CONF $SECTION ${I/=/ }
    done
}

function neutron_plugin_configure_common {
    Q_PLUGIN_CONF_PATH=etc/neutron/plugins/ml2
    Q_PLUGIN_CONF_FILENAME=ml2_conf.ini
    Q_PLUGIN_CLASS="neutron.plugins.ml2.plugin.Ml2Plugin"
    # The ML2 plugin delegates L3 routing/NAT functionality to
    # the L3 service plugin which must therefore be specified.
    _neutron_service_plugin_class_add $ML2_L3_PLUGIN
}

function neutron_plugin_configure_service {
    if [[ "$Q_ML2_TENANT_NETWORK_TYPE" != "local" ]]; then
        Q_SRV_EXTRA_OPTS+=(tenant_network_types=$Q_ML2_TENANT_NETWORK_TYPE)
    elif [[ "$ENABLE_TENANT_TUNNELS" == "True" ]]; then
        # This assumes you want a simple configuration, and will overwrite
        # Q_SRV_EXTRA_OPTS if set in addition to ENABLE_TENANT_TUNNELS.
        Q_SRV_EXTRA_OPTS+=(tenant_network_types=gre)
        Q_ML2_PLUGIN_GRE_TYPE_OPTIONS=(tunnel_id_ranges=$TENANT_TUNNEL_RANGES)
    elif [[ "$ENABLE_TENANT_VLANS" == "True" ]]; then
        Q_SRV_EXTRA_OPTS+=(tenant_network_types=vlan)
    else
        echo "WARNING - The ml2 plugin is using local tenant networks, with no connectivity between hosts."
    fi

    # Allow for overrding VLAN configuration (for example, to configure provider
    # VLANs) by first checking if Q_ML2_PLUGIN_VLAN_TYPE_OPTIONS is set.
    if [ "$Q_ML2_PLUGIN_VLAN_TYPE_OPTIONS" == "" ]; then
        if [[ "$ML2_VLAN_RANGES" == "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]]; then
            ML2_VLAN_RANGES=$PHYSICAL_NETWORK
            if [[ "$TENANT_VLAN_RANGE" != "" ]]; then
                ML2_VLAN_RANGES=$ML2_VLAN_RANGES:$TENANT_VLAN_RANGE
            fi
        fi
        if [[ "$ML2_VLAN_RANGES" != "" ]]; then
            Q_ML2_PLUGIN_VLAN_TYPE_OPTIONS=(network_vlan_ranges=$ML2_VLAN_RANGES)
        fi
    fi

    # REVISIT(rkukura): Setting firewall_driver here for
    # neutron.agent.securitygroups_rpc.is_firewall_enabled() which is
    # used in the server, in case no L2 agent is configured on the
    # server's node. If an L2 agent is configured, this will get
    # overridden with the correct driver. The ml2 plugin should
    # instead use its own config variable to indicate whether security
    # groups is enabled, and that will need to be set here instead.
    if [[ "$Q_USE_SECGROUP" == "True" ]]; then
        iniset /$Q_PLUGIN_CONF_FILE securitygroup firewall_driver neutron.agent.not.a.real.FirewallDriver
    else
        iniset /$Q_PLUGIN_CONF_FILE securitygroup firewall_driver neutron.agent.firewall.NoopFirewallDriver
    fi

    # Since we enable the tunnel TypeDrivers, also enable a local_ip
    iniset /$Q_PLUGIN_CONF_FILE ovs local_ip $TUNNEL_ENDPOINT_IP

    populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2 mechanism_drivers=$Q_ML2_PLUGIN_MECHANISM_DRIVERS

    populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2 type_drivers=$Q_ML2_PLUGIN_TYPE_DRIVERS

    populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2 $Q_SRV_EXTRA_OPTS

    populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_type_gre $Q_ML2_PLUGIN_GRE_TYPE_OPTIONS

    populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_type_vxlan $Q_ML2_PLUGIN_VXLAN_TYPE_OPTIONS

    populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_type_vlan $Q_ML2_PLUGIN_VLAN_TYPE_OPTIONS

    if [[ "$Q_DVR_MODE" != "legacy" ]]; then
        populate_ml2_config /$Q_PLUGIN_CONF_FILE agent l2_population=True
        populate_ml2_config /$Q_PLUGIN_CONF_FILE agent tunnel_types=vxlan
        populate_ml2_config /$Q_PLUGIN_CONF_FILE agent enable_distributed_routing=True
    fi
}

function has_neutron_plugin_security_group {
    return 0
}

# Restore xtrace
$ML2_XTRACE
