is it required to use same source port
The only requirement is that the client has the same SNAT IP each time and that SNAT IP is only associated with that single client - this is primarily for layer 3 protocols such as GRE/PPTP etc which don't care about ports. Haven't tested the theory but I would open up packet filter on the outside interface to allow incoming IP protocols coming back in, SNAT does this on a port level dynamically but we'll need to also do it for layer 3 protocols (not necessarily dynamic as happy to do it via packet filters on the interfaces). Suppose the behavior is more like a static 1:1 NAT on LTM i.e once setup it lets everything through for that client_IP:NAT_IP mapping.
if not, may we use table/subtable command to store these variables instead of global variable? so, the irule will be cmp-compatible
I'm happy with any way to improve it or make it more compatible. This was a bit of a first attempt. What would be ideal is a way to specify the pool subnet as a single variable and it loops through all the IPs in the subnet to find a free one, but i can't think of a way to do it other than the way I've done and specifying first and last values of each octect. I have done a similar thing in PHP with mysql DB, by converting the IP's subnet range etc to decimal and looping through that way, but don't think that very efficient in terms of network traffic as it'll need to keep converting the IP back and forward.
I've being trying to think of a way of incorporating more NAT pools - i.e Pool1 is full, look in say Pool2 for free IP etc. and also I've just been trying to think how i could make it more generic with regards to the size of the pool. This attempt is designed around a pool size which only affects last two octets so I suppose theoretically a maximum /16. Anyway to improve, advance it etc is great. I'm dong this a bit of a theory, as F5 CG-NAT module doesn't support it and it it's pretty important for us going forward.
As ever thanks for your feedback.
Adrian