4
4
#
5
5
import typing
6
6
7
- import netaddr
7
+ import ipaddress
8
8
from box import Box
9
9
10
10
# Related modules
@@ -373,7 +373,7 @@ def set_fhrp_gateway(link: Box, pfx_list: Box, nodes: Box, link_path: str) -> No
373
373
continue
374
374
375
375
try : # Now try to get N-th IP address on that link
376
- link .gateway [af ] = get_nth_ip_from_prefix (netaddr . IPNetwork ( link .prefix [af ]) ,link .gateway .id )
376
+ link .gateway [af ] = addressing . get_nth_ip_from_prefix (link .prefix [af ],link .gateway .id )
377
377
fhrp_assigned = True
378
378
except Exception as ex :
379
379
log .error (
@@ -468,15 +468,15 @@ def assign_link_prefix(
468
468
469
469
Return 'error' if the prefix size is too small
470
470
"""
471
- def get_prefix_IPAM_policy (link : Box , pfx : typing .Union [netaddr . IPNetwork ,bool ], ndict : Box ) -> str :
471
+ def get_prefix_IPAM_policy (link : Box , pfx : typing .Union [ipaddress . _BaseNetwork ,bool ], ndict : Box ) -> str :
472
472
if isinstance (pfx ,bool ):
473
473
return 'unnumbered'
474
474
475
475
gwid = get_gateway_id (link ) or 0 # Get link gateway ID (if set) --- must be int for min to work
476
476
if link .type == 'p2p' and not gwid : # P2P allocation policy cannot be used with default gateway
477
- return 'p2p' if pfx .first != pfx . last else 'error'
477
+ return 'p2p' if pfx .num_addresses > 1 else 'error'
478
478
479
- pfx_size = pfx .last - pfx . first + 1
479
+ pfx_size = pfx .num_addresses
480
480
add_extra_ip = 0
481
481
subtract_reserved_ip = - 2
482
482
@@ -501,19 +501,6 @@ def get_prefix_IPAM_policy(link: Box, pfx: typing.Union[netaddr.IPNetwork,bool],
501
501
502
502
return 'error'
503
503
504
- """
505
- Get Nth IP address in a prefix returned as a nice string with a subnet mask
506
-
507
- *** WARNING *** WARNING *** WARNING ***
508
-
509
- Parent must catch the exception as we don't know what error text to display
510
- """
511
-
512
- def get_nth_ip_from_prefix (pfx : netaddr .IPNetwork , n_id : int ) -> str :
513
- node_addr = netaddr .IPNetwork (pfx [n_id ])
514
- node_addr .prefixlen = pfx .prefixlen
515
- return str (node_addr )
516
-
517
504
"""
518
505
check_interface_host_bits: Check whether the IP addresses on an interface have host bits. The check is disabled
519
506
for special prefixes (IPv4: /31, /32, IPv6: /127, /128)
@@ -533,27 +520,27 @@ def check_interface_host_bits(intf: Box, node: Box, link: typing.Optional[Box] =
533
520
continue
534
521
if not isinstance (intf [af ],str ): # Skip unnumbered interfaces
535
522
continue
536
- pfx = netaddr . IPNetwork (intf [af ])
537
- if pfx [ 0 ]. is_multicast () :
523
+ pfx = ipaddress . ip_interface (intf [af ])
524
+ if pfx . ip . is_multicast :
538
525
log .error (
539
526
f'Interfaces cannot have multicast { af } addresses ({ intf [af ]} on { node .name } /{ intf_name } )' ,
540
527
log .IncorrectValue ,
541
528
'links' )
542
529
OK = False
543
530
continue
544
531
545
- if pfx .last <= pfx . first + 1 : # Are we dealing with special prefix (loopback or /31)
532
+ if pfx .network . num_addresses <= 2 : # Are we dealing with special prefix (loopback or /31)
546
533
continue # ... then it's OK not to have host bits
547
534
548
- if str ( pfx ) == str ( pfx .cidr ): # Does the IP address have host bits -- is it different from its CIDR subnet?
535
+ if pfx . ip == pfx .network . network_address : # Does the IP address have host bits -- is it different from its CIDR subnet?
549
536
log .error (
550
537
f'Address { intf [af ]} on node { node .name } /{ intf_name } does not contain host bits' ,
551
538
log .IncorrectValue ,
552
539
'links' )
553
540
OK = False
554
541
continue
555
542
556
- if str ( pfx [ - 1 ]) == str ( pfx .ip ) and af == 'ipv4' :
543
+ if pfx .ip == pfx . network . broadcast_address :
557
544
log .error (
558
545
f'Address { intf [af ]} on node { node .name } /{ intf_name } is a subnet broadcast address' ,
559
546
log .IncorrectValue ,
@@ -566,7 +553,7 @@ def check_interface_host_bits(intf: Box, node: Box, link: typing.Optional[Box] =
566
553
"""
567
554
Set an interface address based on the link prefix and interface sequential number (could be node.id or counter)
568
555
"""
569
- def set_interface_address (intf : Box , af : str , pfx : netaddr . IPNetwork , node_id : int ) -> bool :
556
+ def set_interface_address (intf : Box , af : str , pfx : ipaddress . _BaseNetwork , node_id : int ) -> bool :
570
557
if af in intf : # Check static interface addresses
571
558
if isinstance (intf [af ],bool ): # unnumbered or unaddressed node, leave it alone
572
559
return True
@@ -575,22 +562,23 @@ def set_interface_address(intf: Box, af: str, pfx: netaddr.IPNetwork, node_id: i
575
562
node_id = intf [af ]
576
563
elif isinstance (intf [af ],str ): # static address specified on the interface
577
564
try :
578
- intf_pfx = netaddr . IPNetwork ( intf [af ]) # Try to parse the interface IP address
579
- if not '/' in intf [af ]:
580
- intf_pfx . prefixlen = pfx . prefixlen # If it lacks a prefix, add link prefix
565
+ if '/' not in intf [af ]: # Add link prefix if needed
566
+ intf [af ] += f'/ { pfx . prefixlen } '
567
+ intf_pfx = ipaddress . ip_interface ( intf [ af ])
581
568
intf [af ] = str (intf_pfx ) # ... and save modified/validated interface IP address
582
569
except Exception as ex :
583
570
log .error (
584
- f'Cannot parse { af } address { intf .af } for node { intf .node } \n ' + strings .extra_data_printout (str (ex )),
585
- log .IncorrectValue ,
586
- 'links' )
571
+ f'Cannot parse { af } address { intf .af } for node { intf .node } ' ,
572
+ more_data = str (ex ),
573
+ category = log .IncorrectValue ,
574
+ module = 'links' )
587
575
return False
588
576
589
577
return True # Further checks done in check_interface_host_bits
590
578
591
579
# No static interface address, or static address specified as relative node_id
592
580
try :
593
- intf [af ] = get_nth_ip_from_prefix (pfx ,node_id )
581
+ intf [af ] = addressing . get_nth_ip_from_prefix (pfx ,node_id )
594
582
return True
595
583
except Exception as ex :
596
584
log .error (
@@ -625,8 +613,8 @@ def IPAM_unnumbered(link: Box, af: str, pfx: typing.Optional[bool], ndict: Box)
625
613
626
614
return OK
627
615
628
- def IPAM_sequential (link : Box , af : str , pfx : netaddr . IPNetwork , ndict : Box ) -> bool :
629
- start = 1 if pfx .last != pfx . first + 1 else 0
616
+ def IPAM_sequential (link : Box , af : str , pfx : ipaddress . _BaseNetwork , ndict : Box ) -> bool :
617
+ start = 1 if pfx .num_addresses > 2 else 0
630
618
gwid = get_gateway_id (link )
631
619
OK = True
632
620
for count ,intf in enumerate (link .interfaces ):
@@ -636,25 +624,25 @@ def IPAM_sequential(link: Box, af: str, pfx: netaddr.IPNetwork, ndict: Box) -> b
636
624
637
625
return OK
638
626
639
- def IPAM_p2p (link : Box , af : str , pfx : netaddr . IPNetwork , ndict : Box ) -> bool :
640
- start = 1 if pfx .last != pfx . first + 1 else 0
627
+ def IPAM_p2p (link : Box , af : str , pfx : ipaddress . _BaseNetwork , ndict : Box ) -> bool :
628
+ start = 1 if pfx .num_addresses > 2 else 0
641
629
OK = True
642
630
for count ,intf in enumerate (sorted (link .interfaces , key = lambda intf : intf .node )):
643
631
OK = set_interface_address (intf ,af ,pfx ,count + start ) and OK
644
632
645
633
return OK
646
634
647
- def IPAM_id_based (link : Box , af : str , pfx : netaddr . IPNetwork , ndict : Box ) -> bool :
635
+ def IPAM_id_based (link : Box , af : str , pfx : ipaddress . _BaseNetwork , ndict : Box ) -> bool :
648
636
OK = True
649
637
for intf in link .interfaces :
650
638
OK = set_interface_address (intf ,af ,pfx ,ndict [intf .node ].id ) and OK
651
639
652
640
return OK
653
641
654
- def IPAM_loopback (link : Box , af : str , pfx : netaddr . IPNetwork , ndict : Box ) -> bool :
642
+ def IPAM_loopback (link : Box , af : str , pfx : ipaddress . _BaseNetwork , ndict : Box ) -> bool :
655
643
for intf in link .interfaces :
656
- pfx . prefixlen = 128 if ':' in str ( pfx ) else 32
657
- intf [af ] = str (pfx )
644
+ prefixlen = 128 if af == 'ipv6' else 32
645
+ intf [af ] = f' { str (pfx . network_address ) } / { prefixlen } '
658
646
659
647
return True
660
648
@@ -699,14 +687,13 @@ def assign_interface_addresses(link: Box, addr_pools: Box, ndict: Box, defaults:
699
687
pfx_net = pfx_list [af ]
700
688
else :
701
689
try : # Parse the AF prefix
702
- pfx_net = netaddr . IPNetwork (pfx_list [af ])
690
+ pfx_net = ipaddress . ip_network (pfx_list [af ])
703
691
except Exception as ex : # Report an error and move on if it cannot be parsed
704
692
log .error (
705
- f'Cannot parse { af } prefix { pfx_list [af ]} on { link ._linkname } \n ' + \
706
- strings .extra_data_printout (f'{ ex } ' ) + '\n ' + \
707
- strings .extra_data_printout (f'{ link } ' ),
708
- log .IncorrectValue ,
709
- 'links' )
693
+ f'Cannot parse { af } prefix { pfx_list [af ]} on { link ._linkname } ' ,
694
+ more_data = [ str (ex ), str (link ) ],
695
+ category = log .IncorrectValue ,
696
+ module = 'links' )
710
697
error = True
711
698
continue
712
699
0 commit comments