#!/bin/bash

# Make sure that the interface has no state leftover from any previous
# network settings.
#

[ -n "$IFACE" ] || exit 1

# Skip if not inet or inet6
[ "$ADDRFAM" = "inet" -o "$ADDRFAM" = "inet6" ] || exit 0

# Skip if zeroconf, it uses addresses on aliased (or labeled) interfaces
# and manages them correctly itself and we do not want to interfere
# with addresses on the non-aliased interface.
[ "$METHOD" = "zeroconf" ] && exit 0

# Skip if interface does not exist yet
[ -e /sys/class/net/"$IFACE" ] || exit 0

# Skip if not of Ethernet or WLAN type
[ "$(< /sys/class/net/$IFACE/type)" = 1 ] || exit 0

# Avoid running this for the main interface (e.g., eth0) on nfsroot systems
# but clear any saved dhclient leases just in case the current IP address is
# not the one in the dhclient lease database (otherwise dhclient will drop the
# current address and try to reacquire the one saved in the lease database).
[ -f /etc/spinetix/identifiers ] && . /etc/spinetix/identifiers
if [ "$IFACE" = "$SPX_MAIN_IFACE_NAME" ] && grep -q nfsroot= /proc/cmdline; then
    [ "$METHOD" = "dhcp" ] && [ -e /var/lib/dhcp/dhclient.leases ] && \
        echo -n > /var/lib/dhcp/dhclient.leases
    exit 0
fi

# Make sure that no leftover IP addresses from previously half
# configured or half unconfigured interfaces are associated with the
# interface; note that if all IPv4 / IPv6 addresses are removed then all
# IPv4 / IPv6 routes associated with the interface are removed as well..
# We keep other addresses (e.g., IPv6 auto-conf, IPv4LL) available.
if [ "$ADDRFAM" = "inet" ]; then
    ip -4 addr flush dev "$IFACE" label "$IFACE" 2>/dev/null
elif [ "$ADDRFAM" = "inet6" ]; then
    # we should leave alone automatic link-local address as well as any
    # auto-configured addresses (dynamic), hence the global scope and
    # permanent attribute
    ip -6 addr flush dev "$IFACE" label "$IFACE" scope global permanent 2>/dev/null
fi

# Remove all routes which have not been truly statically assigned, as
# since other IPv4 / IPv6 addresses may be present the command above does
# not always remove the IPv4 / IPv6 routes through the interface (the boot
# protocol is the default protocol for routes added from user space).
if [ "$ADDRFAM" = "inet" ]; then
    ip -4 route flush proto boot dev "$IFACE" 2>/dev/null
elif [ "$ADDRFAM" = "inet6" ]; then
    # For IPv6 multicast the kernel adds a route for ff00::/8, but uses
    # the boot protocol, and it is added to the main table if the kernel
    # is not compiled with support for multiple IPv6 routing tables. So
    # just flushing all the routes with boot protocol would get rid of it
    # so we just remove default routes, which are the only type we add.
    # See https://bugzilla.kernel.org/show_bug.cgi?id=197319
    ip -6 route flush proto boot to match ::/0 dev "$IFACE"
fi

# Bring up the interface, as some methods (e.g., manual) will not do it
if ! ip link set "$IFACE" up; then
    echo "ERROR: cannot enable $IFACE" >&2
    exit 1
fi

exit 0
