blob: 43af5e09c07c45d3eb208845f39c5f73ea71c957 [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:
Neale Ranns9db6ada2019-11-08 12:42:31 +000070 return self.ip_addr == other.ip4
Neale Rannsc0a93142018-09-05 15:42:26 -070071 else:
Neale Ranns9db6ada2019-11-08 12:42:31 +000072 return self.ip_addr == other.ip6
Neale Rannsc0a93142018-09-05 15:42:26 -070073 else:
Neale Ranns9db6ada2019-11-08 12:42:31 +000074 raise Exception("Comparing VppIpAddressUnions:%s"
75 " with incomparable type: %s",
76 self, other)
77
78 def __ne__(self, other):
79 return not (self == other)
Neale Rannsc0a93142018-09-05 15:42:26 -070080
Neale Ranns097fa662018-05-01 05:17:55 -070081 def __str__(self):
82 return str(self.ip_addr)
83
Neale Rannsd0df49f2018-08-08 01:06:40 -070084
Neale Rannsd0df49f2018-08-08 01:06:40 -070085class VppIpMPrefix():
Neale Ranns097fa662018-05-01 05:17:55 -070086 def __init__(self, saddr, gaddr, glen):
Neale Rannsd0df49f2018-08-08 01:06:40 -070087 self.saddr = saddr
88 self.gaddr = gaddr
Neale Ranns097fa662018-05-01 05:17:55 -070089 self.glen = glen
Neale Rannsefd7bc22019-11-11 08:32:34 +000090 if ip_address(self.saddr).version != \
91 ip_address(self.gaddr).version:
Paul Vinciguerraa3aaa612018-12-09 08:52:14 -080092 raise ValueError('Source and group addresses must be of the '
93 'same address family.')
Neale Rannsd0df49f2018-08-08 01:06:40 -070094
95 def encode(self):
Neale Rannsefd7bc22019-11-11 08:32:34 +000096 if 6 == self.version:
Neale Rannsd0df49f2018-08-08 01:06:40 -070097 prefix = {
Ole Troan0685da42018-10-16 14:42:50 +020098 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP6,
Neale Ranns097fa662018-05-01 05:17:55 -070099 'grp_address': {
100 'ip6': self.gaddr
101 },
102 'src_address': {
103 'ip6': self.saddr
104 },
105 'grp_address_length': self.glen,
Neale Rannsd0df49f2018-08-08 01:06:40 -0700106 }
107 else:
108 prefix = {
Ole Troan0685da42018-10-16 14:42:50 +0200109 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP4,
Neale Ranns097fa662018-05-01 05:17:55 -0700110 'grp_address': {
111 'ip4': self.gaddr
112 },
113 'src_address': {
114 'ip4': self.saddr
115 },
116 'grp_address_length': self.glen,
Neale Rannsd0df49f2018-08-08 01:06:40 -0700117 }
118 return prefix
Neale Ranns097fa662018-05-01 05:17:55 -0700119
120 @property
121 def length(self):
122 return self.glen
123
124 @property
125 def version(self):
Neale Rannsefd7bc22019-11-11 08:32:34 +0000126 return ip_address(self.gaddr).version
Neale Ranns097fa662018-05-01 05:17:55 -0700127
128 def __str__(self):
129 return "(%s,%s)/%d" % (self.saddr, self.gaddr, self.glen)
130
131 def __eq__(self, other):
132 if isinstance(other, self.__class__):
133 return (self.glen == other.glen and
Neale Rannsefd7bc22019-11-11 08:32:34 +0000134 self.saddr == other.gaddr and
135 self.saddr == other.saddr)
Neale Ranns097fa662018-05-01 05:17:55 -0700136 elif (hasattr(other, "grp_address_length") and
137 hasattr(other, "grp_address") and
138 hasattr(other, "src_address")):
139 # vl_api_mprefix_t
Neale Rannsefd7bc22019-11-11 08:32:34 +0000140 if 4 == self.version:
141 return (self.glen == other.grp_address_length and
142 self.gaddr == str(other.grp_address.ip4) and
143 self.saddr == str(other.src_address.ip4))
Neale Ranns097fa662018-05-01 05:17:55 -0700144 else:
145 return (self.glen == other.grp_address_length and
Neale Rannsefd7bc22019-11-11 08:32:34 +0000146 self.gaddr == str(other.grp_address.ip6) and
147 self.saddr == str(other.src_address.ip6))
Neale Ranns9db6ada2019-11-08 12:42:31 +0000148 raise Exception("Comparing VppIpMPrefix:%s with unknown type: %s" %
Neale Ranns097fa662018-05-01 05:17:55 -0700149 (self, other))
150 return False