Forum Discussion

arun_parthas_10's avatar
Icon for Nimbostratus rankNimbostratus
Jan 27, 2011

Help writing iRule based on user login id.




We have a unique requirement where I need your help in coming up with a solution that is least painful to manage :



1. One VIP


2. 4000 pools ( anticipated )


3. 4000 user id's ( anticipated )



We have a requirement to setup ONE VIP on a TCP Port ( this is not a HTTP based traffic ) and come up with a solution to send an user to a specific pool behind the VIP. We are anticipating 4000 users to send it to a appropriate pool ( one of the 4000 pools ) behind the VIP.



The logic is really simple but writing such a tedious iRule for 4000 users is going to be an administrative nightmare to maintain. Is there any recommendation, I would greatly appreciate.






Arun P

7 Replies

  • Hi Arun,



    A few questions about your scenario...



    What is the protocol?



    How do you identify the user ID within the TCP packets?



    Do users share the same TCP connection?



    Do you need a defined pool for each user ID? Or could you just select a destination IP and port based on the user ID?



    You could try collecting the TCP payload using TCP::collect, inspect the payload in CLIENT_DATA and then use the pool command to select a corresponding pool or the node command to select an arbitrary destination IP and port.



    You can get more information on the related events and commands in the iRules wiki:





  • Thanks, Aaron, This will use TCP and we intend to look at the ID using TCP::collect as you mentioned.


    Users do not share the connection. Each user will have their own connection to a specific pool, which answers the other question in that yes, we need to point to a pool.


    We're already going down the general path of creating an iRule in the method you're describing, but the sheer potential size of the rule is what's concerning.



    If we end up with 1000 IDs that we need to look for, that's 1000 if/else statements and it seems pretty cumbersome not only from a management perspective but we're more interested in what kind of load this will put on the F5.



    If a new user comes in, that ID will be at the end of the rule. If many users come in that live at the end of the rule, it would seem that there would be some performance hit. For a rule this large, is there a more efficient method of looking up IDs and matching them to their own pool?
  • Hi Arun,



    Colin's idea of creating a pool with the name specific to the user ID would make this a lot easier. You could extract the user ID from the request packets and use an iRule to select the corresponding pool (like my_${user_id}_pool). If there isn't a one to one user to pool name mapping, you could use a string datagroup that lists the user IDs and corresponding pool names. You could then use 'class lookup -value' to get the pool name for the current user ID.



    Datagroups should easily support thousands of entries. I would suggest doing performance testing with your expected load if possible if you're using tens or hundreds of thousands of entries.



  • Colin_Walker_12's avatar
    Historic F5 Account
    Even past 10k entries classes perform quite well for relatively small strings. Joe tested this recently and I was shocked at how little the load scaled when searching a class of 10k entries vs a class of 1k entries.



  • Hi Aaron / Collin,



    Many thanks for jumping on .. I guess its a great idea to name the pool's matching the userid.. any ideas how we convert this into an iRule ? any help is greatly appreciated.






    Arun P
  • Here is an untested example:

       log local0.debug "Collecting the payload"
    when CLIENT_DATA {
        Do some parsing of [TCP::payload] here to get the user ID
        In this example, we look for userid=, skip past that and read up to the next & or end of string
       set user [findstr [TCP::payload] userid= 7 &]
       log local0. "Parsed User ID: $user"
        If a user wasn't parsed, or there is an error assigning 
         a pool using the format my__pool, select a default pool.
         If there is a $user parsed and no error assigning it with the catch statement,
         that pool will be assigned by using catch.
       if {$user eq "" or [catch {pool my_${user}_pool}]}{
          log local0. "\$user is null or my_\$user_pool doesn't exist. Using a default pool."
          pool my_default_pool

  • Aaron



    Many thanks .. We will test this by implementing in our QA environment..



    Arun P