For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

adick's avatar
adick
Icon for Nimbostratus rankNimbostratus
Feb 09, 2024

TCL errors

Hey Team,

We are experiencing some TCL errors with one of our iRules.  

I didn't build the iRule, but have inherited it from a past engineer, so I don't have a ton of knowledge on the specifics, but I'm wondering if it is something we can discover a fix for:

Error:

partition1/F5_L4_TCP_IPFIX


Feb  8 13:52:18 DN-DC3-LTM-02.domainname.com err tmm5[13713]: 01220001:3: TCL error: /partition1/F5_L4_TCP_IPFIX <CLIENT_CLOSED> - can't read "rule1_msg1": no such variable     while executing "IPFIX::msg set $rule1_msg1 postOctetTotalCount [IP::stats bytes in]"
Feb  8 13:52:19 DN-DC3-LTM-02.domainname.com err tmm4[13713]: 01220001:3: TCL error: /partition1/F5_L4_TCP_IPFIX <SERVER_CLOSED> - can't read "rule1_msg1": no such variable     while executing "IPFIX::msg set $rule1_msg1 octetTotalCount [IP::stats bytes out]"
Feb  8 13:52:19 DN-DC3-LTM-02.domainname.com err tmm4[13713]: 01220001:3: TCL error: /partition1/F5_L4_TCP_IPFIX <CLIENT_CLOSED> - can't read "rule1_msg1": no such variable     while executing "IPFIX::msg set $rule1_msg1 postOctetTotalCount [IP::stats bytes in]"
Feb  8 13:52:19 DN-DC3-LTM-02.domainname.com err tmm5[13713]: 01220001:3: TCL error: /partition1/F5_L4_TCP_IPFIX <SERVER_CLOSED> - can't read "rule1_msg1": no such variable     while executing "IPFIX::msg set $rule1_msg1 octetTotalCount [IP::stats bytes out]"
Feb  8 13:52:19 DN-DC3-LTM-02.domainname.com err tmm5[13713]: 01220001:3: TCL error: /partition1/F5_L4_TCP_IPFIX <CLIENT_CLOSED> - can't read "rule1_msg1": no such variable     while executing "IPFIX::msg set $rule1_msg1 postOctetTotalCount [IP::stats bytes in]"
Feb  8 13:52:20 DN-DC3-LTM-02.domainname.com err tmm3[13713]: 01220001:3: TCL error: /partition1/F5_L4_TCP_IPFIX <SERVER_CLOSED> - can't read "rule1_msg1": no such variable     while executing "IPFIX::msg set $rule1_msg1 octetTotalCount [IP::stats bytes out]"
Feb  8 13:52:20 DN-DC3-LTM-02.domainname.com err tmm3[13713]: 01220001:3: TCL error: /partition1/F5_L4_TCP_IPFIX <CLIENT_CLOSED> - can't read "rule1_msg1": no such variable     while executing "IPFIX::msg set $rule1_msg1 postOctetTotalCount [IP::stats bytes in]"
[user@DN-DC3-LTM-02:Active:In Sync] log #
[user@DN-DC3-LTM-02:Active:In Sync] log #

 

IRULE:

when RULE_INIT {
  set static::http_rule1_dest ""
  set static::http_rule1_tmplt ""
}
 
 
# CLIENT_ACCEPTED event to initiate IPFIX destination and template
when CLIENT_ACCEPTED {
  set start [clock clicks -milliseconds]
  if { $static::http_rule1_dest == ""} {
    # open the logging destination if it has not been opened yet
    set static::http_rule1_dest [IPFIX::destination open -publisher /western-hemisphere/IPFIX-PUB1]
  }
  if { $static::http_rule1_tmplt == ""} {
    # if the template has not been created yet, create the template
    set static::http_rule1_tmplt [IPFIX::template create "flowStartMilliseconds \
                                                          sourceIPv4Address \
                                                          sourceIPv6Address  \
                                                          destinationIPv4Address \
                                                          destinationIPv6Address  \
                                                          sourceTransportPort \
                                                          destinationTransportPort \
                                                          protocolIdentifier \
                                                          octetTotalCount \
                                                          packetTotalCount \
                                                          octetDeltaCount \
                                                          packetDeltaCount \
                                                          postNATSourceIPv4Address \
                                                          postNATSourceIPv6Address  \
                                                          postNATDestinationIPv4Address \
                                                          postNATDestinationIPv6Address  \
                                                          postNAPTSourceTransportPort \
                                                          postNAPTDestinationTransportPort \
                                                          postOctetTotalCount \
                                                          postPacketTotalCount \
                                                          postOctetDeltaCount \
                                                          postPacketDeltaCount \
                                                          flowEndMilliseconds"]
  }
}
 
 
# SERVER_CONNECTED event to initiate flow data to Tetration and populate 5 tuples
when SERVER_CONNECTED {
  set rule1_msg1 [IPFIX::msg create $static::http_rule1_tmplt]
  set client_closed_flag 0
  set server_closed_flag 0
  IPFIX::msg set $rule1_msg1 flowStartMilliseconds $start
  IPFIX::msg set $rule1_msg1 protocolIdentifier [IP::protocol]
 
  # Clientside
  if { [clientside {IP::version}] equals "4" } {
    # Client IPv4 address
    IPFIX::msg set $rule1_msg1 sourceIPv4Address [IP::client_addr]
    # BIG-IP IPv4 VIP address
    IPFIX::msg set $rule1_msg1 destinationIPv4Address [clientside {IP::local_addr}]
  } else {
    # Client IPv6 address
    IPFIX::msg set $rule1_msg1 sourceIPv6Address [IP::client_addr]
    # BIG-IP IPv6 VIP address
    IPFIX::msg set $rule1_msg1 destinationIPv6Address [clientside {IP::local_addr}]
  }
  # Client port
  IPFIX::msg set $rule1_msg1 sourceTransportPort [TCP::client_port]
  # BIG-IP VIP port
  IPFIX::msg set $rule1_msg1 destinationTransportPort [clientside {TCP::local_port}]
 
 
  # Serverside
  if { [serverside {IP::version}] equals "4" } {
    # BIG-IP IPv4 self IP address
    IPFIX::msg set $rule1_msg1 postNATSourceIPv4Address [IP::local_addr]
    # Server IPv4 IP address
    IPFIX::msg set $rule1_msg1 postNATDestinationIPv4Address [IP::server_addr]
  } else {
    # BIG-IP IPv6 self IP address
    IPFIX::msg set $rule1_msg1 postNATSourceIPv6Address [IP::local_addr]
    # Server IPv6 IP address
    IPFIX::msg set $rule1_msg1 postNATDestinationIPv6Address [IP::server_addr]
  }
  # BIG-IP self IP port
  IPFIX::msg set $rule1_msg1 postNAPTSourceTransportPort [TCP::local_port]
  # Server port
  IPFIX::msg set $rule1_msg1 postNAPTDestinationTransportPort [TCP::server_port]
}
 
