[FROG] nhrpd event manager

Joe Maimon jmaimon at jmaimon.com
Sun Feb 28 07:57:56 UTC 2021


This is still broken, the patch is quite simple.

I do have an upgraded script which is pretty nice.

Joe Maimon wrote:
> Fix is pretty straightforward.
>
> --- a/nhrpd/nhrp_event.c
> +++ b/nhrpd/nhrp_event.c
> @@ -59,9 +59,9 @@
>                 buf[len] = 0;
>
>                 debugf(NHRP_DEBUG_EVENT, "evmgr: msg: %s", buf);
> -               if (sscanf(buf, "eventid=%" SCNu32, &eventid) != 1)
> +               if (sscanf(buf, "eventid=%" SCNu32, &eventid) == 1)
>                         continue;
> -               if (sscanf(buf, "result=%63s", result) != 1)
> +               if (sscanf(buf, "result=%63s", result) == 1)
>                         continue;
>         }
>         debugf(NHRP_DEBUG_EVENT, "evmgr: received: eventid=%d result=%s",
>
> Fledgling script actually works now, forgive email formatting errors
>
> ---------cut here----
>
> #!/bin/bash
>
> PROGNAME=`basename $0`
> VERSION="0.0.2"
>
> usage()
> {
>         echo "Usage: $PROGNAME -s nhrp-sock [-i interface-name] [-u 
> user] [-g group] "
>         echo ""
>         echo "-s nhrp-sock file"
>         echo "-i interface-name to execute on, may be repeated 
> multiple times"
>         echo "-u user to own the sock"
>         echo "-g group to own the sock"
>
>         exit 1
> }
>
> SOCK="/var/run/frr/nhrp.sock"
> USER="frr"
> GROUP="frr"
> j=0
>
> while getopts s:i:u:g: opt; do
>         case "$opt" in
>                 s)
>                         SOCK="$OPTARG"
>                         ;;
>                 i)
>                         INTARR[((j++))]="$OPTARG"
>                         ;;
>                 u)
>                         USER="$OPTARG"
>                         ;;
>                 g)
>                         GROUP="$OPTARG"
>                         ;;
>         esac;
> done
>
> coproc socat - UNIX-LISTEN:$SOCK,unlink-early,setuid-early=$USER || 
> exit 1
> chown $USER:$GROUP $SOCK
>
> OLDIFS="$IFS"
>
> while read -r S; do
>         if [[ "$S" == "" ]]; then
>                 if [[ "$EVID" != "" ]]; then
>                         echo -e "eventid=$EVID\nresult=accept\n";
>                 fi
>
>                 for((i=0;i<${#INTARR[@]};i++)); do
>                         if [[ "$EVINT" == "" ]]; then break; fi
>                         if [[ "${INTARR[$i]}" != "$EVINT" ]]; then 
> continue; fi
>                         if [[ "$EVREM" == "" ]]; then break; fi
>                         if [[ "$EVNBMA" == "" ]]; then break; fi
>                         if [[ "$EVTYPE" != "dynamic" ]]; then break; fi
>
>                         ip neigh add $EVREM dev $EVINT lladdr $EVNBMA 
> nud noarp
>                         if [[ "$?" != "0" ]]; then
>                                 ip neigh replace $EVREM dev $EVINT 
> lladdr $EVNBMA nud noarp
>                         fi
>                         break
>                 done
>
>                 unset EVID
>                 unset EVINT
>                 unset EVREM
>                 unset EVNBMA
>                 unset EVTYPE
>                 continue;
>         fi
>         IFS="${IFS}="
>         SA=($S)
>         IFS="$OLDIFS"
>         case "${SA[0]}" in
>                 eventid)
>                         EVID="${SA[1]}"
>                         ;;
>                 interface)
>                         EVINT="${SA[1]}"
>                         ;;
>                 type)
>                         EVTYPE="${SA[1]}"
>                         ;;
>                 remote_addr)
>                         EVREM="${SA[1]}"
>                         ;;
>                 remote_nbma)
>                        EVNBMA="${SA[1]}"
>                         ;;
>         esac
> done <&"${COPROC[0]}" >&"${COPROC[1]}"
>
> kill "$COPROC_PID"
>
>
>

