Forum Discussion

RoutingLoop_179's avatar
Feb 13, 2013

Linking Universal persistence across different dataflows and virtual servers

Hi I've been trying to look at getting this working but sort of going round in circles at the logic.

 

Basically i essentially have three flows of traffic in this order.

 

1st Radius - containing user MAC attribute - on Virtual Server1

 

2nd Radius - containing user MAC + client framed-IP attributes - on Virtual Server 1

 

3rd Client Data - coming from client src IP = radius framed-IP above - on Virtual Server2

 

 

I can see how I could essentially use irule persist command to create UIE persistence for the radius traffic basing it on the MAC attribute. e.g using something onlong the lines of (untested code).

 

set IsPersisted [persist lookup uie [RADIUS::avp 31] pool pool_1]

 

if { $IsPersisted eq "" } {

 

persist add uie [RADIUS::avp 31] 1800

 

 

} else {

 

persist uie [RADIUS::avp 31]

 

}

 

 

But what i'm getting lost with is how I could create a persistence record for the client IP taken from the framed-IP field [RADIUS::avp 8] of the second radius flow but it needs to be sent to the same node used in the original persistence record.

 

 

e.g

 

radius flow1 gets loadbalanced across the pool as normal. UIE persistence record created based on [RADIUS::avp 31]. goes to node1

 

radius flow2 - [RADIUS::avp 31] matches persistence created record above hence traffic goes to node1. But also creates a persistence record for client IP read from the radius data [RADIUS::avp 8] but this also needs to go to the same node 1.

 

Data flow3 - persistence record exists for client source address from above so send it to node 1. if not LB as normal and create persistence based on client address.

 

 

As i said i can't quite work out the link between flow2 and flow3. i can create a new record using "persist add uie [RADIUS::avp 8] 1800" but this I assume would create a new record and could go to any member of the pool - but i need to ensure its stuck to the same node.

 

 

As ever, grateful for any help and suggestions - i'll be plugging away on this myself as well.

 

Adrian

 

 

 

 

