A Simple One-way Generic MRF Implementation to load balance syslog message

The BIG-IP Generic Message Protocol implements a protocol filter compatible with MRF (Message Routing Framework). MRF is designed to implement the most complex use cases, but it can be daunting if you need to create a simple configuration.  This article provides a simple baseline to understand the relationships of the MRF components and how they can be combined for a simple one way implementation . A production implementation will in most case be more complex.

The following virtual, profiles and iRules load balances a one way stream of new line delimited messages (in this case syslog) to a pool of message consumers. The messages will be parsed and distributed with a simple MLB protocol.

Return traffic will not be returned to the client with this configuration.

To implement this we will need these configuration objects:

  • Virtual Server - Accepts incoming traffic and configure the Generic Protocol 
  • Generic Protocol - Defines message parsing. 
  • Generic Router - Configures message routing and point to the Generic Route
  • Generic Route - Points to a Generic Peer
  • Generic Peer - Defines an LTM pool members and points to the Generic Transport Config
  • Generic Transport Config - Defines the server side protocol and server side irule
  • iRule - Defines the message peers (Connections in the message streams)


In this case we have a single client that is sending messages to a virtual server that will then be distributed to 3 pool members. Each message will be sent to one pool member only. This can only be configured from the CLI and the official F5 recommendation is to not make any changes in the web GUI to the virtual server. This was tested with BIG-IP and

Here is the virtual with a tcp profile and required protocol and routing profiles along with an iRule to setup the connection peer on the client side.

ltm virtual /Common/mrftest_simple {
  destination /Common/
  ip-protocol tcp
  profiles {
    /Common/simple_syslog_protocol { }
    /Common/simple_syslog_router { }
    /Common/tcp { }
  rules {
  source-address-translation {
    type automap
  translate-address enabled
  translate-port enabled

The first profile is the protocol. The only difference between the default protocol (genericmsg) is the field no-response must be configured to yes if this is a one way stream. Otherwise the server side will allocate buffers for return traffic that will cause severe free memory depletion. 

ltm message-routing generic protocol simple_syslog_protocol {
  app-service none
  defaults-from genericmsg
  description none
  disable-parser no
  max-egress-buffer 32768
  max-message-size 32768
  message-terminator %0a
  no-response yes


The Generic Router profile points to a generic route

ltm message-routing generic router simple_syslog_router {
  app-service none
  defaults-from messagerouter
  description none
  ignore-client-port no
  max-pending-bytes 23768
  max-pending-messages 64
  mirror disabled
  mirrored-message-sweeper-interval 1000
  routes {
  traffic-group traffic-group-1
  use-local-connection yes


The Generic Route points to the Generic Peer:

ltm message-routing generic route simple_syslog_route {
  peers {


The Generic Peer configures the server pool and points to the Generic Transport Config. Note the pool is configured here instead of the more common configuration in the virtual server.

ltm message-routing generic peer simple_syslog_peer {
  pool mrfpool
  transport-config simple_syslog_tcp_tc


The Generic Transport Config also has the Generic Protocol configured along with the iRule to setup the server side peers.

ltm message-routing generic transport-config simple_syslog_tcp_tc {
  ip-protocol tcp
  profiles {
    simple_syslog_protocol { }
    tcp { }
    rules { mrf_simple }


An iRule must be configured on both the Virtual Server and Generic Transport Config. This iRule must be linked as a profile in both the virtual server and generic transport configuration.

ltm rule /Common/mrf_simple {
        GENERICMESSAGE::peer name "[IP::local_addr]:[TCP::local_port]_[IP::remote_addr]:[TCP::remote_port]"

        GENERICMESSAGE::peer name "[IP::local_addr]:[TCP::local_port]_[IP::remote_addr]:[TCP::remote_port]"


This example is from a user case where a single syslog client was load balanced to multiple syslog server pool members. Messages are parsed with the newline (0x0a) character as configured in the generic protocol, but this can easily be adapted to other message types.

Published Nov 16, 2020
Version 1.0

Was this article helpful?

1 Comment

  • This works really well.  I do have a question though, is there a way to increase buffers to accommodate small bursts in traffic?  Occasionally, I see the LTM send back resets to the device originating the log messages.