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() {
assert isset address
+ # Break if no prefix is provided
+ [[ ${address} =~ \/ ]] || return ${EXIT_OK}
+
echo "${address##*/}"
}
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}
}
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}
+}
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
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?
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})
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}"
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
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}"
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() {
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
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}
}
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}"
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}
}
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
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}
}
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}"