=== modified file 'doc/release-notes/release-3.2.sgml'
--- doc/release-notes/release-3.2.sgml	2011-03-11 22:16:05 +0000
+++ doc/release-notes/release-3.2.sgml	2011-03-28 13:37:19 +0000
@@ -519,7 +519,8 @@
 	<tag>logformat</tag>
         <p><em>%&gt;bs</em> Number of HTTP-equivalent message body bytes received from the next hop.
         <p><em>icap::%&gt;bs</em> Number of message body bytes received from the ICAP server.
-	<p><em>%&gt;lp</em> Local TCP port used by transactions with http servers.
+	<p><em>%&gt;la</em> Local IP address used by last transaction with HTTP servers. Ported from 2.7 where it is called <em>%oa</em>
+	<p><em>%&gt;lp</em> Local TCP port used by transactions with HTTP servers.
 	<p><em>%sn</em> Unique sequence number per log line. Ported from 2.7
 	<p><em>%&gt;eui</em> EUI logging (EUI-48 / MAC address for IPv4, EUI-64 for IPv6)
 	   Both EUI forms are logged in the same field. Type can be identified by length or byte delimiter.
@@ -897,9 +898,6 @@
 	<tag>location_rewrite_program</tag>
 	<p>Not yet ported from 2.6
 
-	<tag>logformat</tag>
-	<p><em>%oa</em> tag not yet ported from 2.7
-
 	<tag>refresh_pattern</tag>
 	<p><em>stale-while-revalidate=</em> not yet ported from 2.7
 	<p><em>ignore-stale-while-revalidate=</em> not yet ported from 2.7

=== modified file 'src/HierarchyLogEntry.h'
--- src/HierarchyLogEntry.h	2010-08-07 14:51:30 +0000
+++ src/HierarchyLogEntry.h	2011-03-28 13:25:46 +0000
@@ -35,6 +35,7 @@
 #define SQUID_HTTPHIERARCHYLOGENTRY_H
 
 #include "hier_code.h"
+#include "ip/Address.h"
 #include "lookup_t.h"
 #include "rfc2181.h"
 #include "PingData.h"
@@ -64,7 +65,7 @@
     int64_t peer_response_time; ///< last peer response delay
     timeval first_conn_start; ///< first connection use among all peers
     int64_t total_response_time; ///< cumulative for all peers
-    u_short peer_local_port; //< local port of the last server-side connection
+    Ip::Address peer_local_addr; ///< local IP:port of the last server-side connection
     int64_t bodyBytesRead;  ///< number of body bytes received from the next hop or -1
 };
 

=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2011-03-25 11:47:08 +0000
+++ src/cf.data.pre	2011-03-28 13:03:47 +0000
@@ -2873,6 +2873,7 @@
 		<A	Server IP address or peer name
 		la	Local IP address (http_port)
 		lp	Local port number (http_port)
+		<la	Local IP address of the last server or peer connection
 		<lp     Local port number of the last server or peer connection
 
 	Time related format codes:

=== modified file 'src/forward.cc'
--- src/forward.cc	2011-03-02 20:43:21 +0000
+++ src/forward.cc	2011-03-28 13:13:31 +0000
@@ -880,8 +880,9 @@
 
         comm_add_close_handler(fd, fwdServerClosedWrapper, this);
 
-        // TODO: Avoid this if %<lp is not used? F->local_port is often cached.
-        request->hier.peer_local_port = comm_local_port(fd);
+        // TODO: Avoid this if %<lp and %<la is not used? F->local_port is often cached.
+        comm_local_port(fd);
+        request->hier.peer_local_addr = fd_table[fd].local_addr;
 
         dispatch();
 
@@ -949,7 +950,8 @@
     if (!fs->_peer)
         origin_tries++;
 
