blob: 21560cb99d07d776acac93f23064ac48b0957890 [file] [log] [blame]
Eyal Bari284293a2017-06-06 14:18:55 +03001from scapy.layers.l2 import Dot1Q
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -08002import abc
Matej Klotton0178d522016-11-04 11:11:44 +01003from vpp_pg_interface import VppPGInterface
Klement Sekerabeaded52018-06-24 10:30:37 +02004from vpp_interface import VppInterface
Jakub Grajciar053204a2019-03-18 13:17:53 +01005from vpp_papi import VppEnum
Klement Sekeraf62ae122016-10-11 11:47:09 +02006
7
Paul Vinciguerra95c0ca42019-03-28 13:07:00 -07008class L2_VTR_OP:
9 L2_DISABLED = 0
10 L2_PUSH_1 = 1
11 L2_PUSH_2 = 2
12 L2_POP_1 = 3
13 L2_POP_2 = 4
14 L2_TRANSLATE_1_1 = 5
15 L2_TRANSLATE_1_2 = 6
16 L2_TRANSLATE_2_1 = 7
17 L2_TRANSLATE_2_2 = 8
18
19
Paul Vinciguerra090096b2020-12-03 00:42:46 -050020class VppSubInterface(VppPGInterface, metaclass=abc.ABCMeta):
Klement Sekeraf62ae122016-10-11 11:47:09 +020021
22 @property
23 def parent(self):
24 """Parent interface for this sub-interface"""
25 return self._parent
26
27 @property
28 def sub_id(self):
29 """Sub-interface ID"""
30 return self._sub_id
31
Eyal Bari284293a2017-06-06 14:18:55 +030032 @property
33 def tag1(self):
34 return self._tag1
35
36 @property
37 def tag2(self):
38 return self._tag2
39
40 @property
41 def vtr(self):
42 return self._vtr
43
Klement Sekeraf62ae122016-10-11 11:47:09 +020044 def __init__(self, test, parent, sub_id):
Matej Klottonc5bf07f2016-11-23 15:27:17 +010045 VppInterface.__init__(self, test)
Klement Sekeraf62ae122016-10-11 11:47:09 +020046 self._parent = parent
47 self._parent.add_sub_if(self)
48 self._sub_id = sub_id
Eyal Bari284293a2017-06-06 14:18:55 +030049 self.DOT1AD_TYPE = 0x88A8
50 self.DOT1Q_TYPE = 0x8100
Klement Sekeraf62ae122016-10-11 11:47:09 +020051
Klement Sekerab9ef2732018-06-24 22:49:33 +020052 def set_sw_if_index(self, sw_if_index):
53 super(VppSubInterface, self).set_sw_if_index(sw_if_index)
54 self.set_vtr(L2_VTR_OP.L2_DISABLED)
55
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080056 @abc.abstractmethod
Klement Sekeraf62ae122016-10-11 11:47:09 +020057 def create_arp_req(self):
58 pass
59
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080060 @abc.abstractmethod
Benoît Ganne2699fe22021-01-18 19:25:38 +010061 def create_ndp_req(self, addr=None):
Klement Sekeraf62ae122016-10-11 11:47:09 +020062 pass
63
Klement Sekerabeaded52018-06-24 10:30:37 +020064 def resolve_arp(self):
65 super(VppSubInterface, self).resolve_arp(self.parent)
66
67 def resolve_ndp(self):
68 super(VppSubInterface, self).resolve_ndp(self.parent)
69
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080070 @abc.abstractmethod
Klement Sekeraf62ae122016-10-11 11:47:09 +020071 def add_dot1_layer(self, pkt):
72 pass
73
Neale Ranns177bbdc2016-11-15 09:46:51 +000074 def remove_vpp_config(self):
Klement Sekerab9ef2732018-06-24 22:49:33 +020075 self.test.vapi.delete_subif(self.sw_if_index)
Neale Ranns177bbdc2016-11-15 09:46:51 +000076
Eyal Bari284293a2017-06-06 14:18:55 +030077 def _add_tag(self, packet, vlan, tag_type):
78 payload = packet.payload
79 inner_type = packet.type
80 packet.remove_payload()
81 packet.add_payload(Dot1Q(vlan=vlan) / payload)
82 packet.payload.type = inner_type
83 packet.payload.vlan = vlan
84 packet.type = tag_type
85 return packet
86
87 def _remove_tag(self, packet, vlan=None, tag_type=None):
88 if tag_type:
89 self.test.instance().assertEqual(packet.type, tag_type)
90
91 payload = packet.payload
92 if vlan:
93 self.test.instance().assertEqual(payload.vlan, vlan)
94 inner_type = payload.type
95 payload = payload.payload
96 packet.remove_payload()
97 packet.add_payload(payload)
98 packet.type = inner_type
99 return packet
100
101 def add_dot1q_layer(self, packet, vlan):
102 return self._add_tag(packet, vlan, self.DOT1Q_TYPE)
103
104 def add_dot1ad_layer(self, packet, outer, inner):
105 p = self._add_tag(packet, inner, self.DOT1Q_TYPE)
106 return self._add_tag(p, outer, self.DOT1AD_TYPE)
107
108 def remove_dot1q_layer(self, packet, vlan=None):
109 return self._remove_tag(packet, vlan, self.DOT1Q_TYPE)
110
111 def remove_dot1ad_layer(self, packet, outer=None, inner=None):
112 p = self._remove_tag(packet, outer, self.DOT1AD_TYPE)
113 return self._remove_tag(p, inner, self.DOT1Q_TYPE)
114
115 def set_vtr(self, vtr, push1q=0, tag=None, inner=None, outer=None):
116 self._tag1 = 0
117 self._tag2 = 0
118 self._push1q = 0
119
120 if (vtr == L2_VTR_OP.L2_PUSH_1 or
121 vtr == L2_VTR_OP.L2_TRANSLATE_1_1 or
122 vtr == L2_VTR_OP.L2_TRANSLATE_2_1):
123 self._tag1 = tag
124 self._push1q = push1q
125 if (vtr == L2_VTR_OP.L2_PUSH_2 or
126 vtr == L2_VTR_OP.L2_TRANSLATE_1_2 or
127 vtr == L2_VTR_OP.L2_TRANSLATE_2_2):
128 self._tag1 = outer
129 self._tag2 = inner
130 self._push1q = push1q
131
Ole Troane1ade682019-03-04 23:55:43 +0100132 self.test.vapi.l2_interface_vlan_tag_rewrite(
Ole Troana5b2eec2019-03-11 19:23:25 +0100133 sw_if_index=self.sw_if_index, vtr_op=vtr, push_dot1q=self._push1q,
Eyal Bari284293a2017-06-06 14:18:55 +0300134 tag1=self._tag1, tag2=self._tag2)
135 self._vtr = vtr
136
Klement Sekeraf62ae122016-10-11 11:47:09 +0200137
138class VppDot1QSubint(VppSubInterface):
139
140 @property
141 def vlan(self):
142 """VLAN tag"""
143 return self._vlan
144
145 def __init__(self, test, parent, sub_id, vlan=None):
Klement Sekerab9ef2732018-06-24 22:49:33 +0200146 super(VppDot1QSubint, self).__init__(test, parent, sub_id)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200147 if vlan is None:
148 vlan = sub_id
Klement Sekeraf62ae122016-10-11 11:47:09 +0200149 self._vlan = vlan
Matej Klottonc5bf07f2016-11-23 15:27:17 +0100150 r = test.vapi.create_vlan_subif(parent.sw_if_index, vlan)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200151 self.set_sw_if_index(r.sw_if_index)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200152
153 def create_arp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100154 packet = VppPGInterface.create_arp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200155 return self.add_dot1_layer(packet)
156
Benoît Ganne2699fe22021-01-18 19:25:38 +0100157 def create_ndp_req(self, addr=None):
158 packet = VppPGInterface.create_ndp_req(self, addr)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200159 return self.add_dot1_layer(packet)
160
Eyal Bari284293a2017-06-06 14:18:55 +0300161 # called before sending packet
Klement Sekeraf62ae122016-10-11 11:47:09 +0200162 def add_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300163 return self.add_dot1q_layer(packet, self.vlan)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200164
Eyal Bari284293a2017-06-06 14:18:55 +0300165 # called on received packet to "reverse" the add call
Klement Sekeraf62ae122016-10-11 11:47:09 +0200166 def remove_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300167 return self.remove_dot1q_layer(packet, self.vlan)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200168
169
170class VppDot1ADSubint(VppSubInterface):
171
172 @property
173 def outer_vlan(self):
174 """Outer VLAN tag"""
175 return self._outer_vlan
176
177 @property
178 def inner_vlan(self):
179 """Inner VLAN tag"""
180 return self._inner_vlan
181
182 def __init__(self, test, parent, sub_id, outer_vlan, inner_vlan):
Klement Sekerab9ef2732018-06-24 22:49:33 +0200183 super(VppDot1ADSubint, self).__init__(test, parent, sub_id)
Jakub Grajciar053204a2019-03-18 13:17:53 +0100184 flags = (VppEnum.vl_api_sub_if_flags_t.SUB_IF_API_FLAG_DOT1AD |
185 VppEnum.vl_api_sub_if_flags_t.SUB_IF_API_FLAG_TWO_TAGS |
186 VppEnum.vl_api_sub_if_flags_t.SUB_IF_API_FLAG_EXACT_MATCH)
Ole Troana5b2eec2019-03-11 19:23:25 +0100187 r = test.vapi.create_subif(sw_if_index=parent.sw_if_index,
188 sub_id=sub_id, outer_vlan_id=outer_vlan,
Jakub Grajciar053204a2019-03-18 13:17:53 +0100189 inner_vlan_id=inner_vlan,
190 sub_if_flags=flags)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200191 self.set_sw_if_index(r.sw_if_index)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200192 self._outer_vlan = outer_vlan
193 self._inner_vlan = inner_vlan
Klement Sekeraf62ae122016-10-11 11:47:09 +0200194
195 def create_arp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100196 packet = VppPGInterface.create_arp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200197 return self.add_dot1_layer(packet)
198
Benoît Ganne2699fe22021-01-18 19:25:38 +0100199 def create_ndp_req(self, addr=None):
200 packet = VppPGInterface.create_ndp_req(self, addr)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200201 return self.add_dot1_layer(packet)
202
203 def add_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300204 return self.add_dot1ad_layer(packet, self.outer_vlan, self.inner_vlan)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200205
206 def remove_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300207 return self.remove_dot1ad_layer(packet, self.outer_vlan,
208 self.inner_vlan)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200209
210
211class VppP2PSubint(VppSubInterface):
212
213 def __init__(self, test, parent, sub_id, remote_mac):
Klement Sekerab9ef2732018-06-24 22:49:33 +0200214 super(VppP2PSubint, self).__init__(test, parent, sub_id)
Ole Troane1ade682019-03-04 23:55:43 +0100215 r = test.vapi.p2p_ethernet_add(parent.sw_if_index,
216 remote_mac, sub_id)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200217 self.set_sw_if_index(r.sw_if_index)
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700218 self.parent_sw_if_index = parent.sw_if_index
219 self.p2p_remote_mac = remote_mac
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200220
221 def add_dot1_layer(self, packet):
222 return packet
223
224 def remove_dot1_layer(self, packet):
225 return packet
226
227 def create_arp_req(self):
228 packet = VppPGInterface.create_arp_req(self)
229 return packet
230
Benoît Ganne2699fe22021-01-18 19:25:38 +0100231 def create_ndp_req(self, addr=None):
232 packet = VppPGInterface.create_ndp_req(self, addr)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200233 return packet