[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 4/5] hotplug/linux: Add IPv6 support to the iptables logic



This adds the same functions for ip6tables as the one for iptables.
The 'ip' variable can now contain ipv6s for the domain and add
appropriate rules

 - If the 'ip' var is empty then both full IPv4 and IPv6 are allowed.
 - If only IPv4 ips are present, then IPv6 will be completely disallowed.
 - If only IPv6 ips are present, then IPv4 will be completely disallowed.
 - You can use ::0/0 or 0.0.0.0/0 to allow v6 or v4 globally but filter
   the other one.

This gracefully handles if the dom0 doesn't have IPv6. If
the call to ip6tables doesn't succeed, it just ignores any
IPv6 stuff.

By default, domains aren't allows to send Router Advertisement
or DHCP responses, see the ipv6_allow_ra to enable them.

Signed-off-by: Sylvain Munaut <s.munaut@xxxxxxxxxxxxxxxxxxxx>
---
 tools/hotplug/Linux/vif-common.sh |   86 +++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/tools/hotplug/Linux/vif-common.sh 
b/tools/hotplug/Linux/vif-common.sh
index e477c81..2f24274 100644
--- a/tools/hotplug/Linux/vif-common.sh
+++ b/tools/hotplug/Linux/vif-common.sh
@@ -121,6 +121,8 @@ fi
 ip=${ip:-}
 ip=$(xenstore_read_default "$XENBUS_PATH/ip" "$ip")
 
+ipv6_allow_ra=$(xenstore_read_default "$XENBUS_PATH/ipv6_allow_ra" "false")
+
 frob_iptable()
 {
   # Add or remove
@@ -161,6 +163,74 @@ frob_iptable()
     fi
   done
 }
+
+frob_ip6table()
+{
+  # Add or remove
+  if [ "$command" == "online" -o "$command" == "add" ]
+  then
+    local c="-I"
+  else
+    local c="-D"
+  fi
+
+  # Always Allow all packets _to_ the domain
+  ip6tables "$c" FORWARD -m physdev --physdev-is-bridged --physdev-out "$dev" \
+    -j ACCEPT 2>/dev/null &&
+
+  # Always allow ICMP messages from link-local addresses (for ND)
+  ip6tables "$c" FORWARD -m physdev --physdev-is-bridged --physdev-in "$dev" \
+    -s fe80::/64 -j ACCEPT 2>/dev/null &&
+
+  # Always allow the domain to talk to a DHCP server
+  ip6tables "$c" FORWARD -m physdev --physdev-is-bridged --physdev-in "$dev" \
+    -p udp --sport 546 --dport 547 -j ACCEPT 2>/dev/null
+
+  if [ \( "$command" == "online" -o "$command" == "add" \) -a $? -ne 0 ]
+  then
+    log err "ip6tables setup failed. This may affect guest networking."
+  fi
+
+  # Add rules for each address
+  local addr
+
+  for addr in $@; do
+    if [ "$addr" = "any" ]; then
+      addr="::0/0"
+    fi
+
+    ip6tables "$c" FORWARD -m physdev --physdev-is-bridged --physdev-in "$dev" 
\
+      -s "$addr" -j ACCEPT 2>/dev/null
+
+    if [ \( "$command" == "online" -o "$command" == "add" \) -a $? -ne 0 ]
+    then
+      log err "ip6tables setup failed. This may affect guest networking."
+    fi
+  done
+
+  # Filter out RA and DHCP server responses if not explicitely allowed
+  if [ "$ipv6_allow_ra" != "true" ]
+  then
+    ip6tables "$c" FORWARD -m physdev --physdev-is-bridged --physdev-in "$dev" 
\
+      -p icmpv6 --icmpv6-type router-advertisement -j DROP 2>/dev/null &&
+
+    ip6tables "$c" FORWARD -m physdev --physdev-is-bridged --physdev-in "$dev" 
\
+      -p udp --sport 547 --dport 546 -j DROP 2>/dev/null
+
+    if [ \( "$command" == "online" -o "$command" == "add" \) -a $? -ne 0 ]
+    then
+      log err "ip6tables setup failed. This may affect guest networking."
+    fi
+  fi
+}
+
+
+##
+# Check if the given IP is IPv6 or not
+#
+is_ipv6()
+{
+        echo "$1" | perl -wane '/:/ && print "yes"'
 }
 
 
@@ -182,25 +252,41 @@ handle_iptable()
     return
   fi
 
+  # User has a working IPv4 iptables, but maybe no IPv6 support ...
+  local do_ipv6="yes"
+
+  if ! ip6tables -L -n >&/dev/null
+  then
+    do_ipv6="no"
+  fi
+
   # Scan through the addresses
   local ipv4_addrs
+  local ipv6_addrs
 
   if [ "$ip" != "" ]
   then
     local addr
     for addr in $ip
     do
+      result=$(is_ipv6 "$addr")
+      if [ -z "$result" ] ; then
         ipv4_addrs="$addr $ipv4_addrs"
+      else
+        ipv6_addrs="$addr $ipv6_addrs"
+      fi
     done
   else
     # No IP addresses have been specified, so allow anything.
     ipv4_addrs="any"
+    ipv6_addrs="any"
   fi
 
   # Actually add the rules
   claim_lock "iptables"
 
   [ "$ipv4_addrs" != "" ] && frob_iptable "$ipv4_addrs"
+  [ "$ipv6_addrs" != "" -a "$do_ipv6" = "yes" ] && frob_ip6table "$ipv6_addrs"
 
   release_lock "iptables"
 }
-- 
1.7.10.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.