Multiple networks / no default route but multiple statics?

Hi,
i am trying to add multiple networks/nics to VMs which one has a public address, and the other should be an internal leg. Now i know about the possibilities by either setting more specific routes e.g. RFC1918 on the internal leg, or using a seperate routing table.

Can this be put into ONE context so people adding another interface will not blow up their networking?

Currently i am instantiating the VMs, purge one-context (Ubuntu) so that it will not touch the network/interfaces after i put the multi-homeing stuff into that file. But it feels very kludgy.

Flo

Okay - After some trying i came to this hackish script. Partially stolen from the one-context network creation. It should run in user-scripts so put it in the context.

Then set an ETH1_ROUTINGTABLE=“internet” for example.

It will move the /etc/network/interfaces entry for eth1 to its own file and add some post-ups for adding routes in a new table and adding rules.

Currently it’ll fail if you have multiple entrys as it does not increment the routing table number etc.

#!/bin/bash

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

mask2cdr () {
	# Assumes there's no "255." after a non-255 byte in the mask
	local x=${1##*255.}
	set -- 0^^^128^192^224^240^248^252^254^ $(( (${#1} - ${#x})*2 )) ${x%%.*}
	x=${1%%$3*}
	echo $(( $2 + (${#x}/4) ))
}


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

# Gets the network part of an IP
get_network() {
    network=$(get_iface_var "NETWORK")

    if [ -z "$network" ]; then
        IFS=. read -r i1 i2 i3 i4 <<< "$IP"
        IFS=. read -r m1 m2 m3 m4 <<< "$(get_mask)"
        network=$(printf "%d.%d.%d.%d\n" "$((i1 & m1))" "$((i2 & m2))" "$((i3 & m3))" "$((i4 & m4))")
    fi

    echo $network
}

# Gets the network mask
get_mask() {
    mask=$(get_iface_var "MASK")

    if [ -z "$mask" ]; then
        mask="255.255.255.0"
    fi

    echo $mask
}

CONTEXT_INTERFACES=$(get_context_interfaces)

mkdir -p /etc/network/interfaces.d

for interface in $CONTEXT_INTERFACES; do
	UPCASE_DEV=$interface	
	ROUTINGTABLE=$(get_iface_var "ROUTINGTABLE")
	DEV=$(ip -br link show | grep $(get_iface_var "MAC") | awk '{ print $1 }')

	if [ -z "${ROUTINGTABLE}" ]; then
		continue
	fi

	cat /etc/network/interfaces \
		| sed -n -e "/auto ${DEV}/,/^$/p" \
		| sed -e '/gateway/d' \
		>/etc/network/interfaces.d/${DEV}.cfg

	sed -i -e "/auto ${DEV}/,/^$/d" \
		/etc/network/interfaces

cat <<EOF >>/etc/network/interfaces.d/${DEV}.cfg
  post-up ip route add $(get_network)/$(mask2cdr $(get_iface_var "MASK")) dev ${DEV} src $(get_iface_var "IP") table ${ROUTINGTABLE}
  post-up ip route add 0.0.0.0/0 dev ${DEV} via $(get_iface_var "GATEWAY") table ${ROUTINGTABLE}
  post-up ip rule add from $(get_iface_var "IP") table ${ROUTINGTABLE}
  post-up ip rule add to $(get_iface_var "IP") table ${ROUTINGTABLE}
EOF

	egrep -q "^[[:digit:]]+ *${ROUTINGTABLE}\$" /etc/iproute2/rt_tables \
		|| echo 1 ${ROUTINGTABLE} >>/etc/iproute2/rt_tables

	ifdown ${DEV}
	ip r flush dev ${DEV}
	ip a flush dev ${DEV}
	ifup ${DEV}
done