Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / logic / subnets.py @ 1fb3293d

History | View | Annotate | Download (11 kB)

1 9eb0710b Dionysis Grigoropoulos
# Copyright 2013 GRNET S.A. All rights reserved.
2 9eb0710b Dionysis Grigoropoulos
#
3 9eb0710b Dionysis Grigoropoulos
# Redistribution and use in source and binary forms, with or
4 9eb0710b Dionysis Grigoropoulos
# without modification, are permitted provided that the following
5 9eb0710b Dionysis Grigoropoulos
# conditions are met:
6 9eb0710b Dionysis Grigoropoulos
#
7 9eb0710b Dionysis Grigoropoulos
#   1. Redistributions of source code must retain the above
8 9eb0710b Dionysis Grigoropoulos
#      copyright notice, this list of conditions and the following
9 9eb0710b Dionysis Grigoropoulos
#      disclaimer.
10 9eb0710b Dionysis Grigoropoulos
#
11 9eb0710b Dionysis Grigoropoulos
#   2. Redistributions in binary form must reproduce the above
12 9eb0710b Dionysis Grigoropoulos
#      copyright notice, this list of conditions and the following
13 9eb0710b Dionysis Grigoropoulos
#      disclaimer in the documentation and/or other materials
14 9eb0710b Dionysis Grigoropoulos
#      provided with the distribution.
15 9eb0710b Dionysis Grigoropoulos
#
16 9eb0710b Dionysis Grigoropoulos
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 9eb0710b Dionysis Grigoropoulos
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 9eb0710b Dionysis Grigoropoulos
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 9eb0710b Dionysis Grigoropoulos
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 9eb0710b Dionysis Grigoropoulos
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 9eb0710b Dionysis Grigoropoulos
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 9eb0710b Dionysis Grigoropoulos
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 9eb0710b Dionysis Grigoropoulos
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 9eb0710b Dionysis Grigoropoulos
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 9eb0710b Dionysis Grigoropoulos
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 9eb0710b Dionysis Grigoropoulos
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 9eb0710b Dionysis Grigoropoulos
# POSSIBILITY OF SUCH DAMAGE.
28 9eb0710b Dionysis Grigoropoulos
#
29 9eb0710b Dionysis Grigoropoulos
# The views and conclusions contained in the software and
30 9eb0710b Dionysis Grigoropoulos
# documentation are those of the authors and should not be
31 9eb0710b Dionysis Grigoropoulos
# interpreted as representing official policies, either expressed
32 9eb0710b Dionysis Grigoropoulos
# or implied, of GRNET S.A.
33 9eb0710b Dionysis Grigoropoulos
34 f82dfec6 Christos Stavrakakis
import ipaddr
35 9eb0710b Dionysis Grigoropoulos
from logging import getLogger
36 f82dfec6 Christos Stavrakakis
from functools import wraps
37 f82dfec6 Christos Stavrakakis
38 f82dfec6 Christos Stavrakakis
from django.conf import settings
39 f82dfec6 Christos Stavrakakis
from django.db import transaction
40 9eb0710b Dionysis Grigoropoulos
from snf_django.lib import api
41 9eb0710b Dionysis Grigoropoulos
from snf_django.lib.api import faults
42 9eb0710b Dionysis Grigoropoulos
43 9eb0710b Dionysis Grigoropoulos
from synnefo.db.models import Subnet, Network, IPPoolTable
44 9eb0710b Dionysis Grigoropoulos
45 9eb0710b Dionysis Grigoropoulos
log = getLogger(__name__)
46 9eb0710b Dionysis Grigoropoulos
47 9eb0710b Dionysis Grigoropoulos
48 9eb0710b Dionysis Grigoropoulos
def subnet_command(action):
49 9eb0710b Dionysis Grigoropoulos
    def decorator(func):
50 9eb0710b Dionysis Grigoropoulos
        @wraps(func)
51 9eb0710b Dionysis Grigoropoulos
        @transaction.commit_on_success()
