From 38f61548e9e2002bddb19630df97aacd26cd7b1f Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Mon, 14 Sep 1981 17:56:44 +0000 Subject: [PATCH] ipv[46]-static: Sum up some functions. I packed some functions together that were kinda redundant for both protocols. Plus a lot of bug fixing. --- functions.device | 41 +++++++------- functions.ip | 77 ++++++++++++++++++++++++++ functions.ipv4 | 19 +++++-- functions.ipv6 | 26 ++++++++- functions.zone | 8 +-- hooks/zones/bridge.configs/ipv4-static | 23 ++------ hooks/zones/bridge.configs/ipv6-static | 24 +++----- 7 files changed, 152 insertions(+), 66 deletions(-) diff --git a/functions.device b/functions.device index 8dea6bd6..1ddc7d2c 100644 --- a/functions.device +++ b/functions.device @@ -472,35 +472,36 @@ function device_discover() { done } -function device_has_ipv4() { +function device_has_ip() { local device=${1} local addr=${2} - if ! device_exists ${device}; then - error "Device '${device}' does not exist." - return ${EXIT_ERROR} - fi + assert isset addr + assert device_exists ${device} + + # IPv6 addresses must be fully imploded + local protocol=$(ip_detect_protocol ${addr}) + case "${protocol}" in + ipv6) + addr=$(ipv6_implode ${addr}) + ;; + esac - ip addr show ${device} | grep -q -e "inet " -e "${addr}" + listmatch ${addr} $(device_get_addresses ${device}) } -function device_has_ipv6() { +function device_get_addresses() { local device=${1} - local addr=${2} - if ! device_exists ${device}; then - error "Device '${device}' does not exist." - return ${EXIT_ERROR} - fi - - local prefix=${addr##*/} - addr=$(ipv6_implode ${addr%%/*}) - - if [ -n "${prefix}" ]; then - addr="${addr}/${prefix}" - fi + assert device_exists ${device} - ip addr show ${device} | grep -q "inet6 ${addr}" + local prot + local addr + local line + ip addr show ${device} | \ + while read prot addr line; do + [ "${prot:0:4}" = "inet" ] && echo "${addr}" + done } function __device_get_file() { diff --git a/functions.ip b/functions.ip index a0dad1a1..1258ac18 100644 --- a/functions.ip +++ b/functions.ip @@ -35,6 +35,9 @@ function ip_get_prefix() { assert isset address + # Break if no prefix is provided + [[ ${address} =~ \/ ]] || return ${EXIT_OK} + echo "${address##*/}" } @@ -46,11 +49,14 @@ function ip_detect_protocol() { local protocol for protocol in ${IP_SUPPORTED_PROTOCOLS}; do if ${protocol}_is_valid ${address}; then + log DEBUG "Address '${address}' was detected to be protocol '${protocol}'." echo "${protocol}" return ${EXIT_OK} fi done + log DEBUG "Protocol version of address '${address}' could not be detected." + return ${EXIT_ERROR} } @@ -61,3 +67,74 @@ function ip_protocol_is_supported() { listmatch ${proto} ${IP_SUPPORTED_PROTOCOLS} } + +function ip_address_add() { + local device=${1} + local address=${2} + + assert isset address + assert device_exists ${device} + + local prefix=$(ip_get_prefix ${address}) + address=$(ip_split_prefix ${address}) + + assert isset prefix + + # Detect the protocol version + local protocol=$(ip_detect_protocol ${address}/${prefix}) + assert ip_protocol_is_supported ${protocol} + + case "${protocol}" in + ipv4) + if ipv4_detect_duplicate ${device} ${address}; then + error_log "Duplicate address detected on zone '${device}' (${address})." + error_log "Cannot continue." + return ${EXIT_ERROR} + fi + ;; + esac + + if ! device_has_ip ${device} ${address}/${prefix}; then + assert ip addr add ${address}/${prefix} dev ${device} + + log DEBUG "IP address '${address}' (${protocol}) was successfully configured on device '${device}'." + + case "${protocol}" in + ipv4) + # Announce our new address to the neighbours + ipv4_update_neighbours ${device} ${address} + ;; + esac + else + log DEBUG "IP address '${address}' (${protocol}) was already configured on device '${device}'." + fi + + return ${EXIT_OK} +} + +function ip_address_del() { + local device=${1} + local address=${2} + + assert isset address + assert device_exists ${device} + + local prefix=$(ip_get_prefix ${address}) + address=$(ip_split_prefix ${address}) + + assert isset prefix + + # Detect the protocol version + local protocol=$(ip_detect_protocol ${address}/${prefix}) + assert ip_protocol_is_supported ${protocol} + + if device_has_ip ${device} ${address}/${prefix}; then + assert ip addr del ${address}/${prefix} dev ${device} + + log DEBUG "IP address '${address}' (${protocol}) was successfully removed from device '${device}'." + else + log DEBUG "IP address '${address}' (${protocol}) was not configured on device '${device}'." + fi + + return ${EXIT_OK} +} diff --git a/functions.ipv4 b/functions.ipv4 index a29fc397..633c5eb4 100644 --- a/functions.ipv4 +++ b/functions.ipv4 @@ -21,17 +21,24 @@ IP_SUPPORTED_PROTOCOLS="${IP_SUPPORTED_PROTOCOLS} ipv4" -function ipv4_split_prefix() { - ip_split_prefix $@ -} - function ipv4_is_valid() { local address=${1} assert isset address - # Cut the /24 if there is one given - address=$(ipv4_split_prefix ${address}) + # Cut the prefix if there is one given + local prefix=$(ip_get_prefix ${address}) + address=$(ip_split_prefix ${address}) + + # If address is larger than 15 characters it cannot be an IPv4 address + [ ${#address} -gt 15 ] && return ${EXIT_ERROR} + + # Check for a valid IPv4 prefix if provided + if [ -n "${prefix}" ]; then + if [ ${prefix} -lt 4 ] || [ ${prefix} -gt 30 ]; then + return ${EXIT_ERROR} + fi + fi local IFS="." local octet diff --git a/functions.ipv6 b/functions.ipv6 index b733d0ca..87e450eb 100644 --- a/functions.ipv6 +++ b/functions.ipv6 @@ -142,9 +142,20 @@ function ipv6_is_valid() { assert isset address + local prefix=$(ip_get_prefix ${address}) + address=$(ip_split_prefix ${address}) + # Check length [ ${#address} -gt 39 ] && return ${EXIT_ERROR} + # Check prefix if provided + if [ -n "${prefix}" ]; then + # XXX need to check was largest prefix is + if [ ${prefix} -lt 0 ] && [ ${prefix} -gt 64 ]; then + return ${EXIT_ERROR} + fi + fi + # XXX find :: twice? # XXX check for documentation prefix? @@ -168,6 +179,10 @@ function ipv6_implode() { return ${EXIT_ERROR} fi + # Save prefix + local prefix=$(ip_get_prefix ${address}) + address=$(ip_split_prefix ${address}) + # Make proper address in exploded format address=$(ipv6_explode ${address}) @@ -253,6 +268,9 @@ function ipv6_implode() { address="${address_new}${address:${pos_end}:${#address}}" fi + # If a prefix was provided we append it in the end + [ -n "${prefix}" ] && address="${address}/${prefix}" + assert ipv6_is_valid ${address} echo "${address}" @@ -263,8 +281,11 @@ function ipv6_explode() { assert isset address + local prefix=$(ip_get_prefix ${address}) + address=$(ip_split_prefix ${address}) + if [ ${#address} -eq 39 ]; then - echo "${address}" + echo "${address}$([ -n "${prefix}" ] && echo "/${prefix}")" return ${EXIT_OK} fi @@ -316,6 +337,9 @@ function ipv6_explode() { done address=${address:1:39} + # If a prefix was provided we append it in the end again + [ -n "${prefix}" ] && address="${address}/${prefix}" + assert ipv6_is_valid ${address} echo "${address}" diff --git a/functions.zone b/functions.zone index 8df8c40d..31c66fb1 100644 --- a/functions.zone +++ b/functions.zone @@ -556,12 +556,8 @@ function zone_configs_status() { zone_configs_cmd config_status $@ } -function zone_has_ipv4() { - device_has_ipv4 $@ -} - -function zone_has_ipv6() { - device_has_ipv6 $@ +function zone_has_ip() { + device_has_ip $@ } function zone_db() { diff --git a/hooks/zones/bridge.configs/ipv4-static b/hooks/zones/bridge.configs/ipv4-static index c9462d5e..b218cf23 100755 --- a/hooks/zones/bridge.configs/ipv4-static +++ b/hooks/zones/bridge.configs/ipv4-static @@ -77,18 +77,7 @@ function _up() { config_read $(zone_dir ${zone})/configs/${config} - if ! zone_has_ipv4 ${zone} ${ADDRESS}/${PREFIX}; then - if ipv4_detect_duplicate ${zone} ${ADDRESS}; then - error_log "Duplicate address detected on zone '${zone}' (${ADDRESS})." - error_log "Cannot continue." - exit ${EXIT_ERROR} - fi - - ip addr add ${ADDRESS}/${PREFIX} dev ${zone} - - # Announce our new address to the neighbours - ipv4_update_neighbours ${zone} ${ADDRESS} - fi + ip_address_add ${zone} ${ADDRESS}/${PREFIX} if zone_is_nonlocal ${zone} && [ -n "${GATEWAY}" ]; then # Save configuration @@ -115,9 +104,7 @@ function _down() { config_read $(zone_dir ${zone})/configs/${config} - if zone_has_ipv4 ${zone} ${ADDRESS}/${PREFIX}; then - ip addr del ${ADDRESS}/${PREFIX} dev ${zone} - fi + ip_address_del ${zone} ${ADDRESS}/${PREFIX} exit ${EXIT_OK} } @@ -135,10 +122,10 @@ function _status() { config_read $(zone_dir ${zone})/configs/${config} printf " %10s - " "${HOOK}" - if zone_has_ipv4 ${zone} ${ADDRESS}/${PREFIX}; then - echo -ne "${COLOUR_ENABLED}ENABLED ${COLOUR_NORMAL}" + if zone_has_ip ${zone} ${ADDRESS}/${PREFIX}; then + echo -ne "${COLOUR_UP} UP ${COLOUR_NORMAL}" else - echo -ne "${COLOUR_DISABLED}DISABLED${COLOUR_NORMAL}" + echo -ne "${COLOUR_DOWN}DOWN${COLOUR_NORMAL}" fi echo " - ${ADDRESS}/${PREFIX}" diff --git a/hooks/zones/bridge.configs/ipv6-static b/hooks/zones/bridge.configs/ipv6-static index f39a293e..d814fe73 100755 --- a/hooks/zones/bridge.configs/ipv6-static +++ b/hooks/zones/bridge.configs/ipv6-static @@ -59,7 +59,7 @@ function _create() { GATEWAY=$(ipv6_explode ${GATEWAY}) fi - config_write $(zone_dir ${zone})/config.${HOOK}.$(ipv6_hash ${ADDRESS}).${PREFIX} ${HOOK_SETTINGS} + config_write $(zone_dir ${zone})/configs/${HOOK}.$(ipv6_hash ${ADDRESS}).${PREFIX} ${HOOK_SETTINGS} exit ${EXIT_OK} } @@ -74,13 +74,9 @@ function _up() { exit ${EXIT_ERROR} fi - config_read $(zone_dir ${zone})/${config} + config_read $(zone_dir ${zone})/configs/${config} - if ! zone_has_ipv6 ${zone} ${ADDRESS}/${PREFIX}; then - ip addr add ${ADDRESS}/${PREFIX} dev ${zone} - else - warning "Do not set IPv6 address '${ADDRESS}/${PREFIX}' because it was already configured on zone '${zone}'." - fi + ip_address_add ${zone} ${ADDRESS}/${PREFIX} if zone_is_nonlocal ${zone} && [ -n "${GATEWAY}" ]; then : # XXX to be done @@ -99,11 +95,9 @@ function _down() { exit ${EXIT_ERROR} fi - config_read $(zone_dir ${zone})/${config} + config_read $(zone_dir ${zone})/configs/${config} - if zone_has_ipv6 ${zone} ${ADDRESS}/${PREFIX}; then - ip addr del ${ADDRESS}/${PREFIX} dev ${zone} - fi + ip_address_del ${zone} ${ADDRESS}/${PREFIX} exit ${EXIT_OK} } @@ -118,13 +112,13 @@ function _status() { exit ${EXIT_ERROR} fi - config_read $(zone_dir ${zone})/${config} + config_read $(zone_dir ${zone})/configs/${config} printf " %10s - " "${HOOK}" - if zone_has_ipv6 ${zone} ${ADDRESS}/${PREFIX}; then - echo -ne "${COLOUR_OK} OK ${COLOUR_NORMAL}" + if zone_has_ip ${zone} ${ADDRESS}/${PREFIX}; then + echo -ne "${COLOUR_UP} UP ${COLOUR_NORMAL}" else - echo -ne "${COLOUR_ERROR}ERROR${COLOUR_NORMAL}" + echo -ne "${COLOUR_DOWN}DOWN${COLOUR_NORMAL}" fi echo " - $(ipv6_implode ${ADDRESS})/${PREFIX}" -- 2.47.2