]> git.proxmox.com Git - mirror_frr.git/blob - tools/nhrpd-event-handler.sh
tools: example bash script client for the nhrpd event sock
[mirror_frr.git] / tools / nhrpd-event-handler.sh
1 #!/bin/bash
2
3 #Author: Joe Maimon
4 #Released to public domain
5
6 PROGNAME=`basename $0`
7 VERSION="0.0.6"
8 #api fields
9 EV_ID="eventid"
10 EV_TYPE="type"
11 EV_OTYPE="old_type"
12 EV_NUMNHS="num_nhs"
13 EV_INT="interface"
14 EV_LADDR="local_address"
15 EV_VCINIT="vc_initiated"
16 EV_LNBMA="local_nbma"
17 EV_LCERT="local_cert"
18 EV_RADDR="remote_addr"
19 EV_RNBMA="remote_nbma"
20 EV_RCERT="remote_cert"
21
22 usage()
23 {
24 echo "Usage: $PROGNAME [-s nhrp-sock] [-d] [-i interface-name] [-t table] [-e execute-cmd] [-u user] [-g group] [-r] [-l logfile]"
25 echo ""
26 echo "-s nhrp-sock file"
27 echo "-i interface-name to execute on, may be repeated multiple times"
28 echo "-t tableid to execute on for immdiate preceeding interface"
29 echo "-e execute command for immmediate preceeding interface"
30 echo " The command will be passed the following arguments $EV_ID $EV_TYPE $EV_INT $EV_LNMBA $EV_RADDR $EV_RNBMA int_table"
31 echo "-u user to own the sock"
32 echo "-g group to own the sock"
33 echo "-r send rejection (testing)"
34 echo "-l logfile to record conversation with nhrpd"
35 echo "-d daemonize"
36
37 exit 1
38 }
39
40 declare -A EXECARR
41 declare -A TABLEARR
42 declare -Ag NHRPEVENT
43 SOCK="/var/run/frr/nhrp.sock"
44 USER="frr"
45 GROUP="frr"
46 DAEMON=0
47 j=0
48 RESULT="accept"
49
50 while getopts rds:i:u:g:l:t:e: opt; do
51 case "$opt" in
52 d)
53 DAEMON=1
54 ;;
55 s)
56 SOCK="$OPTARG"
57 ;;
58 i)
59 INTARR[((j++))]="$OPTARG"
60 ;;
61 e)
62 if [[ "$j" == "0" ]] || [[ "${INTARR[((j-1))]}" == "" ]]; then
63 echo "execute argument must follow interface argument"
64 usage
65 fi
66 EXECARR["${INTARR[((j-1))]}"]="$OPTARG"
67 ;;
68 t)
69 if [[ "$j" == "0" ]] || [[ "${INTARR[((j-1))]}" == "" ]]; then
70 echo "execute argument must follow interface argument"
71 usage
72 fi
73 TABLEARR["${INTARR[((j-1))]}"]="$OPTARG"
74 ;;
75 u)
76 USER="$OPTARG"
77 ;;
78 g)
79 GROUP="$OPTARG"
80 ;;
81 r)
82 RESULT="reject"
83 ;;
84 l)
85 EVLOGFILE="${OPTARG}"
86 ;;
87 esac;
88 done
89
90 if [[ "$EVLOGFILE" != "" ]]; then
91 if [[ ! -w "${EVLOGFILE}" ]]; then
92 touch "$EVLOGFILE" || ( echo "Cannot write to logfile $EVLOGFILE" ; usage )
93 fi
94 echo -e "PROG: $0 Startup\nPROG: Arguments $*" >> $EVLOGFILE
95 fi
96
97
98 function mainloop()
99 {
100
101 if [[ "$EVLOGFILE" != "" ]]; then
102 echo -e "PROG: `date -R`\nPROG: Starting mainloop" >> $EVLOGFILE
103 fi
104
105 coproc socat - UNIX-LISTEN:$SOCK,unlink-early,setuid-early=$USER,unlink-close=0 || exit 1
106 test -S $SOCK && chown $USER:$GROUP $SOCK
107
108 OLDIFS="$IFS"
109
110 TABLE="table "
111
112 while read -r S; do
113 if [[ "$EVLOGFILE" != "" ]]; then
114 echo "IN: $S" >> $EVLOGFILE
115 fi
116 if [[ "$S" == "" ]]; then
117 if [[ "${NHRPEVENT[$EV_ID]}" != "" ]]; then
118 OUTMSG="eventid=${NHRPEVENT[$EV_ID]}\nresult=$RESULT\n"
119 echo -e "$OUTMSG" >&"${COPROC[1]}"
120 if [[ "$EVLOGFILE" != "" ]]; then
121 echo -e "OUT:\n${OUTMSG}" >> $EVLOGFILE;
122 fi
123 fi
124
125
126 for((i=0;i<${#INTARR[@]};i++)); do
127 if [[ "${NHRPEVENT[$EV_INT]}" == "" ]]; then break; fi
128 if [[ "${INTARR[$i]}" != "${NHRPEVENT[$EV_INT]}" ]]; then continue; fi
129 EVINT="${NHRPEVENT[$EV_INT]}"
130 if [[ "${NHRPEVENT[$EV_RADDR]}" == "" ]]; then break; fi
131 if [[ "${NHRPEVENT[$EV_RNBMA]}" == "" ]]; then break; fi
132 if [[ "${NHRPEVENT[$EV_TYPE]}" != "dynamic" ]]; then break; fi
133
134 INTEXEC=${EXECARR["$EVINT"]}
135 INTABLE=${TABLEARR["$EVINT"]}
136
137 unset CMD
138 unset CMDEND
139 CMDADD="ip neigh add "
140 CMDREPL="ip neigh replace"
141 CMDBEG="$CMDADD"
142 if [[ "$INTEXEC" != "" ]]; then
143 CMD="$INTEXEC ${NHRPEVENT[$EV_ID]:-nil}"
144 CMD="$CMD ${NHRPEVENT[$EV_TYPE]:-nil}"
145 CMD="$CMD ${NHRPEVENT[$EV_INT]:-nil}"
146 CMD="$CMD ${NHRPEVENT[$EV_LNBMA]:-nil}"
147 CMD="$CMD ${NHRPEVENT[$EV_RADDR]:-nil}"
148 CMD="$CMD ${NHRPEVENT[$EV_RNBMA]:-nil}"
149 CMD="$CMD ${INTABLE:-nil}"
150 unset CMDBEG
151 else
152 CMDTAB="${INTABLE:+${TABLE}${INTABLE}}"
153 CMDEND="$CMDEND ${NHRPEVENT[$EV_RADDR]} dev $EVINT lladdr ${NHRPEVENT[$EV_RNBMA]} nud noarp"
154 CMD="$CMDEND"
155 fi
156 unset CMDTAB
157 for ((k=0;k<2;k++)); do
158 for ((l=0;l<2;l++)); do
159 if [[ "$EVLOGFILE" != "" ]]; then
160 echo "PROG: Executing $CMD" >> $EVLOGFILE
161 CMDOUT=`$CMDBEG $CMD $CMDTAB 2>&1`
162 CMDRET="$?"
163 if [[ "$CMDOUT" != "" ]]; then
164 echo "PROG: Execution output: $CMDOUT" >> $EVLOGFILE
165 fi
166 else
167 $CMDBEG $CMD $CMDTAB
168 fi
169 if [[ "$CMDTAB" == "" ]] || [[ "$INTEXEC" != "" ]]; then break; fi
170 done
171 if [[ "$INTEXEC" != "" ]] || [[ "$CMDRET" == "0" ]]; then
172 break
173 fi
174 CMDBEG="$CMDREPL"
175 done
176 break
177 done
178
179 unset NHRPEVENT
180 declare -Ag NHRPEVENT
181 continue
182 continue;
183 fi
184 IFS="${IFS}="
185 SA=($S)
186 IFS="$OLDIFS"
187 eval NHRPEVENT[${SA[0]}]="\"${SA[1]}\""
188
189 done <&"${COPROC[0]}"
190
191 if [[ "$COPROC_PID" != "" ]]; then kill "$COPROC_PID"; fi
192
193 }
194
195 while true; do
196 mainloop $*
197 if [[ "$DAEMON" == "0" ]]; then
198 break;
199 fi
200 sleep 10
201 done