52 9eb0710b Dionysis Grigoropoulos
        def wrapper(subnet, *args, **kwargs):
53 9eb0710b Dionysis Grigoropoulos
            return func(subnet, *args, **kwargs)
54 9eb0710b Dionysis Grigoropoulos
        return wrapper
55 9eb0710b Dionysis Grigoropoulos
    return decorator
56 9eb0710b Dionysis Grigoropoulos
57 9eb0710b Dionysis Grigoropoulos
58 9eb0710b Dionysis Grigoropoulos
def list_subnets(user_id):
59 9eb0710b Dionysis Grigoropoulos
    """List all subnets of a user"""
60 9eb0710b Dionysis Grigoropoulos
    log.debug('list_subnets')
61 9eb0710b Dionysis Grigoropoulos
62 9eb0710b Dionysis Grigoropoulos
    user_subnets = Subnet.objects.filter(network__userid=user_id)
63 5d83d2ff Dionysis Grigoropoulos
    return user_subnets
64 9eb0710b Dionysis Grigoropoulos
65 9eb0710b Dionysis Grigoropoulos
66 9eb0710b Dionysis Grigoropoulos
@transaction.commit_on_success
67 f82dfec6 Christos Stavrakakis
def create_subnet(*args, **kwargs):
68 f82dfec6 Christos Stavrakakis
    return _create_subnet(*args, **kwargs)
69 f82dfec6 Christos Stavrakakis
70 f82dfec6 Christos Stavrakakis
71 f82dfec6 Christos Stavrakakis
def _create_subnet(network_id, user_id, cidr, name, ipversion=4, gateway=None,
72 f82dfec6 Christos Stavrakakis
                   dhcp=True, slac=True, dns_nameservers=None,
73 f82dfec6 Christos Stavrakakis
                   allocation_pools=None, host_routes=None):
74 316787ab Dionysis Grigoropoulos
    """Create a subnet
75 f82dfec6 Christos Stavrakakis

76 9eb0710b Dionysis Grigoropoulos
    network_id and the desired cidr are mandatory, everything else is optional
77 316787ab Dionysis Grigoropoulos

78 9eb0710b Dionysis Grigoropoulos
    """
79 9eb0710b Dionysis Grigoropoulos
    try:
80 9eb0710b Dionysis Grigoropoulos
        network = Network.objects.get(id=network_id)
81 9eb0710b Dionysis Grigoropoulos
    except Network.DoesNotExist:
82 9eb0710b Dionysis Grigoropoulos
        raise api.faults.ItemNotFound("No networks found with that id")
83 9eb0710b Dionysis Grigoropoulos
84 5d83d2ff Dionysis Grigoropoulos
    if user_id != network.userid:
85 5d83d2ff Dionysis Grigoropoulos
        raise api.faults.Unauthorized("Unauthorized operation")
86 5d83d2ff Dionysis Grigoropoulos
87 9eb0710b Dionysis Grigoropoulos
    if ipversion not in [4, 6]:
88 9eb0710b Dionysis Grigoropoulos
        raise api.faults.BadRequest("Malformed IP version type")
89 9eb0710b Dionysis Grigoropoulos
90 99718617 Dionysis Grigoropoulos
    check_number_of_subnets(network, ipversion)
91 99718617 Dionysis Grigoropoulos
92 9eb0710b Dionysis Grigoropoulos
    # Returns the first available IP in the subnet
93 99718617 Dionysis Grigoropoulos
    try:
94 f82dfec6 Christos Stavrakakis
        cidr_ip = ipaddr.IPNetwork(cidr)
95 99718617 Dionysis Grigoropoulos
    except ValueError:
96 99718617 Dionysis Grigoropoulos
        raise api.faults.BadRequest("Malformed CIDR")
97 f82dfec6 Christos Stavrakakis
    potential_gateway = str(ipaddr.IPNetwork(cidr).network + 1)
