Forum Discussion

Paula_Roldan_73's avatar
Paula_Roldan_73
Icon for Nimbostratus rankNimbostratus
Oct 18, 2006

iRule bad behavior

Hello everybody!

 

 

I am new in this forum, and I woulkd really appreciate if any of you with your experience could help me to find out wath is wrong with my irule that is not working properly!

 

 

The required behavior is the following:

 

Many clients send UDP (port 50001) messages to different internal servers through BIGIP LTM. BUT, the messages should ONLY be delivered to pool1 (at this moment with only one server, server1) IF and ONLY IF the message contains certain data in the UDP packet payload (the "certain data" is the following binary string 018000000140). IF the packet/message does not match that pattern/data it must be delivered to pool2 (with 2 pool members: server2 and server3).

 

 

So I configured the following:

 

 

a) 3 nodes: server1, server2 and server3 with heath monitor = icmp

 

b) pool1 with 1 pool member: server1 and port 50001 (server1:50001)

 

c) pool2 with 2 pool members: server2:port 50001 and server3:port 50001 (server2:50001 and server3:50001)

 

d) A virtual server with the corresponding virtual IP address (destination address), virtual service port = 50001, UDP protocol, Default Pool =none. And assigned the following iRule to manage the traffic:

 

 

when CLIENT_DATA {

 

binary scan [UDP::payload] H12 datos

 

if { $datos equals "018000000140" } {

 

pool pool1

 

} else {

 

pool pool2

 

}

 

}

 

 

 

PROBLEM: As you can verify the wanted iRule is a very simple one. The "strange" thing, is the "binary scan" statement, but I supposed it is a valid one. Unfortunately I am seing a no deterministic and bad behavior. The iRule is working well with some messages, but not with ALL of them. I saw messages delivered to server1 (in pool1) that should be delivered to pool2 (server2 or server3), and I am also seeing messages that must being delivered to pool1, but they are delivered to pool2.

 

 

I made changes in the iRule to try to find out the problem and did troubleshooting, but I always have the same bad result. Each change was configured and tested with and without the log option, and putting the log sentence after and before the corresponding pool/node sentence, we also reboot the ltm box. But we have the bad behavior: some packets were wrongly delivered.

 

 

Change1: Delete the "else" option AND configured in the Visrtual server a default Pool = pool2.

 

 

when CLIENT_DATA {

 

binary scan [UDP::payload] H12 datos

 

if { $datos equals "018000000140" } {

 

log local0. "THE PAYLOAD IS $datos AND I AM IN IF EVAL" ---------->>>> I add this line for troubleshooting and did the test wit and without it

 

pool pool1

 

}

 

}

 

 

Change2:

 

 

when CLIENT_DATA {

 

binary scan [UDP::payload] H12 datos

 

if { $datos equals "018000000140" } {

 

log local0. "THE PAYLOAD IS $datos AND I AM IN IF EVAL" ---------->>>> I add this line for troubleshooting and did the test wit and without it

 

node

 

}

 

}

 

 

Change3: Use node sentence instead of pool sentence AND add the else option AND configure default Pool = none in the Virtual server

 

 

when CLIENT_DATA {

 

binary scan [UDP::payload] H12 datos

 

if { $datos equals "018000000140" } {

 

log local0. "THE PAYLOAD IS $datos AND I AM IN IF EVAL" ---------->>>> I add this line for troubleshooting and did the test wit and without it

 

node

 

}else {

 

log local0. "THE PAYLOAD IS $datos AND I AM IN ELSE EVAL" ---------->>>> I add this line for troubleshooting and did the test wit and without it

 

pool pool2

 

}

 

}

 

 

 

Change4: change CLIENT_DATA event with CLIENT_ACCEPTED event AND verify that Visrtual server´s default Pool was none.

 

 

when CLIENT_ACCEPTED {

 

binary scan [UDP::payload] H12 datos

 

if { $datos equals "018000000140" } {

 

pool pool1

 

} else {

 

pool pool2

 

}

 

}

 

 

 

Change5:

 

 

when CLIENT_ACCEPTED {

 

binary scan [UDP::payload] H12 datos

 

if { $datos equals "018000000140" } {

 

node

 

} else {

 

pool pool2

 

}

 

}

 

 

