Index: include/http_protocol.h
===================================================================
--- include/http_protocol.h	(revision 1203646)
+++ include/http_protocol.h	(working copy)
@@ -696,6 +696,15 @@
  */
 AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers);
 
+/**
+ * This hook allows modules to override the effective IP address of the
+ * request if desired.
+ * @param r the current request
+ * @param auth_type the configured auth_type
+ * @return OK, DECLINED
+ */
+AP_DECLARE_HOOK(const char *, effective_ip, (request_rec *r));
+
 #ifdef __cplusplus
 }
 #endif
Index: include/httpd.h
===================================================================
--- include/httpd.h	(revision 1203646)
+++ include/httpd.h	(working copy)
@@ -289,6 +289,11 @@
  * @param r The request
  */
 #define ap_http_scheme(r)       ap_run_http_scheme(r)
+/**
+ * Get the effective IP of a request, if different from the real IP.
+ * @param r The request
+ */
+#define ap_effective_ip(r)      ap_run_effective_ip(r)
 
 /** The default string length */
 #define MAX_STRING_LEN HUGE_STRING_LEN
Index: server/util_expr_eval.c
===================================================================
--- server/util_expr_eval.c	(revision 1203646)
+++ server/util_expr_eval.c	(working copy)
@@ -1158,6 +1158,7 @@
     "CONTEXT_PREFIX",           /* 25 */
     "CONTEXT_DOCUMENT_ROOT",    /* 26 */
     "REQUEST_STATUS",           /* 27 */
+    "EFFECTIVE_ADDR",           /* 28 */
     NULL
 };
 
@@ -1243,6 +1244,8 @@
         return ap_context_document_root(r);
     case 27:
         return r->status ? apr_psprintf(ctx->p, "%d", r->status) : "";
+    case 28:
+        return ap_effective_ip(r);
     default:
         ap_assert(0);
         return NULL;
Index: server/core.c
===================================================================
--- server/core.c	(revision 1203646)
+++ server/core.c	(working copy)
@@ -4723,6 +4723,11 @@
 
 }
 
+static const char *core_effective_ip(request_rec *r)
+{
+    return r->connection->remote_ip;
+}
+
 static void register_hooks(apr_pool_t *p)
 {
     errorlog_hash = apr_hash_make(p);
@@ -4757,6 +4762,7 @@
                       APR_HOOK_MIDDLE);
     ap_hook_pre_mpm(ap_create_scoreboard, NULL, NULL, APR_HOOK_MIDDLE);
     ap_hook_child_status(ap_core_child_status, NULL, NULL, APR_HOOK_MIDDLE);
+    ap_hook_effective_ip(core_effective_ip, NULL, NULL, APR_HOOK_REALLY_LAST);
 
     /* register the core's insert_filter hook and register core-provided
      * filters
Index: server/protocol.c
===================================================================
--- server/protocol.c	(revision 1203646)
+++ server/protocol.c	(working copy)
@@ -67,6 +67,7 @@
     APR_HOOK_LINK(http_scheme)
     APR_HOOK_LINK(default_port)
     APR_HOOK_LINK(note_auth_failure)
+    APR_HOOK_LINK(effective_ip)
 )
 
 AP_DECLARE_DATA ap_filter_rec_t *ap_old_write_func = NULL;
@@ -1803,3 +1804,5 @@
 AP_IMPLEMENT_HOOK_RUN_FIRST(int, note_auth_failure,
                             (request_rec *r, const char *auth_type),
                             (r, auth_type), DECLINED)
+AP_IMPLEMENT_HOOK_RUN_FIRST(const char *,effective_ip,
+                            (request_rec *r), (r), NULL)
Index: server/util_script.c
===================================================================
--- server/util_script.c	(revision 1203646)
+++ server/util_script.c	(working copy)
@@ -236,6 +236,7 @@
     add_unless_null(e, "REMOTE_HOST",
                     ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST, NULL));
     apr_table_addn(e, "REMOTE_ADDR", c->remote_ip);
+    apr_table_addn(e, "EFFECTIVE_ADDR", ap_effective_ip(r));
     apr_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r));    /* Apache */
     apr_table_setn(e, "REQUEST_SCHEME", ap_http_scheme(r));
     apr_table_addn(e, "CONTEXT_PREFIX", ap_context_prefix(r));
