90de91695f2e60dd0f24fffa42c7b8eb8964eb8d
[vpp.git] / test / vpp_l2.py
1 """
2   L2/BD Types
3
4 """
5
6 from vpp_object import VppObject
7 from vpp_ip import VppIpAddress
8 from vpp_lo_interface import VppLoInterface
9 from vpp_papi import MACAddress
10 from vpp_sub_interface import L2_VTR_OP
11
12
13 class L2_PORT_TYPE:
14     NORMAL = 0
15     BVI = 1
16     UU_FWD = 2
17
18
19 class BRIDGE_FLAGS:
20     NONE = 0
21     LEARN = 1
22     FWD = 2
23     FLOOD = 4
24     UU_FLOOD = 8
25     ARP_TERM = 16
26     ARP_UFWD = 32
27
28
29 def find_bridge_domain(test, bd_id):
30     bds = test.vapi.bridge_domain_dump(bd_id)
31     return len(bds) == 1
32
33
34 def find_bridge_domain_port(test, bd_id, sw_if_index):
35     bds = test.vapi.bridge_domain_dump(bd_id)
36     for bd in bds:
37         for p in bd.sw_if_details:
38             if p.sw_if_index == sw_if_index:
39                 return True
40     return False
41
42
43 def find_bridge_domain_arp_entry(test, bd_id, mac, ip):
44     vmac = MACAddress(mac)
45     vip = VppIpAddress(ip)
46
47     if vip.version == 4:
48         n = 4
49     else:
50         n = 16
51
52     arps = test.vapi.bd_ip_mac_dump(bd_id)
53     for arp in arps:
54         # do IP addr comparison too once .api is fixed...
55         if vmac.packed == arp.mac_address and \
56                 vip.bytes == arp.ip_address[:n]:
57             return True
58     return False
59
60
61 def find_l2_fib_entry(test, bd_id, mac, sw_if_index):
62     vmac = MACAddress(mac)
63     lfs = test.vapi.l2_fib_table_dump(bd_id)
64     for lf in lfs:
65         if vmac.packed == lf.mac and sw_if_index == lf.sw_if_index:
66             return True
67     return False
68
69
70 class VppBridgeDomain(VppObject):
71
72     def __init__(self, test, bd_id,
73                  flood=1, uu_flood=1, forward=1,
74                  learn=1, arp_term=1, arp_ufwd=0):
75         self._test = test
76         self.bd_id = bd_id
77         self.flood = flood
78         self.uu_flood = uu_flood
79         self.forward = forward
80         self.learn = learn
81         self.arp_term = arp_term
82         self.arp_ufwd = arp_ufwd
83
84     def add_vpp_config(self):
85         self._test.vapi.bridge_domain_add_del(bd_id=self.bd_id,
86                                               flood=self.flood,
87                                               uu_flood=self.uu_flood,
88                                               forward=self.forward,
89                                               learn=self.learn,
90                                               arp_term=self.arp_term,
91                                               arp_ufwd=self.arp_ufwd,
92                                               is_add=1)
93         self._test.registry.register(self, self._test.logger)
94
95     def remove_vpp_config(self):
96         self._test.vapi.bridge_domain_add_del(bd_id=self.bd_id, is_add=0)
97
98     def query_vpp_config(self):
99         return find_bridge_domain(self._test, self.bd_id)
100
101     def object_id(self):
102         return "bridge-domain-%d" % (self.bd_id)
103
104
105 class VppBridgeDomainPort(VppObject):
106
107     def __init__(self, test, bd, itf,
108                  port_type=L2_PORT_TYPE.NORMAL):
109         self._test = test
110         self.bd = bd
111         self.itf = itf
112         self.port_type = port_type
113
114     def add_vpp_config(self):
115         self._test.vapi.sw_interface_set_l2_bridge(
116             rx_sw_if_index=self.itf.sw_if_index, bd_id=self.bd.bd_id,
117             port_type=self.port_type, enable=1)
118         self._test.registry.register(self, self._test.logger)
119
120     def remove_vpp_config(self):
121         self._test.vapi.sw_interface_set_l2_bridge(
122             rx_sw_if_index=self.itf.sw_if_index, bd_id=self.bd.bd_id,
123             port_type=self.port_type, enable=0)
124
125     def query_vpp_config(self):
126         return find_bridge_domain_port(self._test,
127                                        self.bd.bd_id,
128                                        self.itf.sw_if_index)
129
130     def object_id(self):
131         return "BD-Port-%s-%s" % (self.bd, self.itf)
132
133
134 class VppBridgeDomainArpEntry(VppObject):
135
136     def __init__(self, test, bd, mac, ip):
137         self._test = test
138         self.bd = bd
139         self.mac = MACAddress(mac)
140         self.ip = VppIpAddress(ip)
141
142     def add_vpp_config(self):
143         self._test.vapi.bd_ip_mac_add_del(bd_id=self.bd.bd_id, is_add=1,
144                                           ip=self.ip.encode(),
145                                           mac=self.mac.packed)
146         self._test.registry.register(self, self._test.logger)
147
148     def remove_vpp_config(self):
149         self._test.vapi.bd_ip_mac_add_del(bd_id=self.bd.bd_id, is_add=0,
150                                           ip=self.ip.encode(),
151                                           mac=self.mac.packed)
152
153     def query_vpp_config(self):
154         return find_bridge_domain_arp_entry(self._test,
155                                             self.bd.bd_id,
156                                             self.mac.packed,
157                                             self.ip.address)
158
159     def object_id(self):
160         return "BD-Arp-Entry-%s-%s-%s" % (self.bd, self.mac, self.ip.address)
161
162
163 class VppL2FibEntry(VppObject):
164
165     def __init__(self, test, bd, mac, itf,
166                  static_mac=0, filter_mac=0, bvi_mac=-1):
167         self._test = test
168         self.bd = bd
169         self.mac = MACAddress(mac)
170         self.itf = itf
171         self.static_mac = static_mac
172         self.filter_mac = filter_mac
173         if bvi_mac == -1:
174             self.bvi_mac = isinstance(self.itf, VppLoInterface)
175         else:
176             self.bvi_mac = bvi_mac
177
178     def add_vpp_config(self):
179         self._test.vapi.l2fib_add_del(
180             self.mac.packed,
181             self.bd.bd_id,
182             self.itf.sw_if_index,
183             is_add=1,
184             static_mac=self.static_mac,
185             filter_mac=self.filter_mac,
186             bvi_mac=self.bvi_mac)
187         self._test.registry.register(self, self._test.logger)
188
189     def remove_vpp_config(self):
190         self._test.vapi.l2fib_add_del(
191             self.mac.packed,
192             self.bd.bd_id,
193             self.itf.sw_if_index,
194             is_add=0)
195
196     def query_vpp_config(self):
197         return find_l2_fib_entry(self._test,
198                                  self.bd.bd_id,
199                                  self.mac.packed,
200                                  self.itf.sw_if_index)
201
202     def object_id(self):
203         return "L2-Fib-Entry-%s-%s-%s" % (self.bd, self.mac, self.itf)
204
205
206 class VppL2Vtr(VppObject):
207
208     def __init__(self, test, itf, op):
209         self._test = test
210         self.itf = itf
211         self.op = op
212
213     def add_vpp_config(self):
214         self.itf.set_vtr(self.op)
215         self._test.registry.register(self, self._test.logger)
216
217     def remove_vpp_config(self):
218         self.itf.set_vtr(L2_VTR_OP.L2_DISABLED)
219
220     def query_vpp_config(self):
221         ds = self._test.vapi.sw_interface_dump()
222         d = self.itf.get_interface_config_from_dump(ds)
223
224         if d is not None:
225             return (d.vtr_op == self.op)
226         return False
227
228     def object_id(self):
229         return "L2-vtr-%s-%d" % (str(self.itf), self.op)