-------------- next part --------------
#!/bin/bash

PROGNAME=`basename $0`
VERSION="0.0.6"
#api fields
EV_ID="eventid"
EV_TYPE="type"
EV_OTYPE="old_type"
EV_NUMNHS="num_nhs"
EV_INT="interface"
EV_LADDR="local_address"
EV_VCINIT="vc_initiated"
EV_LNBMA="local_nbma"
EV_LCERT="local_cert"
EV_RADDR="remote_addr"
EV_RNBMA="remote_nbma"
EV_RCERT="remote_cert"

usage()
{
	echo "Usage: $PROGNAME [-s nhrp-sock] [-d] [-i interface-name] [-t table] [-e execute-cmd] [-u user] [-g group] [-r] [-l logfile]"
	echo ""
	echo "-s nhrp-sock file"
	echo "-i interface-name to execute on, may be repeated multiple times"
	echo "-t tableid to execute on for immdiate preceeding interface"
	echo "-e execute command for immmediate preceeding interface"
	echo "   The command will be passed the following arguments $EV_ID $EV_TYPE $EV_INT $EV_LNMBA $EV_RADDR $EV_RNBMA int_table"
	echo "-u user to own the sock"
	echo "-g group to own the sock"
	echo "-r send rejection (testing)"
	echo "-l logfile to record conversation with nhrpd"
	echo "-d daemonize"

	exit 1
}

declare -A EXECARR
declare -A TABLEARR
declare -Ag NHRPEVENT
SOCK="/var/run/frr/nhrp.sock"
USER="frr"
GROUP="frr"
DAEMON=0
j=0
RESULT="accept"

while getopts rds:i:u:g:l:t:e: opt; do
	case "$opt" in 
		d)
			DAEMON=1
			;;
		s)
			SOCK="$OPTARG"
			;;
		i)
			INTARR[((j++))]="$OPTARG"
			;;
		e)
			if [[ "$j" == "0" ]] || [[ "${INTARR[((j-1))]}" == "" ]]; then
				echo "execute argument must follow interface argument"
				usage
			fi
			EXECARR["${INTARR[((j-1))]}"]="$OPTARG"
			;;
		t)
			if [[ "$j" == "0" ]] || [[ "${INTARR[((j-1))]}" == "" ]]; then
				echo "execute argument must follow interface argument"
				usage
			fi
			TABLEARR["${INTARR[((j-1))]}"]="$OPTARG"
			;;
		u)
			USER="$OPTARG"
			;;
		g)
			GROUP="$OPTARG"
			;;
		r)
			RESULT="reject"
			;;
		l)
			EVLOGFILE="${OPTARG}"
			;;
	esac;
done

if [[ "$EVLOGFILE" != "" ]]; then
	if [[ ! -w "${EVLOGFILE}" ]]; then
		touch "$EVLOGFILE" || ( echo "Cannot write to logfile $EVLOGFILE" ; usage )
	fi
	echo -e "PROG: $0 Startup\nPROG: Arguments $*" >> $EVLOGFILE
fi


