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