Applies To:

Show Versions Show Versions

Manual Chapter: Generic Message Example
Manual Chapter
Table of Contents   |   << Previous Chapter   |   Next Chapter >>

Generic Message Example

This section provides an example of using Generic Message to implement a simple chat client.

Each new connection will be asked for the peer's name. The provided name will be used to add a dynamic route to the route table.

Subsequent text entered will be treated as a request or response message. Requests are of the form: "<destination>:<text>\n". Responses do not contain a destination. A response message will be routed to the originator of the oldest request received.

BIG-IP Configuration

ltm pool gm_pool {
    members {
        10.1.1.100:1234 {
            address 10.1.1.100
        }
    }
}
  
ltm message-routing generic peer default_peer {
    pool gm_pool
    transport-config my_tc
}
ltm message-routing generic protocol my_gm_proto {
    app-service none
    disable-parser yes
}
ltm message-routing generic route default_route {
    peers {
        default_peer
    }
}
ltm message-routing generic router my_gm_router {
    app-service none
    routes {
        default_route
    }
}
ltm message-routing generic transport-config my_tc {
    ip-protocol tcp
    profiles {
        my_gm_proto { }
        tcp { }
    }
    rules {
        gm_rule
    }
}
  
ltm virtual gm_vs {
    destination 10.1.1.50:1234
    ip-protocol tcp
    mask 255.255.255.255
    profiles {
        my_gm_proto { }
        my_gm_router { }
        tcp { }
    }
    rules {
        gm_rule
    }
    source 0.0.0.0/0
    vs-index 2
}
  
ltm rule gm_rule {
    when CLIENT_ACCEPTED {
        TCP::respond "What is your name\n"
        TCP::collect
        set capture_name 1
    }
  
    when SERVER_CONNECTED {
        TCP::respond "What do you wish to be called\n"
        TCP::collect
        set capture_name 1
    }
  
    when CLIENT_DATA {
        set lines [split [TCP::payload] "\n"]
        TCP::payload 0 0
        foreach line $lines {
            set line [string trim $line]
            if { [string length $line] > 0 } {
                if { $capture_name == 1 } {
                    GENERICMESSAGE::peer name $line
                    set capture_name 0
                    TCP::respond "Welcome [GENERICMESSAGE::peer name]\n"
                } else {
                    set tokens [split $line ":"]
                    if {[llength $tokens] > 1} {
                        GENERICMESSAGE::message create [join [lrange $tokens 1 end] ":"] [lindex $tokens 0]
                    } else {
                        GENERICMESSAGE::message create $line
                    }
                }
            }
        }
        TCP::release
        TCP::collect
    }
  
    when SERVER_DATA {
        set lines [split [TCP::payload] "\n"]
        TCP::payload 0 0
        foreach line $lines {
            set line [string trim $line]
            if { [string length $line] > 0 } {
                if { $capture_name == 1 } {
                    GENERICMESSAGE::peer name $line
                    set capture_name 0
                    TCP::respond "Welcome [GENERICMESSAGE::peer name]\n"
                } else {
                    set tokens [split $line ":"]
                    if {[llength $tokens] > 1} {
                        GENERICMESSAGE::message create [join [lrange $tokens 1 end] ":"] [lindex $tokens 0]
                    } else {
                        GENERICMESSAGE::message create $line
                    }
                }
            }
        }
        TCP::release
        TCP::collect
    }
  
    when GENERICMESSAGE_INGRESS {
#        TCP::respond "GM_INGRESS is_request [GENERICMESSAGE::message is_request] req_seq_num [GENERICMESSAGE::message request_sequence_number]\n"
    }
  
    when MR_INGRESS {
#        TCP::respond "MR_INGRESS src: [GENERICMESSAGE::message src] dest [GENERICMESSAGE::message dest] lasthop [MR::message lasthop] nexthop: [MR::message nexthop]\n"
    }
  
  
    when GENERICMESSAGE_EGRESS {
#        TCP::respond "GM_EGRESS status: [GENERICMESSAGE::message status] is_request [GENERICMESSAGE::message is_request] req_seq_num [GENERICMESSAGE::message request_sequence_number]\n"
        TCP::respond "[GENERICMESSAGE::message data]\n"
    }
}

Client Server Configuration

Server

Execute the following command (with local IP address):

nc -l 10.1.1.100 1234

Client

Execute the following command (with local IP address):

telnet 10.1.1.50 1234

Communication Dialogue

The following example illustrates communication between different clients and a server. The example traverses down with time. Text entered is in courier.

Table 1. Communication Dialog
Client A Client B Server Notes

What is your name

Alex

Welcome Alice

What is your name

Bob

Welcome Bob

  Both clients connect and provide their routing name
Bob: Are you there     Request sent to route Bob (Req 1)
 