7 Replies

  • on flow2, may we insert client framed-IP and node IP in table instead of creating persistence record for flow3?

     

     

    so, on flow3 we can lookup node IP based on client framed-IP and send packet to it.

     

     

    just my 2 cents.
  • Thanks nitass, I've been trying to think along the same lines looking into session commands. I had another thought this morning ( based of what I've read, but i may have massively over simplified it) and i need to test the theory in the lab.

    Irule Virtual server 1 for radius - Load balancing across pool1.

     when CLIENT_DATA {
      USER MAC - radius attribute 31 Calling-Station-Id
      client-IP - radius attribute 8 Framed-IP
      persist based on MAC found in the radius traffic, if exists use it, else create a new one and loadbalance as normal.
     persist uie [RADIUS::avp 31] }
     
    when LB_SELECTED {
    create persist rule for current server but using framed IP or client-IP as the identifier
    persist add uie "[RADIUS::avp 8] pool pool1" 1800}
    

    Irule Virtual server 2 for all traffic - also Load balancing across same pool1.

    
    when CLIENT_DATA {
     If persist exists for client IP use it, otherwise create a new one and loadbalance as normal.
    persist uie [IP::client_addr]}
    

  • what about something like this?

     control plane
    
    [root@ve10:Active] config  b virtual rad_vs list
    virtual rad_vs {
       snat automap
       pool rad_pool
       destination 172.28.19.252:1812
       ip protocol 17
       rules rad_rule
       profiles {
          radiusLB {}
          udp_gtm_dns {}
       }
    }
    [root@ve10:Active] config  b pool rad_pool list
    pool rad_pool {
       members {
          200.200.200.101:1812 {}
          200.200.200.111:1812 {}
       }
    }
    [root@ve10:Active] config  b rule rad_rule list
    rule rad_rule {
       when CLIENT_ACCEPTED {
       log local0. "\[RADIUS::avp 31\] [RADIUS::avp 31]"
       log local0. "\[RADIUS::avp 8\] [RADIUS::avp 8]"
       log local0. "\[persist lookup uie [RADIUS::avp 31]\] [persist lookup uie [RADIUS::avp 31]]"
    
       persist uie [RADIUS::avp 31]
       if {[RADIUS::avp 8] ne ""} {
          if {[scan [persist lookup uie [RADIUS::avp 31]] {%*s%s%*d} ip] == 1} {
             table add [RADIUS::avp 8] $ip
          }
       }
    }
    }
    
     data plane
    
    [root@ve10:Active] config  b virtual data_vs list
    virtual data_vs {
       snat automap
       pool data_pool
       destination 172.28.19.252:80
       ip protocol 6
       rules data_rule
    }
    [root@ve10:Active] config  b pool data_pool list
    pool data_pool {
       members {
          200.200.200.101:80 {}
          200.200.200.111:80 {}
       }
    }
    [root@ve10:Active] config  b rule data_rule list
    rule data_rule {
       when CLIENT_ACCEPTED {
       log local0. "\[table lookup [IP::client_addr]\] [table lookup [IP::client_addr]]"
    
       if {[table lookup [IP::client_addr]] ne ""} {
          pool data_pool member [table lookup [IP::client_addr]] 80
       }
    }
    when SERVER_CONNECTED {
       log local0. "client [IP::client_addr]:[TCP::client_port] server [IP::remote_addr]:[TCP::remote_port]"
    }
    }
    
     flow1
    
    [root@ve10:Active] config  tail -f /var/log/ltm
    Feb 14 20:22:48 local/tmm info tmm[4909]: Rule rad_rule : [RADIUS::avp 31] 0001.0203.0405
    Feb 14 20:22:48 local/tmm info tmm[4909]: Rule rad_rule : [RADIUS::avp 8]
    Feb 14 20:22:48 local/tmm info tmm[4909]: Rule rad_rule : [persist lookup uie 0001.0203.0405]
    
    [root@ve10:Active] config  b persist show all
    PERSISTENT CONNECTIONS
    |     Mode universal   Value 0001.0203.0405
    |        virtual 172.28.19.252:1812   node 200.200.200.101:1812   age 13sec
    
     flow2
    
    [root@ve10:Active] config  tail -f /var/log/ltm
    Feb 14 20:23:17 local/tmm info tmm[4909]: Rule rad_rule : [RADIUS::avp 31] 0001.0203.0405
    Feb 14 20:23:17 local/tmm info tmm[4909]: Rule rad_rule : [RADIUS::avp 8] 192.168.206.31
    Feb 14 20:23:17 local/tmm info tmm[4909]: Rule rad_rule : [persist lookup uie 0001.0203.0405] rad_pool 200.200.200.101 1812
    
     flow3
    
    [root@ve10:Active] config  tail -f /var/log/ltm
    Feb 14 20:23:47 local/tmm info tmm[4909]: Rule data_rule : [table lookup 192.168.206.31] 200.200.200.101
    Feb 14 20:23:47 local/tmm info tmm[4909]: Rule data_rule : client 192.168.206.31:50745 server 200.200.200.101:80
    
  • Brilliant thanks, i've made very small modification and rather than using scan the to grab the IP out i just use node in the lookup and pull the node straight then. e.g

     when CLIENT_ACCEPTED {  USER MAC - radius attribute 31 Calling-Station-Id  client-IP - radius attribute 8 Framed-IP log local0. "Client: [IP::client_addr] Framed-Ip-Address \[RADIUS::avp 8\]: [RADIUS::avp 8] MAC \[RADIUS::avp 31\]: [RADIUS::avp 31]" persist uie [RADIUS::avp 31] if { [RADIUS::avp 8] ne "" } { set node [persist lookup uie "[RADIUS::avp 31] any virtual" node] log local0. "node: $node" table add [RADIUS::avp 8] $node log local0. "created tabledata for framed-ip-address:[RADIUS::avp 8] associated with: $node" } } 

    so the rule seems to be working but i have seen some unexpected behavior regarding the persistence on just the radius traffic flow which should be persistent on MAC attribute. Even if there is a UIE persistence record for the mac attribute, I don't have radius server on the other the server side so on event LB_SELECTED it seems bigip (or client) is retrying and sending the request (i'm a bit unsure why) but it seems to be bigIP doing the retry as i only see retries on LB_SELECTED, but looking at my logs on each retry it seems to round robin across my two live nodes.

    Feb 15 11:12:45 tmm info tmm[6932]: Rule /Common/radius_persist2 : [persist lookup uie [RADIUS::avp 31] any virtual node]: 192.168.71.12

    Feb 15 11:12:45 tmm info tmm[6932]: Rule /Common/radius_persist2 : ClientIP: 10.12.13.4 LB to: 192.168.71.12

    Feb 15 11:12:50 tmm info tmm[6932]: Rule /Common/radius_persist2 : [persist lookup uie [RADIUS::avp 31] any virtual node]: 192.168.71.12

    Feb 15 11:12:50 tmm info tmm[6932]: Rule /Common/radius_persist2 : ClientIP: 10.12.13.4 LB to: 192.168.71.11

    Feb 15 11:12:55 tmm info tmm[6932]: Rule /Common/radius_persist2 : [persist lookup uie [RADIUS::avp 31] any virtual node]: 192.168.71.12

    Feb 15 11:12:55 tmm info tmm[6932]: Rule /Common/radius_persist2 : ClientIP: 10.12.13.4 LB to: 192.168.71.12

    any ideas?

    I'm using VE with 11.2.1 - no hotfixes.

  • looks abit like this - could be similar?? althought we're talking about udp

     

     

    http://support.f5.com/kb/en-us/solutions/public/7000/900/sol7964.html

     

  • Hi - just thought I extend an update - I have found a workaround for it ignoring the persistence on client retries. Rather than setting the radius persistence in the radius irule, I now set in the radius profile which is applied to the virtual server and set the persist attribute in there to be "31". I now do the persist lookup in the LB_SELECTED {} event.

    radius flow irule is now:

     
    when CLIENT_ACCEPTED {
       USER MAC - radius attribute 31 Calling-Station-Id
       client-IP - radius attribute 8 Framed-IP
    set mac [RADIUS::avp 31]
    set FrIP [RADIUS::avp 8]
    log local0. "Client: [IP::client_addr] Framed-Ip-Address \[RADIUS::avp 8\]: $FrIP   MAC \[RADIUS::avp 31\]: $mac"
    
    }
    
    
    when LB_SELECTED {
    
    if { $FrIP ne "" } {
    
    set node [persist lookup uie "$mac any virtual" node]
     log local0. "node: $node"
    table add $FrIP $node
    
    log local0. "created tabledata for framed-ip-address:$FrIP associated with: $node"   
    }
    
    log local0. "\[persist lookup uie \[RADIUS::avp 31\] any virtual node\]: $node"
    log local0. "ClientIP: [IP::client_addr]  LB to:  [LB::server addr]"
    }
    
  • sorry i was not notified when you replied. thanks for update.