blob: b896a6efbe3a7f6c6f1ceb795d5fc1cd97bb407d [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 @property
22 def parent(self):
23 """Parent interface for this sub-interface"""
24 return self._parent
25
26 @property
27 def sub_id(self):
28 """Sub-interface ID"""
29 return self._sub_id
30
Eyal Bari284293a2017-06-06 14:18:55 +030031 @property
32 def tag1(self):
33 return self._tag1
34
35 @property
36 def tag2(self):
37 return self._tag2
38
39 @property
40 def vtr(self):
41 return self._vtr
42
Klement Sekeraf62ae122016-10-11 11:47:09 +020043 def __init__(self, test, parent, sub_id):
Matej Klottonc5bf07f2016-11-23 15:27:17 +010044 VppInterface.__init__(self, test)
Klement Sekeraf62ae122016-10-11 11:47:09 +020045 self._parent = parent
46 self._parent.add_sub_if(self)
47 self._sub_id = sub_id
Eyal Bari284293a2017-06-06 14:18:55 +030048 self.DOT1AD_TYPE = 0x88A8
49 self.DOT1Q_TYPE = 0x8100
Klement Sekeraf62ae122016-10-11 11:47:09 +020050
Klement Sekerab9ef2732018-06-24 22:49:33 +020051 def set_sw_if_index(self, sw_if_index):
52 super(VppSubInterface, self).set_sw_if_index(sw_if_index)
53 self.set_vtr(L2_VTR_OP.L2_DISABLED)
54
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080055 @abc.abstractmethod
Klement Sekeraf62ae122016-10-11 11:47:09 +020056 def create_arp_req(self):
57 pass
58
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080059 @abc.abstractmethod
Benoît Ganne2699fe22021-01-18 19:25:38 +010060 def create_ndp_req(self, addr=None):
Klement Sekeraf62ae122016-10-11 11:47:09 +020061 pass
62
Klement Sekerabeaded52018-06-24 10:30:37 +020063 def resolve_arp(self):
64 super(VppSubInterface, self).resolve_arp(self.parent)
65
66 def resolve_ndp(self):
67 super(VppSubInterface, self).resolve_ndp(self.parent)
68
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080069 @abc.abstractmethod
Klement Sekeraf62ae122016-10-11 11:47:09 +020070 def add_dot1_layer(self, pkt):
71 pass
72
Neale Ranns177bbdc2016-11-15 09:46:51 +000073 def remove_vpp_config(self):
Klement Sekerab9ef2732018-06-24 22:49:33 +020074 self.test.vapi.delete_subif(self.sw_if_index)
Neale Ranns177bbdc2016-11-15 09:46:51 +000075
Eyal Bari284293a2017-06-06 14:18:55 +030076 def _add_tag(self, packet, vlan, tag_type):
77 payload = packet.payload
78 inner_type = packet.type
79 packet.remove_payload()
80 packet.add_payload(Dot1Q(vlan=vlan) / payload)
81 packet.payload.type = inner_type
82 packet.payload.vlan = vlan
83 packet.type = tag_type
84 return packet
85
86 def _remove_tag(self, packet, vlan=None, tag_type=None):
87 if tag_type:
88 self.test.instance().assertEqual(packet.type, tag_type)
89
90 payload = packet.payload
91 if vlan:
92 self.test.instance().assertEqual(payload.vlan, vlan)
93 inner_type = payload.type
94 payload = payload.payload
95 packet.remove_payload()
96 packet.add_payload(payload)
97 packet.type = inner_type
98 return packet
99
100 def add_dot1q_layer(self, packet, vlan):
101 return self._add_tag(packet, vlan, self.DOT1Q_TYPE)
102
103 def add_dot1ad_layer(self, packet, outer, inner):
104 p = self._add_tag(packet, inner, self.DOT1Q_TYPE)
105 return self._add_tag(p, outer, self.DOT1AD_TYPE)
106
107 def remove_dot1q_layer(self, packet, vlan=None):
108 return self._remove_tag(packet, vlan, self.DOT1Q_TYPE)
109
110 def remove_dot1ad_layer(self, packet, outer=None, inner=None):
111 p = self._remove_tag(packet, outer, self.DOT1AD_TYPE)
112 return self._remove_tag(p, inner, self.DOT1Q_TYPE)
113
114 def set_vtr(self, vtr, push1q=0, tag=None, inner=None, outer=None):
115 self._tag1 = 0
116 self._tag2 = 0
117 self._push1q = 0
118
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200119 if (
120 vtr == L2_VTR_OP.L2_PUSH_1
121 or vtr == L2_VTR_OP.L2_TRANSLATE_1_1
122 or vtr == L2_VTR_OP.L2_TRANSLATE_2_1
123 ):
Eyal Bari284293a2017-06-06 14:18:55 +0300124 self._tag1 = tag
125 self._push1q = push1q
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200126 if (
127 vtr == L2_VTR_OP.L2_PUSH_2
128 or vtr == L2_VTR_OP.L2_TRANSLATE_1_2
129 or vtr == L2_VTR_OP.L2_TRANSLATE_2_2
130 ):
Eyal Bari284293a2017-06-06 14:18:55 +0300131 self._tag1 = outer
132 self._tag2 = inner
133 self._push1q = push1q
134
Ole Troane1ade682019-03-04 23:55:43 +0100135 self.test.vapi.l2_interface_vlan_tag_rewrite(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200136 sw_if_index=self.sw_if_index,
137 vtr_op=vtr,
138 push_dot1q=self._push1q,
139 tag1=self._tag1,
140 tag2=self._tag2,
141 )
Eyal Bari284293a2017-06-06 14:18:55 +0300142 self._vtr = vtr
143
Klement Sekeraf62ae122016-10-11 11:47:09 +0200144
145class VppDot1QSubint(VppSubInterface):
Klement Sekeraf62ae122016-10-11 11:47:09 +0200146 @property
147 def vlan(self):
148 """VLAN tag"""
149 return self._vlan
150
151 def __init__(self, test, parent, sub_id, vlan=None):
Klement Sekerab9ef2732018-06-24 22:49:33 +0200152 super(VppDot1QSubint, self).__init__(test, parent, sub_id)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200153 if vlan is None:
154 vlan = sub_id
Klement Sekeraf62ae122016-10-11 11:47:09 +0200155 self._vlan = vlan
Matej Klottonc5bf07f2016-11-23 15:27:17 +0100156 r = test.vapi.create_vlan_subif(parent.sw_if_index, vlan)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200157 self.set_sw_if_index(r.sw_if_index)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200158
159 def create_arp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100160 packet = VppPGInterface.create_arp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200161 return self.add_dot1_layer(packet)
162
Benoît Ganne2699fe22021-01-18 19:25:38 +0100163 def create_ndp_req(self, addr=None):
164 packet = VppPGInterface.create_ndp_req(self, addr)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200165 return self.add_dot1_layer(packet)
166
Eyal Bari284293a2017-06-06 14:18:55 +0300167 # called before sending packet
Klement Sekeraf62ae122016-10-11 11:47:09 +0200168 def add_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300169 return self.add_dot1q_layer(packet, self.vlan)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200170
Eyal Bari284293a2017-06-06 14:18:55 +0300171 # called on received packet to "reverse" the add call
Klement Sekeraf62ae122016-10-11 11:47:09 +0200172 def remove_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300173 return self.remove_dot1q_layer(packet, self.vlan)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200174
175
176class VppDot1ADSubint(VppSubInterface):
Klement Sekeraf62ae122016-10-11 11:47:09 +0200177 @property
178 def outer_vlan(self):
179 """Outer VLAN tag"""
180 return self._outer_vlan
181
182 @property
183 def inner_vlan(self):
184 """Inner VLAN tag"""
185 return self._inner_vlan
186
187 def __init__(self, test, parent, sub_id, outer_vlan, inner_vlan):
Klement Sekerab9ef2732018-06-24 22:49:33 +0200188 super(VppDot1ADSubint, self).__init__(test, parent, sub_id)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200189 flags = (
190 VppEnum.vl_api_sub_if_flags_t.SUB_IF_API_FLAG_DOT1AD
191 | VppEnum.vl_api_sub_if_flags_t.SUB_IF_API_FLAG_TWO_TAGS
192 | VppEnum.vl_api_sub_if_flags_t.SUB_IF_API_FLAG_EXACT_MATCH
193 )
194 r = test.vapi.create_subif(
195 sw_if_index=parent.sw_if_index,
196 sub_id=sub_id,
197 outer_vlan_id=outer_vlan,
198 inner_vlan_id=inner_vlan,
199 sub_if_flags=flags,
200 )
Klement Sekerab9ef2732018-06-24 22:49:33 +0200201 self.set_sw_if_index(r.sw_if_index)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200202 self._outer_vlan = outer_vlan
203 self._inner_vlan = inner_vlan
Klement Sekeraf62ae122016-10-11 11:47:09 +0200204
205 def create_arp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100206 packet = VppPGInterface.create_arp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200207 return self.add_dot1_layer(packet)
208
Benoît Ganne2699fe22021-01-18 19:25:38 +0100209 def create_ndp_req(self, addr=None):
210 packet = VppPGInterface.create_ndp_req(self, addr)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200211 return self.add_dot1_layer(packet)
212
213 def add_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300214 return self.add_dot1ad_layer(packet, self.outer_vlan, self.inner_vlan)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200215
216 def remove_dot1_layer(self, packet):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200217 return self.remove_dot1ad_layer(packet, self.outer_vlan, self.inner_vlan)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200218
219
220class VppP2PSubint(VppSubInterface):
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200221 def __init__(self, test, parent, sub_id, remote_mac):
Klement Sekerab9ef2732018-06-24 22:49:33 +0200222 super(VppP2PSubint, self).__init__(test, parent, sub_id)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200223 r = test.vapi.p2p_ethernet_add(parent.sw_if_index, remote_mac, sub_id)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200224 self.set_sw_if_index(r.sw_if_index)
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700225 self.parent_sw_if_index = parent.sw_if_index
226 self.p2p_remote_mac = remote_mac
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200227
228 def add_dot1_layer(self, packet):
229 return packet
230
231 def remove_dot1_layer(self, packet):
232 return packet
233
234 def create_arp_req(self):
235 packet = VppPGInterface.create_arp_req(self)
236 return packet
237
Benoît Ganne2699fe22021-01-18 19:25:38 +0100238 def create_ndp_req(self, addr=None):
239 packet = VppPGInterface.create_ndp_req(self, addr)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200240 return packet