Forum Discussion

Grzegorz_Skrzyp's avatar
Grzegorz_Skrzyp
Icon for Nimbostratus rankNimbostratus
Jan 28, 2014

Radius attributes based balncing question

Hi Experts, This is my first rule - you know what this mean :) OK - the goal is to have pool member selection based on RADIUS attribute. I have on my box:

when RULE_INIT {
    set static::debug_custom_attribute 1
    set static::pool_name POOL_RADIUS_auth
    set static::pool_odd_member 192.168.36.1
    set static::pool_even_member 192.168.36.2
}
when CLIENT_DATA {
    set nasip  [RADIUS::avp  4 ip4]
    set callingId  [RADIUS::avp  31 "string"]
    set is_odd [expr $callingId & 1]

 if { $is_odd } {
      Calling-Station-Id is odd
      trying to select odd_member of the pool
     pool $static::pool_name member $static::pool_odd_member
     if { [LB::status node $static::pool_odd_member] eq "down" } {
         log local0. "Pool: $static::pool_name member: $static::pool_odd_member -> is down switching to: $static::pool_even_member"
         pool $static::pool_name member $static::pool_even_member
     }
     if { $static::debug_custom_attribute } {
         log local0. "Calling-Station-Id: $callingId is odd"
     }
 } else {
      Calling-Station-Id is even
      trying to select even_member of the pool
     pool $static::pool_name member $static::pool_even_member
     if { [LB::status node $static::pool_even_member] eq "down" } {
         log local0. "Pool: $static::pool_name member: $static::pool_even_member -> is down switching to: $static::pool_odd_member"
         pool $static::pool_name member $static::pool_odd_member
     }
     if { $static::debug_custom_attribute } {
         log local0. "Calling-Station-Id: $callingId is even"
     }
 }
        }

But this is not working as I want. Could someone help me to mak it working? Thanks

7 Replies

  • This is the problem nothing :( It seams that LB_SELECTED event is faster then whole iRule ... Please find below log: Jan 28 18:34:55 roz-1 info tmm[8604]: Rule /Common/F5_EvenOdd : Selected /Common/POOL_RADIUS_auth 192.168.36.1 1812 Jan 28 18:34:55 roz-1 info tmm[8604]: Rule /Common/F5_EvenOdd : NAS-IP-Addr: 192.168.1.10 Jan 28 18:34:55 roz-1 info tmm[8604]: Rule /Common/F5_EvenOdd : Calling-Station-Id: 420730175222 Jan 28 18:34:55 roz-1 info tmm[8604]: Rule /Common/F5_EvenOdd : Calling-Station-Id: 420730175222 is even Jan 28 18:34:55 roz-1 info tmm[8604]: Rule /Common/F5_EvenOdd : LB::Server: 192.168.36.1 Jan 28 18:34:55 roz-1 info tmm[8604]: Rule /Common/F5_EvenOdd : Server connected
  • Hmmm... Why is the load balancing logic in CLIENT_DATA, you're sure that's correct event? How is the UDP profile configured? with datagram load balancing? do you have RADIUS profile too? Are you saying the virtual server works fine, except traffic is not load balanced as you expect it to be?
  • Mohamed, to be honest - I don't know if this is correct or not. Can I access Radius attributes on other event? Which event is the best for that? Please have a look on my VS configuration below: ltm virtual VS_RADIUS_auth_1812 { description "Virtual server for AUTH" destination 10.49.36.4:radius ip-protocol udp mask 255.255.255.255 pool POOL_RADIUS_auth profiles { udp { } } rules { F5_EvenOdd } source 0.0.0.0/0 source-address-translation { type automap } vlans { external } vlans-enabled vs-index 7 } F5 is doing LB just fine (I mean - the load is spread across two Radius servers in Round Robin - configured inside the pool). But this is not my goal - I repeat I need to send all even Calling-Station-ID to one server and odd Calling-Station-ID to another. Is there any other possibility to achieve this?
  • OK - maybe this is not the optimal, but when I changed the event to CLIENT_ACCEPTED I was able to change the pool and its member according to any RADIUS attribute. Mission acomplished :)

     

    • Grzegorz_Skrzyp's avatar
      Grzegorz_Skrzyp
      Icon for Nimbostratus rankNimbostratus
      Yes, thank you Mohamed - it was very inspiring to me. Finally my iRule is looking like this one:
      when RULE_INIT {
          set static::version 1.0
          set static::debug_custom_attribute 1
          set static::auth_pool POOL_RADIUS_auth
          set static::odd_member 192.168.36.1
          set static::even_member 192.168.36.2
      }
      
      when CLIENT_ACCEPTED {
           Displays script version
          if { $static::debug_custom_attribute } {
              log local0. ">>>> iRule script version: $static::version"
          }
      
           getting the Calling-Station-ID from the Radius packet
          set callingId  [RADIUS::avp  31 "string"]
           check if the callingId has any value
          if { $callingId ne ""}{
              checking Calling-Station-ID as callingId priority
              set is_odd [expr $callingId & 1]
              if { $is_odd } {
                  if { $static::debug_custom_attribute } {
                      log local0. "Calling-Station-Id: $callingId is odd"
                  }
                  pool $static::auth_pool member $static::odd_member
              } else {
                  if { $static::debug_custom_attribute } {
                      log local0. "Calling-Station-Id: $callingId is even"
                  }
                  pool $static::auth_pool member $static::even_member
              }
          } else {
               there is no Calling-Station-ID set in Radius packet
              if { $static::debug_custom_attribute } {
                  log local0. "Radius packet hasn't got Calling-Station-Id set"
              }
               we do normal load balancing around servers defined in pool
              pool $static::auth_pool
          }
      }
      when LB_FAILED {
           triggered when selected server is down
          if { $static::debug_custom_attribute } {
              log local0. "Selected server: [LB::server addr] is down"
          }
           doing normal new server election from the pool 
          pool $static::auth_pool
          LB::reselect
      }
      
       for DEBUG only
      when LB_SELECTED {
           triggered when new server is selected: "manually" or by re-election
          if { $static::debug_custom_attribute } {
               log local0. "New server selected: [LB::server addr]"
          }
      }
      when SERVER_CONNECTED {
           triggered when selected server is connected
          if { $static::debug_custom_attribute } {
              log local0. "Server connected: [IP::remote_addr] from: [IP::local_addr]"
          }
      }
      }