Add Steven's __netowrk_interface type

This commit is contained in:
Darko Poljak 2020-01-18 19:47:23 +01:00
parent 87f30b6053
commit e3553b15b6
17 changed files with 1226 additions and 0 deletions

View file

@ -0,0 +1,38 @@
#!/bin/sh
#
# workaround the bloody upstart race conditions
# by delaying the emission of the net-device-up signal until the interface is
# really up and configured.
#
# environment variables:
# METHOD=dhcp
# MODE=start
# LOGICAL=eth0
# PHASE=post-up
# ADDRFAM=inet
# VERBOSITY=0
# PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# IF_METRIC=100
# IFACE=eth0
# PWD=/root
# nothing to do for loopback
[ "$IFACE" = lo ] && exit 0
LOG_FILE="/tmp/wait-for-ip-${IFACE}.log"
cp /dev/null $LOG_FILE
RETRY=20
index=0
if [ "$ADDRFAM" = "inet" -a "$METHOD" = "dhcp" ]; then
until [ -n "$ip" -o $index -eq $RETRY ]; do
ip=$(ip -o -family inet addr show dev $IFACE | awk '{split($4, a, "/"); print a[1]}')
index=$((index+1))
sleep 0.5
done
if [ -n "$ip" ]; then
echo "Interface $IFACE is up with ip $ip after $index of $RETRY tries." >> $LOG_FILE
else
echo "Interface $IFACE failed to come up with an ip address, giving up after $RETRY tries." >> $LOG_FILE
fi
fi

View file

@ -0,0 +1,64 @@
#!/bin/sh
#
# See 'IFACE OPTIONS' in interfaces(5) for available variables.
#
DEBUG=
#DEBUG=1
debug() {
if [ "$DEBUG" ]; then
echo "[DEBUG] $@" >&2
fi
}
interface="$IFACE"
# noop for loopback
[ "$interface" = "lo" ] && exit 0
# only work with ipv4
[ "$ADDRFAM" = "inet" ] || exit 0
# Interface must be explicitly configured to do symmetric routing.
[ "${IF_SYMMETRIC_ROUTING:-no}" = "no" ] && exit 0
case "$MODE" in
start)
action="up"
;;
stop)
action="down"
;;
esac
case "$METHOD" in
dhcp)
LEASEFILE="/var/lib/dhcp/dhclient.${interface}.leases"
ip_address="$(awk '/fixed-address/ {sub(/;$/,""); print $2}' "$LEASEFILE" | tail -1)"
subnet_mask_or_prefix="$(awk '/option subnet-mask/ {sub(/;$/,""); print $3}' "$LEASEFILE" | tail -1)"
gateway="$(awk '/option routers/ {sub(/;$/,""); print $3}' "$LEASEFILE" | tail -1)"
;;
static)
[ -n "$IF_ADDRESS" ] && ip_address="$IF_ADDRESS"
[ -n "$IF_NETMASK" ] && subnet_mask_or_prefix="$IF_NETMASK"
[ -n "$IF_GATEWAY" ] && gateway="$IF_GATEWAY"
;;
*)
echo "Unknown/unsupported METHOD: $METHOD" >&2
exit 1
;;
esac
debug "$interface -----"
debug "action: $action"
debug "interface: $interface"
debug "ip_address: $ip_address"
debug "subnet_mask_or_prefix: $subnet_mask_or_prefix"
debug "gateway: $gateway"
debug "/$interface -----"
if [ -n "$action" -a -n "$interface" -a -n "$ip_address" -a -n "$subnet_mask_or_prefix" ]; then
symmetric-routing "$action" "$interface" "$ip_address" "$subnet_mask_or_prefix" "$gateway"
fi

View file

