2
# vim: tabstop=4 shiftwidth=4 softtabstop=4
4
# Copyright 2010 OpenStack LLC.
7
# Licensed under the Apache License, Version 2.0 (the "License"); you may
8
# not use this file except in compliance with the License. You may obtain
9
# a copy of the License at
11
# http://www.apache.org/licenses/LICENSE-2.0
13
# Unless required by applicable law or agreed to in writing, software
14
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16
# License for the specific language governing permissions and limitations
20
This script is used to configure iptables, ebtables, and arptables rules on
28
# This is written to Python 2.4, since that is what is available on XenServer
29
import simplejson as json
32
def main(dom_id, command, only_this_vif=None):
33
xsls = execute("/usr/bin/xenstore-ls /local/domain/%s/vm-data/networking" \
35
macs = [line.split("=")[0].strip() for line in xsls.splitlines()]
38
xsr = "/usr/bin/xenstore-read /local/domain/%s/vm-data/networking/%s"
39
xsread = execute(xsr % (dom_id, mac), True)
40
data = json.loads(xsread)
41
for ip in data['ips']:
42
if data["label"] == "public":
43
vif = "vif%s.0" % dom_id
45
vif = "vif%s.1" % dom_id
47
if (only_this_vif is None) or (vif == only_this_vif):
48
params = dict(IP=ip['ip'], VIF=vif, MAC=data['mac'])
49
apply_ebtables_rules(command, params)
50
apply_arptables_rules(command, params)
51
apply_iptables_rules(command, params)
54
def execute(command, return_stdout=False):
55
devnull = open(os.devnull, 'w')
56
proc = subprocess.Popen(command, shell=True, close_fds=True,
57
stdout=subprocess.PIPE, stderr=devnull)
60
return proc.stdout.read()
64
# A note about adding rules:
65
# Whenever we add any rule to iptables, arptables or ebtables we first
66
# delete the same rule to ensure the rule only exists once.
69
def apply_iptables_rules(command, params):
70
iptables = lambda rule: execute("/sbin/iptables %s" % rule)
72
iptables("-D FORWARD -m physdev --physdev-in %(VIF)s -s %(IP)s \
74
if command == 'online':
75
iptables("-A FORWARD -m physdev --physdev-in %(VIF)s -s %(IP)s \
79
def apply_arptables_rules(command, params):
80
arptables = lambda rule: execute("/sbin/arptables %s" % rule)
82
arptables("-D FORWARD --opcode Request --in-interface %(VIF)s \
83
--source-ip %(IP)s --source-mac %(MAC)s -j ACCEPT" % params)
84
arptables("-D FORWARD --opcode Reply --in-interface %(VIF)s \
85
--source-ip %(IP)s --source-mac %(MAC)s -j ACCEPT" % params)
86
if command == 'online':
87
arptables("-A FORWARD --opcode Request --in-interface %(VIF)s \
88
--source-ip %(IP)s --source-mac %(MAC)s -j ACCEPT" % params)
89
arptables("-A FORWARD --opcode Reply --in-interface %(VIF)s \
90
--source-ip %(IP)s --source-mac %(MAC)s -j ACCEPT" % params)
93
def apply_ebtables_rules(command, params):
94
ebtables = lambda rule: execute("/sbin/ebtables %s" % rule)
96
ebtables("-D FORWARD -p 0806 -o %(VIF)s --arp-ip-dst %(IP)s -j ACCEPT" %
98
ebtables("-D FORWARD -p 0800 -o %(VIF)s --ip-dst %(IP)s -j ACCEPT" %
100
if command == 'online':
101
ebtables("-A FORWARD -p 0806 -o %(VIF)s --arp-ip-dst %(IP)s \
103
ebtables("-A FORWARD -p 0800 -o %(VIF)s --ip-dst %(IP)s \
106
ebtables("-D FORWARD -s ! %(MAC)s -i %(VIF)s -j DROP" % params)
107
if command == 'online':
108
ebtables("-I FORWARD 1 -s ! %(MAC)s -i %(VIF)s -j DROP" % params)
111
if __name__ == "__main__":
112
if len(sys.argv) < 3:
113
print "usage: %s dom_id online|offline [vif]" % \
114
os.path.basename(sys.argv[0])
117
dom_id, command = sys.argv[1:3]
118
vif = len(sys.argv) == 4 and sys.argv[3] or None
119
main(dom_id, command, vif)