function mainloop()
{

if [[ "$EVLOGFILE" != "" ]]; then
	echo -e "PROG: `date -R`\nPROG: Starting mainloop" >> $EVLOGFILE
fi

coproc socat - UNIX-LISTEN:$SOCK,unlink-early,setuid-early=$USER,unlink-close=0 || exit 1
test -S $SOCK && chown $USER:$GROUP $SOCK

OLDIFS="$IFS"

TABLE="table "

while read -r S; do
	if [[ "$EVLOGFILE" != "" ]]; then
		echo "IN: $S" >> $EVLOGFILE
	fi
	if [[ "$S" == "" ]]; then 
		if [[ "${NHRPEVENT[$EV_ID]}" != "" ]]; then 
			OUTMSG="eventid=${NHRPEVENT[$EV_ID]}\nresult=$RESULT\n"
			echo -e "$OUTMSG" >&"${COPROC[1]}"
			if [[ "$EVLOGFILE" != "" ]]; then 
				echo -e "OUT:\n${OUTMSG}" >> $EVLOGFILE; 
			fi
	       	fi


		for((i=0;i<${#INTARR[@]};i++)); do
			if [[ "${NHRPEVENT[$EV_INT]}" == "" ]]; then break; fi
			if [[ "${INTARR[$i]}" != "${NHRPEVENT[$EV_INT]}" ]]; then continue; fi
			EVINT="${NHRPEVENT[$EV_INT]}"
			if [[ "${NHRPEVENT[$EV_RADDR]}" == "" ]]; then break; fi
			if [[ "${NHRPEVENT[$EV_RNBMA]}" == "" ]]; then break; fi
			if [[ "${NHRPEVENT[$EV_TYPE]}" != "dynamic" ]]; then break; fi

			INTEXEC=${EXECARR["$EVINT"]}
			INTABLE=${TABLEARR["$EVINT"]}

			unset CMD
			unset CMDEND
			CMDADD="ip neigh add "
			CMDREPL="ip neigh replace"
			CMDBEG="$CMDADD"
			if [[ "$INTEXEC" != "" ]]; then
				CMD="$INTEXEC ${NHRPEVENT[$EV_ID]:-nil}"
				CMD="$CMD ${NHRPEVENT[$EV_TYPE]:-nil}"
				CMD="$CMD ${NHRPEVENT[$EV_INT]:-nil}"
				CMD="$CMD ${NHRPEVENT[$EV_LNBMA]:-nil}"
				CMD="$CMD ${NHRPEVENT[$EV_RADDR]:-nil}"
				CMD="$CMD ${NHRPEVENT[$EV_RNBMA]:-nil}"
				CMD="$CMD ${INTABLE:-nil}"
				unset CMDBEG
			else
				CMDTAB="${INTABLE:+${TABLE}${INTABLE}}"
			        CMDEND="$CMDEND ${NHRPEVENT[$EV_RADDR]} dev $EVINT lladdr ${NHRPEVENT[$EV_RNBMA]} nud noarp"
				CMD="$CMDEND"
			fi
			unset CMDTAB
			for ((k=0;k<2;k++)); do
				for ((l=0;l<2;l++)); do
					if [[ "$EVLOGFILE" != "" ]]; then 
						echo "PROG: Executing $CMD" >> $EVLOGFILE
							CMDOUT=`$CMDBEG $CMD $CMDTAB 2>&1`
							CMDRET="$?"
							if [[ "$CMDOUT" != "" ]]; then
								echo "PROG: Execution output: $CMDOUT" >> $EVLOGFILE
							fi
					else
						$CMDBEG $CMD $CMDTAB
					fi
					if [[ "$CMDTAB" == "" ]] || [[ "$INTEXEC" != "" ]]; then break; fi
				done
				if [[ "$INTEXEC" != "" ]] || [[ "$CMDRET" == "0" ]]; then
					break
				fi
				CMDBEG="$CMDREPL"
			done
			break
		done

		unset NHRPEVENT
		declare -Ag NHRPEVENT
		continue
		continue; 
	fi
	IFS="${IFS}="	
	SA=($S)	
	IFS="$OLDIFS"
	eval NHRPEVENT[${SA[0]}]="\"${SA[1]}\""

done <&"${COPROC[0]}" 

if [[ "$COPROC_PID" != "" ]]; then kill "$COPROC_PID"; fi

}

while true; do 
	mainloop $*
	if [[ "$DAEMON" == "0" ]]; then
		break;
	fi
	sleep 10
done
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0005-nhrp-event-reply.patch
Type: text/x-patch
Size: 445 bytes
Desc: not available
URL: <http://lists.frrouting.org/pipermail/frog/attachments/20210228/f39646e8/attachment.bin>


More information about the frog mailing list