~openstack-gd/nova/multi-nic-exp-ip-tables-rel

« back to all changes in this revision

Viewing changes to nova/network/linux_net.py

  • Committer: Ilya Alekseyev
  • Date: 2011-03-10 14:09:26 UTC
  • mfrom: (700.2.81 nova)
  • Revision ID: ialekseev@griddynamics.com-20110310140926-jmy95tmyzm4s7chk
Merge with trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
65
65
 
66
66
def metadata_forward():
67
67
    """Create forwarding rule for metadata"""
68
 
    _confirm_rule("PREROUTING", "-t nat -s 0.0.0.0/0 "
69
 
             "-d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j DNAT "
70
 
             "--to-destination %s:%s" % (FLAGS.ec2_dmz_host, FLAGS.ec2_port))
 
68
    _confirm_rule("PREROUTING", '-t', 'nat', '-s', '0.0.0.0/0',
 
69
             '-d', '169.254.169.254/32', '-p', 'tcp', '-m', 'tcp',
 
70
             '--dport', '80', '-j', 'DNAT',
 
71
             '--to-destination',
 
72
             '%s:%s' % (FLAGS.ec2_dmz_host, FLAGS.ec2_port))
71
73
 
72
74
 
73
75
def init_host():
74
76
    """Basic networking setup goes here"""
75
77
 
76
78
    if FLAGS.use_nova_chains:
77
 
        _execute("sudo iptables -N nova_input", check_exit_code=False)
78
 
        _execute("sudo iptables -D %s -j nova_input" % FLAGS.input_chain,
79
 
                 check_exit_code=False)
80
 
        _execute("sudo iptables -A %s -j nova_input" % FLAGS.input_chain)
81
 
 
82
 
        _execute("sudo iptables -N nova_forward", check_exit_code=False)
83
 
        _execute("sudo iptables -D FORWARD -j nova_forward",
84
 
                 check_exit_code=False)
85
 
        _execute("sudo iptables -A FORWARD -j nova_forward")
86
 
 
87
 
        _execute("sudo iptables -N nova_output", check_exit_code=False)
88
 
        _execute("sudo iptables -D OUTPUT -j nova_output",
89
 
                 check_exit_code=False)
90
 
        _execute("sudo iptables -A OUTPUT -j nova_output")
91
 
 
92
 
        _execute("sudo iptables -t nat -N nova_prerouting",
93
 
                 check_exit_code=False)
94
 
        _execute("sudo iptables -t nat -D PREROUTING -j nova_prerouting",
95
 
                 check_exit_code=False)
96
 
        _execute("sudo iptables -t nat -A PREROUTING -j nova_prerouting")
97
 
 
98
 
        _execute("sudo iptables -t nat -N nova_postrouting",
99
 
                 check_exit_code=False)
100
 
        _execute("sudo iptables -t nat -D POSTROUTING -j nova_postrouting",
101
 
                 check_exit_code=False)
102
 
        _execute("sudo iptables -t nat -A POSTROUTING -j nova_postrouting")
103
 
 
104
 
        _execute("sudo iptables -t nat -N nova_snatting",
105
 
                 check_exit_code=False)
106
 
        _execute("sudo iptables -t nat -D POSTROUTING -j nova_snatting",
107
 
                 check_exit_code=False)
108
 
        _execute("sudo iptables -t nat -A POSTROUTING -j nova_snatting")
109
 
 
110
 
        _execute("sudo iptables -t nat -N nova_output", check_exit_code=False)
111
 
        _execute("sudo iptables -t nat -D OUTPUT -j nova_output",
112
 
                 check_exit_code=False)
113
 
        _execute("sudo iptables -t nat -A OUTPUT -j nova_output")
 
79
        _execute('sudo', 'iptables', '-N', 'nova_input', check_exit_code=False)
 
80
        _execute('sudo', 'iptables', '-D', FLAGS.input_chain,
 
81
                 '-j', 'nova_input',
 
82
                 check_exit_code=False)
 
83
        _execute('sudo', 'iptables', '-A', FLAGS.input_chain,
 
84
                 '-j', 'nova_input')
 
