GTM Translation

Problem this snippet solves:

When GTM responds with the IP address of the virtual server, there are different NAT translations that must be performed depending on where the request is coming from. This iRule looks at 4 classes (DataGroups) to determine which (If any) of the NAT translations it must perform on the response.

This iRule differs from the pinhole example by only examining the response and the 'client' IP address. The hostname requested is ignored so there is only 1 event that needs to fire.

Note that although developed for GTM, this is an LTM iRule and is attached to the LTM VS that is created by the GTM when you configure a listener address

How to use this snippet:

These data-groups are required but MAY be empty if no translations are necessary.

  • local_address_class (type: address) - Holds a list of networks and their type (string internal or 3dp)
  • gte_translate_3dp (type: address) - Translations for 3dp networks
  • gte_translate_internet (type: address) - Translations for the internet
  • gte_translate_internal (type: address) - Translations for internal addresses

Code :

timing on

# gte_translate_external
#
# Hamish Marson (hamish@travellingkiwi.com) 2011
#
# When GTM responds with the IP address of the virtual server, there are different NAT translations that
# must be performed depending on where the request is coming from. This iRule looks at 4 classes (DataGroups)
# to determine which (If any) of the NAT translations it must perform on the response.
#
# CLASS                   Type      Description
# local_address_class     Address - Holds a list of networks and their type. Type is a string internal or 3dp
# gte_translate_3dp       Address - Translations for 3dp networks
# gte_translate_internet  Address - Translations for The Internet
# gte_translate_internal  Address - Translations for Internal addresses
#
# The translation dataGroups MUST exist. But MAY be empty if no translations are requirted (e.g. For Internal)
#
# Extensions... Current.y hardcoded for 3 types of address (internal, 3dp or (default) internet. This could be
# extended by building the translation class name from the value returned from local_address_class. However extra
# error checking would also be required to take into account mis-configuration of the local_address_class dataGroup
# to make non-existant dataGroup names.
#

when DNS_RESPONSE {

  set GTE_CLASS_INTERNET "gte_translate_internet"
  set GTE_CLASS_INTERNAL "gte_translate_internal"  
  set GTE_CLASS_3DP "gte_translate_3dp"
  set LOCAL_CLASS_ADDRESS "local_address_class"
  
  set gteHSL [HSL::open -proto UDP -pool hsl-log-01]
  set gteLogPrefix "<190>[virtual]:gte_translate_external:[IP::client_addr]:0:"

  # Grab the answer from GTM
  set rrs [DNS::answer]

  #HSL::send $gteHSL "$gteLogPrefix: checking DNS::answers"
  
  foreach rr $rrs {
#HSL::send $gteHSL "$gteLogPrefix: checking RR type ==> [DNS::type $rr]"
    
# Lookup the IP address returned in the GTE_CLASS
if { [DNS::type $rr] == "A" } {
      set dstip [DNS::rdata $rr]
  
  #HSL::send $gteHSL "$gteLogPrefix: checking A data ==> [DNS::rdata $rr] ($dstip)"
  set gteAddClass [class match -value [IP::client_addr] equals $LOCAL_CLASS_ADDRESS ]
  switch -exact $gteAddClass {
internal { set transIP  [class match -value $dstip equals $GTE_CLASS_INTERNAL] }
3dp      { set transIP  [class match -value $dstip equals $GTE_CLASS_3DP] }
    default  { set transIP  [class match -value $dstip equals $GTE_CLASS_INTERNET] }
  }
  if { $transIP ne "" } {
HSL::send $gteHSL "$gteLogPrefix: translate ($gteAddClass) $dstip => $transIP" 
        DNS::rdata $rr $transIP
return
  } else {
HSL::send $gteHSL "$gteLogPrefix: no match for ($gteAddClass) $dstip"  
return
  }
}
  }
}
Published Nov 04, 2015
Version 1.0

Was this article helpful?

6 Comments

  • Hi,

     

    When i go to use this GTM rule - i get the following error: 1070151:3: Rule [/Common/GTM_TRANSLATION_IRULE] error: Unable to find pool (hsl-log-01) referenced at line 32: [HSL::open -proto UDP -pool hsl-log-01]

     

    I was trying to attach to LTM VS but that does not have any pool - because its just VS pushed from GTM, when you configure listener IP.

     

    P.S. I have already configured the needed DATA GROUPS.

     

    Appreciate your help?

     

  • just to confirm, you have this iRule applied to an LTM virtual server with a dns services profile, or are you trying to use strictly a GTM iRule? They are different, and not all features work on GTM iRules like they do on LTM.

     

  • I did try to attach on LTM VS but it does not allow to apply with the error above. For UDP - i do see UDP_GTM_DNS profile attached for TCP VS, its not.

     

    Any suggestion to fix it? Looks like, its looking for a pool to be used?

     

  • Hi Madni, the error is from this line:

    set gteHSL [HSL::open -proto UDP -pool hsl-log-01]

    You either need to define an HSL pool named hsl-log-01, or update this line to reflect whatever you named your nsl pool.

  • Hi Jason,

     

    Not sure, why we require HSL pool for GTM.

     

    My requirement is that - i need clients with private IP get privat A record and public clients to get Public A record.

     

  • this iRule uses HSL for logging purposes, not for traffic purposes. If you don't need that, you can trim that out of the rule.