Are you there

Yes, who is this?

 

Request displayed (Req 1)

Response (there is no destination provided), so it is routed to the originator of the oldest request (Rsp 1)

Yes, who is this?

Bob: This is Alex

   

Response delivered (Rsp 1)

New request (Req 2)

 

This is Alice

Alex: hello Alex

 

Request delivered (Req 2)

New request (Req 3)

hello Alex     Request delivered (Req 3)
  Charlie: Are you there?   New request (Req 4), destination does not match any existing routes so the default route is selected.
   

What do you wish to be called

Dave

Welcome Dave

New connection established to pool member of default route
   

Are you there?

Yes, who is this?

Request delivered (Req 4)

Response to Req 4 (Rsp 4)

 

Yes, who is this?

Bob

 

Response delivered (Rsp 4)

Since there is no destination, this is a response. This will be matched to the oldest pending request on this connection which is Req 2 (Rsp 2)

Bob     Response to Req 2 delivered (Rsp 2)

Disaggregation (DAG) Modes

BIG-IP® scalability relies on load balancing (parallelizing) the processing of incoming packets across a large number of TMMs (cores). This is accomplished with various disaggregation algorithms. This section provides a concise description of these algorithms. Note, selecting the wrong disaggregation mode can have a severe impact on performance.

DAG is configured per VLAN. Note, this means that the client and server sides of BIG-IP should be configured on different VLANs. So it's possible to configure different DAG modes for client and server connections. However, when a server responds to a client request, and a connection is already established, DAG is not used.

DAG Modes via TMSH

Table 2. DAG Modes via TMSH
DAG Mode Configuration Object TMSH Commands
Default-DAG VLAN $ modify net vlan <vlan_name> cmp-hash default
SP-DAG VLAN

$ modify net vlan <src_vlan_name> cmp-hash src-ip

$ modify net vlan <dst_vlan_name> cmp-hash dst-ip

RR-DAG VLAN

$ modify net vlan <vlan_name> dag-round-robin enabled

$ modify sys db dag.roundrobin.udp.portlist value "5060"

$ modify ltm profile udp <udp_profile_name> idle-timeout 0

Default DAG

The Default DAG uses a hash of source and destination port. It is useful when ephemeral ports are used in client side and server side connections. When source and destination ports are the same TMM-0 will be used. This is an issue in that the traffic will not be load balanced and TMM-0 will quickly be overloaded. This DAG requires randomness in the source or destination port. If a client doesn't specify a source port then an ephemeral port will be used and Default DAG will work properly. Note, the ephemeral port must increment randomly or by single digits. If it's incremented by an even number, such as two, or by the number of TMMs then it's possible that it will hash to the same TMM or a small set of TMMs, which will negatively impact BIG-IP® performance.

Key Points
  • Port Based.
  • Works best when clients use ephemeral ports.
  • Can work with 1 to n clients.
Default DAG example

Default DAG example

Source/Destination DAG (SP-DAG)

The SP-DAG uses a hash of source IP (from client) and destination IP address (server). This mode should be used when source and destination ports are hardcoded (for example 5060). In that case, a BIG-IP® system requires multiple client IP address or multiple server IP addresses. Keep in mind, most connections are initiated by the client and that's the "Source DAG" option. In this case, the "Destination DAG" could be a single IP, but the source client IP should have more that a single IP address.

Key Points
  • IP Address Based
  • Works best when number of clients is equal to or more than the number of TMMs in BIG-IP system.
  • Performance will be impacted if clients consist of only a few SIP Proxy connections. In this case the IP Address entropy will be too low to load balance the incoming packets across available TMMs.
Source/Destination DAG (SP-DAG) example

Source/Destination DAG (SP-DAG) example

Round Robin DAG (RR-DAG)

R-DAG was designed to overcome the low entropy limitations of Default DAG and SP-Dag; although for UDP only. Furthermore, RR-DAG is hardware only and can't be used in a VE. Round Robin DAG distributes traffic by sending each consecutive packet to a different TMM. It does not rely on the IP address, or source port, of the client. One limitation of RR-DAG is that it's global and can be configured for only one port.

Key Points
  • UDP Only
  • Requires hardware (not an option in VE)
  • Sends each consecutive packet to a different TMM.

$ modify net vlan <vlan_name> dag-round-robin enabled

$ modify sys db dag.roundrobin.udp.portlist value "5060"

Round Robin DAG (RR-DAG) example

Round Robin DAG (RR-DAG) example

Table of Contents   |   << Previous Chapter   |   Next Chapter >>

Was this resource helpful in solving your issue?




NOTE: Please do not provide personal information.



Incorrect answer. Please try again: Please enter the words to the right: Please enter the numbers you hear:

Additional Comments (optional)