Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

Irule persist lookup source_addr for specific virtual server

Is there a way to lookup (persist lookup) the source IP address persistence for a specific VS only?

The tmsh command is like this but is there an equivalent using the persist lookup in Irule?

tmsh ltm persistence persist-records virtual VS1 client-addr 1.1.1.1

0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Unless 'Persist Across Virtuals' is set then the persistence is per virtual server anyway. If it is set then yes, you can control this with the command as per https://devcentral.f5.com/wiki/iRules.persist.ashx

persist lookup <mode> <key> [all|node|port|pool]  
"all" or no specification returns a list containing the node, port and  pool name.  
Specifying any of the other return types will return the specified item only.       
<key> = <mode specific value> | { <value> [any virtual|service|pool] [pool <name>] }        
the latter key specification is used to access persistence entries across virtuals, services, or pools.
0
Comments on this Answer
Comment made 10-Jul-2018 by Marvin 412

Hi Pete, we cannot use persist across Virtuals because the virtual dont share the same IP and also dont share the same pool therefor we need to customize this using the persist lookup feature in Irules, however cant find the syntax to select a specific virtual server.

  if { [persist lookup source_addr [IP::client_addr] node] eq "192.168.96.106" } {
    LB::reselect node 192.168.96.100 443

So in this partial command I want to alter to for example

persist lookup source_addr [IP::client_addr] virtual VS1 node eq "192.168.96.106"

If you know the syntax please let me know.

Thanks

0
Comment made 10-Jul-2018 by Marvin 412

Would this line show the node IP from the persistence table?

if { [persist lookup source_addr [[IP::client_addr] virtual VS1]] eq "192.168.96.106" }

0
Comment made 10-Jul-2018 by Pete White

You need to read the documentation regarding the persist command in some detail. They provide an example:

when HTTP_REQUEST {
# Save the value of the UIE persistence record for a generic token for any  virtual server
set value [persist lookup uie [list $myVar any virtual]]
}

I suggest you also read about the Match Across Virtuals documentation as well, i'm not sure it works the way you are expecting it to.

0
Comment made 10-Jul-2018 by Marvin 412

Hi Pete I really appreciate your help. The Match Across Virtuals wont work because we dont share the same pool member IP addresses on both Virtual servers, so there is nothing in common so the build in features, which are great though, are not going to solve this. Let me put this a bit more in perspective.

VS1 192.168.0.1 has pool A with pool member 10.0.0.1 and 10.0.0.2 VS2 192.168.0.2 has Pool B with pool member 10.0.0.3 and 10.0.0.4, Irule applied here

The requirement is when there is a connection to VS1 and the load balancing decision was made to 10.0.0.1, when the next session is setup to VS2 the load balancing decision has to go to 10.0.0.3. We are already using source address affinity so best way to lookup the persistence table for VS1 because it will stay for some time in the table.

So we created an Irule and it works BUT not in all circumstances because we need to search only the specific node value for the virtual server VS1 and not the complete persistence table, that said we are almost there!

The Irule works when you connect first to VS1 and then to VS2, but if you afterwards connect to VS3 the source IP persistence will be overwritten again. So I would like to narrow the search to specifically lookup the persistence entries of virtual server VS1.

So my question here is how can I modify the persist lookup command so it will only lookup the persistence record of VS1 using the source IP address (public IP) that is connecting to VS2.

when LB_SELECTED {
  log local0. "client = [IP::client_addr]:[TCP::client_port]"
  log local0. "\[persist lookup source_addr [IP::client_addr]\] = [persist lookup 
  source_addr [IP::client_addr]]"
  if { [persist lookup source_addr [IP::client_addr] node] eq "10.0.0.1" } {
        LB::reselect node 10.0.0.3 443
        log local0. "client = [IP::client_addr] Re-loadbalancing to [LB::server]"
    }
    elseif { [persist lookup source_addr [IP::client_addr] node] eq "10.0.0.2" } {
           LB::reselect node 10.0.0.4 443
           log local0. "client = [IP::client_addr] Re-loadbalancing to [LB::server]"
}
}
0
Comment made 11-Jul-2018 by Marvin 412

The problem here is that the current Irule applied on VS2 only shows the local node from the persistence table not from the other Virtual Server VS1.

0
Comment made 11-Jul-2018 by Pete White

Hi Marvin,

Try this:

when LB_SELECTED {
  set persist [persist lookup source_addr [list [IP::client_addr] any virtual]]
  log local0. "client = [IP::client_addr]:[TCP::client_port]"
  log local0. "Persistence = $persist"
}

This should give you the persistence records across both virtuals. Hopefully you can then pull the correct record out of that.

Of course the other option that you have is to create your own persistence using the platform table

0
Comment made 11-Jul-2018 by Marvin 412

Hi Pete, that option gives the same results only shows the value of the second VS2, the first persist lookup log entry is empty indicating that it was not able to look it up on the other VS1.

The other option you mention platform table I still have to investigate its new to me.

0
Comment made 11-Jul-2018 by Marvin 412

It would be very helpful if the persist lookup feature works at a global level that will provide a lot of flexibility.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Marvin,

For the most part, getting an added command to look across other virtuals persist records without enabling persist across * is slim. There are probably too many dark corners around which that could / would break. The preferred mechanism to do this would be with the table commands.

A minimal framework using the table commands could look similar to this:

when RULE_INIT {
    # probably makes more sense to use data groups here
    # quick and dirty PoC
    set static::web1_peer "/Common/vs_web2"
    set static::web2_peer "/Common/vs_web1"
}

when LB_SELECTED {
  table set [virtual name]:[IP::client_addr] [LB::server]
}

when HTTP_REQUEST {
    if { [virtual] eq "/Common/vs_web1" } {
        set peer ${static::web1_peer}
    }
    elseif { [virtual] eq "/Common/vs_web2" } {
        set peer ${static::web2_peer}
    }
    set peer_persist [table lookup ${peer}:[IP::client_addr]]
    if { ${peer_persist} ne "" } {
        log local0. "${peer} persist-record: ${peer_persist}. Select and persist to partner memeber."
    }
    else {
        log local0. "Peer persist-record not found.  Making selection."
    }

}
0