-    request->hier.peer_local_port = comm_local_port(fd);
+    comm_local_port(fd);
+    request->hier.peer_local_addr = fd_table[fd].local_addr;
 
     /*
      * stats.conn_open is used to account for the number of

=== modified file 'src/log/FormatSquidCustom.cc'
--- src/log/FormatSquidCustom.cc	2011-03-11 22:38:29 +0000
+++ src/log/FormatSquidCustom.cc	2011-03-29 01:12:05 +0000
@@ -186,9 +186,17 @@
 
             break;
 
+            // the fmt->type can not be LFT_PEER_LOCAL_IP_OLD_27
+            // but compiler complains if ommited
+        case LFT_PEER_LOCAL_IP_OLD_27:
+        case LFT_PEER_LOCAL_IP:
+            if (!al->hier.peer_local_addr.IsAnyAddr()) {
+                out = al->hier.peer_local_addr.NtoA(tmp,1024);
+            }
+            break;
+
         case LFT_PEER_LOCAL_PORT:
-            if (al->hier.peer_local_port) {
-                outint = al->hier.peer_local_port;
+            if ((outint = al->hier.peer_local_addr.GetPort())) {
                 doint = 1;
             }
 

=== modified file 'src/log/Tokens.cc'
--- src/log/Tokens.cc	2011-02-18 23:58:13 +0000
+++ src/log/Tokens.cc	2011-03-28 13:23:42 +0000
@@ -85,13 +85,14 @@
     /*{ "<p", LFT_SERVER_PORT }, */
     {"<A", LFT_SERVER_IP_OR_PEER_NAME},
 
-    /* {"oa", LFT_OUTGOING_IP}, */
-    /* {"ot", LFT_OUTGOING_TOS}, */
-
     {"la", LFT_LOCAL_IP},
     {"lp", LFT_LOCAL_PORT},
     /*{ "lA", LFT_LOCAL_NAME }, */
+
+    {"<la", LFT_PEER_LOCAL_IP},
+    {"oa", LFT_PEER_LOCAL_IP_OLD_27},
     {"<lp", LFT_PEER_LOCAL_PORT},
+    /* {"ot", LFT_PEER_OUTGOING_TOS}, */
 
     {"ts", LFT_TIME_SECONDS_SINCE_EPOCH},
     {"tu", LFT_TIME_SUBSECOND},
@@ -456,6 +457,12 @@
         debugs(46, 0, "WARNING: the \"Hs\" formating code is deprecated use the \">Hs\" instead");
         lt->type = LFT_HTTP_SENT_STATUS_CODE;
         break;
+
+    case LFT_PEER_LOCAL_IP_OLD_27:
+        debugs(46, 0, "WARNING: the \"oa\" formating code is deprecated use the \"<la\" instead");
+        lt->type = LFT_PEER_LOCAL_IP;
+        break;
+
     default:
         break;
     }

=== modified file 'src/log/Tokens.h'
--- src/log/Tokens.h	2011-02-18 23:58:13 +0000
+++ src/log/Tokens.h	2011-03-28 13:40:19 +0000
@@ -59,6 +59,8 @@
     LFT_LOCAL_IP,
     LFT_LOCAL_PORT,
     /*LFT_LOCAL_NAME, */
+    LFT_PEER_LOCAL_IP,
+    LFT_PEER_LOCAL_IP_OLD_27,
     LFT_PEER_LOCAL_PORT,
 
     LFT_TIME_SECONDS_SINCE_EPOCH,

=== modified file 'src/log/access_log.cc'
--- src/log/access_log.cc	2011-03-11 22:38:29 +0000
+++ src/log/access_log.cc	2011-03-28 13:39:49 +0000
@@ -252,7 +252,7 @@
         peer_reply_status(HTTP_STATUS_NONE),
         peer_response_time(-1),
         total_response_time(-1),
-        peer_local_port(0),
+        peer_local_addr(),
         bodyBytesRead(-1)
 {
     memset(host, '\0', SQUIDHOSTNAMELEN);

=== modified file 'src/tunnel.cc'
--- src/tunnel.cc	2011-03-23 08:55:43 +0000
+++ src/tunnel.cc	2011-03-28 22:43:32 +0000
@@ -688,7 +688,9 @@
         return;
     }
 
-    request->hier.peer_local_port = comm_local_port(sock); // for %<lp logging
+    // record local IP:port for %<la and %<lp logging
+    comm_local_port(sock);
+    request->hier.peer_local_addr = fd_table[sock].local_addr;
 
     tunnelState = new TunnelStateData;
 #if USE_DELAY_POOLS


