#!/bin/sh
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

. /lib/functions/fff/network

setupPorts() {
    # Add a single port to the *_PORTS config
    # Usage: setupPorts <port id> <port mode>

    local port=$1
    local mode=$2

    #default: BATMAN
    if [ "$mode" = "WAN" ] ; then
        WAN_PORTS="${WAN_PORTS} $port"
    elif [ "$mode" = "CLIENT" ] ; then
        CLIENT_PORTS="${CLIENT_PORTS} $port"
    else
        BATMAN_PORTS="${BATMAN_PORTS} $port"
    fi
}

setAutoConf() {
    # Sets ipv6 auto configuration on an interface to on/off
    # Usage: setAutoConf <interface> <[0|1]>
    local iface=$1
    local on=$2

    sysctlfile="/etc/sysctl.d/51-fff-network-$iface.conf"
    echo "# Generated from configurenetwork" > "$sysctlfile"
    echo "net.ipv6.conf.$iface.accept_ra = $on" >> "$sysctlfile"
    echo "net.ipv6.conf.$iface.accept_ra_defrtr = $on" >> "$sysctlfile"
    echo "net.ipv6.conf.$iface.accept_ra_pinfo = $on" >> "$sysctlfile"
    echo "net.ipv6.conf.$iface.autoconf = $on" >> "$sysctlfile"
    echo "net.ipv6.conf.$iface.accept_ra_rtr_pref = $on" >> "$sysctlfile"
    echo "net.ipv6.conf.$iface.forwarding = 0" >> "$sysctlfile"

    /sbin/sysctl -p "$sysctlfile"
}

enableAutoConf() {
    # Enables ipv6 auto configuration on an interface
    # Usage: enableAutoConf <interface>
    local iface=$1

    setAutoConf "$iface" "1"
}

disableAutoConf() {
    # Disables ipv6 auto configuration on an interface
    # Usage: disableAutoConf <interface>
    local iface=$1

    setAutoConf "$iface" "0"
}

BOARD="$(uci get board.model.name)"
. /etc/network.$BOARD

if [ -s /etc/network.config ] ; then
    . /etc/network.config
else
    # Write network.config
    echo "CLIENT_PORTS='$CLIENT_PORTS'" > /etc/network.config
    echo "BATMAN_PORTS='$BATMAN_PORTS'" >> /etc/network.config
    if [ -n "$WAN_PORTS" ] ; then
        echo "WAN_PORTS='$WAN_PORTS'" >> /etc/network.config
    fi
    if [ "$ONE_PORT" = "YES" ] || [ -n "$ETHPORT" ] ; then
        echo "ETHMODE='$ETHMODE' # use BATMAN, CLIENT or WAN" >> /etc/network.config
    fi
    if [ -n "$LAN0PORT" ] ; then
        echo "LAN0MODE='$LAN0MODE' # use BATMAN, CLIENT or WAN" >> /etc/network.config
    fi
    if [ -n "$LAN1PORT" ] ; then
        echo "LAN1MODE='$LAN1MODE' # use BATMAN, CLIENT or WAN" >> /etc/network.config
    fi
    echo "FORCEPARSE='0' # Parse at: 0=first boot only, 1=every reboot, 2=next reboot (once)" >> /etc/network.config
fi

if [ "$FORCEPARSE" = '2' ] ; then
    sed -i '/^FORCEPARSE/d' /etc/network.config
    echo "FORCEPARSE='0' # Parse at: 0=first boot only, 1=every reboot, 2=next reboot (once)" >> /etc/network.config
    FORCEPARSE='1'
fi

if [ -n "$ETHPORT" ] ; then
    #LAN@AR150: default: BATMAN
    setupPorts "$ETHPORT" "${ETHMODE}"
fi
if [ -n "$LAN0PORT" ] ; then
    #LAN0@two-port: default: BATMAN
    setupPorts "$LAN0PORT" "${LAN0MODE}"
fi
if [ -n "$LAN1PORT" ] ; then
    #LAN1@two-port: default: BATMAN
    setupPorts "$LAN1PORT" "${LAN1MODE}"
fi

if ! uci -q get network.$SWITCHDEV > /dev/null || [ "$FORCEPARSE" = '1' ] ; then

    SWITCHHW=$(swconfig list | awk '{ print $4 }')

    uci set network.$SWITCHDEV=switch
    uci set network.$SWITCHDEV.name=$SWITCHHW
    uci set network.$SWITCHDEV.enable=1
    uci set network.$SWITCHDEV.reset=1
    uci set network.$SWITCHDEV.enable_vlan=1

    uci set network.${SWITCHDEV}_1=switch_vlan
    uci set network.${SWITCHDEV}_1.device=$SWITCHHW
    uci set network.${SWITCHDEV}_1.vlan=1
    uci set network.${SWITCHDEV}_1.ports="$CLIENT_PORTS"

    if [ "$WANDEV" = "$SWITCHDEV" ] || ! [ -z "$WAN_PORTS" ]; then
        uci set network.${SWITCHDEV}_2=switch_vlan
        uci set network.${SWITCHDEV}_2.device=$SWITCHHW
        uci set network.${SWITCHDEV}_2.vlan=2
        uci set network.${SWITCHDEV}_2.ports="$WAN_PORTS"

        enableAutoConf "$WANDEV.2"
    else
        enableAutoConf "$WANDEV"
    fi
    
    uci set network.${SWITCHDEV}_3=switch_vlan
    uci set network.${SWITCHDEV}_3.device=$SWITCHHW
    uci set network.${SWITCHDEV}_3.vlan=3
    uci set network.${SWITCHDEV}_3.ports="$BATMAN_PORTS"

    uci set network.mesh.ifname="$SWITCHDEV.1 bat0"

    uci set network.ethmesh.ifname="$SWITCHDEV.3"

    if [ "$WANDEV" = "$SWITCHDEV" ]; then
        uci set network.wan.ifname=$WANDEV.2
    else
        uci set network.wan.ifname=$WANDEV
    fi

    uci commit network