Index: server/log.c
===================================================================
--- server/log.c	(revision 1203646)
+++ server/log.c	(working copy)
@@ -51,6 +51,7 @@
 #include "http_core.h"
 #include "http_log.h"
 #include "http_main.h"
+#include "http_protocol.h"
 #include "util_time.h"
 #include "ap_mpm.h"
 
@@ -568,6 +569,17 @@
         return 0;
 }
 
+static int log_effective_address(const ap_errorlog_info *info, const char *arg,
+                                 char *buf, int buflen)
+{
+    if (info->r)
+        return apr_snprintf(buf, buflen, "%s:%d",
+                ap_effective_ip((request_rec *)info->r),
+                info->c->remote_addr->port);
+    else
+        return 0;
+}
+
 static int log_local_address(const ap_errorlog_info *info, const char *arg,
                              char *buf, int buflen)
 {
@@ -882,6 +894,7 @@
                             APR_HOOK_REALLY_LAST);
 
     ap_register_errorlog_handler(p, "a", log_remote_address, 0);
+    ap_register_errorlog_handler(p, "g", log_effective_address, 0);
     ap_register_errorlog_handler(p, "A", log_local_address, 0);
     ap_register_errorlog_handler(p, "e", log_env_var, 0);
     ap_register_errorlog_handler(p, "E", log_apr_status, 0);
Index: support/suexec.c
===================================================================
--- support/suexec.c	(revision 1203646)
+++ support/suexec.c	(working copy)
@@ -89,6 +89,7 @@
     "DOCUMENT_PATH_INFO=",
     "DOCUMENT_ROOT=",
     "DOCUMENT_URI=",
+    "EFFECTIVE_ADDR=",
     "GATEWAY_INTERFACE=",
     "HTTPS=",
     "LAST_MODIFIED=",
Index: modules/metadata/mod_setenvif.c
===================================================================
--- modules/metadata/mod_setenvif.c	(revision 1203646)
+++ modules/metadata/mod_setenvif.c	(working copy)
@@ -97,6 +97,7 @@
 enum special {
     SPECIAL_NOT,
     SPECIAL_REMOTE_ADDR,
+    SPECIAL_EFFECTIVE_ADDR,
     SPECIAL_REMOTE_HOST,
     SPECIAL_REQUEST_URI,
     SPECIAL_REQUEST_METHOD,
@@ -360,6 +361,9 @@
         if (!strcasecmp(fname, "remote_addr")) {
             new->special_type = SPECIAL_REMOTE_ADDR;
         }
+        else if (!strcasecmp(fname, "effective_addr")) {
+            new->special_type = SPECIAL_EFFECTIVE_ADDR;
+        }
         else if (!strcasecmp(fname, "remote_host")) {
             new->special_type = SPECIAL_REMOTE_HOST;
         }
@@ -529,6 +533,9 @@
                 case SPECIAL_REMOTE_ADDR:
                     val = r->connection->remote_ip;
                     break;
+                case SPECIAL_EFFECTIVE_ADDR:
+                    val = ap_effective_ip(r);
+                    break;
                 case SPECIAL_SERVER_ADDR:
                     val = r->connection->local_ip;
                     break;
Index: modules/aaa/mod_authz_host.c
===================================================================
--- modules/aaa/mod_authz_host.c	(revision 1203646)
+++ modules/aaa/mod_authz_host.c	(working copy)
@@ -214,6 +214,38 @@
      return AUTHZ_DENIED;
 }
 
+static authz_status effective_ip_check_authorization(request_rec *r,
+                                                     const char *require_line,
+                                                     const void *parsed_require_line)
+{
+    /* apr_ipsubnet_test should accept const but doesn't */
+    apr_ipsubnet_t **ip = (apr_ipsubnet_t **)parsed_require_line;
+    apr_sockaddr_t *remote_addr;
+    apr_status_t status;
+
+    const char *effective_ip = ap_effective_ip(r);
+
+    status = apr_sockaddr_info_get(&remote_addr, effective_ip, APR_UNSPEC, 0,
+            0, r->pool);
+    if (APR_SUCCESS != status) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
+                "access check of '%s' to %s failed, reason: unable to parse "
+                "'%s' as an ip address", require_line, r->uri, effective_ip);
+    }
+    else {
+
+        while (*ip) {
+            if (apr_ipsubnet_test(*ip, remote_addr))
+                return AUTHZ_GRANTED;
+            ip++;
+        }
+
+    }
+
+    /* authz_core will log the require line and the result at DEBUG */
+    return AUTHZ_DENIED;
+}
+
 static const authz_provider authz_ip_provider =
 {
     &ip_check_authorization,
@@ -232,7 +264,13 @@
     NULL,
 };
 
