blob: 8c3bbba307aa0346bc2191e9513d7081854ee080 [file] [log] [blame]
Neale Rannsd0df49f2018-08-08 01:06:40 -07001"""
2 IP Types
3
4"""
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -08005import logging
Neale Rannsd0df49f2018-08-08 01:06:40 -07006
7from ipaddress import ip_address
Neale Rannsc0a93142018-09-05 15:42:26 -07008from socket import AF_INET, AF_INET6
Ole Troan0685da42018-10-16 14:42:50 +02009from vpp_papi import VppEnum
Paul Vinciguerra9e315952019-01-29 11:51:44 -080010try:
11 text_type = unicode
12except NameError:
13 text_type = str
Neale Rannsd0df49f2018-08-08 01:06:40 -070014
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080015_log = logging.getLogger(__name__)
16
Neale Rannsd0df49f2018-08-08 01:06:40 -070017
Neale Rannsc0a93142018-09-05 15:42:26 -070018class DpoProto:
19 DPO_PROTO_IP4 = 0
20 DPO_PROTO_IP6 = 1
21 DPO_PROTO_MPLS = 2
22 DPO_PROTO_ETHERNET = 3
23 DPO_PROTO_BIER = 4
24 DPO_PROTO_NSH = 5
25
26
Neale Rannsd0df49f2018-08-08 01:06:40 -070027INVALID_INDEX = 0xffffffff
28
29
Neale Rannsefd7bc22019-11-11 08:32:34 +000030def get_dpo_proto(addr):
31 if ip_address(addr).version == 6:
32 return DpoProto.DPO_PROTO_IP6
33 else:
34 return DpoProto.DPO_PROTO_IP4
35
36
Neale Rannsd0df49f2018-08-08 01:06:40 -070037class VppIpAddressUnion():
38 def __init__(self, addr):
39 self.addr = addr
Paul Vinciguerra9e315952019-01-29 11:51:44 -080040 self.ip_addr = ip_address(text_type(self.addr))
Neale Rannsd0df49f2018-08-08 01:06:40 -070041
Neale Rannsd0df49f2018-08-08 01:06:40 -070042 def encode(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080043 if self.version == 6:
Neale Ranns097fa662018-05-01 05:17:55 -070044 return {'ip6': self.ip_addr}
Neale Rannsd0df49f2018-08-08 01:06:40 -070045 else:
Neale Ranns097fa662018-05-01 05:17:55 -070046 return {'ip4': self.ip_addr}
Neale Rannsd0df49f2018-08-08 01:06:40 -070047
Neale Rannsc0a93142018-09-05 15:42:26 -070048 @property
49 def version(self):
50 return self.ip_addr.version
51
52 @property
53 def address(self):
54 return self.addr
55
56 @property
57 def length(self):
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080058 return self.ip_addr.max_prefixlen
Neale Rannsc0a93142018-09-05 15:42:26 -070059
60 @property
61 def bytes(self):
62 return self.ip_addr.packed
63
64 def __eq__(self, other):
65 if isinstance(other, self.__class__):
66 return self.ip_addr == other.ip_addr
67 elif hasattr(other, "ip4") and hasattr(other, "ip6"):
68 # vl_api_address_union_t
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080069 if 4 == self.version:
Ole Troan8c8acc02018-11-27 10:05:23 +010070 return self.ip_addr.packed == other.ip4
Neale Rannsc0a93142018-09-05 15:42:26 -070071 else:
Ole Troan8c8acc02018-11-27 10:05:23 +010072 return self.ip_addr.packed == other.ip6
Neale Rannsc0a93142018-09-05 15:42:26 -070073 else:
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080074 _log.error("Comparing VppIpAddressUnions:%s"
75 " with incomparable type: %s",
76 self, other)
77 return NotImplemented
Neale Rannsc0a93142018-09-05 15:42:26 -070078
Neale Ranns097fa662018-05-01 05:17:55 -070079 def __str__(self):
80 return str(self.ip_addr)
81
Neale Rannsd0df49f2018-08-08 01:06:40 -070082
Neale Rannsd0df49f2018-08-08 01:06:40 -070083class VppIpMPrefix():
Neale Ranns097fa662018-05-01 05:17:55 -070084 def __init__(self, saddr, gaddr, glen):
Neale Rannsd0df49f2018-08-08 01:06:40 -070085 self.saddr = saddr
86 self.gaddr = gaddr
Neale Ranns097fa662018-05-01 05:17:55 -070087 self.glen = glen
Neale Rannsefd7bc22019-11-11 08:32:34 +000088 if ip_address(self.saddr).version != \
89 ip_address(self.gaddr).version:
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080090 raise ValueError('Source and group addresses must be of the '
91 'same address family.')
Neale Rannsd0df49f2018-08-08 01:06:40 -070092
93 def encode(self):
Neale Rannsefd7bc22019-11-11 08:32:34 +000094 if 6 == self.version:
Neale Rannsd0df49f2018-08-08 01:06:40 -070095 prefix = {
Ole Troan0685da42018-10-16 14:42:50 +020096 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP6,
Neale Ranns097fa662018-05-01 05:17:55 -070097 'grp_address': {
98 'ip6': self.gaddr
99 },
100 'src_address': {
101 'ip6': self.saddr
102 },
103 'grp_address_length': self.glen,
Neale Rannsd0df49f2018-08-08 01:06:40 -0700104 }
105 else:
106 prefix = {
Ole Troan0685da42018-10-16 14:42:50 +0200107 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP4,
Neale Ranns097fa662018-05-01 05:17:55 -0700108 'grp_address': {
109 'ip4': self.gaddr
110 },
111 'src_address': {
112 'ip4': self.saddr
113 },
114 'grp_address_length': self.glen,
Neale Rannsd0df49f2018-08-08 01:06:40 -0700115 }
116 return prefix
Neale Ranns097fa662018-05-01 05:17:55 -0700117
118 @property
119 def length(self):
120 return self.glen
121
122 @property
123 def version(self):
Neale Rannsefd7bc22019-11-11 08:32:34 +0000124 return ip_address(self.gaddr).version
Neale Ranns097fa662018-05-01 05:17:55 -0700125
126 def __str__(self):
127 return "(%s,%s)/%d" % (self.saddr, self.gaddr, self.glen)
128
129 def __eq__(self, other):
130 if isinstance(other, self.__class__):
131 return (self.glen == other.glen and
Neale Rannsefd7bc22019-11-11 08:32:34 +0000132 self.saddr == other.gaddr and
133 self.saddr == other.saddr)
Neale Ranns097fa662018-05-01 05:17:55 -0700134 elif (hasattr(other, "grp_address_length") and
135 hasattr(other, "grp_address") and
136 hasattr(other, "src_address")):
137 # vl_api_mprefix_t
Neale Rannsefd7bc22019-11-11 08:32:34 +0000138 if 4 == self.version:
139 return (self.glen == other.grp_address_length and
140 self.gaddr == str(other.grp_address.ip4) and
141 self.saddr == str(other.src_address.ip4))
Neale Ranns097fa662018-05-01 05:17:55 -0700142 else:
143 return (self.glen == other.grp_address_length and
Neale Rannsefd7bc22019-11-11 08:32:34 +0000144 self.gaddr == str(other.grp_address.ip6) and
145 self.saddr == str(other.src_address.ip6))
Neale Ranns097fa662018-05-01 05:17:55 -0700146 else:
147 raise Exception("Comparing VppIpPrefix:%s with unknown type: %s" %
148 (self, other))
149 return False