#  -*- text -*-
#
#
#	$Id: 784d834fa4d1ecd0a62526075d321f2636e93f10 $

#######################################################################
#
#  = BFD (Bidirectional Forwarding Detection)
#
#  The purpose of `BFD` is to quickly detect if a link is up or down.
#
#  We are using it to determine if a `peer` application is up or down.
#  For example, when two servers are configured in primary / secondary
#  mode, they should be set up as BFD peers.  They can then detect
#  when the other one goes down.
#
#  The code is in FreeRADIUS because we want to know if the *application*
#  is running. It doesn't matter if the link is up, or if the host system
#  is running. If the FreeRADIUS daemon is down, then we want to know ASAP.
#
#  NOTE: See also `raddb/trigger.conf`.  There are BFD-specific triggers
#  which are executed when the link is started, goes up, down, or is
#  administratively down.
#

#
#  ## server bfd  { ... }
#
#  The virtual server which manages BFD.
#
server main {
	#
	#  namespace::
	#
	#  The Bidirectional Forwarding Detection (BFD) protocol.
	#
	namespace = bfd

	#
	#  Common configuration for the BFD state machine.
	#  For now, unused.
	#
	bfd {

	}

	#
	#  ### listen { ... }
	#
	listen {
		#
		#  Only IP transport is supported for BFD.
		#  There is no ethernet type for BFD.
		#
		transport = udp

		#
		#
		#
		udp {
			#
			#  ipaddr::
			#
			#   IP address, or IPv6 address as with other
			#
			ipaddr = 192.0.2.1

			#
			#  port:: Port as normal.
			#
			port = 3784

			#
			#  only_state_changes::
			#
			#  In general the server only needs to know if the BFD session state has changed.  Set
			#  this value to "false" if you want every received and every sent packet to be
			#  processed through this virtual server.
			#
			only_state_changes = true
		}
	}

#
#  peer:: BFD peer
#
#  The peer definition is based on the `client` definition.  The standard client configuration items will work
#  here.
#
peer other {
	#
	#  ipaddr:: address of the peer
	#
	ipaddr = 192.0.2.2

	#
	#  port:: the peers port where we send packets
	#
	port = 3784

	#
	#  src_ipaddr:: Source address used when sending packets to this peer.
	#
	#  This source address should match a `listen` section above.  If not source address is given, then a
	#  "wildcard" listener will be chosen.  i.e. A listener which has `ipaddr = *`
	#
	#  If the source IP address does not match any listener, then the peer will be ignored.
	#
#	src_ipaddr = 192.0.2.1

	#
	#  auth_type:: BFD Authentication method.
	#
	#  May be one of:
	#
	#  [options="header,autowidth"]
	#  |===
	#  | Option         | Description
	#  | none           | no password, not recommended
	#  | simple         | cleartext password in the packet, not recommended
	#  | keyed-md5      | MD5 based, like  RADIUS style shared secret key
	#  | met-keyed-md5  | similar to above
	#  | keyed-sha1     | SHA1 based, like RADIUS style shared secret key
	#  | met-keyed-sha1 | similar to above
	#  |===
	#
	#  NOTE: The other side of the BFD connection has to have the same
	#  kind of authentication set.
	#
	auth_type = none

	#
	#  secret:: The secret key used for authentication.
	#
	#  If it starts with "0x", then it is treated as a hex string. This is recommended
	#  for security.  The secrets should be no more than 16 octets long, and random.
	#
#	secret = "hello"

	#
	#  min_transmit_interval:: Minimum time interval to transmit.
	#
	min_transmit_interval = 250ms

	#
	#  min_receive_interval:: Minimum time interval to receive.
	#
	min_receive_interval = 250ms

	#
	#  max_timeouts:: Max number of timeouts before the session is declared dead.
	#
	max_timeouts = 3

	#
	#  demand:: BFD Demand mode.
	#
	#  allowed values: {no, yes}
	#
	demand = no
}

#
#  ## Packet Processing sections
#
#  Unlike other protocols, BFD does not follow a "request / reply" process.  Instead, there are two
#  independent streams of packets.  One where the peer sends us packets (`recv foo { ... }`), and the other
#  where we send packets to the peer (`send foo { ... }`).
#
#  Note that when running `send`, the packet contents *cannot be changed*.  The contents of the BFD packet
#  are defined by the protocol.  The `send` section is called only for informational purposes.
#

#
#  ### Receive "Admin-Down" packets from the peer.
#
recv Admin-Down {
	ok
}

#
#  ### Receive "Down" packets from the peer.
#
recv Down {
	ok
}

#
#  ### Receive "Init" packets from the peer.
#
recv Init {
	ok
}

#
#  ### Receive "Up" packets from the peer.
#
recv Up {
	ok
}

#
#  ### Send "Admin-Down" packets to the peer.
#
send Admin-Down {
	ok
}

#
#  ### Send "Down" packets to the peer.
#
send Down {
	ok
}

#
#  ### Send "Init" packets to the peer.
#
send Init {
	ok
}

#
#  ### Send "Up" packets to the peer.
#
send Up {
#	octets more-data

	ok

	#
	#  Sneak in more data after a BFD packet!
	#
#	&reply.Additional-Data := {
#		&more-data := 0xabcdef
#	}
}

}