@ -0,0 +1,9 @@
# Generated by cdist __network_interface
# Changes will be overwritten.
# loopback
auto lo
iface lo inet loopback
# include per interface configurations
source /etc/network/interfaces.d/*.conf

View file

@ -0,0 +1,233 @@
#!/bin/sh -e
#
# 2012-2018 Steven Armstrong (steven-cdist at armstrong.cc)
#
# This file is part of cdist.
#
# cdist 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.
#
# cdist 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.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
__package ifupdown
# Use cumulus ifupdown2 instead of ifupown and ifenslave
# ifupdown2 is currently not compatible with network-wait-online.
#__package ifupdown \
# --name ifupdown2
type_files="$__type/files/debian"
mkdir "$__object/files"
interface_filename="${__object_id}.conf"
(
cat << DONE
# Created by cdist ${__type##*/}
# Do not change. Changes will be overwritten.
#
DONE
if [ -f "$__object/parameter/comment" ]; then
cat "$__object/parameter/comment" | awk '{ print "# "$0 }'
fi
if [ -f "$__object/parameter/onboot" ]; then
printf "auto %s\n" "$name"
elif [ -f "$__object/parameter/hotplug" ]; then
printf "allow-hotplug %s\n" "$name"
fi
ignored_parameters="linkdelay"
manually_handled_parameters="name comment extra-config state method onboot hotplug nodns noroute no-network-wait-online symmetric-routing bond-slaves"
case "$method" in
dhcp)
printf "iface %s inet %s\n" "$name" "$method"
ignored_parameters="$ignored_parameters address broadcast gateway netmask"
;;
static|manual)
printf "iface %s inet %s\n" "$name" "$method"
;;
*)
echo "Unsupported value for parameter --method. Got '$method'. See man page for supported values." >&2
exit 1
;;
esac
for param in $(ls "$__object/parameter/"); do
if echo "$ignored_parameters" | grep -w -q "$param"; then
continue
fi
if echo "$manually_handled_parameters" | grep -w -q "$param"; then
continue
fi
if [ -f "$type_files/name-map" ]; then
key="$(awk -v param=$param '{ if ($1 == param) {print $2;} else { print param;} }' "$type_files/name-map")"
else
key="$param"
fi
printf " %s %s\n" "$key" "$(cat "$__object/parameter/$param")"
done
if [ -f "$__object/parameter/bond-mode" -o -f "$__object/parameter/bond-primary" ]; then
# Note: ifenslave is not needed when using ifupdown2
# install package required for bonding
__package ifenslave
if [ -f "$__object/parameter/bond-slaves" ]; then
printf ' bond-slaves %s\n' "$(cat "$__object/parameter/bond-slaves")"
else
# need this or the slave tries to bring the master up, but the master hangs waiting for a slave
printf ' bond-slaves none\n'
fi
fi
if [ -f "$__object/parameter/no-network-wait-online" ]; then
# Do not consider this interface in network-wait-online.service
printf ' no-network-wait-online yes\n'
fi
if [ -f "$__object/parameter/symmetric-routing" ]; then
# Deploy scripts that implement the feature ...
__file /sbin/symmetric-routing \
--owner root --group root --mode 0755 \
--source "$__type/files/symmetric-routing"
require="__package/ifupdown __file/sbin/symmetric-routing" \
__file /etc/network/if-up.d/symmetric-routing \
--owner root --group root --mode 0755 \
--source "$__type/files/debian/ifupdown-symmetric-routing"
require="__package/ifupdown __file/etc/network/if-up.d/symmetric-routing" \
__link /etc/network/if-down.d/symmetric-routing \
--type symbolic \
--source ../if-up.d/symmetric-routing
# ... then enable it in interface stanza file.
printf ' symmetric-routing yes\n'
fi
if [ -n "$vlan" -a -n "$device" ]; then
# Explicit parent interface for vlans
printf ' vlan-raw-device %s\n' "$device"
fi
if [ -f "$__object/parameter/extra-config" ]; then
extra_config="$(cat "$__object/parameter/extra-config")"
if [ "$extra_config" = "-" ]; then
extra_config="$__object/stdin"
fi
awk '{print " " $0}' "$extra_config"
fi
) >> "$__object/files/$interface_filename"
__directory /etc/network \
--state present \
--owner root \
--group root \
--mode 755
require="__directory/etc/network" \
__directory /etc/network/interfaces.d \
--state present \
--owner root \
--group root \
--mode 755
require="__directory/etc/network" \
__file /etc/network/interfaces \
--source "$type_files/interfaces" \
--owner root \
--group root \
--mode 644
require="__file/etc/network/interfaces __directory/etc/network/interfaces.d" \
__file "/etc/network/interfaces.d/$interface_filename" \
--owner root \
--group root \
--mode 644 \
--source "$__object/files/$interface_filename" \
--state "$state"
if [ "$method" = "dhcp" -a -f "$__object/parameter/noroute" ]; then
(
cat << DONE
# Created by cdist ${__type##*/}
# Do not change. Changes will be overwritten.
#
if [ "\$interface" = "$name" ]; then
case "\$reason" in
BOUND|RENEW|REBIND|REBOOT)
# prevent default gateway to be set by this interface
unset new_routers
;;
esac
fi
DONE
) | \
__file "/etc/dhcp/dhclient-enter-hooks.d/cdist-__network_interface-${name}-noroute" \
--owner root \
--group root \
--mode 644 \
--source - \
--state "$state"
fi # end noroute
if [ "$method" = "dhcp" -a -f "$__object/parameter/nodns" ]; then
(
cat << DONE
# Created by cdist ${__type##*/}
# Do not change. Changes will be overwritten.
#
if [ "\$interface" = "$name" ]; then
# Prevent /etc/resolv.conf from being changed by this interface
# by overriding the default 'make_resolv_conf' function.
make_resolv_conf(){
:
}
fi
DONE
) | \
__file "/etc/dhcp/dhclient-enter-hooks.d/cdist-__network_interface-${name}-nodns" \
--owner root \
--group root \
--mode 644 \
--source - \
--state "$state"
fi # end nodns
os=$(cat "$__global/explorer/os")
if [ "$os" = "ubuntu" ]; then
# workaround the bloody upstart race conditions
# by deploying a script that delays the emission of the net-device-up
# signal until the interface is really up and configured.
#script_name="00000-wait-for-ip"
#__file "/etc/network/if-up.d/$script_name" \
# --owner root --group root --mode 755 \
# --source "$type_files/$script_name"
# Deal with systemd network-online.target race conditions
require="__package/ifupdown" \
__file /etc/network/if-pre-up.d/network-online \
--owner root --group root --mode 0755 \
--source "$__type/files/debian/network-online"
require="__file/etc/network/if-pre-up.d/network-online" \
__link /etc/network/if-up.d/network-online \
--type symbolic \
--source ../if-pre-up.d/network-online
fi

