blob: b84eea37bea864e40ba6732574d619e219e78975 [file] [log] [blame]
Kris Michielsen91074432017-06-22 13:00:20 +02001"""
2 SRv6 LocalSIDs
3
4 object abstractions for representing SRv6 localSIDs in VPP
5"""
6
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -08007from vpp_object import VppObject
Kris Michielsen91074432017-06-22 13:00:20 +02008from socket import inet_pton, inet_ntop, AF_INET, AF_INET6
9
10
11class SRv6LocalSIDBehaviors():
12 # from src/vnet/srv6/sr.h
13 SR_BEHAVIOR_END = 1
14 SR_BEHAVIOR_X = 2
15 SR_BEHAVIOR_T = 3
16 SR_BEHAVIOR_D_FIRST = 4 # Unused. Separator in between regular and D
17 SR_BEHAVIOR_DX2 = 5
18 SR_BEHAVIOR_DX6 = 6
19 SR_BEHAVIOR_DX4 = 7
20 SR_BEHAVIOR_DT6 = 8
21 SR_BEHAVIOR_DT4 = 9
22 SR_BEHAVIOR_LAST = 10 # Must always be the last one
23
24
25class SRv6PolicyType():
26 # from src/vnet/srv6/sr.h
27 SR_POLICY_TYPE_DEFAULT = 0
28 SR_POLICY_TYPE_SPRAY = 1
29
30
31class SRv6PolicySteeringTypes():
32 # from src/vnet/srv6/sr.h
33 SR_STEER_L2 = 2
34 SR_STEER_IPV4 = 4
35 SR_STEER_IPV6 = 6
36
37
38class VppSRv6LocalSID(VppObject):
39 """
40 SRv6 LocalSID
41 """
42
Pablo Camarillo3337bd22018-06-19 15:49:02 +020043 def __init__(self, test, localsid, behavior, nh_addr4, nh_addr6,
44 end_psp, sw_if_index, vlan_index, fib_table):
Kris Michielsen91074432017-06-22 13:00:20 +020045 self._test = test
Pablo Camarillo3337bd22018-06-19 15:49:02 +020046 self.localsid = localsid
47 # keep binary format in _localsid
48 self.localsid["addr"] = inet_pton(AF_INET6, self.localsid["addr"])
Kris Michielsen91074432017-06-22 13:00:20 +020049 self.behavior = behavior
Pablo Camarillo3337bd22018-06-19 15:49:02 +020050 self.nh_addr4 = inet_pton(AF_INET, nh_addr4)
51 self.nh_addr6 = inet_pton(AF_INET6, nh_addr6)
Kris Michielsen91074432017-06-22 13:00:20 +020052 self.end_psp = end_psp
53 self.sw_if_index = sw_if_index
54 self.vlan_index = vlan_index
55 self.fib_table = fib_table
56 self._configured = False
57
58 def add_vpp_config(self):
59 self._test.vapi.sr_localsid_add_del(
Pablo Camarillo3337bd22018-06-19 15:49:02 +020060 self.localsid,
Kris Michielsen91074432017-06-22 13:00:20 +020061 self.behavior,
Pablo Camarillo3337bd22018-06-19 15:49:02 +020062 self.nh_addr4,
63 self.nh_addr6,
Kris Michielsen91074432017-06-22 13:00:20 +020064 is_del=0,
65 end_psp=self.end_psp,
66 sw_if_index=self.sw_if_index,
67 vlan_index=self.vlan_index,
68 fib_table=self.fib_table)
69 self._configured = True
70
71 def remove_vpp_config(self):
72 self._test.vapi.sr_localsid_add_del(
Pablo Camarillo3337bd22018-06-19 15:49:02 +020073 self.localsid,
Kris Michielsen91074432017-06-22 13:00:20 +020074 self.behavior,
Pablo Camarillo3337bd22018-06-19 15:49:02 +020075 self.nh_addr4,
76 self.nh_addr6,
Kris Michielsen91074432017-06-22 13:00:20 +020077 is_del=1,
78 end_psp=self.end_psp,
79 sw_if_index=self.sw_if_index,
80 vlan_index=self.vlan_index,
81 fib_table=self.fib_table)
82 self._configured = False
83
84 def query_vpp_config(self):
85 # sr_localsids_dump API is disabled
86 # use _configured flag for now
87 return self._configured
88
89 def __str__(self):
90 return self.object_id()
91
92 def object_id(self):
93 return ("%d;%s,%d"
94 % (self.fib_table,
Pablo Camarillo3337bd22018-06-19 15:49:02 +020095 self.localsid,
Kris Michielsen91074432017-06-22 13:00:20 +020096 self.behavior))
97
98
99class VppSRv6Policy(VppObject):
100 """
101 SRv6 Policy
102 """
103
104 def __init__(self, test, bsid,
105 is_encap, sr_type, weight, fib_table,
106 segments, source):
107 self._test = test
108 self.bsid = bsid
109 # keep binary format in _bsid
110 self._bsid = inet_pton(AF_INET6, bsid)
111 self.is_encap = is_encap
112 self.sr_type = sr_type
113 self.weight = weight
114 self.fib_table = fib_table
115 self.segments = segments
116 # keep binary format in _segments
117 self._segments = []
118 for seg in segments:
119 self._segments.extend(inet_pton(AF_INET6, seg))
120 self.n_segments = len(segments)
121 # source not passed to API
122 # self.source = inet_pton(AF_INET6, source)
123 self.source = source
124 self._configured = False
125
126 def add_vpp_config(self):
127 self._test.vapi.sr_policy_add(
128 self._bsid,
129 self.weight,
130 self.is_encap,
131 self.sr_type,
132 self.fib_table,
133 self.n_segments,
134 self._segments)
135 self._configured = True
136
137 def remove_vpp_config(self):
138 self._test.vapi.sr_policy_del(
139 self._bsid)
140 self._configured = False
141
142 def query_vpp_config(self):
143 # no API to query SR Policies
144 # use _configured flag for now
145 return self._configured
146
147 def __str__(self):
148 return self.object_id()
149
150 def object_id(self):
151 return ("%d;%s-><%s>;%d"
152 % (self.sr_type,
153 self.bsid,
154 ','.join(self.segments),
155 self.is_encap))
156
157
158class VppSRv6Steering(VppObject):
159 """
160 SRv6 Steering
161 """
162
163 def __init__(self, test,
164 bsid,
165 prefix,
166 mask_width,
167 traffic_type,
168 sr_policy_index,
169 table_id,
170 sw_if_index):
171 self._test = test
172 self.bsid = bsid
173 # keep binary format in _bsid
174 self._bsid = inet_pton(AF_INET6, bsid)
175 self.prefix = prefix
176 # keep binary format in _prefix
177 if ':' in prefix:
178 # IPv6
179 self._prefix = inet_pton(AF_INET6, prefix)
180 else:
181 # IPv4
182 # API expects 16 octets (128 bits)
183 # last 4 octets are used for IPv4
184 # --> prepend 12 octets
185 self._prefix = ('\x00' * 12) + inet_pton(AF_INET, prefix)
186 self.mask_width = mask_width
187 self.traffic_type = traffic_type
188 self.sr_policy_index = sr_policy_index
189 self.sw_if_index = sw_if_index
190 self.table_id = table_id
191 self._configured = False
192
193 def add_vpp_config(self):
194 self._test.vapi.sr_steering_add_del(
195 0,
196 self._bsid,
197 self.sr_policy_index,
198 self.table_id,
199 self._prefix,
200 self.mask_width,
201 self.sw_if_index,
202 self.traffic_type)
203 self._configured = True
204
205 def remove_vpp_config(self):
206 self._test.vapi.sr_steering_add_del(
207 1,
208 self._bsid,
209 self.sr_policy_index,
210 self.table_id,
211 self._prefix,
212 self.mask_width,
213 self.sw_if_index,
214 self.traffic_type)
215 self._configured = False
216
217 def query_vpp_config(self):
218 # no API to query steering entries
219 # use _configured flag for now
220 return self._configured
221
222 def __str__(self):
223 return self.object_id()
224
225 def object_id(self):
226 return ("%d;%d;%s/%d->%s"
227 % (self.table_id,
228 self.traffic_type,
229 self.prefix,
230 self.mask_width,
231 self.bsid))