~ubuntu-branches/ubuntu/vivid/neutron/vivid-updates

« back to all changes in this revision

Viewing changes to neutron/agent/l3/dvr_fip_ns.py

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2015-03-30 11:17:19 UTC
  • mfrom: (1.1.21)
  • Revision ID: package-import@ubuntu.com-20150330111719-h0gx7233p4jkkgfh
Tags: 1:2015.1~b3-0ubuntu1
* New upstream milestone release:
  - d/control: Align version requirements with upstream.
  - d/control: Add new dependency on oslo-log.
  - d/p/*: Rebase.
  - d/control,d/neutron-plugin-hyperv*: Dropped, decomposed into
    separate project upstream.
  - d/control,d/neutron-plugin-openflow*: Dropped, decomposed into
    separate project upstream.
  - d/neutron-common.install: Add neutron-rootwrap-daemon and 
    neutron-keepalived-state-change binaries.
  - d/rules: Ignore neutron-hyperv-agent when installing; only for Windows.
  - d/neutron-plugin-cisco.install: Drop neutron-cisco-cfg-agent as
    decomposed into separate project upstream.
  - d/neutron-plugin-vmware.install: Drop neutron-check-nsx-config and
    neutron-nsx-manage as decomposed into separate project upstream.
  - d/control: Add dependency on python-neutron-fwaas to neutron-l3-agent.
* d/pydist-overrides: Add overrides for oslo packages.
* d/control: Fixup type in package description (LP: #1263539).
* d/p/fixup-driver-test-execution.patch: Cherry pick fix from upstream VCS
  to support unit test exection in out-of-tree vendor drivers.
* d/neutron-common.postinst: Allow general access to /etc/neutron but limit
  access to root/neutron to /etc/neutron/neutron.conf to support execution
  of unit tests in decomposed vendor drivers.
* d/control: Add dependency on python-neutron-fwaas to neutron-l3-agent
  package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#    License for the specific language governing permissions and limitations
13
13
#    under the License.
14
14
 
 
15
import os
 
16
 
15
17
import netaddr
16
 
import os
 
18
from oslo_log import log as logging
17
19
 
18
20
from neutron.agent.l3 import link_local_allocator as lla
 
21
from neutron.agent.l3 import namespaces
19
22
from neutron.agent.linux import ip_lib
20
23
from neutron.agent.linux import iptables_manager
21
24
from neutron.common import utils as common_utils
22
 
from neutron.i18n import _LE
23
 
from neutron.openstack.common import log as logging
24
25
 
25
26
LOG = logging.getLogger(__name__)
26
27
 
27
28
FIP_NS_PREFIX = 'fip-'
28
29
FIP_EXT_DEV_PREFIX = 'fg-'
29
30
FIP_2_ROUTER_DEV_PREFIX = 'fpr-'
30
 
ROUTER_2_FIP_DEV_PREFIX = 'rfp-'
 
31
ROUTER_2_FIP_DEV_PREFIX = namespaces.ROUTER_2_FIP_DEV_PREFIX
31
32
# Route Table index for FIPs
32
33
FIP_RT_TBL = 16
33
34
FIP_LL_SUBNET = '169.254.30.0/23'
36
37
FIP_PR_END = FIP_PR_START + 40000
37
38
 
38
39
 
39
 
class FipNamespace(object):
40
 
    def __init__(self, ext_net_id, agent_conf, driver, root_helper, use_ipv6):
 
40
class FipNamespace(namespaces.Namespace):
 
41
 
 
42
    def __init__(self, ext_net_id, agent_conf, driver, use_ipv6):
 
43
        name = FIP_NS_PREFIX + ext_net_id
 
44
        super(FipNamespace, self).__init__(
 
45
            name, agent_conf, driver, use_ipv6)
 
46
 
41
47
        self._ext_net_id = ext_net_id
42
48
        self.agent_conf = agent_conf
43
49
        self.driver = driver
44
 
        self.root_helper = root_helper
45
50
        self.use_ipv6 = use_ipv6
46
51
        self.agent_gateway_port = None
47
52
        self._subscribers = set()
48
53
        self._rule_priorities = set(range(FIP_PR_START, FIP_PR_END))
49
54
        self._iptables_manager = iptables_manager.IptablesManager(
50
 
            root_helper=self.root_helper,
51
55
            namespace=self.get_name(),
52
56
            use_ipv6=self.use_ipv6)
53
57
        path = os.path.join(agent_conf.state_path, 'fip-linklocal-networks')
54
58
        self.local_subnets = lla.LinkLocalAllocator(path, FIP_LL_SUBNET)
 
59
        self.destroyed = False
55
60
 
56
61
    def get_name(self):
57
62
        return (FIP_NS_PREFIX + self._ext_net_id)
86
91
    def _gateway_added(self, ex_gw_port, interface_name):
87
92
        """Add Floating IP gateway port."""
88
93
        ns_name = self.get_name()
89
 
        if not ip_lib.device_exists(interface_name,
90
 
                                    root_helper=self.root_helper,
91
 
                                    namespace=ns_name):
 
94
        if not ip_lib.device_exists(interface_name, namespace=ns_name):
92
95
            self.driver.plug(ex_gw_port['network_id'],
93
96
                             ex_gw_port['id'],
94
97
                             interface_name,
105
108
        ip_lib.send_gratuitous_arp(ns_name,
106
109
                                   interface_name,
107
110
                                   ip_address,
108
 
                                   self.agent_conf.send_arp_for_ha,
109
 
                                   self.root_helper)
 
111
                                   self.agent_conf.send_arp_for_ha)
110
112
 
111
113
        gw_ip = ex_gw_port['subnet']['gateway_ip']
112
114
        if gw_ip:
113
 
            ipd = ip_lib.IPDevice(interface_name,
114
 
                                  self.root_helper,
115
 
                                  namespace=ns_name)
 
115
            ipd = ip_lib.IPDevice(interface_name, namespace=ns_name)
116
116
            ipd.route.add_gateway(gw_ip)
117
117
 
118
118
        cmd = ['sysctl', '-w', 'net.ipv4.conf.%s.proxy_arp=1' % interface_name]
119
119
        # TODO(Carl) mlavelle's work has self.ip_wrapper
120
 
        ip_wrapper = ip_lib.IPWrapper(self.root_helper, namespace=ns_name)
 
120
        ip_wrapper = ip_lib.IPWrapper(namespace=ns_name)
121
121
        ip_wrapper.netns.execute(cmd, check_exit_code=False)
122
122
 
123
123
    def create(self):
124
124
        # TODO(Carl) Get this functionality from mlavelle's namespace baseclass
125
 
        ip_wrapper_root = ip_lib.IPWrapper(self.root_helper)
 
125
        ip_wrapper_root = ip_lib.IPWrapper()
126
126
        ip_wrapper = ip_wrapper_root.ensure_namespace(self.get_name())
127
127
        ip_wrapper.netns.execute(['sysctl', '-w', 'net.ipv4.ip_forward=1'])
128
128
        if self.use_ipv6:
134
134
                                                    '-j CT --notrack')
135
135
        self._iptables_manager.apply()
136
136
 
137
 
    def destroy(self):
138
 
        ns = self.get_name()
139
 
        # TODO(carl) Reconcile this with mlavelle's namespace work
140
 
        # TODO(carl) mlavelle's work has self.ip_wrapper
141
 
        ip_wrapper = ip_lib.IPWrapper(self.root_helper, namespace=ns)
 
137
    def delete(self):
 
138
        self.destroyed = True
 
139
        ip_wrapper = ip_lib.IPWrapper(namespace=self.name)
142
140
        for d in ip_wrapper.get_devices(exclude_loopback=True):
143
141
            if d.name.startswith(FIP_2_ROUTER_DEV_PREFIX):
144
142
                # internal link between IRs and FIP NS
150
148
                ext_net_bridge = self.agent_conf.external_network_bridge
151
149
                self.driver.unplug(d.name,
152
150
                                   bridge=ext_net_bridge,
153
 
                                   namespace=ns,
 
151
                                   namespace=self.name,
154
152
                                   prefix=FIP_EXT_DEV_PREFIX)
155
 
        LOG.debug('DVR: destroy fip ns: %s', ns)
 
153
        self.agent_gateway_port = None
 
154
 
156
155
        # TODO(mrsmith): add LOG warn if fip count != 0
157
 
        if self.agent_conf.router_delete_namespaces:
158
 
            try:
159
 
                ip_wrapper.netns.delete(ns)
160
 
            except RuntimeError:
161
 
                LOG.exception(_LE('Failed trying to delete namespace: %s'), ns)
162
 
 
163
 
        self.agent_gateway_port = None
 
156
        LOG.debug('DVR: destroy fip ns: %s', self.name)
 
157
        super(FipNamespace, self).delete()
164
158
 
165
159
    def create_gateway_port(self, agent_gateway_port):
166
160
        """Create Floating IP gateway port.
178
172
 
179
173
    def _internal_ns_interface_added(self, ip_cidr,
180
174
                                    interface_name, ns_name):
181
 
        ip_wrapper = ip_lib.IPWrapper(self.root_helper, namespace=ns_name)
 
175
        ip_wrapper = ip_lib.IPWrapper(namespace=ns_name)
182
176
        ip_wrapper.netns.execute(['ip', 'addr', 'add',
183
177
                                  ip_cidr, 'dev', interface_name])
184
178
 
192
186
        if ri.rtr_fip_subnet is None:
193
187
            ri.rtr_fip_subnet = self.local_subnets.allocate(ri.router_id)
194
188
        rtr_2_fip, fip_2_rtr = ri.rtr_fip_subnet.get_pair()
195
 
        ip_wrapper = ip_lib.IPWrapper(self.root_helper,
196
 
                                      namespace=ri.ns_name)
 
189
        ip_wrapper = ip_lib.IPWrapper(namespace=ri.ns_name)
197
190
        device_exists = ip_lib.device_exists(rtr_2_fip_name,
198
 
                                             self.root_helper,
199
191
                                             namespace=ri.ns_name)
200
192
        if not device_exists:
201
193
            int_dev = ip_wrapper.add_veth(rtr_2_fip_name,
211
203
            int_dev[1].link.set_up()
212
204
 
213
205
        # add default route for the link local interface
214
 
        device = ip_lib.IPDevice(rtr_2_fip_name,
215
 
                                 self.root_helper,
216
 
                                 namespace=ri.ns_name)
 
206
        device = ip_lib.IPDevice(rtr_2_fip_name, namespace=ri.ns_name)
217
207
        device.route.add_gateway(str(fip_2_rtr.ip), table=FIP_RT_TBL)
218
208
        #setup the NAT rules and chains
219
209
        ri._handle_fip_nat_rules(rtr_2_fip_name, 'add_rules')
226
216
        # scan system for any existing fip ports
227
217
        ri.dist_fip_count = 0
228
218
        rtr_2_fip_interface = self.get_rtr_ext_device_name(ri.router_id)
229
 
        if ip_lib.device_exists(rtr_2_fip_interface,
230
 
                                root_helper=self.root_helper,
231
 
                                namespace=ri.ns_name):
232
 
            device = ip_lib.IPDevice(rtr_2_fip_interface,
233
 
                                     self.root_helper,
234
 
                                     namespace=ri.ns_name)
 
219
        if ip_lib.device_exists(rtr_2_fip_interface, namespace=ri.ns_name):
 
220
            device = ip_lib.IPDevice(rtr_2_fip_interface, namespace=ri.ns_name)
235
221
            existing_cidrs = [addr['cidr'] for addr in device.addr.list()]
236
222
            fip_cidrs = [c for c in existing_cidrs if
237
223
                         common_utils.is_cidr_host(c)]