98 9eb0710b Dionysis Grigoropoulos
99 99718617 Dionysis Grigoropoulos
    if gateway is "":
100 5d83d2ff Dionysis Grigoropoulos
        gateway = potential_gateway
101 5d83d2ff Dionysis Grigoropoulos
102 9eb0710b Dionysis Grigoropoulos
    if ipversion == 6:
103 f82dfec6 Christos Stavrakakis
        validate_subnet_params(None, None, cidr, gateway)
104 9eb0710b Dionysis Grigoropoulos
        if slac is not None:
105 9eb0710b Dionysis Grigoropoulos
            dhcp = check_boolean_value(slac, "enable_slac")
106 9eb0710b Dionysis Grigoropoulos
        else:
107 9eb0710b Dionysis Grigoropoulos
            dhcp = check_boolean_value(dhcp, "dhcp")
108 9eb0710b Dionysis Grigoropoulos
    else:
109 f82dfec6 Christos Stavrakakis
        validate_subnet_params(cidr, gateway)
110 9eb0710b Dionysis Grigoropoulos
        dhcp = check_boolean_value(dhcp, "dhcp")
111 9eb0710b Dionysis Grigoropoulos
112 9eb0710b Dionysis Grigoropoulos
    name = check_name_length(name)
113 9eb0710b Dionysis Grigoropoulos
114 f82dfec6 Christos Stavrakakis
    gateway_ip = ipaddr.IPAddress(gateway)
115 9eb0710b Dionysis Grigoropoulos
116 9eb0710b Dionysis Grigoropoulos
    sub = Subnet.objects.create(name=name, network=network, cidr=cidr,
117 9eb0710b Dionysis Grigoropoulos
                                ipversion=ipversion, gateway=gateway,
118 5d83d2ff Dionysis Grigoropoulos
                                dhcp=dhcp, host_routes=host_routes,
119 5d83d2ff Dionysis Grigoropoulos
                                dns_nameservers=dns_nameservers)
120 9eb0710b Dionysis Grigoropoulos
121 9eb0710b Dionysis Grigoropoulos
    if allocation_pools is not None:
122 9eb0710b Dionysis Grigoropoulos
        # If the user specified IP allocation pools, validate them and use them
123 9eb0710b Dionysis Grigoropoulos
        if ipversion == 6:
124 9eb0710b Dionysis Grigoropoulos
            raise api.faults.Conflict("Can't allocate an IP Pool in IPv6")
125 5d83d2ff Dionysis Grigoropoulos
        validate_subpools(allocation_pools, cidr_ip, gateway_ip)
126 9eb0710b Dionysis Grigoropoulos
    if allocation_pools is None and ipversion == 4:
127 9eb0710b Dionysis Grigoropoulos
        # Check if the gateway is the first IP of the subnet, in this case
128 9eb0710b Dionysis Grigoropoulos
        # create a single ip pool
129 9eb0710b Dionysis Grigoropoulos
        if int(gateway_ip) - int(cidr_ip) == 1:
130 5d83d2ff Dionysis Grigoropoulos
            allocation_pools = [[gateway_ip + 1, cidr_ip.broadcast - 1]]
131 9eb0710b Dionysis Grigoropoulos
        else:
132 9eb0710b Dionysis Grigoropoulos
            # If the gateway isn't the first available ip, create two different
133 9eb0710b Dionysis Grigoropoulos
            # ip pools adjacent to said ip
134 8646e606 Dionysis Grigoropoulos
            allocation_pools = (([cidr_ip.network + 1, gateway_ip - 1]),
135 8646e606 Dionysis Grigoropoulos
                                ([gateway_ip + 1, cidr_ip.broadcast - 1]))
136 9eb0710b Dionysis Grigoropoulos
137 5d83d2ff Dionysis Grigoropoulos
    if allocation_pools:
138 5d83d2ff Dionysis Grigoropoulos
        create_ip_pools(allocation_pools, cidr_ip, sub)