fi

if [ "$ONE_PORT" = "YES" ] && ( ! uci -q get network.$SWITCHDEV.ifname || [ "$FORCEPARSE" = '1' ] ) ; then
    uci set network.$SWITCHDEV=interface
    uci set network.$SWITCHDEV.ifname=$SWITCHDEV
    if [ "$ETHMODE" = "WAN" ]; then
        enableAutoConf "$WANDEV"
        uci set network.mesh.ifname="bat0"
        uci set network.wan.ifname="$WANDEV"
        uci del uci set network.ethmesh.ifname
        uci del network.eth0.macaddr
    elif [ "$ETHMODE" = "CLIENT" ] ; then
        disableAutoConf "$WANDEV"
        uci set network.mesh.ifname="bat0 $SWITCHDEV"
        uci set network.wan.ifname="eth1" #eth1 because it is default in config file
        uci del network.ethmesh.ifname
        uci del network.eth0.macaddr
    elif [ "$ETHMODE" = "BATMAN" ] ; then
        disableAutoConf "$WANDEV"
        uci set network.mesh.ifname="bat0"
        uci set network.wan.ifname="eth1" #eth1 because it is default in config file
        uci set network.ethmesh.ifname="$SWITCHDEV"
        ETH0MAC="w2ap"
    fi
    uci commit network
fi

/etc/init.d/network restart

if [ -n "$ETHMESHMAC" ]; then
    if uci get network.ethmesh.macaddr
    then
        echo "MAC for ethmesh is set already"
    else
        echo "Fixing MAC on $SWITCHDEV.3 (ethmesh)"
        sleep 10

        uci set network.ethmesh.macaddr=$ETHMESHMAC
        uci commit network

        ifconfig $SWITCHDEV.3 down
        ifconfig $SWITCHDEV.3 hw ether $ETHMESHMAC
        ifconfig $SWITCHDEV.3 up
        /etc/init.d/network restart
    fi
fi

if [ -n "$ROUTERMAC" ]; then
    if uci get network.mesh.macaddr
    then
        echo "MAC for mesh is set already"
    else
        echo "Fixing MAC on br-mesh (mesh)"
        sleep 10

        uci set network.mesh.macaddr=$ROUTERMAC
        uci commit network

        ifconfig br-mesh down
        ifconfig br-mesh hw ether $ROUTERMAC
        ifconfig br-mesh up
        /etc/init.d/network restart
    fi
fi

if [ -n "$ETH0MAC" ]; then
        echo "Fixing MAC on eth0"
        sleep 10
        NEW_MACADDR=$(cat "/sys/class/net/${ETH0MAC}/address")
        uci set network.eth0.macaddr=$NEW_MACADDR
        uci commit network
        ifconfig eth0 down
        ifconfig eth0 hw ether $NEW_MACADDR
        ifconfig eth0 up
        /etc/init.d/network restart
fi

if uci -q get "network.mesh.ip6addr" > /dev/null
then
    echo "IPv6 for mesh is set already"
else
    echo "Setting IPv6 addresses"
    # Some time needed :(
    sleep 5

    for ip in $(ip -6 addr show br-mesh | awk '/fdff/{ print $2 }'); do
        ip -6 addr del $ip dev br-mesh
    done

    prefix="fdff:0::/64"
    # Set $prefix::MAC as IP
    addr="$(ipMacAssemble "$prefix" "$ROUTERMAC")"
    ip -6 addr add $addr dev br-mesh

    uci -q del network.globals
    uci -q set network.globals=globals
    uci -q set network.globals.ula_prefix=$prefix
    uci -q add_list network.mesh.ip6addr=$addr
    uci -q set network.mesh.proto=static

    # Set $prefix::1 as IP
    addr="$(ipAssemble "$prefix" "1")"
    ip -6 addr add $addr dev br-mesh
    uci -q add_list network.mesh.ip6addr=$addr

    # Set $prefix::link-local as IP
    addr="$(ipEUIAssemble "$prefix" "$ROUTERMAC")"
    ip -6 addr add $addr dev br-mesh
    uci -q add_list network.mesh.ip6addr=$addr

    uci -q commit network

    /etc/init.d/fff-uradvd restart
fi
