The vpnc-script used by OpenConnect only supports "split include" rules (default route unchanged, specific VPN routes added). We add support for Pulse's "split exclude" rules (default route to VPN, exclude rules for targets to be connected via normal uplink). For targets specified as split-exclude by the gateway, we add additional routes which keep traffic as-is (i.e. separate from tunnel). On platforms only providing /sbin/route, we guess that those are reached via default gateway. Tested on Linux/OpenSUSE (using ip and route command). Signed-off-by: Gernot Hillier <gernot.hillier at siemens.com> --- vpnc-script | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/vpnc-script b/vpnc-script index b7a9d40..ad514dd 100755 --- a/vpnc-script +++ b/vpnc-script @@ -258,6 +258,26 @@ if [ -n "$IPROUTE" ]; then $IPROUTE route flush cache } + set_exclude_route() { + # add explicit route to keep current routing for this target + # (keep traffic separate from VPN tunnel) + NETWORK="$1" + NETMASK="$2" + NETMASKLEN="$3" + $IPROUTE route add `$IPROUTE route get "$NETWORK/$NETMASKLEN" | fix_ip_get_output` + $IPROUTE route flush cache + } + + del_exclude_route() { + # FIXME: This can delete existing routes in case they're + # identical to split-exclude routes specificed by VPNGATEWAY + NETWORK="$1" + NETMASK="$2" + NETMASKLEN="$3" + $IPROUTE route $route_syntax_del "$NETWORK/$NETMASKLEN" + $IPROUTE route flush cache + } + reset_default_route() { if [ -s "$DEFAULT_ROUTE_FILE" ]; then $IPROUTE route replace `cat "$DEFAULT_ROUTE_FILE"` @@ -342,6 +362,28 @@ else # use route command route add -net "$NETWORK" $route_syntax_netmask "$NETMASK" $route_syntax_gw "$NETGW" $route_syntax_interface } + set_exclude_route() { + NETWORK="$1" + NETMASK="$2" + NETMASKLEN="$3" + if [ -z "$DEFAULTGW" ]; then + DEFAULTGW="`get_default_gw`" + fi + # Add explicit route to keep traffic for this target separate + # from tunnel. FIXME: We use default gateway - this is our best + # guess in absence of "ip" command to query effective route. + route add -net "$NETWORK" $route_syntax_netmask "$NETMASK" $route_syntax_gw "$DEFAULTGW" $route_syntax_interface + } + + del_exclude_route() { + # FIXME: This can delete existing routes in case they're + # identical to split-exclude routes specified by VPNGATEWAY + NETWORK="$1" + NETMASK="$2" + NETMASKLEN="$3" + route $route_syntax_del -net "$NETWORK" $route_syntax_netmask "$NETMASK" + } + reset_default_route() { if [ -s "$DEFAULT_ROUTE_FILE" ]; then route $route_syntax_del default $route_syntax_gw "`get_default_gw`" $route_syntax_interface @@ -782,6 +824,16 @@ do_connect() { set_vpngateway_route do_ifconfig + if [ -n "$CISCO_SPLIT_EXC" ]; then + i=0 + while [ $i -lt $CISCO_SPLIT_EXC ] ; do + eval NETWORK="\${CISCO_SPLIT_EXC_${i}_ADDR}" + eval NETMASK="\${CISCO_SPLIT_EXC_${i}_MASK}" + eval NETMASKLEN="\${CISCO_SPLIT_EXC_${i}_MASKLEN}" + set_exclude_route "$NETWORK" "$NETMASK" "$NETMASKLEN" + i=`expr $i + 1` + done + fi if [ -n "$CISCO_SPLIT_INC" ]; then i=0 while [ $i -lt $CISCO_SPLIT_INC ] ; do @@ -850,6 +902,16 @@ do_disconnect() { else reset_default_route fi + if [ -n "$CISCO_SPLIT_EXC" ]; then + i=0 + while [ $i -lt $CISCO_SPLIT_EXC ] ; do + eval NETWORK="\${CISCO_SPLIT_EXC_${i}_ADDR}" + eval NETMASK="\${CISCO_SPLIT_EXC_${i}_MASK}" + eval NETMASKLEN="\${CISCO_SPLIT_EXC_${i}_MASKLEN}" + del_exclude_route "$NETWORK" "$NETMASK" "$NETMASKLEN" "$UPLINKDEV" "$UPLINKGW" + i=`expr $i + 1` + done + fi if [ -n "$CISCO_IPV6_SPLIT_INC" ]; then i=0 while [ $i -lt $CISCO_IPV6_SPLIT_INC ] ; do -- 2.13.6