blob: 4961ba5ff696dfa2210e4ae27c512038b66c3a89 [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
3import six
Matej Klotton0178d522016-11-04 11:11:44 +01004from vpp_pg_interface import VppPGInterface
Klement Sekerabeaded52018-06-24 10:30:37 +02005from vpp_interface import VppInterface
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 Vinciguerra3bce8eb2018-11-24 21:46:05 -080020@six.add_metaclass(abc.ABCMeta)
Matej Klotton0178d522016-11-04 11:11:44 +010021class VppSubInterface(VppPGInterface):
Klement Sekeraf62ae122016-10-11 11:47:09 +020022
23 @property
24 def parent(self):
25 """Parent interface for this sub-interface"""
26 return self._parent
27
28 @property
29 def sub_id(self):
30 """Sub-interface ID"""
31 return self._sub_id
32
Eyal Bari284293a2017-06-06 14:18:55 +030033 @property
34 def tag1(self):
35 return self._tag1
36
37 @property
38 def tag2(self):
39 return self._tag2
40
41 @property
42 def vtr(self):
43 return self._vtr
44
Klement Sekeraf62ae122016-10-11 11:47:09 +020045 def __init__(self, test, parent, sub_id):
Matej Klottonc5bf07f2016-11-23 15:27:17 +010046 VppInterface.__init__(self, test)
Klement Sekeraf62ae122016-10-11 11:47:09 +020047 self._parent = parent
48 self._parent.add_sub_if(self)
49 self._sub_id = sub_id
Eyal Bari284293a2017-06-06 14:18:55 +030050 self.DOT1AD_TYPE = 0x88A8
51 self.DOT1Q_TYPE = 0x8100
Klement Sekeraf62ae122016-10-11 11:47:09 +020052
Klement Sekerab9ef2732018-06-24 22:49:33 +020053 def set_sw_if_index(self, sw_if_index):
54 super(VppSubInterface, self).set_sw_if_index(sw_if_index)
55 self.set_vtr(L2_VTR_OP.L2_DISABLED)
56
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080057 @abc.abstractmethod
Klement Sekeraf62ae122016-10-11 11:47:09 +020058 def create_arp_req(self):
59 pass
60
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080061 @abc.abstractmethod
Klement Sekeraf62ae122016-10-11 11:47:09 +020062 def create_ndp_req(self):
63 pass
64
Klement Sekerabeaded52018-06-24 10:30:37 +020065 def resolve_arp(self):
66 super(VppSubInterface, self).resolve_arp(self.parent)
67
68 def resolve_ndp(self):
69 super(VppSubInterface, self).resolve_ndp(self.parent)
70
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080071 @abc.abstractmethod
Klement Sekeraf62ae122016-10-11 11:47:09 +020072 def add_dot1_layer(self, pkt):
73 pass
74
Neale Ranns177bbdc2016-11-15 09:46:51 +000075 def remove_vpp_config(self):
Klement Sekerab9ef2732018-06-24 22:49:33 +020076 self.test.vapi.delete_subif(self.sw_if_index)
Neale Ranns177bbdc2016-11-15 09:46:51 +000077
Eyal Bari284293a2017-06-06 14:18:55 +030078 def _add_tag(self, packet, vlan, tag_type):
79 payload = packet.payload
80 inner_type = packet.type
81 packet.remove_payload()
82 packet.add_payload(Dot1Q(vlan=vlan) / payload)
83 packet.payload.type = inner_type
84 packet.payload.vlan = vlan
85 packet.type = tag_type
86 return packet
87
88 def _remove_tag(self, packet, vlan=None, tag_type=None):
89 if tag_type:
90 self.test.instance().assertEqual(packet.type, tag_type)
91
92 payload = packet.payload
93 if vlan:
94 self.test.instance().assertEqual(payload.vlan, vlan)
95 inner_type = payload.type
96 payload = payload.payload
97 packet.remove_payload()
98 packet.add_payload(payload)
99 packet.type = inner_type
100 return packet
101
102 def add_dot1q_layer(self, packet, vlan):
103 return self._add_tag(packet, vlan, self.DOT1Q_TYPE)
104
105 def add_dot1ad_layer(self, packet, outer, inner):
106 p = self._add_tag(packet, inner, self.DOT1Q_TYPE)
107 return self._add_tag(p, outer, self.DOT1AD_TYPE)
108
109 def remove_dot1q_layer(self, packet, vlan=None):
110 return self._remove_tag(packet, vlan, self.DOT1Q_TYPE)
111
112 def remove_dot1ad_layer(self, packet, outer=None, inner=None):
113 p = self._remove_tag(packet, outer, self.DOT1AD_TYPE)
114 return self._remove_tag(p, inner, self.DOT1Q_TYPE)
115
116 def set_vtr(self, vtr, push1q=0, tag=None, inner=None, outer=None):
117 self._tag1 = 0
118 self._tag2 = 0
119 self._push1q = 0
120
121 if (vtr == L2_VTR_OP.L2_PUSH_1 or
122 vtr == L2_VTR_OP.L2_TRANSLATE_1_1 or
123 vtr == L2_VTR_OP.L2_TRANSLATE_2_1):
124 self._tag1 = tag
125 self._push1q = push1q
126 if (vtr == L2_VTR_OP.L2_PUSH_2 or
127 vtr == L2_VTR_OP.L2_TRANSLATE_1_2 or
128 vtr == L2_VTR_OP.L2_TRANSLATE_2_2):
129 self._tag1 = outer
130 self._tag2 = inner
131 self._push1q = push1q
132
Ole Troane1ade682019-03-04 23:55:43 +0100133 self.test.vapi.l2_interface_vlan_tag_rewrite(
Ole Troana5b2eec2019-03-11 19:23:25 +0100134 sw_if_index=self.sw_if_index, vtr_op=vtr, push_dot1q=self._push1q,
Eyal Bari284293a2017-06-06 14:18:55 +0300135 tag1=self._tag1, tag2=self._tag2)
136 self._vtr = vtr
137
Klement Sekeraf62ae122016-10-11 11:47:09 +0200138
139class VppDot1QSubint(VppSubInterface):
140
141 @property
142 def vlan(self):
143 """VLAN tag"""
144 return self._vlan
145
146 def __init__(self, test, parent, sub_id, vlan=None):
Klement Sekerab9ef2732018-06-24 22:49:33 +0200147 super(VppDot1QSubint, self).__init__(test, parent, sub_id)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200148 if vlan is None:
149 vlan = sub_id
Klement Sekeraf62ae122016-10-11 11:47:09 +0200150 self._vlan = vlan
Matej Klottonc5bf07f2016-11-23 15:27:17 +0100151 r = test.vapi.create_vlan_subif(parent.sw_if_index, vlan)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200152 self.set_sw_if_index(r.sw_if_index)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200153
154 def create_arp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100155 packet = VppPGInterface.create_arp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200156 return self.add_dot1_layer(packet)
157
158 def create_ndp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100159 packet = VppPGInterface.create_ndp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200160 return self.add_dot1_layer(packet)
161
Eyal Bari284293a2017-06-06 14:18:55 +0300162 # called before sending packet
Klement Sekeraf62ae122016-10-11 11:47:09 +0200163 def add_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300164 return self.add_dot1q_layer(packet, self.vlan)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200165
Eyal Bari284293a2017-06-06 14:18:55 +0300166 # called on received packet to "reverse" the add call
Klement Sekeraf62ae122016-10-11 11:47:09 +0200167 def remove_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300168 return self.remove_dot1q_layer(packet, self.vlan)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200169
170
171class VppDot1ADSubint(VppSubInterface):
172
173 @property
174 def outer_vlan(self):
175 """Outer VLAN tag"""
176 return self._outer_vlan
177
178 @property
179 def inner_vlan(self):
180 """Inner VLAN tag"""
181 return self._inner_vlan
182
183 def __init__(self, test, parent, sub_id, outer_vlan, inner_vlan):
Klement Sekerab9ef2732018-06-24 22:49:33 +0200184 super(VppDot1ADSubint, self).__init__(test, parent, sub_id)
Ole Troana5b2eec2019-03-11 19:23:25 +0100185 r = test.vapi.create_subif(sw_if_index=parent.sw_if_index,
186 sub_id=sub_id, outer_vlan_id=outer_vlan,
Ole Trøan3b0d7e42019-03-15 16:14:41 +0000187 inner_vlan_id=inner_vlan, two_tags=1,
188 dot1ad=1, exact_match=1)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200189 self.set_sw_if_index(r.sw_if_index)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200190 self._outer_vlan = outer_vlan
191 self._inner_vlan = inner_vlan
Klement Sekeraf62ae122016-10-11 11:47:09 +0200192
193 def create_arp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100194 packet = VppPGInterface.create_arp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200195 return self.add_dot1_layer(packet)
196
197 def create_ndp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100198 packet = VppPGInterface.create_ndp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200199 return self.add_dot1_layer(packet)
200
201 def add_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300202 return self.add_dot1ad_layer(packet, self.outer_vlan, self.inner_vlan)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200203
204 def remove_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300205 return self.remove_dot1ad_layer(packet, self.outer_vlan,
206 self.inner_vlan)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200207
208
209class VppP2PSubint(VppSubInterface):
210
211 def __init__(self, test, parent, sub_id, remote_mac):
Klement Sekerab9ef2732018-06-24 22:49:33 +0200212 super(VppP2PSubint, self).__init__(test, parent, sub_id)
Ole Troane1ade682019-03-04 23:55:43 +0100213 r = test.vapi.p2p_ethernet_add(parent.sw_if_index,
214 remote_mac, sub_id)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200215 self.set_sw_if_index(r.sw_if_index)
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700216 self.parent_sw_if_index = parent.sw_if_index
217 self.p2p_remote_mac = remote_mac
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200218
219 def add_dot1_layer(self, packet):
220 return packet
221
222 def remove_dot1_layer(self, packet):
223 return packet
224
225 def create_arp_req(self):
226 packet = VppPGInterface.create_arp_req(self)
227 return packet
228
229 def create_ndp_req(self):
230 packet = VppPGInterface.create_ndp_req(self)
231 return packet