blob: 2a1c5a7b2c0589a5266a0d6a9aea34dcfb4db149 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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
}
|