85
        _execute('sudo', 'iptables', '-N', 'nova_forward',
 
86
                 check_exit_code=False)
 
87
        _execute('sudo', 'iptables', '-D', 'FORWARD', '-j', 'nova_forward',
 
88
                 check_exit_code=False)
 
89
        _execute('sudo', 'iptables', '-A', 'FORWARD', '-j', 'nova_forward')
 
90
        _execute('sudo', 'iptables', '-N', 'nova_output',
 
91
                 check_exit_code=False)
 
92
        _execute('sudo', 'iptables', '-D', 'OUTPUT', '-j', 'nova_output',
 
93
                 check_exit_code=False)
 
94
        _execute('sudo', 'iptables', '-A', 'OUTPUT', '-j', 'nova_output')
 
95
        _execute('sudo', 'iptables', '-t', 'nat', '-N', 'nova_prerouting',
 
96
                 check_exit_code=False)
 
97
        _execute('sudo', 'iptables', '-t', 'nat', '-D', 'PREROUTING',
 
98
                 '-j', 'nova_prerouting', check_exit_code=False)
 
99
        _execute('sudo', 'iptables', '-t', 'nat', '-A', 'PREROUTING',
 
100
                 '-j', 'nova_prerouting')
 
101
        _execute('sudo', 'iptables', '-t', 'nat', '-N', 'nova_postrouting',
 
102
                 check_exit_code=False)
 
103
        _execute('sudo', 'iptables', '-t', 'nat', '-D', 'POSTROUTING',
 
104
                 '-j', 'nova_postrouting', check_exit_code=False)
 
105
        _execute('sudo', 'iptables', '-t', 'nat', '-A', 'POSTROUTING',
 
106
                 '-j', 'nova_postrouting')
 
107
        _execute('sudo', 'iptables', '-t', 'nat', '-N', 'nova_snatting',
 
108
                 check_exit_code=False)
 
109
        _execute('sudo', 'iptables', '-t', 'nat', '-D', 'POSTROUTING',
 
110
                 '-j nova_snatting', check_exit_code=False)
 
111
        _execute('sudo', 'iptables', '-t', 'nat', '-A', 'POSTROUTING',
 
112
                 '-j', 'nova_snatting')
 
113
        _execute('sudo', 'iptables', '-t', 'nat', '-N', 'nova_output',
 
114
                 check_exit_code=False)
 
115
        _execute('sudo', 'iptables', '-t', 'nat', '-D', 'OUTPUT',
 
116
                 '-j nova_output', check_exit_code=False)
 
117
        _execute('sudo', 'iptables', '-t', 'nat', '-A', 'OUTPUT',
 
118
                 '-j', 'nova_output')
114
119
    else:
115
120
        # NOTE(vish): This makes it easy to ensure snatting rules always
116
121
        #             come after the accept rules in the postrouting chain
117
 
        _execute("sudo iptables -t nat -N SNATTING",
118
 
                 check_exit_code=False)
119
 
        _execute("sudo iptables -t nat -D POSTROUTING -j SNATTING",
120
 
                 check_exit_code=False)
121
 
        _execute("sudo iptables -t nat -A POSTROUTING -j SNATTING")
 
122
        _execute('sudo', 'iptables', '-t', 'nat', '-N', 'SNATTING',
 
123
                 check_exit_code=False)
 
124
        _execute('sudo', 'iptables', '-t', 'nat', '-D', 'POSTROUTING',
 
125
                 '-j', 'SNATTING', check_exit_code=False)
 
126
        _execute('sudo', 'iptables', '-t', 'nat', '-A', 'POSTROUTING',
 
127
                 '-j', 'SNATTING')
122
128
 
123
129
    # NOTE(devcamcar): Cloud public SNAT entries and the default
124
130
    # SNAT rule for outbound traffic.
125
 
    _confirm_rule("SNATTING", "-t nat -s %s "
126
 
             "-j SNAT --to-source %s"
127
 
             % (FLAGS.fixed_range, FLAGS.routing_source_ip), append=True)
 
