@@ -72,7 +72,7 @@ def get_net(net, depth=-1):
72
72
c = db_conn .cursor ()
73
73
c .execute ("SELECT net, address, netmask FROM networks "
74
74
"WHERE netmask >= ? AND address >= ? AND "
75
- "address <= ? ORDER BY netmask, address ASC" ,
75
+ "address <= ? ORDER BY address ASC, netmask ASC" ,
76
76
(network .prefixlen ,
77
77
network_address_to_int (network ),
78
78
network_broadcast_to_int (network )))
@@ -81,7 +81,7 @@ def get_net(net, depth=-1):
81
81
# raise_fault("NetworkNotInDatabase")
82
82
83
83
if len (results ) == 0 or results [0 ]["net" ] != str (network ):
84
- ret = { "address" : network .network_address ,
84
+ ret = { "address" : str ( network .network_address ) ,
85
85
"cidr" : str (network ),
86
86
"netmask" : network .prefixlen ,
87
87
"children" : list (),
@@ -177,21 +177,32 @@ def claim_net(net, size):
177
177
network = ip_network (net )
178
178
required_gap = 2 ** (network .max_prefixlen - size )
179
179
180
- if size > network . max_prefixlen - network .prefixlen :
180
+ if size < network .prefixlen :
181
181
raise_fault ("NoMatchingGapAvailable" )
182
182
183
183
nets = get_net (net , depth = 1 )
184
184
185
185
if len (nets ["children" ]) == 0 :
186
- add_net (net )
187
- return get_net (net , depth = 0 )
186
+ network_string = str (network .network_address ) + "/" + str (size )
187
+ add_net (network_string )
188
+ return get_net (network_string , depth = 0 )
188
189
else : #at least one child exists.
190
+
191
+ def next_start_address (net , size ):
192
+ if size >= net .prefixlen :
193
+ start_addr = network_broadcast_to_int (net ) + 1
194
+ else :
195
+ size_diff = net .prefixlen - size
196
+ supernet = net .supernet (size_diff )
197
+ start_addr = int (supernet .network_address ) + 2 ** (supernet .max_prefixlen - supernet .prefixlen )
198
+ return start_addr
199
+
189
200
smallest_gap = None
201
+
190
202
# start and end gaps
191
203
first_block = ip_network (nets ["children" ][0 ]["cidr" ])
192
- last_block = ip_network (nets ["children" ][- 1 ]["cidr" ])
193
204
first_gap = network_address_to_int (first_block ) - network_address_to_int (network )
194
- last_gap = network_broadcast_to_int ( network ) - network_broadcast_to_int ( last_block ) - 1
205
+
195
206
if first_gap >= required_gap :
196
207
smallest_gap = { "address" : network .network_address ,
197
208
"length" : first_gap }
@@ -200,12 +211,18 @@ def claim_net(net, size):
200
211
for i , n in enumerate (nets ["children" ][:- 1 ]):
201
212
net1 = ip_network (n ["cidr" ])
202
213
net2 = ip_network (nets ["children" ][i + 1 ]["cidr" ])
203
- gap = network_address_to_int (net2 ) - network_broadcast_to_int (net1 ) - 1
214
+ start_addr = next_start_address (net1 , size )
215
+ gap = network_address_to_int (net2 ) - start_addr
204
216
if gap >= required_gap and (smallest_gap is None or gap < smallest_gap ["length" ]):
205
- smallest_gap = {"address" : ip_address (network_broadcast_to_int ( net1 ) + 1 ),
217
+ smallest_gap = {"address" : ip_address (start_addr ),
206
218
"length" : gap }
207
- if last_gap > required_gap and (smallest_gap is None or last_gap < smallest_gap ["length" ]):
208
- smallest_gap = { "address" : ip_address (network_broadcast_to_int (last_block ) + 1 ),
219
+
220
+ # the last gap
221
+ last_block = ip_network (nets ["children" ][- 1 ]["cidr" ])
222
+ last_gap_start = next_start_address (last_block , size )
223
+ last_gap = network_broadcast_to_int (network ) - last_gap_start + 1
224
+ if last_gap >= required_gap and (smallest_gap is None or last_gap < smallest_gap ["length" ]):
225
+ smallest_gap = { "address" : ip_address (last_gap_start ),
209
226
"length" :last_gap }
210
227
211
228
if smallest_gap is None :
0 commit comments