To be undependent from the IP protocol we use, when we use tunnel modes in our code, this function converts the modes to the modes the iproute2 tool uses which often depend on the IP protocol version.
Signed-off-by: Jonatan Schlag jonatan.schlag@ipfire.org --- src/functions/functions.ip-tunnel | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/src/functions/functions.ip-tunnel b/src/functions/functions.ip-tunnel index 7bb4e3f..550b0b3 100644 --- a/src/functions/functions.ip-tunnel +++ b/src/functions/functions.ip-tunnel @@ -21,6 +21,34 @@
IP_TUNNEL_MODES="gre sit vti"
+# This function converts our modes into the type +# the iproute2 tool uses +ip_tunnel_convert_mode_to_iproute2_mode() { + local mode=${1} + local protocol=${2} + + if ! isset mode || ! isset protocol; then + log ERROR "Did not get mode and/or protocol" + return ${EXIT_ERROR} + fi + + if [[ "${protocol}" = "ipv4" ]]; then + # When we use IPv4 we can use our modes + echo "${mode}" + fi + + if [[ "${protocol}" = "ipv6" ]]; then + # When we use IPv6 we have to convert + case "${mode}" in + "vti") + echo "vti6" + ;; + "gre") + echo "ip6gre" + esac + fi +} + ip_tunnel_add() { local device=${1} shift
This functions checks if a device is a vti6 device.
Signed-off-by: Jonatan Schlag jonatan.schlag@ipfire.org --- src/functions/functions.device | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/src/functions/functions.device b/src/functions/functions.device index 2de1ad9..a04111e 100644 --- a/src/functions/functions.device +++ b/src/functions/functions.device @@ -286,6 +286,14 @@ device_is_vti() { [ "${type}" = "768" ] && return ${EXIT_OK} || return ${EXIT_ERROR} }
+device_is_vti6() { + local device=${1} + + local type=$(__device_get_file ${device} type) + + [ "${type}" = "769" ] && return ${EXIT_OK} || return ${EXIT_ERROR} +} + device_get_phy() { local device="${1}"
If we already know that the device must be a ip-tunnel device we can save time when we check just for the types a ip-tunnel device can have.
To avoid code duplication we call this function from device_get_type()
Signed-off-by: Jonatan Schlag jonatan.schlag@ipfire.org --- src/functions/functions.device | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/src/functions/functions.device b/src/functions/functions.device index a04111e..0cd6e4e 100644 --- a/src/functions/functions.device +++ b/src/functions/functions.device @@ -396,9 +396,27 @@ device_get_type() { elif device_is_phy ${device}; then echo "phy"
+ else + echo "$(device_tunnel_get_type "${device}")" + fi +} + +# This function just checks the types a ip-tunnel device usually have +# so when we know that the device is an ip-tunnel device we save time +device_tunnel_get_type() { + local device=${1} + + # If the device does not exist (happens on udev remove events), + # we do not bother to run all checks. + if ! device_exists "${device}"; then + echo "unknown" + elif device_is_vti ${device}; then echo "vti"
+ elif device_is_vti6 ${device}; then + echo "vti6" + else echo "unknown" fi
We cannot mix ipv6 and ipv4 and we also need to detect the IP protocol version to decide which mode we have to use. This is done in a seperated commit.
Signed-off-by: Jonatan Schlag jonatan.schlag@ipfire.org --- src/functions/functions.ip-tunnel | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/src/functions/functions.ip-tunnel b/src/functions/functions.ip-tunnel index 550b0b3..0a0c210 100644 --- a/src/functions/functions.ip-tunnel +++ b/src/functions/functions.ip-tunnel @@ -98,6 +98,24 @@ ip_tunnel_add() { return ${EXIT_ERROR} fi
+ # Detect the IP protocol, which is important to decide which mode we have to use + local remote_address_protocol="$(ip_detect_protocol "${remote_address}")" + + # If we could not detect the IP protocol something with + # ${remote_address} is wrong + if ! isset remote_address_protocol; then + log ERROR "Could not determine remote address IP protocol" + return ${EXIT_ERROR} + fi + + # We cannot mix IPv6 and IPv4 + if [[ "${remote_address_protocol}" != \ + "$(ip_detect_protocol "${local_address}")" ]] ; then + log ERROR "Local and remote address\ + are not from the same IP protocol" + return ${EXIT_ERROR} + fi + # ikey and okey must be set for VTI devices if [ "${mode}" = "vti" ] && (! isset ikey || ! isset okey); then error "--ikey= and --okey= must be set for VTI device"
IPv4 and IPv6 need different types for iproute2. So in the _add function we have to determine the mode based on the IP protocol of the ${remote_address}.
When we change ikey and okey we have to dertermine the mode the device have currently.
Fixes: #11431
Signed-off-by: Jonatan Schlag jonatan.schlag@ipfire.org --- src/functions/functions.ip-tunnel | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/functions/functions.ip-tunnel b/src/functions/functions.ip-tunnel index 0a0c210..3baf280 100644 --- a/src/functions/functions.ip-tunnel +++ b/src/functions/functions.ip-tunnel @@ -150,6 +150,9 @@ ip_tunnel_add() { cmd_args="${cmd_args} ikey ${ikey} okey ${okey}" fi
+ # Determine the mode based on the IP protocol + mode=$(ip_tunnel_convert_mode_to_iproute2_mode "${mode}" "${remote_address_protocol}") + log DEBUG "Creating tunnel device '${device}' (mode=${mode})..."
# Create the device. @@ -208,8 +211,16 @@ ip_tunnel_change_keys() { return ${EXIT_ERROR} fi
+ # Determine the device type + local type="$(device_tunnel_get_type ${device})" + + if ! isoneof "type" vti vti6; then + log ERROR "Device type '${type}' is invalid" + return ${EXIT_ERROR} + fi + if ! cmd ip link change dev "${device}" \ - type vti ikey "${ikey}" okey "${okey}"; then + type "${type}" ikey "${ikey}" okey "${okey}"; then log ERROR "Could not change keys of device ${device}" return ${EXIT_ERROR} fi