diff options
Diffstat (limited to 'net-scripts/net.modules.d/iproute2.sh')
-rw-r--r-- | net-scripts/net.modules.d/iproute2.sh | 392 |
1 files changed, 392 insertions, 0 deletions
diff --git a/net-scripts/net.modules.d/iproute2.sh b/net-scripts/net.modules.d/iproute2.sh new file mode 100644 index 0000000..498eea6 --- /dev/null +++ b/net-scripts/net.modules.d/iproute2.sh @@ -0,0 +1,392 @@ +# Copyright (c) 2004-2006 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# Contributed by Roy Marples (uberlord@gentoo.org) + +# Fix any potential localisation problems +# Note that LC_ALL trumps LC_anything_else according to locale(7) +ip() { + LC_ALL=C /sbin/ip "$@" +} +iproute2_tunnel() { + LC_ALL=C /sbin/ip tunnel "$@" +} + +# void iproute2_depend(void) +# +# Sets up the dependancies for the module +iproute2_depend() { + provide interface + functions interface_device +} + +# void iproute2_expose(void) +# +# Expose variables that can be configured +iproute2_expose() { + variables config routes fallback metric ipaddr ipaddr_fallback iproute inet6 +} + +# bool iproute2_check_installed(void) +# +# Returns 1 if iproute2 is installed, otherwise 0 +iproute2_check_installed() { + local report="${1:-false}" installed="0" + if [[ ! -x /sbin/ip ]] ; then + installed="1" + ${report} && eerror "For iproute2 support, emerge sys-apps/iproute2" + fi + if [[ ! -e /proc/net/netlink ]] ; then + installed="1" + ${report} && eerror "iproute2 requires NetLink enabled in the kernel" + fi + return "${installed}" +} + +# bool iproute2_exists(char *interface, bool report) +# +# Returns 1 if the interface exists, otherwise 0 +iproute2_exists() { + local e="$( ip addr show label "$1" )" report="${2:-false}" + [[ -n ${e} ]] && return 0 + + if ${report} ; then + eerror "network interface $1 does not exist" + eerror "Please verify hardware or kernel module (driver)" + fi + return 1 +} + +# void iproute2_up(char *interface) +# +# provides a generic interface for bringing interfaces up +iproute2_up() { + ip link set up dev "$1" +} + +# void iproute2_down(char *interface) +# +# provides a generic interface for bringing interfaces up +iproute2_down() { + ip link set down dev "$1" +} + +# bool ifproute2_is_up(char *iface, bool withaddress) +# +# Returns 0 if the interface is up, otherwise 1 +# If withaddress is true then the interface has to have an IPv4 address +# assigned as well +iproute2_is_up() { + local check="\<UP\>" addr="${2:-false}" + ${addr} && check="${check}.*inet " + ip addr show "$1" | xargs | grep -Eq "${check}" && return 0 + return 1 +} + +# void iproute2_set_flag(char *iface, char *flag, bool enabled) +# +# Sets or disables the interface flag +iproute2_set_flag() { + local enable="$3" opt="on" + ${enable} || opt="off" + ip link set "$1" "$2" "${opt}" +} + +# void iproute2_get_address(char *interface) +# +# Fetch the address retrieved by DHCP. If successful, echoes the +# address on stdout, otherwise echoes nothing. +iproute2_get_address() { + ip -family inet addr show "$1" | sed -n -e 's/.*inet \([^ ]*\).*/\1/p' +} + +# bool iproute2_is_ethernet(char *interface) +# +# Return 0 if the link is ethernet, otherwise 1. +iproute2_is_ethernet() { + ip link show "$1" | grep -q "^[[:space:]]*link/ether[[:space:]]*" +} + +# void iproute2_get_mac_address(char *interface) +# +# Fetch the mac address assingned to the network card +iproute2_get_mac_address() { + local mac="$( ip link show "$1" | sed -n -e \ + '/link\// s/^.*\<\(..:..:..:..:..:..\)\>.*/\U\1/p' )" + [[ ${mac} != '00:00:00:00:00:00' \ + && ${mac} != '44:44:44:44:44:44' \ + && ${mac} != 'FF:FF:FF:FF:FF:FF' ]] \ + && echo "${mac}" +} + +# void iproute2_set_mac_address(char *interface, char *mac) +# +# Assigned the mac address to the network card +iproute2_set_mac_address() { + ip link set address "$2" dev "$1" +} + +# int iproute2_set_name(char *interface, char *new_name) +# +# Renames the interface +# This will not work if the interface is setup! +iproute2_set_name() { + ip link set name "$2" dev "$1" +} + +# void iproute2_get_aliases_rev(char *interface) +# +# Fetch the list of aliases for an interface. +# Outputs a space-separated list on stdout, in reverse order, for +# example "eth0:2 eth0:1" +iproute2_get_aliases_rev() { + local iface="$( interface_device "$1" )" + ip addr show dev "${iface}" | grep -o "${iface}:[0-9].*" | tac +} + +# bool iproute2_del_addresses(char *interface, bool onlyinet) +# +# Remove addresses from interface. +# If onlyinet is true, then we only remove IPv4 / inet addresses. +iproute2_del_addresses() { + local pre="" + ${2:-false} && pre="-f inet" + ip ${pre} addr flush label "$1" scope global &>/dev/null + ip ${pre} addr flush label "$1" scope site &>/dev/null + ip ${pre} addr flush label "$1" scope host &>/dev/null + return 0 +} + +# bool iproute2_get_old_config(char *iface) +# +# Returns config and config_fallback for the given interface +iproute2_get_old_config() { + local ifvar="$( bash_variable "$1" )" inet6="" t="" + + # iproute2-style config vars + t="ipaddr_${ifvar}[@]" + config=( "${!t}" ) + t="config_fallback_${ifvar}[@]" + config_fallback=( "${!t}" ) + t="inet6_${ifvar}[@]" + inet6=( "${!t}" ) + + # BACKWARD COMPATIBILITY: check for space-separated inet6 addresses + [[ ${#inet6[@]} == "1" && ${inet6} == *" "* ]] && inet6=( ${inet6} ) + + # Add inet6 addresses to our config if required + [[ -n ${inet6} ]] && config=( "${config[@]}" "${inet6[@]}" ) + + # Support old style iface_xxx syntax + if [[ -z ${config} ]] ; then + if is_function ifconfig_get_old_config ; then + ifconfig_get_old_config "${iface}" + fi + fi + + return 0 +} + +# bool iproute2_iface_stop(char *interface) +# +# Do final shutdown for an interface or alias. +# +# Returns 0 (true) when successful, non-zero (false) on failure +iproute2_iface_stop() { + local label="$1" iface="$( interface_device "$1" )" + + # Shut down the link if this isn't an alias or vlan + if [[ ${label} == "${iface}" ]] ; then + iproute2_down "${iface}" + return $? + fi + return 0 +} + +# bool iproute2_add_address(char *interface, char *options ...) +# +# Adds an the specified address to the interface +# returns 0 on success and non-zero on failure +iproute2_add_address() { + local iface="$1" x="" + + iproute2_exists "${iface}" true || return 1 + + # Extract the config + local -a config=( "$@" ) + config=( ${config[@]:1} ) + + # Convert an ifconfig line to iproute2 + local n="${#config[@]}" + for (( x=0; x<n; x++ )); do + case "${config[x]}" in + netmask) + config[0]="${config[0]}/$( netmask2cidr "${config[x+1]}" )" + unset config[x] config[x+1] + ;; + mtu) + ip link set mtu "${config[x+1]}" dev "${iface}" + unset config[x] config[x+1] + ;; + esac + done + config=( "${config[@]//pointopoint/peer}" ) + + # Always scope lo addresses as host unless specified otherwise + [[ ${iface} == "lo" && " ${config[@]} " != *" scope "* ]] \ + && config=( "${config[@]}" "scope host" ) + + # IPv4 specifics + if [[ ${config[@]} == *.*.*.* ]] ; then + # Work out a broadcast if none supplied + [[ ${config[@]} != *" brd "* && ${config[@]} != *" broadcast "* ]] \ + && config=( "${config[@]}" "brd +" ) + fi + + # Ensure that the interface is up so we can add IPv6 addresses + interface_up "${iface}" + + # Some kernels like to apply lo with an address when they are brought up + if [[ ${iface} == "lo" \ + && ${config[@]} == "127.0.0.1/8 brd 127.255.255.255 scope host" ]] ; then + ip addr del dev "${iface}" 127.0.0.1/8 2>/dev/null + fi + + ip addr add dev "${iface}" ${config[@]} + local r="$?" + [[ ${r} != "0" ]] && return "${r}" + + local ifvar="$( bash_variable "${iface}" )" + # Remove the newly added route and replace with our metric + local metric="metric_${ifvar}" + [[ ${!metric:-0} == "0" ]] && return "${r}" + + local network="$( ip_network "${config[0]}" )" + [[ -z ${network} ]] && return "${r}" + + local cidr="${config[0]##*/}" + if ip route del "${network}/${cidr}" metric 0 dev "${iface}" \ + 2>/dev/null ; then + ip route add "${network}/${cidr}" metric "${!metric:-0}" dev "${iface}" + fi + + return "${r}" +} + +# bool iproute2_pre_start(char *interface) +# +# Runs any pre_start stuff on our interface - just the MTU atm +# We set MTU twice as it may be needed for DHCP - a dhcp client could +# change it in error, so we set MTU in post start too +iproute2_pre_start() { + local iface="$1" + + interface_exists "${iface}" || return 0 + + local ifvar="$( bash_variable "$1" )" + + # MTU support + local mtu="mtu_${ifvar}" + [[ -n ${!mtu} ]] && ip link set mtu "${!mtu}" dev "${iface}" + + return 0 +} + +# bool iproute2_post_start(char *interface) +# +# Runs any post_start stuff on our interface and adds routes +# Always returns 0 +iproute2_post_start() { + local iface="$1" ifvar="$( bash_variable "$1" )" x="" + + iproute2_exists "${iface}" || return 0 + + # Make sure interface is marked UP + iproute2_up "${iface}" + + # MTU support + local mtu="mtu_${ifvar}" + [[ -n ${!mtu} ]] && ip link set mtu "${!mtu}" dev "${iface}" + + local x="routes_${ifvar}[@]" + local -a routes=( "${!x}" ) + local metric="metric_${ifvar}" + + # Test for old style ipaddr variable + if [[ -z ${routes} ]] ; then + t="iproute_${ifvar}[@]" + routes=( "${!t}" ) + fi + + # Set routes with ip route -- this might also include default route + if [[ -n ${routes} ]] ; then + einfo "Adding routes" + eindent + for x in "${routes[@]}"; do + ebegin "${x}" + + # Support net-tools routing too + x="${x//gw/via}" + x="${x//-A inet6/}" + x="${x//-net/}" + [[ " ${x} " == *" -host "* ]] && x="${x//-host/} scope host" + + # Attempt to support net-tools route netmask option + netmask="${x##* netmask }" + if [[ -n ${netmask} && ${x} != "${netmask}" ]] ; then + netmask="${netmask%% *}" + x="${x// netmask ${netmask} / }" + local -a a=( ${x} ) + a[0]="${a[0]}/$( netmask2cidr "${netmask}")" + x="${a[@]}" + fi + + # Add a metric if we don't have one + [[ " ${x} " != *" metric "* ]] && x="${x} metric ${!metric}" + + ip route append ${x} dev "${iface}" + eend $? + done + eoutdent + fi + + # Flush the route cache + ip route flush cache dev "${iface}" + + return 0 +} + +# void iproute2_route_metric(char* interface, int metric) +# +# Change all routes for an interface to a given metric +iproute2_route_metric() { + local route="" + ip route | grep " dev $1" | { + while read route ; do + ip route del ${route} + ip route add ${route} metric "$2" + done + } +} + +# void iproute2_default_route(char* interface, char* gateway_ip, int metric) +# +# Force default route to the specified gateway, optionally on +# the given interface +iproute2_default_route() { + local metric="${3:-0}" + + ip route change default via "$2" metric "${metric}" dev "$1" 2>/dev/null \ + || ip route append default via "$2" metric "${metric}" dev "$1" 2>/dev/null +} + +# void iproute2_post_stop(char* interface) +iproute2_post_stop() { + local iface="$1" rule="" + + iproute2_exists "${iface}" || return + + # Flush the route cache + ip route flush cache dev "${iface}" +} + +# vim: set ft=sh ts=4 : |