Change6: Delete the else option AND configured in the Virtual server a default Pool = pool2

 

 

when CLIENT_ACCEPTED {

 

binary scan [UDP::payload] H12 datos

 

if { $datos equals "018000000140" } {

 

log local0. "THE PAYLOAD IS $datos AND I AM IN IF EVAL" >>> I add this line for troubleshooting and did the test wit and without it >>>>>>>>>>>>>>

 

node

 

}

 

}

 

 

In all the described situations/configurations we still saw some udp messages/packets delivered to pool1 or server that should be delivered to pool2 (server2 or server3), and some messages that should be delivered to server1 that were delivered to pool2.

 

 

When I saw the statistics, or the /var/log/ltm file I saw that some messages that should be delivered to pool1 or server were delivered to pool2 (server2 or server3).

 

 

For more information, the source IP address not always is the same. There is no pattern. At one time, we had the behavior with certain source IP addresses, 15 minutes later we have the same behavior with other source IP addresses and the first ones then work fine. As I told you, it is NO deterministic.

 

 

Perhaps the problem would be in the expression when comparing the variable (with a binary value assigned) with the static value between quotation marks. So then, sometimes the expression evaluates the comparison correctly and sometimes it is not. But I really do not know...

 

 

Could anyone help me with this iRule?

 

 

Thanks in advance for your help!

 

Kind regards,

 

Paula

6 Replies

  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    Does datos contain what you expect it to contain?

     

     

    Also, do you have the UDP profile datagram_lb attribute enabled?

     

     

    If not, then you would need to explicitly LB::detach to get the server detached so that the following packet would be routed to the new server.

     

     

  • First of all thanks very much for your answer!!!

     

     

    >>> Does datos contain what you expect it to contain?

     

    Yes, it does. I verified that putting the following line before the IF-THEN sentences:

     

     

    log local0. "THE PAYLOAD IS $datos"

     

     

    and verified if I was getting the correct data. And the answer is yes. At that time, then I also put the log sentence inside IF and THEN sentence to determine which one was working, and there I found out (well confirm) that sometimes the iRule was working fine and sometimes not.

     

     

    >>>> Also, do you have the UDP profile datagram_lb attribute enabled?

     

    Well, let me know if I am understanding you correctly. You are refer ring to the protocol type profile. and I have assigned the default UDP protocol profile to the corresponding virtual server, so unfortunatelly by default datagram_lb is disabled.

     

     

    I am going to enable it and verify the behavior and let you know the results.

     

     

    Thanks very much for your help!

     

    Regards,

     

    Paula
  • Did you ever find out if this fix worked for you?? I'm having a similar non-determinisitic problem.

     

     

    I have this iRule:

     

    when HTTP_REQUEST {

     

    if {[HTTP::uri] starts_with "/v6" } {

     

    pool WebApache

     

    }

     

    }

     

     

    Send requests to Apache on port 81

     

     

    When a request that starts with "/v6", I want it to go to my Apache server, otherwise IIS should handle the request. For most of the request it works, but it seems that the iRule is allowing some requests that don't start with "/v6" through to Apache.
  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    I'd recommend setting the default pool you want your traffic to go to (the one with your IIS servers in it) at the beginning of the rule, or in an else clause after the if statement. This has to do with the way that the LB pointer is updated on multiple passes through a rule.

    Something like:

    
    when HTTP_REQUEST {
      if { [HTTP::uri] starts_with "/v6" } {
        pool WebApache
      } else {
        pool WebIIS
      }
    }

    Colin
  • Sorry for the delayed update!!!! I configured the lb_datagram option in the assigned UDP profile and I am happy to say that I do not see any non-wanted traffic reaching the server1 in pool1.

     

     

    THANKSSSSSSSSSS!!!!!!!

     

     

    However, I still do see that the servers in pool2 (server2 and server3) still receive a fair amount (1700-4200/day) of requests which should have been delivered to pool1 (server1).

     

     

    Do you think the problem would be in the expression evaluation? i.e. when I compare the variable (with a binary value assigned) with the static value between quotation marks?.

     

     

    Any idea or suggestion?