+static const authz_provider authz_effective_ip_provider =
+{
+    &effective_ip_check_authorization,
+    NULL,
+};
 
+
 static int authz_host_pre_config(apr_pool_t *p, apr_pool_t *plog,
                                  apr_pool_t *ptemp)
 {
@@ -273,6 +311,9 @@
     ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "local",
                               AUTHZ_PROVIDER_VERSION,
                               &authz_local_provider, AP_AUTH_INTERNAL_PER_CONF);
+    ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "effective-ip",
+                              AUTHZ_PROVIDER_VERSION,
+                              &authz_effective_ip_provider, AP_AUTH_INTERNAL_PER_CONF);
 }
 
 AP_DECLARE_MODULE(authz_host) =
Index: modules/ssl/ssl_engine_vars.c
===================================================================
--- modules/ssl/ssl_engine_vars.c	(revision 1203646)
+++ modules/ssl/ssl_engine_vars.c	(working copy)
@@ -156,6 +156,11 @@
      */
     if (r != NULL) {
         switch (var[0]) {
+        case 'E':
+        case 'e':
+            if (strcEQ(var, "EFFECTIVE_ADDR"))
+                result = ap_effective_ip(r);
+            break;
         case 'H':
         case 'h':
             if (strcEQ(var, "HTTP_USER_AGENT"))
Index: modules/loggers/mod_log_config.c
===================================================================
--- modules/loggers/mod_log_config.c	(revision 1203646)
+++ modules/loggers/mod_log_config.c	(working copy)
@@ -313,6 +313,11 @@
     return r->connection->remote_ip;
 }
 
+static const char *log_effective_address(request_rec *r, char *a)
+{
+    return ap_effective_ip(r);
+}
+
 static const char *log_local_address(request_rec *r, char *a)
 {
     return r->connection->local_ip;
@@ -1633,6 +1638,7 @@
     if (log_pfn_register) {
         log_pfn_register(p, "h", log_remote_host, 0);
         log_pfn_register(p, "a", log_remote_address, 0 );
+        log_pfn_register(p, "g", log_effective_address, 0 );
         log_pfn_register(p, "A", log_local_address, 0 );
         log_pfn_register(p, "l", log_remote_logname, 0);
         log_pfn_register(p, "u", log_remote_user, 0);
Index: modules/mappers/mod_rewrite.c
===================================================================
--- modules/mappers/mod_rewrite.c	(revision 1203646)
+++ modules/mappers/mod_rewrite.c	(working copy)
@@ -2084,6 +2084,9 @@
             else if (var[8] == 'M' && !strcmp(var, "REQUEST_METHOD")) {
                 result = r->method;
             }
+            else if (*var == 'E' && !strcmp(var, "EFFECTIVE_ADDR")) {
+                result = ap_effective_ip(r);
+            }
             else if (!strcmp(var, "REQUEST_SCHEME")) {
                 result = ap_http_scheme(r);
             }
Index: modules/filters/mod_ext_filter.c
===================================================================
--- modules/filters/mod_ext_filter.c	(revision 1203646)
+++ modules/filters/mod_ext_filter.c	(working copy)
@@ -406,7 +406,7 @@
     apr_file_printf(stderr_log,
                     "[%s] [client %s] mod_ext_filter (%d)%s: %s\n",
                     time_str,
-                    r->connection->remote_ip,
+                    ap_effective_ip(r),
                     err,
                     apr_strerror(err, errbuf, sizeof(errbuf)),
                     description);
Index: modules/arch/netware/mod_nw_ssl.c
===================================================================
--- modules/arch/netware/mod_nw_ssl.c	(revision 1203646)
+++ modules/arch/netware/mod_nw_ssl.c	(working copy)
@@ -963,6 +963,11 @@
      */
     if (r != NULL) {
         switch (var[0]) {
+        case 'E':
+        case 'e':
+            if (strcEQ(var, "EFFECTIVE_ADDR"))
+                result = ap_effective_ip(r);
+            break;
         case 'H':
         case 'h':
             if (strcEQ(var, "HTTP_USER_AGENT"))
