#!/bin/bash -e

function generate_veth_name() {
    local BASE_NAME=$1
    local rand=$(tr -dc 'a-f0-9' < /dev/urandom | head -c4)
    local VETH_NAME="veth${rand}-${BASE_NAME}"
    echo $VETH_NAME
}

function link_ns_to_container_id() {
    local NETNS=$1
    local CONTAINER_ID=$2
    mkdir -p /var/run/netns/
    ln -sfT ${NETNS} /var/run/netns/${CONTAINER_ID}
    echo "ln -sfT ${NETNS} /var/run/netns/${CONTAINER_ID}"
}

function create_veth_pair() {
    local BRIDGE_NAME=$1
    local CONTAINER_ID=$2
    local IFNAME=$3

    HOST_VETH=$(generate_veth_name ${BRIDGE_NAME})
    echo "link add ${IFNAME} type veth peer name ${HOST_VETH}"
    ip link add ${IFNAME} type veth peer name ${HOST_VETH}
    echo "connect interface ${IFNAME} to namespace ${CONTAINER_ID}"
    ip link set ${IFNAME} netns ${CONTAINER_ID}
    echo "connect interface ${HOST_VETH} to bridge ${BRIDGE_NAME}"
    ip link set ${HOST_VETH} master ${BRIDGE_NAME}
    ip link set ${HOST_VETH} up
}

function config_ns() {
    local CONTAINER_ID=$1
    local IFNAME=$2
    local SUBNET_SZ=$3
    local GATEWAY=$4
    local IP_ADDR=$5

    ip netns exec ${CONTAINER_ID} ip link set ${IFNAME} up
    ip netns exec ${CONTAINER_ID} ip addr add ${IP_ADDR}/${SUBNET_SZ} dev ${IFNAME}
    ip netns exec ${CONTAINER_ID} ip route add default via ${GATEWAY} dev ${IFNAME}

    MAC_ADDR=$(ip netns exec ${CONTAINER_ID} ip link show ${IFNAME} | awk '/ether/ {print $2}')

    echo "$MAC_ADDR"
}

function config_interface {
    local BRIDGE_NAME=$1
    local NETNS=$2
    local CONTAINER_ID=$3
    local IFNAME=$4
    local SUBNET_SZ=$5
    local GATEWAY=$6
    local IP_ADDR=$7
    local MAC_ADDR

    link_ns_to_container_id "$NETNS" "$CONTAINER_ID"
    create_veth_pair "$BRIDGE_NAME" "$CONTAINER_ID" "$IFNAME"
    MAC_ADDR=$(config_ns "$CONTAINER_ID" "$IFNAME" "$SUBNET_SZ" "$GATEWAY" "$IP_ADDR")

    cat <<EOF >&3
{
    "cniVersion": "0.4.0",
    "interfaces": [
        {
            "name": "${IFNAME}",
            "mac": "${MAC_ADDR}",
            "sandbox": "${NETNS}"
        }
    ],
    "ips": [
        {
            "version": "4",
            "address": "${IP_ADDR}/${SUBNET_SZ}",
            "gateway": "${GATEWAY}",
            "interface": 0
        }
    ]
}
EOF
}
