summaryrefslogtreecommitdiff
path: root/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
diff options
context:
space:
mode:
Diffstat (limited to 'src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper')
-rw-r--r--src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper110
1 files changed, 110 insertions, 0 deletions
diff --git a/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
new file mode 100644
index 0000000..2a1c5a7
--- /dev/null
+++ b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
@@ -0,0 +1,110 @@
+# redefine ip command to use FRR when it is available
+
+# default route distance
+IF_METRIC=${IF_METRIC:-210}
+
+# Check if interface is inside a VRF
+VRF_OPTION=$(/usr/sbin/ip -j -d link show ${interface} | awk '{if(match($0, /.*"master":"(\w+)".*"info_slave_kind":"vrf"/, IFACE_DETAILS)) printf("vrf %s", IFACE_DETAILS[1])}')
+
+# get status of FRR
+function frr_alive () {
+ /usr/lib/frr/watchfrr.sh all_status
+ if [ "$?" -eq "0" ] ; then
+ logmsg info "FRR status: running"
+ return 0
+ else
+ logmsg info "FRR status: not running"
+ return 1
+ fi
+}
+
+# convert ip route command to vtysh
+function iptovtysh () {
+ # prepare variables for vtysh command
+ local VTYSH_ACTION=$3
+ local VTYSH_NETADDR=""
+ local VTYSH_GATEWAY=""
+ local VTYSH_DEV=""
+ local VTYSH_TAG="210"
+ local VTYSH_DISTANCE=$IF_METRIC
+ # convert default route to 0.0.0.0/0
+ if [ "$4" == "default" ] ; then
+ VTYSH_NETADDR="0.0.0.0/0"
+ else
+ VTYSH_NETADDR=$4
+ fi
+ # add /32 to ip addresses without netmasks
+ if [[ ! $VTYSH_NETADDR =~ ^.*/[[:digit:]]+$ ]] ; then
+ VTYSH_NETADDR="$VTYSH_NETADDR/32"
+ fi
+ shift 4
+ # get gateway address
+ if [ "$1" == "via" ] ; then
+ VTYSH_GATEWAY=$2
+ shift 2
+ fi
+ # get device name
+ if [ "$1" == "dev" ]; then
+ VTYSH_DEV=$2
+ shift 2
+ fi
+ # get distance
+ if [ "$1" == "metric" ]; then
+ VTYSH_DISTANCE=$2
+ shift 2
+ fi
+
+ VTYSH_CMD="ip route $VTYSH_NETADDR $VTYSH_GATEWAY $VTYSH_DEV tag $VTYSH_TAG $VTYSH_DISTANCE $VRF_OPTION"
+
+ # delete route if the command is "del"
+ if [ "$VTYSH_ACTION" == "del" ] ; then
+ VTYSH_CMD="no $VTYSH_CMD"
+ fi
+ logmsg info "Converted vtysh command: \"$VTYSH_CMD\""
+}
+
+# delete the same route from kernel before adding new one
+function delroute () {
+ logmsg info "Checking if the route presented in kernel: $@ $VRF_OPTION"
+ if /usr/sbin/ip route show $@ $VRF_OPTION | grep -qx "$1 " ; then
+ logmsg info "Deleting IP route: \"/usr/sbin/ip route del $@ $VRF_OPTION\""
+ /usr/sbin/ip route del $@ $VRF_OPTION
+ fi
+}
+
+# try to communicate with vtysh
+function vtysh_conf () {
+ # perform 10 attempts with 1 second delay for retries
+ for i in {1..10} ; do
+ if vtysh -c "conf t" -c "$1" ; then
+ logmsg info "Command was executed successfully via vtysh: \"$1\""
+ return 0
+ else
+ logmsg info "Failed to send command to vtysh, retrying in 1 second"
+ sleep 1
+ fi
+ done
+ logmsg error "Failed to execute command via vtysh after 10 attempts: \"$1\""
+ return 1
+}
+
+# replace ip command with this wrapper
+function ip () {
+ # pass comand to system `ip` if this is not related to routes change
+ if [ "$2" != "route" ] ; then
+ logmsg info "Passing command to /usr/sbin/ip: \"$@\""
+ /usr/sbin/ip $@
+ else
+ # if we want to work with routes, try to use FRR first
+ if frr_alive ; then
+ delroute ${@:4}
+ iptovtysh $@
+ logmsg info "Sending command to vtysh"
+ vtysh_conf "$VTYSH_CMD"
+ else
+ # add ip route to kernel
+ logmsg info "Modifying routes in kernel: \"/usr/sbin/ip $@\""
+ /usr/sbin/ip $@ $VRF_OPTION
+ fi
+ fi
+}