Skip to content

Commit bc34540

Browse files
authored
Merge pull request #3483 from sever-sever/T6364
T6364: CGNAT drop hard limit that allows only one translation rule
2 parents 65c8e9e + 2371c26 commit bc34540

File tree

2 files changed

+67
-44
lines changed

2 files changed

+67
-44
lines changed

interface-definitions/nat_cgnat.xml.in

+1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@
123123
<validator name="ipv4-host"/>
124124
<validator name="ipv4-range"/>
125125
</constraint>
126+
<multi/>
126127
</properties>
127128
</leafNode>
128129
</children>

src/conf_mode/nat_cgnat.py

+66-44
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,6 @@ def verify(config):
189189
if 'rule' not in config:
190190
raise ConfigError(f'Rule must be defined!')
191191

192-
# As PoC allow only one rule for CGNAT translations
193-
# one internal pool and one external pool
194-
if len(config['rule']) > 1:
195-
raise ConfigError(f'Only one rule is allowed for translations!')
196-
197192
for pool in ('external', 'internal'):
198193
if pool not in config['pool']:
199194
raise ConfigError(f'{pool} pool must be defined!')
@@ -208,6 +203,8 @@ def verify(config):
208203
internal_pools_query = "keys(pool.internal)"
209204
internal_pools: list = jmespath.search(internal_pools_query, config)
210205

206+
used_external_pools = {}
207+
used_internal_pools = {}
211208
for rule, rule_config in config['rule'].items():
212209
if 'source' not in rule_config:
213210
raise ConfigError(f'Rule "{rule}" source pool must be defined!')
@@ -217,57 +214,82 @@ def verify(config):
217214
if 'translation' not in rule_config:
218215
raise ConfigError(f'Rule "{rule}" translation pool must be defined!')
219216

217+
# Check if pool exists
220218
internal_pool = rule_config['source']['pool']
221219
if internal_pool not in internal_pools:
222220
raise ConfigError(f'Internal pool "{internal_pool}" does not exist!')
223-
224221
external_pool = rule_config['translation']['pool']
225222
if external_pool not in external_pools:
226223
raise ConfigError(f'External pool "{external_pool}" does not exist!')
227224

225+
# Check pool duplication in different rules
226+
if external_pool in used_external_pools:
227+
raise ConfigError(
228+
f'External pool "{external_pool}" is already used in rule '
229+
f'{used_external_pools[external_pool]} and cannot be used in '
230+
f'rule {rule}!'
231+
)
232+
233+
if internal_pool in used_internal_pools:
234+
raise ConfigError(
235+
f'Internal pool "{internal_pool}" is already used in rule '
236+
f'{used_internal_pools[internal_pool]} and cannot be used in '
237+
f'rule {rule}!'
238+
)
239+
240+
used_external_pools[external_pool] = rule
241+
used_internal_pools[internal_pool] = rule
242+
228243

229244
def generate(config):
230245
if not config:
231246
return None
232-
# first external pool as we allow only one as PoC
233-
ext_pool_name = jmespath.search("rule.*.translation | [0]", config).get('pool')
234-
int_pool_name = jmespath.search("rule.*.source | [0]", config).get('pool')
235-
ext_query = f'pool.external."{ext_pool_name}".range | keys(@)'
236-
int_query = f'pool.internal."{int_pool_name}".range'
237-
external_ranges = jmespath.search(ext_query, config)
238-
internal_ranges = [jmespath.search(int_query, config)]
239-
240-
external_list_count = []
241-
external_list_hosts = []
242-
internal_list_count = []
243-
internal_list_hosts = []
244-
for ext_range in external_ranges:
245-
# External hosts count
246-
e_count = IPOperations(ext_range).get_ips_count()
247-
external_list_count.append(e_count)
248-
# External hosts list
249-
e_hosts = IPOperations(ext_range).convert_prefix_to_list_ips()
250-
external_list_hosts.extend(e_hosts)
251-
for int_range in internal_ranges:
252-
# Internal hosts count
253-
i_count = IPOperations(int_range).get_ips_count()
254-
internal_list_count.append(i_count)
255-
# Internal hosts list
256-
i_hosts = IPOperations(int_range).convert_prefix_to_list_ips()
257-
internal_list_hosts.extend(i_hosts)
258-
259-
external_host_count = sum(external_list_count)
260-
internal_host_count = sum(internal_list_count)
261-
ports_per_user = int(
262-
jmespath.search(f'pool.external."{ext_pool_name}".per_user_limit.port', config)
263-
)
264-
external_port_range: str = jmespath.search(
265-
f'pool.external."{ext_pool_name}".external_port_range', config
266-
)
267247

268-
proto_maps, other_maps = generate_port_rules(
269-
external_list_hosts, internal_list_hosts, ports_per_user, external_port_range
270-
)
248+
proto_maps = []
249+
other_maps = []
250+
251+
for rule, rule_config in config['rule'].items():
252+
ext_pool_name: str = rule_config['translation']['pool']
253+
int_pool_name: str = rule_config['source']['pool']
254+
255+
external_ranges: list = [range for range in config['pool']['external'][ext_pool_name]['range']]
256+
internal_ranges: list = [range for range in config['pool']['internal'][int_pool_name]['range']]
257+
external_list_hosts_count = []
258+
external_list_hosts = []
259+
internal_list_hosts_count = []
260+
internal_list_hosts = []
261+
262+
for ext_range in external_ranges:
263+
# External hosts count
264+
e_count = IPOperations(ext_range).get_ips_count()
265+
external_list_hosts_count.append(e_count)
266+
# External hosts list
267+
e_hosts = IPOperations(ext_range).convert_prefix_to_list_ips()
268+
external_list_hosts.extend(e_hosts)
269+
270+
for int_range in internal_ranges:
271+
# Internal hosts count
272+
i_count = IPOperations(int_range).get_ips_count()
273+
internal_list_hosts_count.append(i_count)
274+
# Internal hosts list
275+
i_hosts = IPOperations(int_range).convert_prefix_to_list_ips()
276+
internal_list_hosts.extend(i_hosts)
277+
278+
external_host_count = sum(external_list_hosts_count)
279+
internal_host_count = sum(internal_list_hosts_count)
280+
ports_per_user = int(
281+
jmespath.search(f'pool.external."{ext_pool_name}".per_user_limit.port', config)
282+
)
283+
external_port_range: str = jmespath.search(
284+
f'pool.external."{ext_pool_name}".external_port_range', config
285+
)
286+
287+
rule_proto_maps, rule_other_maps = generate_port_rules(
288+
external_list_hosts, internal_list_hosts, ports_per_user, external_port_range
289+
)
290+
291+
proto_maps.extend(rule_proto_maps)
292+
other_maps.extend(rule_other_maps)
271293

272294
config['proto_map_elements'] = ', '.join(proto_maps)
273295
config['other_map_elements'] = ', '.join(other_maps)

0 commit comments

Comments
 (0)