125
125
chain = '%s-%s' % (binary_name, self.chain)
127
127
chain = self.chain
128
return '-A %s %s' % (chain, self.rule)
128
# new rules should have a zero [packet: byte] count
129
return '[0:0] -A %s %s' % (chain, self.rule)
131
132
class IptablesTable(object):
178
# non-wrapped chains and rules need to be dealt with specially,
179
# so we keep a list of them to be iterated over in apply()
181
self.remove_chains.add(name)
175
182
chain_set.remove(name)
184
self.remove_rules += filter(lambda r: r.chain == name, self.rules)
176
185
self.rules = filter(lambda r: r.chain != name, self.rules)
181
190
jump_snippet = '-j %s' % (name,)
193
self.remove_rules += filter(lambda r: jump_snippet in r.rule,
183
195
self.rules = filter(lambda r: jump_snippet not in r.rule, self.rules)
185
197
def add_rule(self, chain, rule, wrap=True, top=False):
218
230
self.rules.remove(IptablesRule(chain, rule, wrap, top))
232
self.remove_rules.append(IptablesRule(chain, rule, wrap, top))
219
233
except ValueError:
220
234
LOG.warn(_('Tried to remove rule that was not there:'
221
235
' %(chain)r %(rule)r %(wrap)r %(top)r'),
312
328
self.ipv4['nat'].add_chain('float-snat')
313
329
self.ipv4['nat'].add_rule('snat', '-j $float-snat')
331
def defer_apply_on(self):
332
self.iptables_apply_deferred = True
334
def defer_apply_off(self):
335
self.iptables_apply_deferred = False
339
if self.iptables_apply_deferred:
315
344
@utils.synchronized('iptables', external=True)
317
346
"""Apply the current in-memory set of iptables rules.
319
348
This will blow away any rules left over from previous runs of the
328
357
for cmd, tables in s:
329
358
for table in tables:
330
current_table, _err = self.execute('%s-save' % (cmd,),
359
current_table, _err = self.execute('%s-save' % (cmd,), '-c',
331
360
'-t', '%s' % (table,),
332
361
run_as_root=True,
334
363
current_lines = current_table.split('\n')
335
364
new_filter = self._modify_rules(current_lines,
337
self.execute('%s-restore' % (cmd,), run_as_root=True,
366
self.execute('%s-restore' % (cmd,), '-c', run_as_root=True,
338
367
process_input='\n'.join(new_filter),
340
369
LOG.debug(_("IPTablesManager.apply completed with success"))
342
371
def _modify_rules(self, current_lines, table, binary=None):
343
372
unwrapped_chains = table.unwrapped_chains
344
373
chains = table.chains
374
remove_chains = table.remove_chains
345
375
rules = table.rules
376
remove_rules = table.remove_rules
347
378
# Remove any trace of our rules
348
379
new_filter = filter(lambda line: binary_name not in line,
362
394
for rule in rules:
363
395
rule_str = str(rule)
365
397
# rule.top == True means we want this rule to be at the top.
366
398
# Further down, we weed out duplicates from the bottom of the
367
399
# list, so here we remove the dupes ahead of time.
368
new_filter = filter(lambda s: s.strip() != rule_str.strip(),
370
our_rules += [rule_str]
401
# We don't want to remove an entry if it has non-zero
402
# [packet:byte] counts and replace it with [0:0], so let's
403
# go look for a duplicate, and over-ride our table rule if
406
# ignore [packet:byte] counts at beginning of line
407
if rule_str.startswith('['):
408
rule_str = rule_str.split(']', 1)[1]
409
dup_filter = filter(lambda s: rule_str.strip() in s.strip(),
412
new_filter = filter(lambda s:
413
rule_str.strip() not in s.strip(),
415
# if no duplicates, use original rule
417
# grab the last entry, if there is one
424
our_rules += [rule_str]
426
bot_rules += [rule_str]
428
our_rules += bot_rules
372
430
new_filter[rules_index:rules_index] = our_rules
387
448
seen_lines.add(line)
451
def _weed_out_removes(line):
452
# We need to find exact matches here
453
if line.startswith(':'):
454
# it's a chain, for example, ":nova-billing - [0:0]"
455
# strip off everything except the chain name
456
line = line.split(':')[1]
457
line = line.split('- [')[0]
459
for chain in remove_chains:
461
remove_chains.remove(chain)
463
elif line.startswith('['):
465
# ignore [packet:byte] counts at beginning of lines
466
line = line.split(']', 1)[1]
468
for rule in remove_rules:
469
# ignore [packet:byte] counts at beginning of rules
471
rule_str = rule_str.split(' ', 1)[1]
472
rule_str = rule_str.strip()
474
remove_rules.remove(rule)
390
480
# We filter duplicates, letting the *last* occurrence take
481
# precendence. We also filter out anything in the "remove"
392
483
new_filter.reverse()
393
484
new_filter = filter(_weed_out_duplicates, new_filter)
485
new_filter = filter(_weed_out_removes, new_filter)
394
486
new_filter.reverse()
488
# flush lists, just in case we didn't find something
489
remove_chains.clear()
490
for rule in remove_rules:
491
remove_rules.remove(rule)
395
493
return new_filter
632
instance_set = set([datum['instance_id'] for datum in data])
729
instance_set = set([datum['instance_uuid'] for datum in data])
633
730
default_gw_vif = {}
634
for instance_id in instance_set:
635
vifs = db.virtual_interface_get_by_instance(context, instance_id)
731
for instance_uuid in instance_set:
732
vifs = db.virtual_interface_get_by_instance(context,
637
735
#offer a default gateway to the first virtual interface
638
default_gw_vif[instance_id] = vifs[0]['id']
736
default_gw_vif[instance_uuid] = vifs[0]['id']
640
738
for datum in data:
641
if instance_id in default_gw_vif:
739
if instance_uuid in default_gw_vif:
642
740
# we don't want default gateway for this fixed ip
643
if default_gw_vif[instance_id] != datum['vif_id']:
741
if default_gw_vif[instance_uuid] != datum['vif_id']:
644
742
hosts.append(_host_dhcp_opts(datum))
645
743
return '\n'.join(hosts)
724
822
'--pid-file=%s' % _dhcp_file(dev, 'pid'),
725
823
'--listen-address=%s' % network_ref['dhcp_server'],
726
824
'--except-interface=lo',
727
'--dhcp-range=%s,static,%ss' % (network_ref['dhcp_start'],
728
FLAGS.dhcp_lease_time),
825
'--dhcp-range=set:\'%s\',%s,static,%ss' %
826
(network_ref['label'],
827
network_ref['dhcp_start'],
828
FLAGS.dhcp_lease_time),
729
829
'--dhcp-lease-max=%s' % len(netaddr.IPNetwork(network_ref['cidr'])),
730
830
'--dhcp-hostsfile=%s' % _dhcp_file(dev, 'conf'),
731
831
'--dhcp-script=%s' % FLAGS.dhcpbridge,
987
1087
LOG.debug(_('Starting VLAN inteface %s'), interface)
988
1088
_execute('ip', 'link', 'add', 'link', bridge_interface,
989
1089
'name', interface, 'type', 'vlan',
990
'id', vlan_num, run_as_root=True)
1090
'id', vlan_num, run_as_root=True,
1091
check_exit_code=[0, 2, 254])
991
1092
# (danwent) the bridge will inherit this address, so we want to
992
1093
# make sure it is the value set from the NetworkManager
994
1095
_execute('ip', 'link', 'set', interface, 'address',
995
mac_address, run_as_root=True)
996
_execute('ip', 'link', 'set', interface, 'up', run_as_root=True)
1096
mac_address, run_as_root=True,
1097
check_exit_code=[0, 2, 254])
1098
_execute('ip', 'link', 'set', interface, 'up', run_as_root=True,
1099
check_exit_code=[0, 2, 254])
997
1100
if FLAGS.network_device_mtu:
998
1101
_execute('ip', 'link', 'set', interface, 'mtu',
999
FLAGS.network_device_mtu, run_as_root=True)
1102
FLAGS.network_device_mtu, run_as_root=True,
1103
check_exit_code=[0, 2, 254])
1000
1104
return interface
1165
1269
utils.execute('brctl', 'setfd', bridge, str(0), run_as_root=True)
1166
1270
utils.execute('brctl', 'stp', bridge, 'off', run_as_root=True)
1167
1271
utils.execute('ip', 'link', 'set', bridge, 'address', mac_address,
1169
utils.execute('ip', 'link', 'set', bridge, 'up', run_as_root=True)
1272
run_as_root=True, check_exit_code=[0, 2, 254])
1273
utils.execute('ip', 'link', 'set', bridge, 'up', run_as_root=True,
1274
check_exit_code=[0, 2, 254])
1170
1275
LOG.debug(_("Done starting bridge %s"), bridge)
1172
1277
full_ip = '%s/%s' % (network['dhcp_server'],
1173
1278
network['cidr'].rpartition('/')[2])
1174
1279
utils.execute('ip', 'address', 'add', full_ip, 'dev', bridge,
1280
run_as_root=True, check_exit_code=[0, 2, 254])
1186
utils.execute('ip', 'link', 'delete', dev, run_as_root=True)
1291
utils.execute('ip', 'link', 'delete', dev, run_as_root=True,
1292
check_exit_code=[0, 2, 254])
1187
1293
except exception.ProcessExecutionError:
1188
1294
LOG.error(_("Failed unplugging gateway interface '%s'"), dev)
1197
1303
# First, try with 'ip'
1198
1304
utils.execute('ip', 'tuntap', 'add', dev, 'mode', 'tap',
1305
run_as_root=True, check_exit_code=[0, 2, 254])
1200
1306
except exception.ProcessExecutionError:
1201
1307
# Second option: tunctl
1202
1308
utils.execute('tunctl', '-b', '-t', dev, run_as_root=True)
1203
1309
if mac_address:
1204
1310
utils.execute('ip', 'link', 'set', dev, 'address', mac_address,
1206
utils.execute('ip', 'link', 'set', dev, 'up', run_as_root=True)
1311
run_as_root=True, check_exit_code=[0, 2, 254])
1312
utils.execute('ip', 'link', 'set', dev, 'up', run_as_root=True,
1313
check_exit_code=[0, 2, 254])
1208
1315
def get_dev(self, network):
1209
1316
dev = self.GATEWAY_INTERFACE_PREFIX + str(network['uuid'][0:11])