FRR/ospf: demote/promote carp when no neighbors are found (#1460)

FRR: Inspired by OpenBSD's handling of carp demotion in ospfd (https://man.openbsd.org/ospfd.conf.5), this should lead to a similar result. Event handling is not complete yet, but the concept seems to be working.

- The basic idea is actually quite simple, create a ospf status monitor script to utilize our new carp hooks (https://docs.opnsense.org/development/backend/carp.html)
- Use Syslog-NG's functionality to filter messages and use those as events, so we can trigger "configctl interface update carp service_status" when our state changes

and carp should do the rest.
This commit is contained in:
Ad Schellevis
2019-09-03 15:48:17 +02:00
committed by GitHub
parent 3f780ed4ce
commit ad3c3e745a
6 changed files with 64 additions and 0 deletions
+25
View File
@@ -0,0 +1,25 @@
#!/bin/sh
if [ -f /etc/rc.conf.d/frr ]; then
. /etc/rc.conf.d/frr
fi
if [ "$frr_enable" == "YES" ] && (`echo "$frr_daemons" | /usr/bin/grep -F -q -w "ospfd"`) &&
(`echo "$frr_carp_demote" | /usr/bin/grep -F -q -w "ospfd"`) ; then
# OSPF enabled
OSPF_NEIGHBOR=`echo "show ip ospf neighbor" | /usr/local/bin/vtysh 2>&1` IFS=
if [ "$?" -eq 0 ]; then
# running, check if we can find any neighbors
IFS=
neighbors_count=`echo $OSPF_NEIGHBOR | grep "Full/" | wc -l`
unset IFS
if [ "$neighbors_count" -eq 0 ]; then
# no neighbors in state Full/* found
exit 2
else
exit 0
fi
else
# not running
exit 1
fi
fi
@@ -5,6 +5,16 @@
<type>checkbox</type>
<help>This will activate the OSPF service if routing protocols are enabled in "General".</help>
</field>
<field>
<id>ospf.carp_demote</id>
<label>CARP demote</label>
<type>checkbox</type>
<help>
Register CARP status monitor, when no neighbors are found, consider this node less attractive.
This feature needs syslog enabled using "Debugging" logging to catch all relevant status events.
This option is not compatible with "Enable CARP Failover".
</help>
</field>
<field>
<id>ospf.routerid</id>
<label>Router ID</label>
@@ -7,6 +7,10 @@
<default>0</default>
<Required>Y</Required>
</enabled>
<carp_demote type="BooleanField">
<default>0</default>
<Required>Y</Required>
</carp_demote>
<routerid type="TextField">
<default></default>
<Required>N</Required>
@@ -5,3 +5,4 @@ ripd.conf:/usr/local/etc/frr/ripd.conf
frr:/etc/rc.conf.d/frr
zebra.conf:/usr/local/etc/frr/zebra.conf
vtysh.conf:/usr/local/etc/frr/vtysh.conf
syslog-ng-frr-events.conf:/usr/local/etc/syslog-ng.conf.d/frr-events.conf
@@ -11,6 +11,7 @@ if helpers.exists('OPNsense.quagga.bgp.enabled') and OPNsense.quagga.bgp.enabled
if helpers.exists('OPNsense.quagga.ospf6.enabled') and OPNsense.quagga.ospf6.enabled == '1' %} ospf6d{% endif %}{%
if helpers.exists('OPNsense.quagga.ripng.enabled') and OPNsense.quagga.ripng.enabled == '1' %} ripngd{% endif %}{%
if helpers.exists('OPNsense.quagga.isis.enabled') and OPNsense.quagga.isis.enabled == '1' %} isisd{% endif %}"
frr_carp_demote="{% if not helpers.empty('OPNsense.quagga.ospf.carp_demote') %} ospfd{% endif %}"
{% else %}
frr_enable="NO"
{% endif %}
@@ -0,0 +1,23 @@
{% if not helpers.empty('OPNsense.quagga.general.enabled')
and not helpers.empty('OPNsense.quagga.ospf.enabled')
and not helpers.empty('OPNsense.quagga.ospf.carp_demote') %}
destination d_frr_event {
program("/usr/local/sbin/configctl -e -t 0.5 interface update carp service_status");
};
filter f_frr_ospf {
program("ospfd") and (
(
level("info") or level("notice")
) or (
level("debug") and message(".*EXT .*ospf_ext_link_ism_change.*")
)
);
};
log {
source(s_all);
filter(f_frr_ospf);
destination(d_frr_event);
};
{% endif %}