139 9eb0710b Dionysis Grigoropoulos
140 9eb0710b Dionysis Grigoropoulos
    return sub
141 9eb0710b Dionysis Grigoropoulos
142 9eb0710b Dionysis Grigoropoulos
143 9eb0710b Dionysis Grigoropoulos
def get_subnet(sub_id):
144 9eb0710b Dionysis Grigoropoulos
    """Show info of a specific subnet"""
145 9eb0710b Dionysis Grigoropoulos
    log.debug('get_subnet %s', sub_id)
146 9eb0710b Dionysis Grigoropoulos
    try:
147 9eb0710b Dionysis Grigoropoulos
        subnet = Subnet.objects.get(id=sub_id)
148 9eb0710b Dionysis Grigoropoulos
    except Subnet.DoesNotExist:
149 9eb0710b Dionysis Grigoropoulos
        raise api.faults.ItemNotFound("Subnet not found")
150 9eb0710b Dionysis Grigoropoulos
151 5d83d2ff Dionysis Grigoropoulos
    return subnet
152 9eb0710b Dionysis Grigoropoulos
153 9eb0710b Dionysis Grigoropoulos
154 9eb0710b Dionysis Grigoropoulos
def delete_subnet():
155 316787ab Dionysis Grigoropoulos
    """Delete a subnet, raises BadRequest
156 9eb0710b Dionysis Grigoropoulos
    A subnet is deleted ONLY when the network that it belongs to is deleted
157 316787ab Dionysis Grigoropoulos

158 9eb0710b Dionysis Grigoropoulos
    """
159 9eb0710b Dionysis Grigoropoulos
    raise api.faults.BadRequest("Deletion of a subnet is not supported")
160 9eb0710b Dionysis Grigoropoulos
161 9eb0710b Dionysis Grigoropoulos
162 9eb0710b Dionysis Grigoropoulos
@transaction.commit_on_success
163 8646e606 Dionysis Grigoropoulos
def update_subnet(sub_id, name, user_id):
164 316787ab Dionysis Grigoropoulos
    """Update the fields of a subnet
165 9eb0710b Dionysis Grigoropoulos
    Only the name can be updated
166 316787ab Dionysis Grigoropoulos

167 9eb0710b Dionysis Grigoropoulos
    """
168 5d83d2ff Dionysis Grigoropoulos
    log.info('Update subnet %s, name %s' % (sub_id, name))
169 9eb0710b Dionysis Grigoropoulos
170 9eb0710b Dionysis Grigoropoulos
    try:
171 9eb0710b Dionysis Grigoropoulos
        subnet = Subnet.objects.get(id=sub_id)
172 9eb0710b Dionysis Grigoropoulos
    except:
173 9eb0710b Dionysis Grigoropoulos
        raise api.faults.ItemNotFound("Subnet not found")
174 9eb0710b Dionysis Grigoropoulos
175 8646e606 Dionysis Grigoropoulos
    if user_id != subnet.network.userid:
176 8646e606 Dionysis Grigoropoulos
        raise api.faults.Unauthorized("Unauthorized operation")
177 8646e606 Dionysis Grigoropoulos
178 9eb0710b Dionysis Grigoropoulos
    check_name_length(name)
179 9eb0710b Dionysis Grigoropoulos
180 9eb0710b Dionysis Grigoropoulos
    subnet.name = name
181 9eb0710b Dionysis Grigoropoulos
    subnet.save()
182 9eb0710b Dionysis Grigoropoulos
183 9eb0710b Dionysis Grigoropoulos
    return subnet
184 9eb0710b Dionysis Grigoropoulos
185 9eb0710b Dionysis Grigoropoulos
186 9eb0710b Dionysis Grigoropoulos
#Utility functions
187 9eb0710b Dionysis Grigoropoulos
def create_ip_pools(pools, cidr, subnet):
188 9eb0710b Dionysis Grigoropoulos
    """Create IP Pools in the database"""