View file

@ -0,0 +1,49 @@
#!/bin/sh
#
# See 'IFACE OPTIONS' in interfaces(5) for available variables.
#
DEBUG=
#DEBUG=1
debug() {
if [ "$DEBUG" ]; then
echo "[DEBUG] $@" >&2
fi
}
interface="$IFACE"
# noop for loopback
[ "$interface" = "lo" ] && exit 0
# nothing usefull we could do for '--all'
[ "$interface" = "--all" ] && exit 0
# Interface is configured to not be considered by network-wait-online.service
[ "${IF_NO_NETWORK_WAIT_ONLINE:-no}" = "yes" ] && exit 0
case "$MODE" in
start)
action="up"
;;
stop)
action="down"
;;
esac
state_dir=/run/network-online-interfaces
mkdir -p "$state_dir"
case "$PHASE" in
pre-up)
# Create flag file to wait for in network-wait-online.service
touch "$state_dir/$interface"
;;
post-up)
# This interface is up!
# Remove the flag file that was created in /sbin/ifup-pre-local
# so that the network-wait-online.service can reach the network-online.target
rm -rf "$state_dir/$interface"
;;
esac

View file

@ -0,0 +1,17 @@
[Unit]
Description=Wait for network to be configured
Documentation=man:ifup(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=%NETWORK_SERVICE_NAME%
Before=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
TimeoutStartSec=3min
ExecStart=/bin/sh -ec 'while [ "$(ls -1 /run/network-online-interfaces/)" ]; do sleep 1; done'
[Install]
WantedBy=network-online.target

View file

@ -0,0 +1,39 @@
#!/bin/sh
#echo "/sbin/ifup-pre-local" >&2
#set -x
config="$1"
interface="$1"
cd /etc/sysconfig/network-scripts
. ./network-functions
[ -f ../network ] && . ../network
need_config "$config"
source_config
# If not started at boot we don't care
[ "${ONBOOT:-no}" = "no" ] && exit 0
# noop for loopback
[ "$DEVICE" = "lo" ] && exit 0
state_dir=/run/network-online-interfaces
mkdir -p "$state_dir"
if [ "${NO_NETWORK_WAIT_ONLINE:-no}" = "no" ]; then
# remember device for later use in network-wait-online.service
touch "$state_dir/$DEVICE"
fi
# hackaround bugs in /etc/sysconfig/network-scripts/ifup
wait_for_device=20
index=0
until [ -d "/sys/class/net/$DEVICE" -o $index -eq $wait_for_device ]; do
echo "waiting for /sys/class/net/$DEVICE $index/$wait_for_device" >&2
sleep 1
index=$(($index + 1))
done

View file

@ -0,0 +1,84 @@
#!/bin/sh
myname="${0##*/}"
case "$myname" in
ifup-local)
action="up"
;;
ifdown-local|ifdown-pre-local)
action="down"
;;
*)
echo "Unable to determine action from script name: $myname" >&2
exit 1
;;
esac
DEBUG=
#DEBUG=1
debug() {
if [ "$DEBUG" ]; then
echo "[DEBUG] $@" >&2
fi
}
interface="$1"
# noop for loopback
[ "$interface" = "lo" ] && exit 0
cd /etc/sysconfig/network-scripts
. ./network-functions
[ -f ../network ] && . ../network
need_config "$interface"
source_config
case "${BOOTPROTO}" in
bootp|dhcp)
generate_lease_file_name
ip_address="$(awk '/fixed-address/ {sub(/;$/,""); print $2}' "$LEASEFILE" | tail -1)"
subnet_mask_or_prefix="$(awk '/option subnet-mask/ {sub(/;$/,""); print $3}' "$LEASEFILE" | tail -1)"
gateway="$(awk '/option routers/ {sub(/;$/,""); print $3}' "$LEASEFILE" | tail -1)"
;;
none)
# No ip address set -> nothing we could do
[ -n "$IPADDR" ] && ip_address="$IPADDR"
[ -n "$PREFIX" ] && subnet_mask_or_prefix="$PREFIX" || {
[ -n "$NETMASK" ] && subnet_mask_or_prefix="$NETMASK"
}
[ -n "$GATEWAY" ] && gateway="$GATEWAY"
;;
*)
echo "Unknown/unsupported BOOTPROTO: $BOOTPROTO" >&2
exit 1
;;
esac
debug "$interface -----"
debug "action: $action"
debug "interface: $interface"
debug "ip_address: $ip_address"
debug "subnet_mask_or_prefix: $subnet_mask_or_prefix"
debug "gateway: $gateway"
debug "/$interface -----"
# Interface must be explicitly configured to do symmetric routing.
if [ "${SYMMETRIC_ROUTING:-no}" = "yes" ]; then
if [ -n "$action" -a -n "$interface" -a -n "$ip_address" -a -n "$subnet_mask_or_prefix" ]; then
symmetric-routing "$action" "$interface" "$ip_address" "$subnet_mask_or_prefix" "$gateway"
fi
fi
case "$action" in
up)
# This interface is up!
# Remove the flag file that was created in /sbin/ifup-pre-local
# so that the network-wait-online.service can reach the network-online.target
state_dir=/run/network-online-interfaces
rm -rf "$state_dir/$interface"
;;
esac

