#!/usr/bin/env bash

# -------------------------------------------------------------------------- #
# Copyright 2002-2020, OpenNebula Project, OpenNebula Systems                #
#                                                                            #
# 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.                                             #
#--------------------------------------------------------------------------- #

get_iface_var()
{
    var_name="${UPCASE_DEV}_$1"
    var=$(eval "echo \"\${$var_name}\"")

    echo $var
}

get_pci_interfaces()
{
    env | grep -E "^PCI[0-9]+_MAC=" | sed 's/_.*$//' | sort
}

get_dev_from_pci()
{
    DEV=$(find /sys/class/net/*/device -lname "*$1" 2>/dev/null | awk -F '/' '{print $5}')

    if [ -z "$DEV" ]; then
        echo "PCI Device $1 not found" >&2
        return
    fi

    if [ `echo "$DEV" | wc -l` -gt 1 ]; then
        echo "More than one PCI Device $1 found" >&2
        return
    fi

    echo "$DEV"
}

PCI_INTERFACES=$(get_pci_interfaces)

for pci in $PCI_INTERFACES; do
    UPCASE_DEV=$pci

    IP=$(get_iface_var "IP")
    MAC=$(get_iface_var "MAC")
    MASK=$(get_iface_var "MASK")
    MASK=${MASK:-255.255.255.0}
    GATEWAY=$(get_iface_var "GATEWAY")
    METRIC=$(get_iface_var "METRIC")
    MTU=$(get_iface_var "MTU")
    MTU=${MTU:-1500}
    VLAN_ID=$(get_iface_var "VLAN_ID")

    IP6=$(get_iface_var "IP6")
    IP6_PREFIX_LENGTH=$(get_iface_var "IP6_PREFIX_LENGTH")
    IP6_PREFIX_LENGTH=${IP6_PREFIX_LENGTH:-64}
    IP6_ULA=$(get_iface_var "IP6_ULA")
    GATEWAY6=$(get_iface_var "GATEWAY6")

    ADDRESS=$(get_iface_var "ADDRESS")
    [ -z "$ADDRESS" ] && continue

    DEV=$(get_dev_from_pci "$ADDRESS")
    [ -z "$DEV" ] && continue

    # MAC
    ip link set dev $DEV address $MAC
    ip link set dev $DEV up

    # MTU
    if [ -n "$MTU" ]; then
        ip link set dev $DEV mtu $MTU
    fi

    # VLAN (802.1Q)
    if [ -n "$VLAN_ID" ]; then
        ip link add link $DEV name $DEV.$VLAN_ID type vlan id $VLAN_ID
        ip link set dev $DEV.$VLAN_ID up
        DEV=$DEV.$VLAN_ID
    fi

    # IPv4
    if [ -n "$IP" ]; then
        ip address add $IP/$MASK dev $DEV

        if [ -n "$GATEWAY" ]; then
            ip route add default via $GATEWAY dev $DEV ${METRIC:+metric ${METRIC}}
        fi
    fi

    # IPv6
    if [ -n "$IP6" ]; then
        ip -6 address add $IP6/$IP6_PREFIX_LENGTH dev $DEV

        if [ -n "$IP6_ULA" ]; then
            ip -6 address add $IP6_ULA/64 dev $DEV
        fi

        if [ -n "$GATEWAY6" ]; then
            ip -6 route add default via $GATEWAY6 dev $DEV
        fi
    fi
done