189 f82dfec6 Christos Stavrakakis
    ip_pools = []
190 9eb0710b Dionysis Grigoropoulos
    for pool in pools:
191 9eb0710b Dionysis Grigoropoulos
        size = int(pool[1]) - int(pool[0]) + 1
192 9eb0710b Dionysis Grigoropoulos
        base = str(cidr)
193 9eb0710b Dionysis Grigoropoulos
        offset = int(pool[0]) - int(cidr.network)
194 9eb0710b Dionysis Grigoropoulos
        ip_pool = IPPoolTable.objects.create(size=size, offset=offset,
195 9eb0710b Dionysis Grigoropoulos
                                             base=base, subnet=subnet)
196 f82dfec6 Christos Stavrakakis
        ip_pools.append(ip_pool)
197 f82dfec6 Christos Stavrakakis
    return ip_pools
198 9eb0710b Dionysis Grigoropoulos
199 9eb0710b Dionysis Grigoropoulos
200 9eb0710b Dionysis Grigoropoulos
def check_empty_lists(value):
201 9eb0710b Dionysis Grigoropoulos
    """Check if value is Null/None, in which case we return an empty list"""
202 9eb0710b Dionysis Grigoropoulos
    if value is None:
203 9eb0710b Dionysis Grigoropoulos
        return []
204 9eb0710b Dionysis Grigoropoulos
    return value
205 9eb0710b Dionysis Grigoropoulos
206 9eb0710b Dionysis Grigoropoulos
207 9eb0710b Dionysis Grigoropoulos
def check_number_of_subnets(network, version):
208 9eb0710b Dionysis Grigoropoulos
    """Check if a user can add a subnet in a network"""
209 9eb0710b Dionysis Grigoropoulos
    if network.subnets.filter(ipversion=version):
210 9eb0710b Dionysis Grigoropoulos
        raise api.faults.BadRequest("Only one subnet of IPv4/IPv6 per "
211 9eb0710b Dionysis Grigoropoulos
                                    "network is allowed")
212 9eb0710b Dionysis Grigoropoulos
213 9eb0710b Dionysis Grigoropoulos
214 9eb0710b Dionysis Grigoropoulos
def check_boolean_value(value, key):
215 9eb0710b Dionysis Grigoropoulos
    """Check if dhcp value is in acceptable values"""
216 9eb0710b Dionysis Grigoropoulos
    if value not in [True, False]:
217 9eb0710b Dionysis Grigoropoulos
        raise api.faults.BadRequest("Malformed request, %s must "
218 9eb0710b Dionysis Grigoropoulos
                                    "be True or False" % key)
219 9eb0710b Dionysis Grigoropoulos
    return value
220 9eb0710b Dionysis Grigoropoulos
221 9eb0710b Dionysis Grigoropoulos
222 9eb0710b Dionysis Grigoropoulos
def check_name_length(name):
223 9eb0710b Dionysis Grigoropoulos
    """Check if the length of a name is within acceptable value"""
224 9eb0710b Dionysis Grigoropoulos
    if len(str(name)) > Subnet.SUBNET_NAME_LENGTH:
225 9eb0710b Dionysis Grigoropoulos
        raise api.faults.BadRequest("Subnet name too long")
226 9eb0710b Dionysis Grigoropoulos
    return name
227 9eb0710b Dionysis Grigoropoulos
228 9eb0710b Dionysis Grigoropoulos
229 9eb0710b Dionysis Grigoropoulos
def get_subnet_fromdb(subnet_id, user_id, for_update=False):
230 316787ab Dionysis Grigoropoulos
    """Return a Subnet instance or raise ItemNotFound.
231 9eb0710b Dionysis Grigoropoulos
    This is the same as util.get_network
232 316787ab Dionysis Grigoropoulos

233 9eb0710b Dionysis Grigoropoulos
    """
234 9eb0710b Dionysis Grigoropoulos
    try:
