#  -*- text -*-
#
#
#	$Id: 24abc732c03098cfae8f7770ed5f615637cda09f $

#######################################################################
#
#  = 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 `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
##	}
}

}