131
    _confirm_rule("SNATTING", '-t', 'nat', '-s', FLAGS.fixed_range,
 
132
             '-j', 'SNAT', '--to-source', FLAGS.routing_source_ip,
 
133
             append=True)
128
134
 
129
 
    _confirm_rule("POSTROUTING", "-t nat -s %s -d %s -j ACCEPT" %
130
 
                  (FLAGS.fixed_range, FLAGS.dmz_cidr))
131
 
    _confirm_rule("POSTROUTING", "-t nat -s %(range)s -d %(range)s -j ACCEPT" %
132
 
                  {'range': FLAGS.fixed_range})
 
135
    _confirm_rule("POSTROUTING", '-t', 'nat', '-s', FLAGS.fixed_range,
 
136
                  '-d', FLAGS.dmz_cidr, '-j', 'ACCEPT')
 
137
    _confirm_rule("POSTROUTING", '-t', 'nat', '-s', FLAGS.fixed_range,
 
138
                  '-d', FLAGS.fixed_range, '-j', 'ACCEPT')
133
139
 
134
140
 
135
141
def bind_floating_ip(floating_ip, check_exit_code=True):
136
142
    """Bind ip to public interface"""
137
 
    _execute("sudo ip addr add %s dev %s" % (floating_ip,
138
 
                                             FLAGS.public_interface),
 
143
    _execute('sudo', 'ip', 'addr', 'add', floating_ip,
 
144
             'dev', FLAGS.public_interface,
139
145
             check_exit_code=check_exit_code)
140
146
 
141
147
 
142
148
def unbind_floating_ip(floating_ip):
143
149
    """Unbind a public ip from public interface"""
144
 
    _execute("sudo ip addr del %s dev %s" % (floating_ip,
145
 
                                             FLAGS.public_interface))
 
150
    _execute('sudo', 'ip', 'addr', 'del', floating_ip,
 
151
             'dev', FLAGS.public_interface)
146
152
 
147
153
 
148
154
def ensure_vlan_forward(public_ip, port, private_ip):
149
155
    """Sets up forwarding rules for vlan"""
150
 
    _confirm_rule("FORWARD", "-d %s -p udp --dport 1194 -j ACCEPT" %
151
 
                  private_ip)
152
 
    _confirm_rule("PREROUTING",
153
 
                  "-t nat -d %s -p udp --dport %s -j DNAT --to %s:1194"
154
 
            % (public_ip, port, private_ip))
 
156
    _confirm_rule("FORWARD", '-d', private_ip, '-p', 'udp',
 
157
                  '--dport', '1194', '-j', 'ACCEPT')
 
158
    _confirm_rule("PREROUTING", '-t', 'nat', '-d', public_ip, '-p', 'udp',
 
159
                  '--dport', port, '-j', 'DNAT', '--to', '%s:1194'
 
160
                  % private_ip)
155
161
 
156
162
 
157
163
def ensure_floating_forward(floating_ip, fixed_ip):
158
164
    """Ensure floating ip forwarding rule"""
159
 
    _confirm_rule("PREROUTING", "-t nat -d %s -j DNAT --to %s"
160
 
                           % (floating_ip, fixed_ip))
161
 
    _confirm_rule("OUTPUT", "-t nat -d %s -j DNAT --to %s"
162
 
                           % (floating_ip, fixed_ip))
163
 
    _confirm_rule("SNATTING", "-t nat -s %s -j SNAT --to %s"
164
 
                           % (fixed_ip, floating_ip))
 
165
    _confirm_rule("PREROUTING", '-t', 'nat', '-d', floating_ip, '-j', 'DNAT',
 
166
                  '--to', fixed_ip)
 
167
    _confirm_rule("OUTPUT", '-t', 'nat', '-d', floating_ip, '-j', 'DNAT',
 
168
                  '--to', fixed_ip)
 
169
    _confirm_rule("SNATTING", '-t', 'nat', '-s', fixed_ip, '-j', 'SNAT',
 
170
                  '--to', floating_ip)
165
171
 
166
172
 
167
173
def remove_floating_forward(floating_ip, fixed_ip):
168
174
    """Remove forwarding for floating ip"""
169
 
    _remove_rule("PREROUTING", "-t nat -d %s -j DNAT --to %s"
170
 
                          % (floating_ip, fixed_ip))
171
 
    _remove_rule("OUTPUT", "-t nat -d %s -j DNAT --to %s"
172
 
                          % (floating_ip, fixed_ip))
173
 
    _remove_rule("SNATTING", "-t nat -s %s -j SNAT --to %s"
174
 
                          % (fixed_ip, floating_ip))
 
175
    _remove_rule("PREROUTING", '-t', 'nat', '-d', floating_ip, '-j', 'DNAT',
 
176
                 '--to', fixed_ip)
 
177
    _remove_rule("OUTPUT", '-t', 'nat', '-d', floating_ip, '-j', 'DNAT',
 
178
                 '--to', fixed_ip)
 
179
    _remove_rule("SNATTING", '-t', 'nat', '-s', fixed_ip, '-j', 'SNAT',
 
180
                 '--to', floating_ip)
175
181
 
176
182
 
177
183
def ensure_vlan_bridge(vlan_num, bridge, net_attrs=None):
185
191
    interface = "vlan%s" % vlan_num
186
192
    if not _device_exists(interface):
187
193
        LOG.debug(_("Starting VLAN inteface %s"), interface)
188
 
        _execute("sudo vconfig set_name_type VLAN_PLUS_VID_NO_PAD")
189
 
        _execute("sudo vconfig add %s %s" % (FLAGS.vlan_interface, vlan_num))
190
 
        _execute("sudo ip link set %s up" % interface)
 
194
        _execute('sudo', 'vconfig', 'set_name_type', 'VLAN_PLUS_VID_NO_PAD')
 
195
        _execute('sudo', 'vconfig', 'add', FLAGS.vlan_interface, vlan_num)
 
196
        _execute('sudo', 'ip', 'link', 'set', interface, 'up')
191
197
    return interface
192
198
 
193
199
 
206
212
    """
207
213
    if not _device_exists(bridge):
208
214
        LOG.debug(_("Starting Bridge interface for %s"), interface)
209
 
        _execute("sudo brctl addbr %s" % bridge)
210
 
        _execute("sudo brctl setfd %s 0" % bridge)
 
215
        _execute('sudo', 'brctl', 'addbr', bridge)
 
216
        _execute('sudo', 'brctl', 'setfd', bridge, 0)
211
217
        # _execute("sudo brctl setageing %s 10" % bridge)
212
 
        _execute("sudo brctl stp %s off" % bridge)
213
 
        _execute("sudo ip link set %s up" % bridge)
 
218
        _execute('sudo', 'brctl', 'stp', bridge, 'off')
 
219
        _execute('sudo', 'ip', 'link', 'set', bridge, up)
214
220
    if net_attrs:
215
221
        # NOTE(vish): The ip for dnsmasq has to be the first address on the
216
222
        #             bridge for it to respond to reqests properly
217
223
        suffix = net_attrs['cidr'].rpartition('/')[2]
218
 
        out, err = _execute("sudo ip addr add %s/%s brd %s dev %s" %
219
 
                            (net_attrs['gateway'],
220
 
                             suffix,
221
 
                             net_attrs['broadcast'],
222
 
                             bridge),
 
224
        out, err = _execute('sudo', 'ip', 'addr', 'add',
 
225
                            "%s/%s" %
 
226
                            (net_attrs['gateway'], suffix),
 
227
                            'brd',
 
228
                            net_attrs['broadcast'],
 
229
                            'dev',
 
230
                            bridge,
223
231
                            check_exit_code=False)
224
232
        if err and err != "RTNETLINK answers: File exists\n":
225
233
            raise exception.Error("Failed to add ip: %s" % err)
226
234
        if(FLAGS.use_ipv6):
227
 
            _execute("sudo ip -f inet6 addr change %s dev %s" %
228
 
                     (net_attrs['cidr_v6'], bridge))
 
235
            _execute('sudo', 'ip', '-f', 'inet6', 'addr',
 
236
                     'change', net_attrs['cidr_v6'],
 
237
                     'dev', bridge)
229
238
        # NOTE(vish): If the public interface is the same as the
230
239
        #             bridge, then the bridge has to be in promiscuous
231
240
        #             to forward packets properly.
232
241
        if(FLAGS.public_interface == bridge):
233
 
            _execute("sudo ip link set dev %s promisc on" % bridge)
 
242
            _execute('sudo', 'ip', 'link', 'set',
 
243
                     'dev', bridge, 'promisc', 'on')
234
244
    if interface:
235
245
        # NOTE(vish): This will break if there is already an ip on the
236
246
        #             interface, so we move any ips to the bridge
237
247
        gateway = None
238
 
        out, err = _execute("sudo route -n")
 
248
        out, err = _execute('sudo', 'route', '-n')
239
249
        for line in out.split("\n"):
240
250
            fields = line.split()
241
251
            if fields and fields[0] == "0.0.0.0" and fields[-1] == interface:
242
252
                gateway = fields[1]
243
 
        out, err = _execute("sudo ip addr show dev %s scope global" %
244
 
                            interface)
 
253
        out, err = _execute('sudo', 'ip', 'addr', 'show', 'dev', interface,
 
254
                            'scope', 'global')
245
255
        for line in out.split("\n"):
246
256
            fields = line.split()
247
257
            if fields and fields[0] == "inet":
248
258
                params = ' '.join(fields[1:-1])
249
 
                _execute("sudo ip addr del %s dev %s" % (params, fields[-1]))
250
 
                _execute("sudo ip addr add %s dev %s" % (params, bridge))
 
259
                _execute('sudo', 'ip', 'addr',
 
260
                         'del', params, 'dev', fields[-1])
 
261
                _execute('sudo', 'ip', 'addr',
 
262
                         'add', params, 'dev', bridge)
251
263
        if gateway:
252
 
            _execute("sudo route add 0.0.0.0 gw %s" % gateway)
253
 
        out, err = _execute("sudo brctl addif %s %s" %
254
 
                            (bridge, interface),
 
264
            _execute('sudo', 'route', 'add', '0.0.0.0', 'gw', gateway)
 
265
        out, err = _execute('sudo', 'brctl', 'addif', bridge, interface,
255
266
                            check_exit_code=False)
256
267
 
257
268
        if (err and err != "device %s is already a member of a bridge; can't "
259
270
            raise exception.Error("Failed to add interface: %s" % err)
260
271
 
261
272
    if FLAGS.use_nova_chains:
262
 
        (out, err) = _execute("sudo iptables -N nova_forward",
 
273
        (out, err) = _execute('sudo', 'iptables', '-N', 'nova_forward',
263
274
                              check_exit_code=False)
264
275
        if err != 'iptables: Chain already exists.\n':
265
276
            # NOTE(vish): chain didn't exist link chain
266
 
            _execute("sudo iptables -D FORWARD -j nova_forward",
 
277
            _execute('sudo', 'iptables', '-D', 'FORWARD', '-j', 'nova_forward',
267
278
                     check_exit_code=False)
268
 
            _execute("sudo iptables -A FORWARD -j nova_forward")
 
279
            _execute('sudo', 'iptables', '-A', 'FORWARD', '-j', 'nova_forward')
269
280
 
270
 
    _confirm_rule("FORWARD", "--in-interface %s -j ACCEPT" % bridge)
271
 
    _confirm_rule("FORWARD", "--out-interface %s -j ACCEPT" % bridge)
272
 
    _execute("sudo iptables -N nova-local", check_exit_code=False)
273
 
    _confirm_rule("FORWARD", "-j nova-local")
 
281
    _confirm_rule("FORWARD", '--in-interface', bridge, '-j', 'ACCEPT')
 
282
    _confirm_rule("FORWARD", '--out-interface', bridge, '-j', 'ACCEPT')
 
283
    _execute('sudo', 'iptables', '-N', 'nova-local', check_exit_code=False)
 
284
    _confirm_rule("FORWARD", '-j', 'nova-local')
274
285
 
275
286
 
276
287
def get_dhcp_hosts(context, network_id):
304
315
 
305
316
    # if dnsmasq is already running, then tell it to reload
306
317
    if pid:
307
 
        out, _err = _execute('cat /proc/%d/cmdline' % pid,
 
318
        out, _err = _execute('cat', "/proc/%d/cmdline" % pid,
308
319
                             check_exit_code=False)
309
320
        if conffile in out:
310
321
            try:
311
 
                _execute('sudo kill -HUP %d' % pid)
 
322
                _execute('sudo', 'kill', '-HUP', pid)
312
323
                return
313
324
            except Exception as exc:  # pylint: disable-msg=W0703
314
325
                LOG.debug(_("Hupping dnsmasq threw %s"), exc)
349
360
 
350
361
    # if radvd is already running, then tell it to reload
351
362
    if pid:
352
 
        out, _err = _execute('cat /proc/%d/cmdline'
 
363
        out, _err = _execute('cat', '/proc/%d/cmdline'
353
364
                             % pid, check_exit_code=False)
354
365
        if conffile in out:
355
366
            try:
356
 
                _execute('sudo kill %d' % pid)
 
367
                _execute('sudo', 'kill', pid)
357
368
            except Exception as exc:  # pylint: disable-msg=W0703
358
369
                LOG.debug(_("killing radvd threw %s"), exc)
359
370
        else:
374
385
                                   fixed_ip_ref['address'])
375
386
 
376
387
 
377
 
def _execute(cmd, *args, **kwargs):
 
388
def _execute(*cmd, **kwargs):
378
389
    """Wrapper around utils._execute for fake_network"""
379
390
    if FLAGS.fake_network:
380
 
        LOG.debug("FAKE NET: %s", cmd)
 
391
        LOG.debug("FAKE NET: %s", " ".join(map(str, cmd)))
381
392
        return "fake", 0
382
393
    else:
383
 
        return utils.execute(cmd, *args, **kwargs)
 
394
        return utils.execute(*cmd, **kwargs)
384
395
 
385
396
 
386
397
def _device_exists(device):
387
398
    """Check if ethernet device exists"""
388
 
    (_out, err) = _execute("ip link show dev %s" % device,
 
399
    (_out, err) = _execute('ip', 'link', 'show', 'dev', device,
389
400
                           check_exit_code=False)
390
401
    return not err
391
402
 
392
403
 
393
 
def _confirm_rule(chain, cmd, append=False):
 
404
def _confirm_rule(chain, *cmd, **kwargs):
 
405
    append = kwargs.get('append', False)
394
406
    """Delete and re-add iptables rule"""
395
407
    if FLAGS.use_nova_chains:
396
408
        chain = "nova_%s" % chain.lower()
398
410
        loc = "-A"
399
411
    else:
400
412
        loc = "-I"
401
 
    _execute("sudo iptables --delete %s %s" % (chain, cmd),
 
413
    _execute('sudo', 'iptables', '--delete', chain, *cmd,
402
414
             check_exit_code=False)
403
 
    _execute("sudo iptables %s %s %s" % (loc, chain, cmd))
404
 
 
405
 
 
406
 
def _remove_rule(chain, cmd):
 
415
    _execute('sudo', 'iptables', loc, chain, *cmd)
 
416
 
 
417
 
 
418
def _remove_rule(chain, *cmd):
407
419
    """Remove iptables rule"""
408
420
    if FLAGS.use_nova_chains:
409
421
        chain = "%s" % chain.lower()
410
 
    _execute("sudo iptables --delete %s %s" % (chain, cmd))
 
422
    _execute('sudo', 'iptables', '--delete', chain, *cmd)
411
423
 
412
424
 
413
425
def _dnsmasq_cmd(net):
444
456
 
445
457
    if pid:
446
458
        try:
447
 
            _execute('sudo kill -TERM %d' % pid)
 
459
            _execute('sudo', 'kill', '-TERM', pid)
448
460
        except Exception as exc:  # pylint: disable-msg=W0703
449
461
            LOG.debug(_("Killing dnsmasq threw %s"), exc)
450
462