From 247e67860343d7110cbd58ce071d4eed3a06542b Mon Sep 17 00:00:00 2001 From: Jaymin Patel Date: Sun, 31 Jul 2022 12:30:26 +0530 Subject: [PATCH] libreswan: uci configuration support - add patch to call hotplug script - handle uci config with reload in init script Signed-off-by: Jaymin Patel --- net/libreswan/Makefile | 30 ++- net/libreswan/files/ipsec.init | 234 +++++++++++++++++- net/libreswan/files/iptables.hotplug | 44 ++++ net/libreswan/files/libreswan.defaults | 31 +++ net/libreswan/files/libreswan.rpcd | 180 ++++++++++++++ net/libreswan/files/libreswan.uci | 37 +++ net/libreswan/files/user.hotplug | 7 + net/libreswan/files/vti.hotplug | 28 +++ .../patches/050-updown-hotplug.patch | 8 + 9 files changed, 580 insertions(+), 19 deletions(-) mode change 100755 => 100644 net/libreswan/files/ipsec.init create mode 100644 net/libreswan/files/iptables.hotplug create mode 100644 net/libreswan/files/libreswan.defaults create mode 100644 net/libreswan/files/libreswan.rpcd create mode 100644 net/libreswan/files/libreswan.uci create mode 100644 net/libreswan/files/user.hotplug create mode 100644 net/libreswan/files/vti.hotplug create mode 100644 net/libreswan/patches/050-updown-hotplug.patch diff --git a/net/libreswan/Makefile b/net/libreswan/Makefile index b05b29e59e062d..031ac0265b3178 100644 --- a/net/libreswan/Makefile +++ b/net/libreswan/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libreswan PKG_VERSION:=4.7 -PKG_RELEASE:=1 +PKG_RELEASE:=$(AUTORELEASE) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://download.libreswan.org/ @@ -61,9 +61,10 @@ endef define Package/libreswan/conffiles /etc/ipsec.d -/etc/ipsec.conf -/etc/ipsec.secrets +/etc/config/libreswan +/etc/ipsec.user endef + TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed TARGET_CFLAGS += -flto @@ -101,20 +102,33 @@ endef define Package/libreswan/install $(INSTALL_DIR) \ - $(1)/etc/init.d \ $(1)/etc/ipsec.d/policies \ $(1)/usr/libexec/ipsec \ - $(1)/usr/sbin + $(1)/usr/sbin \ + $(1)/etc/uci-defaults \ + $(1)/etc/config \ + $(1)/etc/init.d \ + $(1)/etc/hotplug.d/ipsec \ + $(1)/usr/libexec/rpcd $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/ipsec \ $(1)/usr/sbin/ipsec - $(INSTALL_BIN) ./files/ipsec.init $(1)/etc/init.d/ipsec - $(INSTALL_DATA) ./files/ipsec.conf $(1)/etc/ipsec.conf - $(INSTALL_DATA) ./files/ipsec.secrets $(1)/etc/ipsec.secrets $(INSTALL_DATA) $(PKG_INSTALL_DIR)/etc/ipsec.d/policies/* \ $(1)/etc/ipsec.d/policies/ $(CP) $(PKG_INSTALL_DIR)/usr/libexec/ipsec/* \ $(1)/usr/libexec/ipsec/ + + $(INSTALL_BIN) ./files/ipsec.init $(1)/etc/init.d/ipsec + $(INSTALL_DATA) ./files/ipsec.conf $(1)/etc/ipsec.conf + $(INSTALL_DATA) ./files/ipsec.secrets $(1)/etc/ipsec.secrets + + $(INSTALL_DATA) ./files/libreswan.uci $(1)/etc/config/libreswan + + $(INSTALL_DATA) ./files/user.hotplug $(1)/etc/hotplud.d/libreswan/01-user + $(INSTALL_DATA) ./files/vti.hotplug $(1)/etc/hotplud.d/libreswan/02-vti + $(INSTALL_DATA) ./files/iptables.hotplug $(1)/etc/hotplud.d/libreswan/03-iptables + + $(INSTALL_BIN) ./files/libreswan.rpcd $(1)/usr/libexec/rpcd/libreswan endef $(eval $(call BuildPackage,libreswan)) diff --git a/net/libreswan/files/ipsec.init b/net/libreswan/files/ipsec.init old mode 100755 new mode 100644 index f33d41292420a8..3ff5f5cd45e072 --- a/net/libreswan/files/ipsec.init +++ b/net/libreswan/files/ipsec.init @@ -1,36 +1,248 @@ #!/bin/sh /etc/rc.common +. /lib/functions/network.sh + START=90 STOP=10 USE_PROCD=1 + PROG="/usr/libexec/ipsec/pluto" -IPSEC_SECRETS=/etc/ipsec.secrets -IPSEC_CONF=/etc/ipsec.conf -IPSEC_BIN=/usr/sbin/ipsec +IPSEC_BIN="/usr/sbin/ipsec" + +IPSEC_DIR="/var/run/ipsec" +IPSEC_CONF="$IPSEC_DIR/ipsec.conf" +IPSEC_SECRETS="$IPSEC_DIR/ipsec.secrets" +IPSEC_CONF_DIR="$IPSEC_DIR/conf.d" checkconfig() { - ${IPSEC_BIN} addconn --checkconfig || return 1 - mkdir -p /var/run/pluto + ${IPSEC_BIN} addconn --checkconfig || return 1 + mkdir -p /var/run/pluto +} + +expand_ike() { + local id="$1" + local encryption_algorithm hash_algorithm dh_group proposal + + config_get encryption_algorithm "${id}" encryption_algorithm + config_get hash_algorithm "${id}" hash_algorithm + config_get dh_group "${id}" dh_group + + proposal="${encryption_algorithm:+${encryption_algorithm}${hash_algorithm:+-${hash_algorithm}${dh_group:+;${dh_group%% *}}}}" + append ike_proposal "$proposal" "," +} + +expand_phase2alg() { + local id="$1" + local encryption_algorithm hash_algorithm dh_group + + config_get encryption_algorithm "${id}" encryption_algorithm + config_get hash_algorithm "${id}" hash_algorithm + config_get dh_group "${id}" dh_group + + phase2alg_proposal="${encryption_algorithm:+${encryption_algorithm// /+}${hash_algorithm:+-${hash_algorithm// /+}${dh_group:+-${dh_group// /+}}}}" +} + +generate_tunnel_config() { + local id=$1 + local config_file="$IPSEC_CONF_DIR/$id.conf" + local secret_file="$IPSEC_CONF_DIR/$id.secret" + + config_get auto "$id" auto + config_get left "$id" left + config_get right "$id" right + config_get leftid "$id" leftid "$left" + config_get rightid "$id" rightid "$right" + config_get leftsourceip "$id" leftsourceip + config_get rightsourceip "$id" rightsourceip + config_get leftsubnets "$id" leftsubnets + config_get rightsubnets "$id" rightsubnets + config_get_bool ikev2 "$id" ikev2 + [ "$ikev2" = "1" ] && ikev2=yes || ikev2=no + config_get_bool rekey "$id" rekey + [ "$rekey" = "1" ] && rekey=yes || rekey=no + config_get ikelifetime "$id" ikelifetime + config_get rekeymargin "$id" rekeymargin + config_get dpdaction "$id" dpdaction + config_get dpdtimeout "$id" dpdtimeout + config_get dpddelay "$id" dpddelay + config_get phase2 "$id" phase2 + config_get phase2alg "$id" phase2alg + config_get vti_interface "$id" vti_interface + + if [ -n "$vti_interface" ]; then + config_get leftvti "$id" leftvti + config_get mark "$id" mark + fi + + config_list_foreach "$id" ike expand_ike + config_list_foreach "$id" phase2alg expand_phase2alg + + config_get authby "$id" authby + config_get psk "$id" psk + + if [ -n "$leftsubnets" ]; then + [[ "$leftsubnets" =~ 0.0.0.0* ]] && leftsubnets="0.0.0.0/0" + leftsubnets="{${leftsubnets// /,}}" + fi + + if [ -n "$rightsubnets" ]; then + [[ "$rightsubnets" =~ 0.0.0.0* ]] && rightsubnets="0.0.0.0/0" + rightsubnets="{${rightsubnets// /,}}" + fi + + cat << EOF > "$config_file" +conn $id + auto=${auto} + authby=${authby} + ikev2=${ikev2} + left=${left%% *} + ${leftid:+leftid=${leftid}} + ${leftsourceip:+leftsourceip=${leftsourceip}} + ${leftsubnets:+leftsubnets=${leftsubnets}} + right=${right%% *} + ${rightid:+rightid=${rightid}} + ${rightsourceip:+rightsourceip=${rightsourceip}} + ${rightsubnets:+rightsubnets=${rightsubnets}} + ${dpdaction:+dpdaction=${dpdaction}} + ${dpdtimeout:+dpdtimeout=${dpdtimeout}} + ${dpddelay:+dpddelay=${dpddelay}} + ${ikelifetime:+ikelifetime=${ikelifetime}s} + ${rekey:+rekey=${rekey}} + ${rekeymargin:+rekeymargin=${rekeymargin}s} + ${rekeyfuzz:+rekeyfuzz=${rekeyfuzz}} + ${phase2:+phase2=${phase2}} + ${ike_proposal:+ike=${ike_proposal}} + ${phase2alg_proposal:+phase2alg=${phase2alg_proposal}} + ${vti_interface:+vti-interface=${vti_interface}} + ${leftvti:+leftvti=${leftvti}} + ${mark:+mark=${mark}} +EOF + +cat << EOF > "$secret_file" +$leftid $rightid : PSK "$psk" +EOF + + unset ike_proposal phase2alg_proposal +} + +generate_daemon_config() { + config_get_bool debug globals debug 0 + [ "$debug" = "0" ] && debug=none || debug=all + config_get_bool uniqueids globals uniqueids 0 + [ "$uniqueids" = "0" ] && uniqueids=no || uniqueids=yes + config_get listen globals listen + config_get listen_interface globals listen_interface + [ -n "$listen_interface" ] && network_get_ipaddr listen "$listen_interface" + config_get virtual_private globals virtual_private + [ -z "$virtual_private" ] && virtual_private='10.0.0.0/8 192.168.0.0/16 172.16.0.0/12 25.0.0.0/8 100.64.0.0/10 !100.64.0.0/24' + + [ ! -d $IPSEC_DIR ] && mkdir -p $IPSEC_DIR + [ ! -d $IPSEC_CONF_DIR ] && mkdir -p $IPSEC_CONF_DIR + + cat << EOF > "$IPSEC_SECRETS" +include /etc/ipsec.d/*.secrets +include $IPSEC_CONF_DIR/*.secret +EOF + + cat << EOF > "$IPSEC_CONF" +config setup + ${debug:+plutodebug=${debug}} + ${uniqueids:+uniqueids=${uniqueids}} + ${listen:+listen=${listen}} + ${virtual_private:+virtual-private=%v4:${virtual_private// /,%v4:}} + secretsfile=${IPSEC_SECRETS} + +include /etc/ipsec.d/*.conf +include $IPSEC_CONF_DIR/*.conf +EOF +} + +clean_config() { + rm -f $IPSEC_CONF_DIR/*.conf $IPSEC_CONF_DIR/*.secret +} + +config_cb() { + local var="CONFIG_${1}_SECTIONS" + export $var + append "$var" "$2" +} + +generate_config() { + config_load libreswan + generate_daemon_config + config_foreach generate_tunnel_config tunnel +} + +regenerate_config() { + clean_config + generate_config +} + +active_conns() { + local active_conns file _file + + active_conns=$(${IPSEC_BIN} --trafficstatus | awk -F'[":/]' '{print $3}' | sort -u) + + for file in $IPSEC_CONF_DIR/*.conf; do + _file="${file##*/}" + list_contains active_conns "$_file" || append active_conns "${_file%%.*}" + done + + echo "$active_conns" } start_service() { + generate_config checkconfig || return 1 - ipsec _stackmanager start + ${IPSEC_BIN} _stackmanager start # Enable nflog if configured - ipsec --checknflog > /dev/null + ${IPSEC_BIN} --checknflog > /dev/null procd_open_instance - procd_set_param command $PROG --config ${IPSEC_CONF} --nofork --secretsfile ${IPSEC_SECRETS} + procd_set_param command $PROG --config ${IPSEC_CONF} --nofork procd_set_param respawn procd_close_instance } stop_service() { - ipsec whack --shutdown - ipsec _stackmanager stop - ipsec --stopnflog > /dev/null + ${IPSEC_BIN} whack --shutdown + ${IPSEC_BIN} _stackmanager stop + ${IPSEC_BIN} --stopnflog > /dev/null +} +delete_tunnel() { + ${IPSEC_BIN} auto --delete "$1" > /dev/null 2>&1 + rm -f ${IPSEC_CONF_DIR}/$1.* } +add_tunnel() { + generate_tunnel_config "$1" + ${IPSEC_BIN} auto --add "$1" > /dev/null 2>&1 + ${IPSEC_BIN} auto --rereadsecrets + ${IPSEC_BIN} auto --up "$1" > /dev/null 2>&1 & +} + +reload_service() { + local active_tunnels uci_tunnels + + config_load libreswan + config_get uci_tunnels tunnel SECTIONS + + active_tunnels="$(active_conns)" + + for tunnel in $active_tunnels; do + list_contains uci_tunnels "$tunnel" || delete_tunnel "$tunnel" + done + + for tunnel in $uci_tunnels; do + list_contains active_tunnels "$tunnel" || add_tunnel "$tunnel" + done + + ${IPSEC_BIN} auto --rereadall +} + +service_triggers() { + procd_add_reload_trigger 'libreswan' +} diff --git a/net/libreswan/files/iptables.hotplug b/net/libreswan/files/iptables.hotplug new file mode 100644 index 00000000000000..6d5470ddb238c4 --- /dev/null +++ b/net/libreswan/files/iptables.hotplug @@ -0,0 +1,44 @@ +#!/bin/sh + +. /lib/functions.sh + +IPTABLES="iptables -w" +IPSEC_HOOK="ipsec_hook" +IPSEC_SET="IPSEC_REMOTE_SUBNETS" + +init_ipsec_chains_rules() { + $IPTABLES -t filter -N "$IPSEC_HOOK" + $IPTABLES -t filter -C forwarding_rule -j "$IPSEC_HOOK" + [ $? -ne 0 ] && $IPTABLES -t filter -I forwarding_rule -j "$IPSEC_HOOK" + + $IPTABLES -t filter -C "$IPSEC_HOOK" -m set --match-set "$IPSEC_SET" src -j ACCEPT + [ $? -ne 0 ] && $IPTABLES -t filter -A "$IPSEC_HOOK" -m set --match-set "$IPSEC_SET" src -j ACCEPT + + $IPTABLES -t nat -N "$IPSEC_HOOK" + $IPTABLES -t nat -C postrouting_rule -j "$IPSEC_HOOK" + [ $? -ne 0 ] && $IPTABLES -t nat -I postrouting_rule -j "$IPSEC_HOOK" + + $IPTABLES -t nat -C "$IPSEC_HOOK" -m set --match-set "$IPSEC_SET" dst -m policy --dir out --pol ipsec -j ACCEPT + [ $? -ne 0 ] && $IPTABLES -t nat -A "$IPSEC_HOOK" -m set --match-set "$IPSEC_SET" dst -m policy --dir out --pol ipsec -j ACCEPT +} + +rightsubnets_rules() { + local id=$1 + local subnet + + config_get rightsubnets "$id" rightsubnets + + ipset flush "$IPSEC_SET" + for subnet in $rightsubnets; do + [ -z "$subnet" ] && continue + ipset -exist add "$IPSEC_SET" "$subnet" comment "$id" + done +} + +update_ipsec_ipsets() { + config_load libreswan + config_foreach rightsubnets_rules tunnel +} + +init_ipsec_chains_rules +update_ipsec_ipsets diff --git a/net/libreswan/files/libreswan.defaults b/net/libreswan/files/libreswan.defaults new file mode 100644 index 00000000000000..57230ecf8e3e33 --- /dev/null +++ b/net/libreswan/files/libreswan.defaults @@ -0,0 +1,31 @@ +#!/bin/sh + +. /lib/functions.sh + +add_firewall_include() { + local include=libreswan_rules + + if [ "$(uci_get firewall $include)" != "include" ]; then + uci_add firewall include "$include" + uci_set firewall "$include" path "/etc/hotplud.d/ipsec/03-iptables" + uci_set firewall "$include" reload "1" + fi +} + +add_firewall_ipset() { + local ipset=IPSEC_REMOTE_SUBNETS + + if [ "$(uci_get firewall $ipset)" != "ipset" ]; then + uci_add firewall ipset "$ipset" + uci_set firewall "$ipset" name "$ipset" + uci_set firewall "$ipset" match "dst_net" + uci_set firewall "$ipset" storage "hash" + uci_set firewall "$ipset" enabled "1" + uci_set firewall "$ipset" comment "1" + fi +} + +add_firewall_include +add_firewall_ipset + +uci_commit firewall diff --git a/net/libreswan/files/libreswan.rpcd b/net/libreswan/files/libreswan.rpcd new file mode 100644 index 00000000000000..65a04472baac8d --- /dev/null +++ b/net/libreswan/files/libreswan.rpcd @@ -0,0 +1,180 @@ +#!/bin/sh + +. /lib/functions.sh +. /usr/share/libubox/jshn.sh + +RPC_SCRIPTS=/usr/libexec/libreswan/rpc + +[ -d $RPC_SCRIPTS ] && include $RPC_SCRIPTS + +IPSEC_TRAFFIC_STATES="/tmp/ipsec_traffic.$$" +IPSEC_TUNNEL_STATES="/tmp/ipsec_states.$$" + +__function__() { + type "$1" > /dev/null 2>&1 +} + +foreach_extra() { + local file obj + + [ ! -d $RPC_SCRIPTS ] && return + + for file in $RPC_SCRIPTS/*; do + obj="${file##*/}" + $1 "${obj%%.*}" + done +} + +get_index() { + [ $# -lt 2 ] && return 1 + + local var=$1 + local str=$2 + local ele + local i=1 + + eval "val=\"\${$var}\"" + + for ele in ${val}; do + if [[ "$ele" = "$str" ]]; then + echo "$i" + return 0 + fi + ((i++)) + done + + return 1 +} + +phase1_established() { + grep -q "\"$1\":500 .*(IKE SA established)" "$IPSEC_TUNNEL_STATES" +} + +phase2_established() { + grep -q "\"$1\":500 .*(IPsec SA established)" "$IPSEC_TUNNEL_STATES" +} + +add_tunnel_object() { + local id="$1" + local leftsubnets rightsubnets right ctime + local phase1=0 phase2=0 + + config_get right "$id" right + config_get leftsubnets "$id" leftsubnets + config_get rightsubnets "$id" rightsubnets + + json_add_array tunnels + + for lsubnet in $leftsubnets; do + lidx=$(get_index leftsubnets $lsubnet) + for rsubnet in $rightsubnets; do + ridx=$(get_index rightsubnets $rsubnet) + tid="${id}/${lidx}x${ridx}" + + eval $(awk -F, '{if ($1 ~ "'"$tid"'" ) {printf("%s %s %s", $3, $4, $5)};}' "$IPSEC_TRAFFIC_STATES") + json_add_object tunnels + json_add_string name "$id" + json_add_string right "$right" + json_add_string leftsubnet "$lsubnet" + json_add_string rightsubnet "$rsubnet" + json_add_int tx "$outBytes" + json_add_int rx "$inBytes" + + phase1_established "$tid" && phase1=1 + phase2_established "$tid" && phase2=1 + + json_add_boolean phase1 "$phase1" + json_add_boolean phase2 "$phase2" + + if [ "$phase1" = "1" ] && [ "$phase2" = "1" ]; then + ctime="$(date +%s)" + json_add_boolean connected 1 + json_add_int uptime "$((ctime - add_time))" + else + json_add_boolean connected 0 + json_add_int uptime 0 + fi + + json_close_object + done + done + json_close_array +} + +generate_libreswan_states() { + ipsec trafficstatus > "$IPSEC_TRAFFIC_STATES" + ipsec showstates > "$IPSEC_TUNNEL_STATES" +} + +clean_libreswan_states() { + return + rm -f "$IPSEC_TRAFFIC_STATES" "$IPSEC_TUNNEL_STATES" +} + +libreswan_status() { + config_load libreswan + + generate_libreswan_states + + json_init + config_foreach add_tunnel_object tunnel + json_dump + + clean_libreswan_states +} + +call_extra() { + if __function__ "$1"; then + $1 + else + json_init + json_add_string error "invalid call $1" + json_dump + fi +} + +call_method() { + case "$1" in + status) + libreswan_status + ;; + *) + call_extra $1 + ;; + esac +} + +list_extra() { + if __function__ "${1}_help"; then + ${1}_help + else + json_add_object "$1" + json_close_object + fi +} + +list_methods() { + local file + + json_init + + json_add_object status + json_close_object + + foreach_extra list_extra ${1} + + json_dump +} + +main () { + case "$1" in + list) + list_methods + ;; + call) + call_method $2 + ;; + esac +} + +main "$@" diff --git a/net/libreswan/files/libreswan.uci b/net/libreswan/files/libreswan.uci new file mode 100644 index 00000000000000..2e3718a1936c52 --- /dev/null +++ b/net/libreswan/files/libreswan.uci @@ -0,0 +1,37 @@ +config libreswan 'globals' + option debug '0' # set debug mode none/all + list virtual_private '10.0.0.0/8' + list virtual_private '192.168.0.0/16' + list virtual_private '172.16.0.0/12' + list virtual_private '25.0.0.0/8' + list virtual_private '100.64.0.0/10' + list virtual_private '!100.64.0.0/24' # the address ranges that may live behind a NAT router through which a client connects + # option listen '192.168.2.100' # listening address, if set listen_interface would not be used + # option listen_interface 'wan' # listening interface + # option uniqueids 'yes' # yes/no + +# config crypto_proposal 'p1' +# option encryption_algorithm '3des' # possible values: 3des, aes, aes_ctr, aes_cbc, aes128, aes192, aes256, camellia_cbc +# option hash_algorithm 'md5' # possible values: md5, sha1, sha256, sha384, sha512 +# list dh_group 'modp1536' # possible values: modp1536, modp2048, modp3072, modp4096, modp6144, modp8192, dh19, dh20, dh21, dh22, dh31 + +# config tunnel 'vti2_1_5' +# option left '%wan' # left can be interface of ipaddress +# option leftid '@left' # local id +# option right '192.168.2.201' # remote endpoint public ip +# option rightid '@62dd3e3f82339b002405245b' # rightid +# option auto 'start' # what operation, should be done automatically at IPsec startup +# option authby 'secret' # how the two security gateways should authenticate each other +# option psk 'AyG9RlTtQJIUxgxG' # preshare key +# option ikev2 '1' # ike version +# option ikelifetime '10800' +# option rekey '1' +# option rekeymargin '540' +# option dpdaction 'restart' +# option dpddelay '30' +# option dpdtimeout '150' +# option vti_interface 'vti2_1_5' # only for route based tunnels +# option leftvti '172.16.31.2/30' # only for route based tunnels +# option mark '0x5' # only if vti interface is set +# list leftsubnets '0.0.0.0/0' +# list rightsubnets '0.0.0.0/0' diff --git a/net/libreswan/files/user.hotplug b/net/libreswan/files/user.hotplug new file mode 100644 index 00000000000000..120260957a21bd --- /dev/null +++ b/net/libreswan/files/user.hotplug @@ -0,0 +1,7 @@ +#!/bin/sh + +[ -e "/etc/ipsec.user" ] && { + . /etc/ipsec.user +} + +exit 0 diff --git a/net/libreswan/files/vti.hotplug b/net/libreswan/files/vti.hotplug new file mode 100644 index 00000000000000..59e883223aed1c --- /dev/null +++ b/net/libreswan/files/vti.hotplug @@ -0,0 +1,28 @@ +#!/bin/sh + +addvti() { + [ -d /proc/sys/net/ipv4/conf/${VTI_IFACE} ] && ip tun del ${VTI_IFACE} + ip tunnel add ${VTI_IFACE} mode vti local ${PLUTO_ME} remote ${PLUTO_PEER} okey ${CONNMARK_OUT%/*} ikey ${CONNMARK_IN%/*} + sysctl -w net.ipv4.conf.${VTI_IFACE}.disable_policy=1 + sysctl -w net.ipv4.conf.${VTI_IFACE}.rp_filter=0 + sysctl -w net.ipv4.conf.${VTI_IFACE}.forwarding=1 + [ -n "${VTI_IP}" ] && ip addr add ${VTI_IP} dev ${VTI_IFACE} + ip link set ${VTI_IFACE} up +} + +delvti() { + if [ -n "${VTI_IFACE}" -a -d /proc/sys/net/ipv4/conf/${VTI_IFACE} ]; then + ip tun del ${VTI_IFACE} + fi +} + +[ -z "$VTI_IFACE" ] && exit 0 + +case "${PLUTO_VERB}" in + up-host | up-client) + addvti + ;; + down-host | down-client) + delvti + ;; +esac diff --git a/net/libreswan/patches/050-updown-hotplug.patch b/net/libreswan/patches/050-updown-hotplug.patch new file mode 100644 index 00000000000000..905c3240632eac --- /dev/null +++ b/net/libreswan/patches/050-updown-hotplug.patch @@ -0,0 +1,8 @@ +--- a/programs/_updown.xfrm/_updown.xfrm.in ++++ b/programs/_updown.xfrm/_updown.xfrm.in +@@ -1025,3 +1025,5 @@ case "${PLUTO_VERB}" in + exit 1 + ;; + esac ++ ++/sbin/hotplug-call libreswan