# SERVER_CLOSED event to collect IP pkts and bytes count on serverside
when SERVER_CLOSED {
  set server_closed_flag 1
  # when flow is completed, BIG-IP to server REQUEST pkts and bytes count
  IPFIX::msg set $rule1_msg1 octetTotalCount [IP::stats bytes out]
  IPFIX::msg set $rule1_msg1 packetTotalCount [IP::stats pkts out]
  # when flow is completed, server to BIG-IP RESPONSE pkts and bytes count 
  IPFIX::msg set $rule1_msg1 octetDeltaCount [IP::stats bytes in]
  IPFIX::msg set $rule1_msg1 packetDeltaCount [IP::stats pkts in]
  if { $client_closed_flag == 1} {
    # send the IPFIX log
    IPFIX::destination send $static::http_rule1_dest $rule1_msg1
  }
}
 
 
# CLIENT_CLOSED event to collect IP pkts and bytes count on clientside
when CLIENT_CLOSED {
  set client_closed_flag 1
  # when flow is completed, client to BIG-IP REQUEST pkts and bytes octetDeltaCount
  IPFIX::msg set $rule1_msg1 postOctetTotalCount [IP::stats bytes in]
  IPFIX::msg set $rule1_msg1 postPacketTotalCount [IP::stats pkts in]
  # when flow is completed, BIG-IP to client RESPONSE pkts and bytes count
  IPFIX::msg set $rule1_msg1 postOctetDeltaCount [IP::stats bytes out]
  IPFIX::msg set $rule1_msg1 postPacketDeltaCount [IP::stats pkts out]
  # record the client closed time in ms
  IPFIX::msg set $rule1_msg1 flowEndMilliseconds [clock click -milliseconds]
  if { $server_closed_flag == 1} {
    # send the IPFIX log
    IPFIX::destination send $static::http_rule1_dest $rule1_msg1
  }
}

 

4 Replies

  • Hi,

    The error occurs when the rule1_msg1 variable is empty.
    This could happen if a client doesn't complete the 3way handshake and send a reset. Then the CLIENT_CLOSE event is hit without the client sending any data, leaving rule1_msg1 being never created in the other events.

    Maybe you can solve this by adding this line in the when RULE_INIT { section

    when RULE_INIT {
        set static::http_rule1_dest ""
        set static::http_rule1_tmplt ""
        set rule1_msg1 ""
    }

    Hope it helps.

    Cheers,

    Kees

    • adick's avatar
      adick
      Icon for Nimbostratus rankNimbostratus

      Thanks Kees!

      This seems to be a good solution.  

      Could there be other reasons the CLIENT_CLOSE event could get hit without the client sending data?  I'm wondering if this iRule could be causing any problems with the VIPs that it is configured on?  I heard from someone when you see TCL errors it usually means the VIP communication was cut off early.

      Or if because it only triggers on CLIENT_CLOSE maybe it is something where the client already had problems communicating and this is just the error that triggers when there is another issue present.

       

      Thanks

      • Your welcome.

        CLIENT_CLOSED events gets triggers by the client ending the connection. And yes it is true, any TCL error will cause the Virtual Server to stop processing traffic.

        rule1_msg1 not being filled with data (and causing the TCL error) will only happen if a client doesn't send any data after the connection has been created, same for SERVER_CLOSED TCL error. If this irule is attached to a virtual server without a proxy profile (L7 connection) the BIG-IP will create the server connection the moment thhttps://my.f5.com/manage/s/article/K8082e client connection is completed. If the client doesn't send any data, in the end the pool member will close its connection with the BIG-IP.
        K8082 explains the differences between virtual server types.

        It could be a client issue causing these erros' Still it is better to first create an empty variable to make sure you do not run into issues.

        Cheers,
        Kees