MAP: Use explicit address/prefix types in API
[vpp.git] / test / vpp_ip.py
1 """
2   IP Types
3
4 """
5
6 from ipaddress import ip_address
7 from socket import AF_INET, AF_INET6
8 from vpp_papi import VppEnum
9
10
11 class DpoProto:
12     DPO_PROTO_IP4 = 0
13     DPO_PROTO_IP6 = 1
14     DPO_PROTO_MPLS = 2
15     DPO_PROTO_ETHERNET = 3
16     DPO_PROTO_BIER = 4
17     DPO_PROTO_NSH = 5
18
19
20 INVALID_INDEX = 0xffffffff
21
22
23 class VppIpAddressUnion():
24     def __init__(self, addr):
25         self.addr = addr
26         self.ip_addr = ip_address(unicode(self.addr))
27
28     def encode(self):
29         if self.version is 6:
30             return {
31                 'ip6': {
32                     'address': self.ip_addr.packed
33                 },
34             }
35         else:
36             return {
37                 'ip4': {
38                     'address': self.ip_addr.packed
39                 },
40             }
41
42     @property
43     def version(self):
44         return self.ip_addr.version
45
46     @property
47     def address(self):
48         return self.addr
49
50     @property
51     def length(self):
52         if self.version is 6:
53             return 128
54         else:
55             return 32
56
57     @property
58     def bytes(self):
59         return self.ip_addr.packed
60
61     def __eq__(self, other):
62         if isinstance(other, self.__class__):
63             return self.ip_addr == other.ip_addr
64         elif hasattr(other, "ip4") and hasattr(other, "ip6"):
65             # vl_api_address_union_t
66             if 4 is self.version:
67                 return self.ip_addr.packed == other.ip4.address
68             else:
69                 return self.ip_addr.packed == other.ip6.address
70         else:
71             raise Exception("Comparing VppIpAddresUnions:%s"
72                             " with unknown type: %s" %
73                             (self, other))
74
75         return False
76
77
78 class VppIpAddress():
79     def __init__(self, addr):
80         self.addr = VppIpAddressUnion(addr)
81
82     def encode(self):
83         if self.addr.version is 6:
84             return {
85                 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP6,
86                 'un': self.addr.encode()
87             }
88         else:
89             return {
90                 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP4,
91                 'un': self.addr.encode()
92             }
93
94     def __eq__(self, other):
95         if isinstance(other, self.__class__):
96             return self.addr == other.addr
97         elif hasattr(other, "af") and hasattr(other, "un"):
98             # a vp_api_address_t
99             if 4 is self.version:
100                 return other.af == \
101                     VppEnum.vl_api_address_family_t.ADDRESS_IP4 and \
102                     other.un == self.addr
103             else:
104                 return other.af == \
105                     VppEnum.vl_api_address_family_t.ADDRESS_IP6 and \
106                     other.un == self.addr
107         else:
108             raise Exception("Comparing VppIpAddress:%s with unknown type: %s" %
109                             (self, other))
110         return False
111
112     def __ne__(self, other):
113         return not (self == other)
114
115     def __str__(self):
116         return self.address
117
118     @property
119     def bytes(self):
120         return self.addr.bytes
121
122     @property
123     def bytes(self):
124         return self.addr.bytes
125
126     @property
127     def address(self):
128         return self.addr.address
129
130     @property
131     def length(self):
132         return self.addr.length
133
134     @property
135     def version(self):
136         return self.addr.version
137
138     @property
139     def is_ip6(self):
140         return (self.version == 6)
141
142     @property
143     def af(self):
144         if self.version == 6:
145             return AF_INET6
146         else:
147             return AF_INET
148
149     @property
150     def dpo_proto(self):
151         if self.version is 6:
152             return DpoProto.DPO_PROTO_IP6
153         else:
154             return DpoProto.DPO_PROTO_IP4
155
156
157 class VppIpPrefix():
158     def __init__(self, addr, len):
159         self.addr = VppIpAddress(addr)
160         self.len = len
161
162     def __eq__(self, other):
163         if self.addr == other.addr and self.len == other.len:
164             return True
165         return False
166
167     def encode(self):
168         return {'address': self.addr.encode(),
169                 'address_length': self.len}
170
171     @property
172     def address(self):
173         return self.addr.address
174
175     @property
176     def bytes(self):
177         return self.addr.bytes
178
179     @property
180     def length(self):
181         return self.len
182
183     @property
184     def is_ip6(self):
185         return self.addr.is_ip6
186
187     def __str__(self):
188         return "%s/%d" % (self.address, self.length)
189
190     def __eq__(self, other):
191         if isinstance(other, self.__class__):
192             return (self.len == other.len and self.addr == other.addr)
193         elif hasattr(other, "address") and hasattr(other, "address_length"):
194             # vl_api_prefix_t
195             return self.len == other.address_length and \
196                 self.addr == other.address
197         else:
198             raise Exception("Comparing VppIpPrefix:%s with unknown type: %s" %
199                             (self, other))
200         return False
201
202
203 class VppIp6Prefix():
204     def __init__(self, prefix, prefixlen):
205         self.ip_prefix = ip_address(unicode(prefix))
206         self.prefixlen = prefixlen
207
208     def encode(self):
209         return {'prefix': {'address': self.ip_prefix.packed},
210                 'len': self.prefixlen}
211
212
213 class VppIp4Prefix(VppIp6Prefix):
214     pass
215
216
217 class VppIpMPrefix():
218     def __init__(self, saddr, gaddr, len):
219         self.saddr = saddr
220         self.gaddr = gaddr
221         self.len = len
222         self.ip_saddr = ip_address(unicode(self.saddr))
223         self.ip_gaddr = ip_address(unicode(self.gaddr))
224
225     def encode(self):
226
227         if 6 is self.ip_saddr.version:
228             prefix = {
229                 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP6,
230                 'grp_address': {
231                     'ip6': {
232                         'address': self.ip_gaddr.packed
233                     },
234                 },
235                 'src_address': {
236                     'ip6': {
237                         'address': self.ip_saddr.packed
238                     },
239                 },
240                 'grp_address_length': self.len,
241             }
242         else:
243             prefix = {
244                 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP4,
245                 'grp_address': {
246                     'ip4': {
247                         'address': self.ip_gaddr.packed
248                     },
249                 },
250                 'src_address': {
251                     'ip4': {
252                         'address': self.ip_saddr.packed
253                     },
254                 },
255                 'grp_address_length': self.len,
256             }
257         return prefix