#!/bin/bash

# For Ethernet / WLAN interfaces we insert a number of routes
# which are normally not inserted by ifup.

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

# Skip if not inet
[ "$ADDRFAM" = "inet" ] || exit 0

# Note that if we get here the interface is necessarily UP (or the
# scripts are messed up) and it does exist.

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

# Check if the interface has an IP address (otherwise we cannot
# add IPv4 routes on it)
[ -z "$(ip -o -4 addr show dev "$IFACE")" ] && exit 0

# use a high but interface specific metric for the routes,
# this allows to have one high metric per interface route
ifindex="$(< /sys/class/net/"$IFACE"/ifindex)" || ifindex=0
metric=$((30000 + ifindex))

# We need a multicast route, otherwise there is no default output
# interface for multicast traffic and the kernel returns a "network
# unreachable" unless the application specifically sepecifies an
# output interface; also if the interface has only a link local
# address the kernel will use no source address (i.e. 0.0.0.0) on
# output packets if the matching route has global scope. Note that
# when a default route is present and a global IP address is
# configured everything magically works since the default route
# matches all multicast destinations and the kernel always sends
# packets to multicast addresses on link, but this it breaks down when
# there is no default route or when there is no global address on the
# device. Note that by default multicast routes have link scope, unlike
# unicast routes, we use replace since the same route may already be defined.
ip route replace multicast 224.0.0.0/4 dev "$IFACE" metric $metric proto static

# Make sure that we have a route to reach IPv4LL addresses (see RFC
# 3927), so that we can reach hosts with only one such addresses. We
# use a high metric to avoid interfering with the kernel added route
# when an interface gets an IPv4LL address, we use replace since the
# same route may already be defined.
ip route replace 169.254.0.0/16 dev "$IFACE" scope link metric $metric proto static

# Add a default route with a high metric as a last resort route, we
# set it to link scope so that it is also valid with link local
# addresses (i.e. a source address is correctly set), we use replace
# since the same route may already be defined.
ip route replace default dev "$IFACE" metric $metric scope link proto static

exit 0
