summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorCory Wright <cory.wright@rackspace.com>2011-03-18 20:35:44 -0400
committerCory Wright <cory.wright@rackspace.com>2011-03-18 20:35:44 -0400
commitf835c01f41fdba5791190b9275775ae7fcfcafc6 (patch)
treedd5f44d8b83e5287b304685b81014dcf2b3039b6 /plugins
parentabe147f756f13d4f968aa075d709e5c6643d310a (diff)
* committing ovs scripts
Diffstat (limited to 'plugins')
-rwxr-xr-xplugins/xenserver/networking/etc/xensource/scripts/ovs_configure_base_flows.py68
-rwxr-xr-xplugins/xenserver/networking/etc/xensource/scripts/ovs_configure_vif_flows.py194
-rwxr-xr-xplugins/xenserver/networking/etc/xensource/scripts/vif_rules.py9
3 files changed, 267 insertions, 4 deletions
diff --git a/plugins/xenserver/networking/etc/xensource/scripts/ovs_configure_base_flows.py b/plugins/xenserver/networking/etc/xensource/scripts/ovs_configure_base_flows.py
new file mode 100755
index 000000000..c46fb4b60
--- /dev/null
+++ b/plugins/xenserver/networking/etc/xensource/scripts/ovs_configure_base_flows.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010-2011 OpenStack LLC.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""
+This script is used to configure base openvswitch flows for XenServer hosts.
+"""
+
+import os
+import subprocess
+import sys
+
+
+PNIC_NAME="eth1"
+XEN_BRIDGE="xenbr1"
+
+def main(dom_id, command, only_this_vif=None):
+ pnic_ofport = execute('/usr/bin/ovs-ofctl', 'get', 'Interface', PNIC_NAME,
+ 'ofport', return_stdout=True)
+ ovs_ofctl = lambda *rule: execute('/usr/bin/ovs-ofctl', *rule)
+
+ # clear all flows
+ ovs_ofctl('del-flows', XEN_BRIDGE)
+
+ # these flows are lower priority than all VM-specific flows.
+
+ # allow all traffic from the physical NIC, as it is trusted (i.e., from a
+ # filtered vif, or from the physical infrastructure
+ ovs_ofctl('add-flow', XEN_BRIDGE,
+ "priority=2,in_port=%s,action=normal" % pnic_ofport)
+
+ # default drop
+ ovs_ofctl('add-flow', XEN_BRIDGE, 'priority=1,action=drop')
+
+
+def execute(*command, return_stdout=False):
+ devnull = open(os.devnull, 'w')
+ command = map(str, command)
+ proc = subprocess.Popen(command, close_fds=True,
+ stdout=subprocess.PIPE, stderr=devnull)
+ devnull.close()
+ if return_stdout:
+ return proc.stdout.read()
+ else:
+ return None
+
+
+if __name__ == "__main__":
+ if sys.argv:
+ print "This script configures base ovs flows."
+ print "usage: %s" % os.path.basename(sys.argv[0])
+ sys.exit(1)
+ else:
+ main()
diff --git a/plugins/xenserver/networking/etc/xensource/scripts/ovs_configure_vif_flows.py b/plugins/xenserver/networking/etc/xensource/scripts/ovs_configure_vif_flows.py
new file mode 100755
index 000000000..a77bbbf4b
--- /dev/null
+++ b/plugins/xenserver/networking/etc/xensource/scripts/ovs_configure_vif_flows.py
@@ -0,0 +1,194 @@
+#!/usr/bin/env python
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010-2011 OpenStack LLC.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""
+This script is used to configure openvswitch flows on XenServer hosts.
+"""
+
+import os
+import subprocess
+import sys
+
+# This is written to Python 2.4, since that is what is available on XenServer
+import simplejson as json
+
+
+XEN_BRIDGE = 'xenbr1'
+OVS_OFCTL = '/usr/bin/ovs-ofctl'
+
+
+def execute(*command, return_stdout=False):
+ devnull = open(os.devnull, 'w')
+ command = map(str, command)
+ proc = subprocess.Popen(command, close_fds=True,
+ stdout=subprocess.PIPE, stderr=devnull)
+ devnull.close()
+ if return_stdout:
+ return proc.stdout.read()
+ else:
+ return None
+
+
+class OvsFlow():
+ def __init__(self, command, params, bridge=None):
+ self.command = command
+ self.params = params
+ self.bridge = bridge or XEN_BRIDGE
+
+ def add(self, rule):
+ execute(OVS_OFCTL, 'add-flow', self.bridge, rule)
+
+ def delete(self, rule):
+ execute(OVS_OFCTL, 'del-flow', self.bridge, rule)
+
+ def apply(self, rule):
+ self.delete(rule % self.params)
+ if self.command == 'online':
+ self.add(rule % params)
+
+
+def main(dom_id, command, net, only_this_vif=None):
+ vif_ofport = execute('/usr/bin/ovs-ofctl', 'get', 'Interface',
+ only_this_vif, 'ofport', return_stdout=True)
+
+ xsls = execute('/usr/bin/xenstore-ls',
+ '/local/domain/%s/vm-data/networking' % dom_id,
+ return_stdout=True)
+ macs = [line.split("=")[0].strip() for line in xsls.splitlines()]
+
+ for mac in macs:
+ xsread = execute('/usr/bin/enstore-read',
+ '/local/domain/%s/vm-data/networking/%s' %
+ (dom_id, mac), True)
+ data = json.loads(xsread)
+ if data["label"] == "public":
+ vif = "vif%s.0" % dom_id
+ else:
+ vif = "vif%s.1" % dom_id
+
+ if (only_this_vif is None) or (vif == only_this_vif):
+ params = dict(VIF=vif, MAC=data['mac'])
+ if net in ('ipv4', 'all'):
+ for ip4 in data['ips']:
+ params.update({'IP': ip4['ip']})
+ apply_ovs_ipv4_flows(command, params)
+ if net in ('ipv6', 'all'):
+ for ip6 in data['ip6s']:
+ params.update({'IP': ip6['ip']})
+ apply_ovs_ipv6_flows(command, params)
+
+
+# usage: <vif device> <vif mac> <vif v4 IP> <vif v6 global IP> <vif v6 linklocal IP>
+# XEN_BRIDGE=xenbr1
+# VIF_NAME=$1
+# VIF_MAC=$2
+# VIF_IPv4=$3
+# VIF_GLOBAL_IPv6=$4
+# VIF_LOCAL_IPv6=$5
+
+# # find the openflow port number associated with the vif interface
+# VIF_OFPORT=`ovs-vsctl get Interface $VIF_NAME ofport`
+
+def apply_ovs_ipv4_flows(command, params):
+ flow = OvsFlow(command, params)
+
+ # allow valid ARP outbound (both request / reply)
+ flow.apply("priority=3,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,arp,"
+ "arp_sha=$VIF_MAC,nw_src=$VIF_IPv4,action=normal")
+
+ flow.apply("priority=3,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,arp,"
+ "arp_sha=$VIF_MAC,nw_src=0.0.0.0,action=normal")
+
+ # allow valid IPv4 outbound
+ flow.apply("priority=3,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,ip,"
+ "nw_src=$VIF_IPv4,action=normal")
+
+
+def apply_ovs_ipv6_flows(command, params):
+ flow = OvsFlow(command, params)
+
+ # allow valid IPv6 ND outbound (are both global and local IPs needed?)
+ # Neighbor Solicitation
+ flow.apply("priority=6,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,icmp6,"
+ "ipv6_src=$VIF_LOCAL_IPv6,icmp_type=135,nd_sll=$VIF_MAC,"
+ "action=normal")
+ flow.apply("priority=6,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,icmp6,"
+ "ipv6_src=$VIF_LOCAL_IPv6,icmp_type=135,action=normal")
+ flow.apply("priority=6,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,icmp6,"
+ "ipv6_src=$VIF_GLOBAL_IPv6,icmp_type=135,nd_sll=$VIF_MAC,"
+ "action=normal")
+ flow.apply("priority=6,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,icmp6,"
+ "ipv6_src=$VIF_GLOBAL_IPv6,icmp_type=135,action=normal")
+
+ # Neighbor Advertisement
+ flow.apply("priority=6,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,icmp6,"
+ "ipv6_src=$VIF_LOCAL_IPv6,icmp_type=136,"
+ "nd_target=$VIF_LOCAL_IPv6,action=normal")
+ flow.apply("priority=6,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,icmp6,"
+ "ipv6_src=$VIF_LOCAL_IPv6,icmp_type=136,action=normal")
+ flow.apply("priority=6,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,icmp6,"
+ "ipv6_src=$VIF_GLOBAL_IPv6,icmp_type=136,"
+ "nd_target=$VIF_GLOBAL_IPv6,action=normal")
+ flow.apply("priority=6,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,icmp6,"
+ "ipv6_src=$VIF_GLOBAL_IPv6,icmp_type=136,action=normal")
+
+ # drop all other neighbor discovery (required because we permit all icmp6 below)
+ flow.apply("priority=5,in_port=$VIF_OFPORT,icmp6,icmp_type=135,action=drop")
+ flow.apply("priority=5,in_port=$VIF_OFPORT,icmp6,icmp_type=136,action=drop")
+
+ # do not allow sending specifc ICMPv6 types
+ # Router Advertisement
+ flow.apply("priority=5,in_port=$VIF_OFPORT,icmp6,icmp_type=134,action=drop")
+ # Redirect Gateway
+ flow.apply("priority=5,in_port=$VIF_OFPORT,icmp6,icmp_type=137,action=drop")
+ # Mobile Prefix Solicitation
+ flow.apply("priority=5,in_port=$VIF_OFPORT,icmp6,icmp_type=146,action=drop")
+ # Mobile Prefix Advertisement
+ flow.apply("priority=5,in_port=$VIF_OFPORT,icmp6,icmp_type=147,action=drop")
+ # Multicast Router Advertisement
+ flow.apply("priority=5,in_port=$VIF_OFPORT,icmp6,icmp_type=151,action=drop")
+ # Multicast Router Solicitation
+ flow.apply("priority=5,in_port=$VIF_OFPORT,icmp6,icmp_type=152,action=drop")
+ # Multicast Router Termination
+ flow.apply("priority=5,in_port=$VIF_OFPORT,icmp6,icmp_type=153,action=drop")
+
+ # allow valid IPv6 outbound, by type
+ flow.apply("priority=4,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,"
+ "ipv6_src=$VIF_GLOBAL_IPv6,icmp6,action=normal")
+ flow.apply("priority=4,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,"
+ "ipv6_src=$VIF_LOCAL_IPv6,icmp6,action=normal")
+ flow.apply("priority=4,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,"
+ "ipv6_src=$VIF_GLOBAL_IPv6,tcp6,action=normal")
+ flow.apply("priority=4,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,"
+ "ipv6_src=$VIF_LOCAL_IPv6,tcp6,action=normal")
+ flow.apply("priority=4,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,"
+ "ipv6_src=$VIF_GLOBAL_IPv6,udp6,action=normal")
+ flow.apply("priority=4,in_port=$VIF_OFPORT,dl_src=$VIF_MAC,"
+ "ipv6_src=$VIF_LOCAL_IPv6,udp6,action=normal")
+ # all else will be dropped ...
+
+
+if __name__ == "__main__":
+ if len(sys.argv) < 3:
+ print "usage: %s dom_id online|offline ipv4|ipv6|all [vif]" % \
+ os.path.basename(sys.argv[0])
+ sys.exit(1)
+ else:
+ dom_id, command, net = sys.argv[1:4]
+ vif = len(sys.argv) == 5 and sys.argv[4] or None
+ main(dom_id, command, net, vif)
diff --git a/plugins/xenserver/networking/etc/xensource/scripts/vif_rules.py b/plugins/xenserver/networking/etc/xensource/scripts/vif_rules.py
index 48122e6d6..500e055d8 100755
--- a/plugins/xenserver/networking/etc/xensource/scripts/vif_rules.py
+++ b/plugins/xenserver/networking/etc/xensource/scripts/vif_rules.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2010 OpenStack LLC.
+# Copyright 2010-2011 OpenStack LLC.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -31,7 +31,8 @@ import simplejson as json
def main(dom_id, command, only_this_vif=None):
xsls = execute('/usr/bin/xenstore-ls',
- '/local/domain/%s/vm-data/networking' % dom_id, True)
+ '/local/domain/%s/vm-data/networking' % dom_id,
+ return_stdout=True)
macs = [line.split("=")[0].strip() for line in xsls.splitlines()]
for mac in macs:
@@ -113,8 +114,8 @@ def apply_ebtables_rules(command, params):
ebtables('-D', 'FORWARD', '-p', '0806', '-o', params['VIF'],
'--arp-ip-dst', params['IP'],
'-j', 'ACCEPT')
- ebtables('-D', 'FORWARD', '-p', '0800', '-o',
- params['VIF'], '--ip-dst', params['IP'],
+ ebtables('-D', 'FORWARD', '-p', '0800', '-o', params['VIF'],
+ '--ip-dst', params['IP'],
'-j', 'ACCEPT')
if command == 'online':
ebtables('-A', 'FORWARD', '-p', '0806',