View file

@ -0,0 +1,171 @@
#!/bin/sh -e
#
# 2014 Steven Armstrong (steven-cdist at armstrong.cc)
#
# This file is part of cdist.
#
# cdist 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.
#
# cdist 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.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
type_files="$__type/files/redhat"
mkdir "$__object/files"
interface_filename="ifcfg-${name}"
(
cat << DONE
# Created by cdist ${__type##*/}
# Do not change. Changes will be overwritten.
#
DONE
if [ -f "$__object/parameter/comment" ]; then
cat "$__object/parameter/comment" | awk '{ print "# "$0 }'
fi
printf 'DEVICE="%s"\n' "$name"
printf 'NM_CONTROLLED=no\n'
printf 'USERCTL=no\n'
if [ -f "$__object/parameter/onboot" ]; then
printf 'ONBOOT=yes\n'
else
printf 'ONBOOT=no\n'
fi
if [ -f "$__object/parameter/hotplug" ]; then
printf 'HOTPLUG=yes\n'
else
printf 'HOTPLUG=no\n'
fi
if [ -f "$__object/parameter/nodns" ]; then
printf 'PEERDNS=no\n'
else
printf 'PEERDNS=yes\n'
fi
if [ -f "$__object/parameter/noroute" ]; then
printf 'DEFROUTE=no\n'
else
printf 'DEFROUTE=yes\n'
fi
if [ -f "$__object/parameter/no-network-wait-online" ]; then
printf 'NO_NETWORK_WAIT_ONLINE=yes\n'
fi
if [ -f "$__object/parameter/symmetric-routing" ]; then
# Deploy scripts that implement the feature ...
__file /sbin/symmetric-routing \
--owner root --group root --mode 0755 \
--source "$__type/files/symmetric-routing"
# ... then enable it in interface cfg file.
printf 'SYMMETRIC_ROUTING=yes\n'
fi
ignored_parameters=""
manually_handled_parameters="name comment extra-config state method onboot hotplug nodns noroute no-network-wait-online symmetric-routing"
case "$method" in
dhcp)
printf 'BOOTPROTO=dhcp\n'
ignored_parameters="$ignored_parameters address broadcast gateway netmask"
;;
static|manual)
printf 'BOOTPROTO=none\n'
;;
*)
echo "Unsupported value for parameter --method. Got '$method'. See man page for supported values." >&2
exit 1
;;
esac
for param in $(ls "$__object/parameter/"); do
if echo "$ignored_parameters" | grep -w -q "$param"; then
continue
fi
if echo "$manually_handled_parameters" | grep -w -q "$param"; then
continue
fi
case "$param" in
bond-master)
# if someone is my master, I am a slave
printf 'SLAVE=yes\n'
printf 'MASTER=%s\n' "$(cat "$__object/parameter/$param")"
;;
bond-*)
key="$(echo "${param#*bond-}" | tr - _)"
if [ "$param" = "bond-arp-ip-target" ]; then
value="$(cat "$__object/parameter/$param" | tr '\n' ,)"
# strip trailing comma
value="${value%,}"
else
value="$(cat "$__object/parameter/$param")"
fi
printf '%s=%s\n' "$key" "$value" >> "$__object/files/bonding_opts"
;;
*)
# check for redhat specific name for this parameter
if [ -f "$type_files/name-map" ]; then
key="$(awk -v param=$param '{ if ($1 == param) {print $2;} else { print param;} }' "$type_files/name-map")"
else
key="$param"
fi
# redhat likes things uppercase
key="$(echo "$key" | tr '[:lower:]' '[:upper:]')"
printf '%s=%s\n' "$key" "$(cat "$__object/parameter/$param")"
;;
esac
done
if [ -f "$__object/files/bonding_opts" ]; then
value="$(cat "$__object/files/bonding_opts" | tr '\n' ' ')"
# strip trailing space
value="${value% }"
printf 'BONDING_OPTS="%s"\n' "$value"
fi
if [ -n "$vlan" -a -n "$device" ]; then
# Enable vlan for this interface
printf 'VLAN=yes\n'
fi
if [ -f "$__object/parameter/extra-config" ]; then
extra_config="$(cat "$__object/parameter/extra-config")"
if [ "$extra_config" = "-" ]; then
extra_config="$__object/stdin"
fi
cat "$extra_config"
fi
) >> "$__object/files/$interface_filename"
__file "/etc/sysconfig/network-scripts/$interface_filename" \
--owner root \
--group root \
--mode 644 \
--source "$__object/files/$interface_filename" \
--state "$state"
# Deploy helper scripts
__file /sbin/ifupdown-local \
--owner root --group root --mode 0755 \
--source "$__type/files/redhat/ifupdown-local"
require="__file/sbin/ifupdown-local" \
__link /sbin/ifup-local \
--type symbolic \
--source ./ifupdown-local
require="__file/sbin/ifupdown-local" \
__link /sbin/ifdown-pre-local \
--type symbolic \
--source ./ifupdown-local
__file /sbin/ifup-pre-local \
--owner root --group root --mode 0755 \
--source "$__type/files/redhat/ifup-pre-local"

