Forum Discussion

deepfried78's avatar
deepfried78
Icon for Altostratus rankAltostratus
Jul 24, 2024

Trouble with TCP::option set 28

Using my lab VE, running 17.1.1.3, the following iRule returns the following error. I can't seem to find what's wrong with the format. Any help would be very appreciated. For context, I'm trying to build a basic test of setting TCP option 28 for a particular use case, but can't really get to the test because the baseline config for a simple http vip is returning this error.

when SERVER_CONNECTED {
    scan [IP::client_addr] {%d.%d.%d.%d} a b c d
    TCP::option set 28 [binary format cccc $a $b $c $d] all
}

TCL error: /Common/irule_tcp_option28 <SERVER_CONNECTED> - Illegal argument (line 2) invoked from within "TCP::option set 28 [binary format cccc $a $b $c $d] all"

  • deepfried78's avatar
    deepfried78
    Jul 26, 2024

    Thanks, I think we solved this around the same time. My first problem was that I was mistakenly enabling TCP options in my client TCP profile, but using the SERVER_CONNECTED event. When I enabled TCP options in the server event (by just configuring the virtual server to use the same profile for the server), I stopped getting the error.

    Here is the profile config:

    ltm profile tcp tcp_opt {

    app-service none

    tcp-options "{28 first}"

     

    Reading https://clouddocs.f5.com/api/irules/SERVER_CONNECTED.html I found that, for a standard profile, I'd find the options set in the first packet after the TCP 3-way handshake, but if I had used a fastL4 VIP, I would see it in the first syn, as you did.

    I also noticed that Wireshark interpreted option 28 as "user timeout", and also see the odd length of "6", but when I converted the 6 hex numbers, I got "28" (the option number), "6" (the size), "192" (first octet of true source IP address), "168" (second octet), third octet, and fourth octet. It worked.

5 Replies

    • deepfried78's avatar
      deepfried78
      Icon for Altostratus rankAltostratus

      I appreciate the help, but I'm having a hard time applying anything in that thread to this use case. The solution in that thread deals with logging the true source IP address to local0, but the line in my iRule above that is causing the error attempts to use "TCP::option" to set TCP option 28 with the values of variables a, b, c, and d,  which come from IP::client_addr.

      I appear to be successfully storing IP::client_addr in these variables because, when playing around with syntax to make sure that wasn't my problem, I got an error that "192" (the value of "a", which corresponds to the first octet of the client IP address in my testing) was not a valid command. It's the next line, where I try to set the TCP option 28 using the variables corresponding to the octets in the client address that throws the error and, as best I can tell, is the correct syntax. I'm really not positive, though, and would appreciate any help anyone may have.

      • Lucas_Thompson's avatar
        Lucas_Thompson
        Icon for Employee rankEmployee

         

        Thanks. Since there doesn't seem to be a good reference doc on this, and this functionality is confusing, and this functionality changed between v13 and v15, it seems like a good puzzle to unravel.

        Do you have an example packet capture or RFC or other specification of what data you want this to look like?

         

        I did some quick testing using a simple irule:

        when SERVER_INIT { 
          scan [IP::client_addr] {%d.%d.%d.%d} a b c d 
          TCP::option set 28 [binary format cccc $a $b $c $d] all 
        }

        and a TCP profile like this:

        ltm profile tcp tcp_opt { app-service none tcp-options "{28 last}" }

        NOTE: without the tcp-options section in the TCP profile, SERVER_INIT does not fire. In v14, an enhancement was made so that the TCP option can be injected into the very first server-side SYN packet.

         

        I get this this sort of traffic out of the backend:

        The "length 6" part doesn't seem quite right, but I'm not precisely sure what reference standard (RFC, etc) defines what "right" looks like here.

         

        Another note about this:

        Be careful with this "tcp-options" setting. It must be formatted in pairs like a TCL list (value space value space) or the parser can't parse it correctly. If this parser fails, it puts the BIG-IP into kind of a "dead" state where the TCP profile is broken. Making a change to the iRule attached to the vip causes the parser to re-read the tcp-options parameter. The log when this happens looks like this (in /var/log/ltm):

        Jul 26 11:50:56 west.lab.local warning tmm3[28927]: 01010039:4: Bad tcp options value in profile: Could not parse TCP options settings
        Jul 26 11:50:56 west.lab.local err tmm3[28927]: 01010356:3: hudfilter_init: filter 'TCP' init failed.
        Jul 26 11:50:56 west.lab.local err tmm3[28927]: 01010008:3: Proxy initialization failed for /Common/user107. Defaulting to DENY.