diff --git a/README.md b/README.md
index bab619a9f931b3e6cd5e9dd27b922cd9a8848c98..c0c5c9bfb055f3dafe517340a563eff8ff64cbb5 100644
--- a/README.md
+++ b/README.md
@@ -19,10 +19,20 @@ configured independently from its own subdirectory named after the
 table, with a `.d` extension. Individual files from each directory are
 loaded in lexicographical order using *run-parts(8)*.
 
+Once the new rules have been loaded, the firewall script will invoke
+all executable scripts from the */etc/firewall/reload-hooks* directory
+(again using *run-parts*). Use this to reload daemons that maintain
+their own firewall setup (docker, libvirtd, etc), or to perform
+additional non-iptables networking setup.
+
 # Configuration
 
-Configuration files are simple shell scripts. Rules are generated by
-invoking the following predefined helper functions:
+Configuration files are simple shell scripts. Their purpose is to
+generate output for *iptables-restore*, rather than invoking
+*iptables* directly, so that we can load the new rules atomically.
+
+Rules are generated by invoking the following predefined helper
+functions:
 
 #### `create_chain` *CHAIN_NAME*
 
@@ -56,3 +66,9 @@ iptables options (the default is simply `-j ALLOW`).
 
 Allow incoming traffic to the specified ports. *PORT_SPEC*
 should be a comma-separated list of destination ports.
+
+# Notes
+
+The firewall script will always attempt to setup IPv6 rules, even if
+IPv6 is disabled on the host. To disable IPv6 functionality, run the
+script with the *-4* command-line option.
diff --git a/firewall b/firewall
index 71c1880ca68b128957e7f3ef229da471e1fda3cc..f8b7afce833d7ff873d1cc81fdc675dfc7de77db 100755
--- a/firewall
+++ b/firewall
@@ -177,6 +177,11 @@ load_firewall() {
     else
         [ ${enable_ipv4} -eq 0 ] || iptables-restore <${v4rules}
         [ ${enable_ipv6} -eq 0 ] || ip6tables-restore <${v6rules}
+
+        # Invoke reload hooks.
+        if [ -d "${CONFIG_DIR}/reload-hooks" ]; then
+            run-parts ${CONFIG_DIR}/reload-hooks
+        fi
     fi
 }