View file

@ -0,0 +1 @@
address ipaddr

View file

@ -0,0 +1,240 @@
#!/bin/sh
#
set -e
error() {
echo "[ERROR] $@" >&2
}
die() {
error "$@"
exit 1
}
info() {
echo "[INFO] $@" >&2
}
debug() {
if [ "$DEBUG" ]; then
echo "[DEBUG] $@" >&2
fi
}
usage() {
cat << EOS 1>&2
Usage: ${0##*/} [OPTIONS] ACTION INTERFACE IP_ADDRESS SUBNET_MASK_OR_PREFIX [GATEWAY]
(see -h for more information)
EOS
}
help() {
usage 2>&1 | head -n -1 1>&2
cat << EOS 1>&2
Setup policy based routing for the given interface
to ensure symmetric routing.
ACTION must be either 'up' or 'down' to add respectively remove the
routing table entries.
Options:
-h show this help message
-d run in debug mode
-x run with 'set -x' set
-n no action, just show what would be done without doing it
Examples:
${0##*/} up eth1 192.168.42.23 255.255.255.0 192.168.0.1
${0##*/} down eth1 192.168.42.23 255.255.255.0 192.168.0.1
# gateway is optional
${0##*/} up eth1 192.168.42.23 255.255.255.0
${0##*/} down eth1 192.168.42.23 255.255.255.0
# same but using prefix instead of subnet mask
${0##*/} up eth1 192.168.42.23 24 192.168.0.1
${0##*/} down eth1 192.168.42.23 24 192.168.0.1
EOS
}
die_usage() {
error "$@"
usage
exit 1
}
### Utility functions
# Convert ip to int.
ip2int() {
_ip="$1"
{ IFS=. read _a _b _c _d; } << _done
$_ip
_done
echo $(((((((_a << 8) | _b) << 8) | _c) << 8) | _d))
unset _ip _a _b _c _d
}
# Convert int to ip.
int2ip() {
_ui32=$1; shift
_ip=
for _n in 1 2 3 4; do
_ip=$((_ui32 & 0xff))${_ip:+.}$_ip
_ui32=$((_ui32 >> 8))
done
echo $_ip
unset _ui32 _ip _n
}
# Convert the given prefix into a subnet mask.
mask_from_prefix() {
_prefix="$1"
_mask=$((0xffffffff << (32 - $_prefix)))
int2ip $_mask
unset _prefix _mask
}
# Calculate network number from the given ip and prefix.
network_from_ip_and_prefix() {
_ip="$1"
_prefix="$2"
_addr=$(ip2int $_ip)
_mask=$((0xffffffff << (32 - $_prefix)))
int2ip $((_addr & _mask))
unset _ip _prefix _addr _mask
}
# Calculate number of bits in the given subnet mask.
prefix_from_mask() {
# Assumes there's no "255." after a non-255 byte in the mask
_mask="$1"
_x=${_mask##*255.}
set -- 0^^^128^192^224^240^248^252^254^ $(( (${#1} - ${#_x})*2 )) ${_x%%.*}
_x=${1%%$3*}
echo $(( $2 + (${#_x}/4) ))
unset _mask _x
}
rt_tables=/etc/iproute2/rt_tables
#rt_tables=/tmp/rt_tables
# Get and if required create a routing table for the given table name.
table_id_from_name() {
_interface="$1"
_table_id=$(awk -vname=$_interface '{ if ($2 == name) print $1 }' "$rt_tables")
if [ -z "$_table_id" ]; then
# find unused table id and create a new table for this interface
_used_ids=$(awk '$1 !~ /^(#| |255|254|253|0)/ { print $1 }' "$rt_tables")
for _tid in $(seq 1 252); do
if echo "$_used_ids" | grep -q "$_tid"; then
continue
else
_table_id="$_tid"
[ $NOACTION ] || printf '%s %s\n' "$_table_id" "$_interface" >> "$rt_tables"
break
fi
done
fi
echo "$_table_id"
unset _interface _table_id _used_ids _tid
}
### Parse command line arguments
NOACTION=
DEBUG=
SETX=
while getopts "ndxh" options
do
#echo "$flag" $OPTIND $OPTARG
case $options in
n) NOACTION=1;;
d) DEBUG=1;;
x) SETX=1;;
?|h) help
exit 0
;;
*) usage
exit 1
;;
esac
done
# Strip arguments allready handled by getopts
shift $((OPTIND-1))
[ "$SETX" ] && set -x
# Validate arguments
[ "$#" -ge 4 ] || die_usage "Expected at least 4 arguments, got: $#"
action="$1" # up | down
interface="$2"
ip_address="$3"
subnet_mask_or_prefix="$4"
gateway="$5"
debug "action: $action"
debug "interface: $interface"
debug "ip_address: $ip_address"
debug "subnet_mask_or_prefix: $subnet_mask_or_prefix"
debug "gateway: $gateway"
case "$subnet_mask_or_prefix" in
*.*)
# has a dot, must be a subnet mask
subnet_mask="$subnet_mask_or_prefix"
prefix=$(prefix_from_mask "$subnet_mask")
network="$(network_from_ip_and_prefix "$ip_address" "$prefix")"
;;
*)
# no dot, must be prefix
prefix="$subnet_mask_or_prefix"
subnet_mask="$(mask_from_prefix "$prefix")"
network="$(network_from_ip_and_prefix "$ip_address" "$prefix")"
;;
esac
table_name="$interface"
table_id="$(table_id_from_name "$table_name")"
debug "subnet_mask: $subnet_mask"
debug "prefix: $prefix"
debug "network: $network"
debug "table_name: $table_name"
debug "table_id: $table_id"
(
case "$action" in
up)
# setup routing table for interface
printf 'ip route add "%s/%s" dev "%s" proto static src "%s" table "%s"\n' \
"$network" "$prefix" "$interface" "$ip_address" "$table_name"
if [ -n "$gateway" ]; then
printf 'ip route add default via "%s" table "%s"\n' "$gateway" "$table_name"
fi
printf 'ip rule add from "%s" table "%s"\n' "$ip_address" "$table_name"
;;
down)
printf 'ip rule del from "%s" table "%s"\n' "$ip_address" "$table_name"
if [ -n "$gateway" ]; then
printf 'ip route del default via "%s" table "%s"\n' "$gateway" "$table_name"
fi
printf 'ip route del "%s/%s" dev "%s" proto static src "%s" table "%s"\n' \
"$network" "$prefix" "$interface" "$ip_address" "$table_name"
;;
*)
echo "Unknown action: $action" >&2
exit 1
;;
esac
# tell the kernel that it needs to re-parse the policy database
printf 'ip route flush cache\n'
) | (
if [ "$NOACTION" ]; then
cat
else
/bin/sh -s
fi
)

View file

@ -0,0 +1,167 @@
cdist-type__network_interface(7)
================================
Steven Armstrong <steven-cdist--@--armstrong.cc>
NAME
----
cdist-type__network_interface - configure network interfaces
DESCRIPTION
-----------
Configures network interfaces on debian an redhat based systems.
Interface names containing a dot are assumed to be vlan tagged sub interfaces.
e.g. eth0.10 is vlan 10 on physical device eth0
REQUIRED PARAMETERS
-------------------
OPTIONAL PARAMETERS
-------------------
name::
The name of the physical or logical network device.
Defaults to __object_id.
method::
The method for determining an IP address for the interface.
'dhcp', 'static' or 'manual'.
Defaults to 'dhcp'.
address::
The IP address of the network interface.
Only used if --method is not 'dhcp'
broadcast::
Only used if --method is not 'dhcp'
comment::
extra-config::
additional config that is added to the generated interfaces file verbatim
gateway::
Default gateway (dotted quad)
Only used if --method is not 'dhcp'
netmask::
The subnet mask to apply to the interface
Only used if --method is not 'dhcp'
metric::
Routing metric for the default gateway
mtu::
The Maximum Transmission Unit size to use for the interface
state::
'present' or 'absent', defaults to 'present'
bond-arp-interval::
Specifies (in milliseconds) how often ARP monitoring occurs.
bond-arp-ip-target::
Specifies the target IP address of ARP requests when the arp_interval parameter is enabled.
Can be specified up to 16 times.
bond-master::
The name of the master (bonding) interface to which this slave should be enslaved.
bond-miimon::
Specifies (in milliseconds) how often MII link monitoring occurs.
bond-mode::
Allows you to specify the bonding policy. The value can be one of:
balance-rr (0)
active-backup (1)
balance-xor (2)
broadcast (3)
802.3ad (4)
balance-tlb (5)
balance-alb (6)
bond-primary::
Specifies the interface name, such as eth0, of the primary device.
bond-slaves::
The slave interfaces that form this bonding.
linkdelay::
Only useable on Redhat based systems.
Time in seconds that the system should pause after the specific interface
is enabled. This may be useful if one interface is connected to a
switch which has spanning tree enabled and must wait for STP to
converge before the interface should be considered usable.
BOOLEAN PARAMETERS
------------------
onboot:
Whether to bring the interface up on boot
hotplug::
Allow/disallow hotplug support for this interface
nodns::
Do not configure nameservers in /etc/resolv.conf.
noroute::
Do not set default route.
no-network-wait-online::
Do not consider this network interface in the network-wait-online.service unit.
symmetric-routing::
Manage routing tables and rules to ensure symmetric routing.
EXAMPLES
--------
--------------------------------------------------------------------------------
__network_interface eth0 --onboot
# Same thing, but explicitly define method
__network_interface eth0 --method dhcp --onboot
__network_interface eth1 \
--method static \
--address 192.168.42.23 \
--netmask 255.255.255.0 \
--gateway 192.168.42.1 \
--onboot
__network_interface eth3 --method dhcp --hotplug
# Don't wait for Infiniband interface to be up before reaching systemd network-online.target
__network_interface ib0 --method dhcp --no-network-wait-online
# active-backup bonding with 2 slaves
__network_interface bond0 \
--onboot \
--method static \
--bond-mode active-backup \
--bond-miimon 500 \
--bond-primary eth5 \
--address 10.205.9.65 \
--netmask 255.255.224.0
__network_interface eth5 \
--onboot \
--method manual \
--bond-master bond0
__network_interface eth6 \
--onboot \
--method manual \
--bond-master bond0
# extra config
__network_interface eth0 \
--method dhcp \
--extra-config - << DONE
post-up ip route add 10.205.0.0/19 via 10.205.161.1
post-up ip route add 10.205.96.0/19 via 10.205.161.1
pre-down ip route del 10.205.0.0/19 via 10.205.161.1
pre-down ip route del 10.205.96.0/19 via 10.205.161.1
DONE
--------------------------------------------------------------------------------
SEE ALSO
--------
- cdist-type(7)
- Redhat bonding documentation
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/sec-Using_Channel_Bonding.html
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Networking_Guide/sec-Using_Channel_Bonding.html
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/s2-networkscripts-interfaces-chan.html
- Debian bonding documentation
/usr/share/doc/ifenslave-2.6/README.Debian.gz
- Symmetric routing
http://www.microhowto.info/howto/ensure_symmetric_routing_on_a_server_with_multiple_default_gateways.html
COPYING
-------
Copyright \(C) 2012-2016 Steven Armstrong. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

View file

@ -0,0 +1,86 @@
#!/bin/sh -e
#
# 2012-2014 Steven Armstrong (steven-cdist at armstrong.cc)
# 2020 Adapted for upstream cdist by Darko Poljak (darko.poljak at gmail.com)
#
# This file is part of cdist.
#
# cdist 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.
#
# cdist 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.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
os=$(cat "$__global/explorer/os")
osv="$(cat "$__global/explorer/os_version")"
not_supported() {
echo "Your operating system ($os $osv) is currently not supported by this type (${__type##*/})." >&2
echo "Please contribute an implementation for it if you can." >&2
exit 1
}
case "$os" in
ubuntu)
osv_int="$(echo "$osv" | tr -d .)"
if [ "$osv_int" -lt 1110 ]; then
not_supported
fi
manifest_file="$__type/files/debian/manifest"
systemd_network_service_name="networking.service"
;;
debian)
manifest_file="$__type/files/debian/manifest"
systemd_network_service_name="networking.service"
;;
centos|redhat)
manifest_file="$__type/files/redhat/manifest"
systemd_network_service_name="network.service"
;;
*)
not_supported
;;
esac
name="$(cat "$__object/parameter/name" 2>/dev/null || echo "$__object_id")"
method="$(cat "$__object/parameter/method")"
state="$(cat "$__object/parameter/state")"
device=
vlan=
case "$name" in
*.*)
device="${name%.*}"
vlan="${name#*.}"
;;
esac
# export variables
export name
export device
export vlan
export method
export state
# run os specific manifest
"$manifest_file"
if grep -q systemd "$__global/explorer/init"; then
sed -e "s|%NETWORK_SERVICE_NAME%|${systemd_network_service_name}|" \
"$__type/files/network-wait-online.service" | \
__file /etc/systemd/system/network-wait-online.service \
--owner root --group root --mode 0644 \
--source -
require="__file/etc/systemd/system/network-wait-online.service" \
__service network-wait-online --no-start
fi

View file

@ -0,0 +1,6 @@
hotplug
nodns
noroute
onboot
no-network-wait-online
symmetric-routing

View file

@ -0,0 +1 @@
dhcp

View file

@ -0,0 +1 @@
present

View file

@ -0,0 +1,20 @@
address
bond-arp-interval
bond-arp-ip-target
bond-master
bond-miimon
bond-mode
bond-primary
bond-slaves
broadcast
comment
extra-config
gateway
linkdelay
method
metric
mtu
name
netmask
network
state