235 9eb0710b Dionysis Grigoropoulos
        subnet_id = int(subnet_id)
236 9eb0710b Dionysis Grigoropoulos
        if for_update:
237 9eb0710b Dionysis Grigoropoulos
            return Subnet.objects.select_for_update().get(id=subnet_id,
238 9eb0710b Dionysis Grigoropoulos
                                                          network__userid=
239 9eb0710b Dionysis Grigoropoulos
                                                          user_id)
240 9eb0710b Dionysis Grigoropoulos
        return Subnet.objects.get(id=subnet_id, network__userid=user_id)
241 9eb0710b Dionysis Grigoropoulos
    except (ValueError, Subnet.DoesNotExist):
242 9eb0710b Dionysis Grigoropoulos
        raise api.faults.ItemNotFound('Subnet not found')
243 9eb0710b Dionysis Grigoropoulos
244 9eb0710b Dionysis Grigoropoulos
245 9eb0710b Dionysis Grigoropoulos
def validate_subpools(pool_list, cidr, gateway):
246 316787ab Dionysis Grigoropoulos
    """Validate IP Pools
247 316787ab Dionysis Grigoropoulos

248 9eb0710b Dionysis Grigoropoulos
    Validate the given IP pools are inside the cidr range
249 9eb0710b Dionysis Grigoropoulos
    Validate there are no overlaps in the given pools
250 9eb0710b Dionysis Grigoropoulos
    Finally, validate the gateway isn't in the given ip pools
251 9eb0710b Dionysis Grigoropoulos
    Input must be a list containing a sublist with start/end ranges as
252 9eb0710b Dionysis Grigoropoulos
    ipaddr.IPAddress items eg.,
253 9eb0710b Dionysis Grigoropoulos
    [[IPv4Address('192.168.42.11'), IPv4Address('192.168.42.15')],
254 9eb0710b Dionysis Grigoropoulos
     [IPv4Address('192.168.42.30'), IPv4Address('192.168.42.60')]]
255 316787ab Dionysis Grigoropoulos

256 9eb0710b Dionysis Grigoropoulos
    """
257 9eb0710b Dionysis Grigoropoulos
    if pool_list[0][0] <= cidr.network:
258 9eb0710b Dionysis Grigoropoulos
        raise api.faults.Conflict("IP Pool out of bounds")
259 9eb0710b Dionysis Grigoropoulos
    elif pool_list[-1][1] >= cidr.broadcast:
260 9eb0710b Dionysis Grigoropoulos
        raise api.faults.Conflict("IP Pool out of bounds")
261 9eb0710b Dionysis Grigoropoulos
262 9eb0710b Dionysis Grigoropoulos
    for start, end in pool_list:
263 9eb0710b Dionysis Grigoropoulos
        if start > end:
264 9eb0710b Dionysis Grigoropoulos
            raise api.faults.Conflict("Invalid IP pool range")
265 9eb0710b Dionysis Grigoropoulos
        # Raise BadRequest if gateway is inside the pool range
266 9eb0710b Dionysis Grigoropoulos
        if not (gateway < start or gateway > end):
267 9eb0710b Dionysis Grigoropoulos
            raise api.faults.Conflict("Gateway cannot be in pool range")
268 9eb0710b Dionysis Grigoropoulos
269 9eb0710b Dionysis Grigoropoulos
    # Check if there is a conflict between the IP Poll ranges
270 9eb0710b Dionysis Grigoropoulos
    end = cidr.network
271 9eb0710b Dionysis Grigoropoulos
    for pool in pool_list:
272 9eb0710b Dionysis Grigoropoulos
        if end >= pool[0]:
273 9eb0710b Dionysis Grigoropoulos
            raise api.faults.Conflict("IP Pool range conflict")
274 9eb0710b Dionysis Grigoropoulos
        end = pool[1]
