mirror of
https://github.com/CumulusNetworks/ifupdown2.git
synced 2024-05-06 15:54:50 +00:00
nlmanager: ipnetwork: don't set prefixlen flag if prefix has default value
nlmanager: ipnetwork: fix 'IPv4Address' object has no attribute 'split' exception nlpacket: use IP[v4|6]Address object when network mask is not provided or needed nlpacket: AttributeIPAddress: fix decode handler for Routes During the python2 to 3 migration there was some refactoring Seems like some code specific to Route-decoding was removed This patch is fixing the issue by re-adding this code and tweaking it a little bit (to make it nice and clean :)) Signed-off-by: Julien Fortin <julien@cumulusnetworks.com>
This commit is contained in:
@@ -27,16 +27,25 @@ class IPNetwork:
|
||||
|
||||
__INIT_WITH_PREFIXLEN = 0b01
|
||||
|
||||
def __init__(self, ip, prefixlen=None, scope=0):
|
||||
ip_family_handler = {
|
||||
0: ipaddress.ip_address,
|
||||
4: ipaddress.IPv4Address,
|
||||
6: ipaddress.IPv6Address
|
||||
}
|
||||
|
||||
def __init__(self, ip, prefixlen=None, scope=0, family=0):
|
||||
|
||||
if isinstance(ip, IPNetwork):
|
||||
prefixlen = ip.prefixlen
|
||||
scope = ip.scope
|
||||
family = ip.version
|
||||
ip = ip.ip
|
||||
|
||||
self.__scope = scope
|
||||
self.__flags = 0
|
||||
|
||||
if isinstance(ip, int):
|
||||
self._ip = ipaddress.ip_address(ip)
|
||||
ip = str(self._ip)
|
||||
elif isinstance(ip, IPNetwork):
|
||||
self._ip = ip._ip
|
||||
self.__prefixlen = ip.prefixlen
|
||||
self._ip = self.ip_family_handler[family](ip)
|
||||
else:
|
||||
if not prefixlen:
|
||||
try:
|
||||
@@ -53,11 +62,12 @@ class IPNetwork:
|
||||
self.__prefixlen = int(prefixlen)
|
||||
except ValueError:
|
||||
if isinstance(prefixlen, str) and "." in prefixlen:
|
||||
self.__prefixlen = ipaddress.ip_network("{}/{}".format(ip, prefixlen), strict=False).prefixlen
|
||||
self.__prefixlen = ipaddress.ip_network("{}/{}".format(self.ip, prefixlen), strict=False).prefixlen
|
||||
else:
|
||||
raise
|
||||
|
||||
self.__flags |= self.__INIT_WITH_PREFIXLEN
|
||||
if (self.ip.version == 4 and self.prefixlen != 32) or (self.ip.version == 6 and self.prefixlen != 128):
|
||||
self.__flags |= self.__INIT_WITH_PREFIXLEN
|
||||
|
||||
def __hash__(self):
|
||||
return int(self._ip) ^ self.__prefixlen ^ self.version
|
||||
@@ -105,7 +115,7 @@ class IPNetwork:
|
||||
|
||||
class IPv4Network(IPNetwork):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(IPv4Network, self).__init__(*args, **kwargs)
|
||||
super(IPv4Network, self).__init__(family=4, *args, **kwargs)
|
||||
|
||||
if self.version != 4:
|
||||
self._ip = ipaddress.IPv4Address(self._ip)
|
||||
@@ -113,7 +123,7 @@ class IPv4Network(IPNetwork):
|
||||
|
||||
class IPv6Network(IPNetwork):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(IPv6Network, self).__init__(*args, **kwargs)
|
||||
super(IPv6Network, self).__init__(family=6, *args, **kwargs)
|
||||
|
||||
if self.version != 6:
|
||||
self._ip = ipaddress.IPv6Address(self._ip)
|
||||
@@ -151,3 +161,11 @@ class IPv4Address(IPv4Network):
|
||||
def __repr__(self):
|
||||
return str(self._ip)
|
||||
|
||||
|
||||
class IPv6Address(IPv6Network):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(IPv6Address, self).__init__(*args, **kwargs)
|
||||
self.ignore_prefixlen()
|
||||
|
||||
def __repr__(self):
|
||||
return str(self._ip)
|
||||
|
@@ -1053,12 +1053,12 @@ class Attribute(object):
|
||||
|
||||
@staticmethod
|
||||
def decode_ipv4_address_attribute(data, _=None):
|
||||
return ipnetwork.IPNetwork(unpack(">L", data[4:8])[0])
|
||||
return ipnetwork.IPv4Address(unpack(">L", data[4:8])[0])
|
||||
|
||||
@staticmethod
|
||||
def decode_ipv6_address_attribute(data, _=None):
|
||||
(data1, data2) = unpack(">QQ", data[4:20])
|
||||
return ipnetwork.IPNetwork(data1 << 64 | data2)
|
||||
return ipnetwork.IPv6Address(data1 << 64 | data2)
|
||||
|
||||
@staticmethod
|
||||
def decode_bond_ad_info_attribute(data, info_data_end):
|
||||
@@ -1391,11 +1391,11 @@ class AttributeIPAddress(Attribute):
|
||||
prefixlen = parent_msg.dst_len
|
||||
|
||||
if self.family in (AF_INET, AF_BRIDGE):
|
||||
self.value = ipnetwork.IPNetwork(unpack(self.PACK, self.data[4:])[0], prefixlen, scope)
|
||||
self.value = ipnetwork.IPv4Network(unpack(self.PACK, self.data[4:])[0], prefixlen, scope)
|
||||
|
||||
elif self.family == AF_INET6:
|
||||
(data1, data2) = unpack(self.PACK, self.data[4:])
|
||||
self.value = ipnetwork.IPNetwork(data1 << 64 | data2, prefixlen, scope)
|
||||
self.value = ipnetwork.IPv6Network(data1 << 64 | data2, prefixlen, scope)
|
||||
|
||||
else:
|
||||
self.log.debug("AttributeIPAddress: decode: unsupported address family ({})".format(self.family))
|
||||
@@ -1437,6 +1437,12 @@ class AttributeIPAddress(Attribute):
|
||||
return line_number
|
||||
|
||||
|
||||
class AttributeIPAddressNoMask(AttributeIPAddress):
|
||||
def decode(self, *args, **kwargs):
|
||||
super(AttributeIPAddressNoMask, self).decode(*args, **kwargs)
|
||||
self.value = self.value.ip
|
||||
|
||||
|
||||
class AttributeMACAddress(Attribute):
|
||||
|
||||
def __init__(self, atype, string, family, logger):
|
||||
@@ -1453,7 +1459,7 @@ class AttributeMACAddress(Attribute):
|
||||
try:
|
||||
# GRE interface uses a 4-byte IP address for this attribute
|
||||
if self.length == 8:
|
||||
self.value = ipnetwork.IPNetwork(unpack('>L', self.data[4:])[0])
|
||||
self.value = ipnetwork.IPv4Address(unpack('>L', self.data[4:])[0])
|
||||
|
||||
# MAC Address
|
||||
elif self.length == 10:
|
||||
@@ -1462,7 +1468,7 @@ class AttributeMACAddress(Attribute):
|
||||
self.value = mac_int_to_str(self.raw)
|
||||
# GREv6 interface uses a 16-byte IP address for this attribute
|
||||
elif self.length == 20:
|
||||
self.value = ipnetwork.IPNetwork(unpack('>L', self.data[16:])[0])
|
||||
self.value = ipnetwork.IPv6Address(unpack('>L', self.data[16:])[0])
|
||||
|
||||
else:
|
||||
self.log.info("Length of MACAddress attribute not supported: %d" % self.length)
|
||||
@@ -1959,14 +1965,14 @@ struct rtnexthop {
|
||||
if self.family == AF_INET:
|
||||
if len(data) < self.IPV4_LEN:
|
||||
break
|
||||
nexthop = ipnetwork.IPNetwork(unpack('>L', data[:self.IPV4_LEN])[0])
|
||||
nexthop = ipnetwork.IPv4Address(unpack('>L', data[:self.IPV4_LEN])[0])
|
||||
self.value.append((nexthop, rtnh_ifindex, rtnh_flags, rtnh_hops))
|
||||
|
||||
elif self.family == AF_INET6:
|
||||
if len(data) < self.IPV6_LEN:
|
||||
break
|
||||
(data1, data2) = unpack('>QQ', data[:self.IPV6_LEN])
|
||||
nexthop = ipnetwork.IPNetwork(data1 << 64 | data2)
|
||||
nexthop = ipnetwork.IPv6Address(data1 << 64 | data2)
|
||||
self.value.append((nexthop, rtnh_ifindex, rtnh_flags, rtnh_hops))
|
||||
|
||||
data = data[(rtnh_len-self.RTNH_LEN-self.HEADER_LEN):]
|
||||
@@ -2845,8 +2851,7 @@ class AttributeIFLA_LINKINFO(Attribute):
|
||||
sub_attr_payload[sub_attr_length_index] = sub_attr_length
|
||||
|
||||
# add padding
|
||||
for x in range(self.pad_bytes_needed(sub_attr_length)):
|
||||
sub_attr_pack_layout.append('x')
|
||||
sub_attr_pack_layout[-1] = "%s%s" % (sub_attr_pack_layout[-1], "x" * self.pad_bytes_needed(sub_attr_length))
|
||||
|
||||
# The [1:] is to remove the leading = so that when we do the ''.join() later
|
||||
# we do not end up with an = in the middle of the pack layout string. There
|
||||
@@ -3088,7 +3093,6 @@ class AttributeIFLA_PROTINFO(Attribute):
|
||||
#
|
||||
# Until we cross that bridge though we will keep things nice and simple and
|
||||
# pack everything via a single pack() call.
|
||||
|
||||
for (sub_attr_type, sub_attr_value) in self.value.items():
|
||||
sub_attr_pack_layout = ['=', 'HH']
|
||||
sub_attr_payload = [0, sub_attr_type]
|
||||
@@ -4502,10 +4506,10 @@ class AttributeMDBA_MDB(Attribute):
|
||||
info = [ifindex,state,flags,vid]
|
||||
proto = unpack('=H',sub_attr_data[28:30])[0]
|
||||
if proto == htons(ETH_P_IP):
|
||||
ip_addr = ipnetwork.IPNetwork(unpack('>L', sub_attr_data[12:16])[0])
|
||||
ip_addr = ipnetwork.IPv4Address(unpack('>L', sub_attr_data[12:16])[0])
|
||||
else:
|
||||
(data1, data2) = unpack('>QQ',sub_attr_data[12:28])
|
||||
ip_addr = ipnetwork.IPNetwork(data1 << 64 | data2)
|
||||
ip_addr = ipnetwork.IPv6Address(data1 << 64 | data2)
|
||||
|
||||
info.append(ip_addr)
|
||||
|
||||
@@ -4540,10 +4544,10 @@ class AttributeMDBA_MDB(Attribute):
|
||||
info = list(info)
|
||||
proto = unpack('=H',sub_attr_data[28:30])[0]
|
||||
if proto == 8:
|
||||
ip_addr = ipnetwork.IPNetwork(unpack('>L', sub_attr_data[12:16])[0])
|
||||
ip_addr = ipnetwork.IPv4Address(unpack('>L', sub_attr_data[12:16])[0])
|
||||
else:
|
||||
(data1, data2) = unpack('>QQ',sub_attr_data[12:28])
|
||||
ip_addr = ipnetwork.IPNetwork(data1 << 64 | data2)
|
||||
ip_addr = ipnetwork.IPv6Address(data1 << 64 | data2)
|
||||
|
||||
info.append(ip_addr)
|
||||
self.value[MDB.MDBA_MDB_ENTRY][MDB.MDBA_MDB_ENTRY_INFO] = info
|
||||
@@ -4677,7 +4681,7 @@ class AttributeMDBA_SET_ENTRY(Attribute):
|
||||
elif proto == htons(ETH_P_IPV6):
|
||||
self.PACK = '=IBBHQQHxx'
|
||||
(ifindex, flags, state,vid, data1,data2, proto) = unpack(self.PACK, self.data[4:])
|
||||
ip = ipnetwork.IPNetwork(data1 << 64 | data2)
|
||||
ip = ipnetwork.IPv6Address(data1 << 64 | data2)
|
||||
else:
|
||||
raise Exception("%d Invalid Proto" % proto)
|
||||
self.LEN = calcsize(self.PACK)
|
||||
@@ -4951,7 +4955,7 @@ class Neighbor(NetlinkPacket):
|
||||
|
||||
attribute_to_class = {
|
||||
NDA_UNSPEC : ('NDA_UNSPEC', AttributeGeneric),
|
||||
NDA_DST : ('NDA_DST', AttributeIPAddress),
|
||||
NDA_DST : ('NDA_DST', AttributeIPAddressNoMask),
|
||||
NDA_LLADDR : ('NDA_LLADDR', AttributeMACAddress),
|
||||
NDA_CACHEINFO : ('NDA_CACHEINFO', AttributeFourByteList),
|
||||
NDA_PROBES : ('NDA_PROBES', AttributeFourByteValue),
|
||||
@@ -5300,7 +5304,7 @@ class Route(NetlinkPacket):
|
||||
dst = self.get_attribute_value(self.RTA_DST)
|
||||
|
||||
if dst:
|
||||
return "%s/%d" % (dst, self.src_len)
|
||||
return "%s" % dst
|
||||
else:
|
||||
if self.family == AF_INET:
|
||||
return "0.0.0.0/0"
|
||||
|
Reference in New Issue
Block a user