Event Driven Scripts

Let’s make an event driven Lua script for processing when some kind of event occurs at the router.

Events Driven by Logs

With the Lua script functionality, a library function, rt.syslogwatch is prepared by which, until a specified string is output in the log a script can be temporarily halted and remain on standby. Event driven is achieved thus.

A tunnel interface switches route via up / down

Let's try making a script that switches the tunnel interface route up / down.

When up / down occurs on a tunnel interface, the following is recorded in the log.

IP Tunnel[1] Up
IP Tunnel[1] Down

rt.syslogwatch captures this log, and then switches the route.

[Event1.lua] Download

function tunnel_up (route, tnum)
  rt.command("ip route " .. route .. " gateway tunnel " .. tnum)
end

function tunnel_down (route, tnum)
  rt.command("ip route " .. route .. " gateway null")
end

route = "192.168.20.0/24"

PATTERN = "IP Tunnel%[(%d+)%] ([UD][po]w?n?)"

while true do
  rtn, str = rt.syslogwatch(PATTERN)
  if rtn > 0 then
    tnum, up_or_down = string.match(str[1], PATTERN)
    if tnum then
      if up_or_down == "Up" then
        tunnel_up(route, tnum)
      else
        tunnel_down(route, tnum)
      end
    end
  end
end

The functions tunnel_up and tunnel_down, change routes using rt.command when any tunnel interface goes up or down.

With the variable PATTERN configure the waiting log pattern.

PATTERN = "IP Tunnel %[(%d+)%] ([UD][po]w?n?)"

With this pattern, with the infinite loop of the while sentence, wait until the tunnel up / down is recorded in the following line in the log. In the rt.syslogwatchargument, write the log to capture with a pattern. The return value is the number of times the log is found and the actually captured arrays of the log string. In this example, rt.syslogwatch omits the number of instances of detection and the argument to specify the monitoring time, so the variable rtn is always 1.

rtn, str = rt.syslogwatch(PATTERN)

Next, whether or not the tunnel is up or down and the tunnel no. are checked by string.match and PATTERN. In PATTERN there are two capture instances and both support tunnel no. and "Up"/"Down” strings. So, if the tunnel is up, tunnel_up is called, and if it is not, tunnel_down is called.

tnum, up_or_down = string.match(str[1], PATTERN)
if tnum then
  if up_or_down == "Up" then
	tunnel_up(route, tnum)
  else
	tunnel_down(route, tnum)
  end
end

Return to Top