275 f82dfec6 Christos Stavrakakis
276 f82dfec6 Christos Stavrakakis
277 f82dfec6 Christos Stavrakakis
def validate_subnet_params(subnet=None, gateway=None, subnet6=None,
278 f82dfec6 Christos Stavrakakis
                           gateway6=None):
279 f82dfec6 Christos Stavrakakis
    if subnet:
280 f82dfec6 Christos Stavrakakis
        try:
281 f82dfec6 Christos Stavrakakis
            # Use strict option to not all subnets with host bits set
282 f82dfec6 Christos Stavrakakis
            network = ipaddr.IPv4Network(subnet, strict=True)
283 f82dfec6 Christos Stavrakakis
        except ValueError:
284 f82dfec6 Christos Stavrakakis
            raise faults.BadRequest("Invalid network IPv4 subnet")
285 f82dfec6 Christos Stavrakakis
286 f82dfec6 Christos Stavrakakis
        # Check that network size is allowed!
287 f82dfec6 Christos Stavrakakis
        prefixlen = network.prefixlen
288 f82dfec6 Christos Stavrakakis
        if prefixlen > 29 or prefixlen <= settings.MAX_CIDR_BLOCK:
289 f82dfec6 Christos Stavrakakis
            raise faults.OverLimit(
290 f82dfec6 Christos Stavrakakis
                message="Unsupported network size",
291 f82dfec6 Christos Stavrakakis
                details="Netmask must be in range: (%s, 29]" %
292 f82dfec6 Christos Stavrakakis
                settings.MAX_CIDR_BLOCK)
293 f82dfec6 Christos Stavrakakis
        if gateway:  # Check that gateway belongs to network
294 f82dfec6 Christos Stavrakakis
            try:
295 f82dfec6 Christos Stavrakakis
                gateway = ipaddr.IPv4Address(gateway)
296 f82dfec6 Christos Stavrakakis
            except ValueError:
297 f82dfec6 Christos Stavrakakis
                raise faults.BadRequest("Invalid network IPv4 gateway")
298 f82dfec6 Christos Stavrakakis
            if not gateway in network:
299 f82dfec6 Christos Stavrakakis
                raise faults.BadRequest("Invalid network IPv4 gateway")
300 f82dfec6 Christos Stavrakakis
301 f82dfec6 Christos Stavrakakis
    if subnet6:
302 f82dfec6 Christos Stavrakakis
        try:
303 f82dfec6 Christos Stavrakakis
            # Use strict option to not all subnets with host bits set
304 f82dfec6 Christos Stavrakakis
            network6 = ipaddr.IPv6Network(subnet6, strict=True)
305 f82dfec6 Christos Stavrakakis
        except ValueError:
306 f82dfec6 Christos Stavrakakis
            raise faults.BadRequest("Invalid network IPv6 subnet")
307 f82dfec6 Christos Stavrakakis
        # Check that network6 is an /64 subnet, because this is imposed by
308 f82dfec6 Christos Stavrakakis
        # 'mac2eui64' utiity.
309 f82dfec6 Christos Stavrakakis
        if network6.prefixlen != 64:
310 f82dfec6 Christos Stavrakakis
            msg = ("Unsupported IPv6 subnet size. Network netmask must be"
311 f82dfec6 Christos Stavrakakis
                   " /64")
312 f82dfec6 Christos Stavrakakis
            raise faults.BadRequest(msg)
313 f82dfec6 Christos Stavrakakis
        if gateway6:
314 f82dfec6 Christos Stavrakakis
            try:
315 f82dfec6 Christos Stavrakakis
                gateway6 = ipaddr.IPv6Address(gateway6)
316 f82dfec6 Christos Stavrakakis
            except ValueError:
317 f82dfec6 Christos Stavrakakis
                raise faults.BadRequest("Invalid network IPv6 gateway")
318 f82dfec6 Christos Stavrakakis
            if not gateway6 in network6:
319 f82dfec6 Christos Stavrakakis
                raise faults.BadRequest("Invalid network IPv6 gateway")