blob: 15cd6edb8e016961e1dae842820e0c5bd1f86719 [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
Eyal Bari284293a2017-06-06 14:18:55 +03005from vpp_papi_provider import L2_VTR_OP
Klement Sekerabeaded52018-06-24 10:30:37 +02006from vpp_interface import VppInterface
Klement Sekeraf62ae122016-10-11 11:47:09 +02007
8
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -08009@six.add_metaclass(abc.ABCMeta)
Matej Klotton0178d522016-11-04 11:11:44 +010010class VppSubInterface(VppPGInterface):
Klement Sekeraf62ae122016-10-11 11:47:09 +020011
12 @property
13 def parent(self):
14 """Parent interface for this sub-interface"""
15 return self._parent
16
17 @property
18 def sub_id(self):
19 """Sub-interface ID"""
20 return self._sub_id
21
Eyal Bari284293a2017-06-06 14:18:55 +030022 @property
23 def tag1(self):
24 return self._tag1
25
26 @property
27 def tag2(self):
28 return self._tag2
29
30 @property
31 def vtr(self):
32 return self._vtr
33
Klement Sekeraf62ae122016-10-11 11:47:09 +020034 def __init__(self, test, parent, sub_id):
Matej Klottonc5bf07f2016-11-23 15:27:17 +010035 VppInterface.__init__(self, test)
Klement Sekeraf62ae122016-10-11 11:47:09 +020036 self._parent = parent
37 self._parent.add_sub_if(self)
38 self._sub_id = sub_id
Eyal Bari284293a2017-06-06 14:18:55 +030039 self.DOT1AD_TYPE = 0x88A8
40 self.DOT1Q_TYPE = 0x8100
Klement Sekeraf62ae122016-10-11 11:47:09 +020041
Klement Sekerab9ef2732018-06-24 22:49:33 +020042 def set_sw_if_index(self, sw_if_index):
43 super(VppSubInterface, self).set_sw_if_index(sw_if_index)
44 self.set_vtr(L2_VTR_OP.L2_DISABLED)
45
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080046 @abc.abstractmethod
Klement Sekeraf62ae122016-10-11 11:47:09 +020047 def create_arp_req(self):
48 pass
49
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080050 @abc.abstractmethod
Klement Sekeraf62ae122016-10-11 11:47:09 +020051 def create_ndp_req(self):
52 pass
53
Klement Sekerabeaded52018-06-24 10:30:37 +020054 def resolve_arp(self):
55 super(VppSubInterface, self).resolve_arp(self.parent)
56
57 def resolve_ndp(self):
58 super(VppSubInterface, self).resolve_ndp(self.parent)
59
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080060 @abc.abstractmethod
Klement Sekeraf62ae122016-10-11 11:47:09 +020061 def add_dot1_layer(self, pkt):
62 pass
63
Neale Ranns177bbdc2016-11-15 09:46:51 +000064 def remove_vpp_config(self):
Klement Sekerab9ef2732018-06-24 22:49:33 +020065 self.test.vapi.delete_subif(self.sw_if_index)
Neale Ranns177bbdc2016-11-15 09:46:51 +000066
Eyal Bari284293a2017-06-06 14:18:55 +030067 def _add_tag(self, packet, vlan, tag_type):
68 payload = packet.payload
69 inner_type = packet.type
70 packet.remove_payload()
71 packet.add_payload(Dot1Q(vlan=vlan) / payload)
72 packet.payload.type = inner_type
73 packet.payload.vlan = vlan
74 packet.type = tag_type
75 return packet
76
77 def _remove_tag(self, packet, vlan=None, tag_type=None):
78 if tag_type:
79 self.test.instance().assertEqual(packet.type, tag_type)
80
81 payload = packet.payload
82 if vlan:
83 self.test.instance().assertEqual(payload.vlan, vlan)
84 inner_type = payload.type
85 payload = payload.payload
86 packet.remove_payload()
87 packet.add_payload(payload)
88 packet.type = inner_type
89 return packet
90
91 def add_dot1q_layer(self, packet, vlan):
92 return self._add_tag(packet, vlan, self.DOT1Q_TYPE)
93
94 def add_dot1ad_layer(self, packet, outer, inner):
95 p = self._add_tag(packet, inner, self.DOT1Q_TYPE)
96 return self._add_tag(p, outer, self.DOT1AD_TYPE)
97
98 def remove_dot1q_layer(self, packet, vlan=None):
99 return self._remove_tag(packet, vlan, self.DOT1Q_TYPE)
100
101 def remove_dot1ad_layer(self, packet, outer=None, inner=None):
102 p = self._remove_tag(packet, outer, self.DOT1AD_TYPE)
103 return self._remove_tag(p, inner, self.DOT1Q_TYPE)
104
105 def set_vtr(self, vtr, push1q=0, tag=None, inner=None, outer=None):
106 self._tag1 = 0
107 self._tag2 = 0
108 self._push1q = 0
109
110 if (vtr == L2_VTR_OP.L2_PUSH_1 or
111 vtr == L2_VTR_OP.L2_TRANSLATE_1_1 or
112 vtr == L2_VTR_OP.L2_TRANSLATE_2_1):
113 self._tag1 = tag
114 self._push1q = push1q
115 if (vtr == L2_VTR_OP.L2_PUSH_2 or
116 vtr == L2_VTR_OP.L2_TRANSLATE_1_2 or
117 vtr == L2_VTR_OP.L2_TRANSLATE_2_2):
118 self._tag1 = outer
119 self._tag2 = inner
120 self._push1q = push1q
121
Ole Troane1ade682019-03-04 23:55:43 +0100122 self.test.vapi.l2_interface_vlan_tag_rewrite(
Ole Troana5b2eec2019-03-11 19:23:25 +0100123 sw_if_index=self.sw_if_index, vtr_op=vtr, push_dot1q=self._push1q,
Eyal Bari284293a2017-06-06 14:18:55 +0300124 tag1=self._tag1, tag2=self._tag2)
125 self._vtr = vtr
126
Klement Sekeraf62ae122016-10-11 11:47:09 +0200127
128class VppDot1QSubint(VppSubInterface):
129
130 @property
131 def vlan(self):
132 """VLAN tag"""
133 return self._vlan
134
135 def __init__(self, test, parent, sub_id, vlan=None):
Klement Sekerab9ef2732018-06-24 22:49:33 +0200136 super(VppDot1QSubint, self).__init__(test, parent, sub_id)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200137 if vlan is None:
138 vlan = sub_id
Klement Sekeraf62ae122016-10-11 11:47:09 +0200139 self._vlan = vlan
Matej Klottonc5bf07f2016-11-23 15:27:17 +0100140 r = test.vapi.create_vlan_subif(parent.sw_if_index, vlan)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200141 self.set_sw_if_index(r.sw_if_index)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200142
143 def create_arp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100144 packet = VppPGInterface.create_arp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200145 return self.add_dot1_layer(packet)
146
147 def create_ndp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100148 packet = VppPGInterface.create_ndp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200149 return self.add_dot1_layer(packet)
150
Eyal Bari284293a2017-06-06 14:18:55 +0300151 # called before sending packet
Klement Sekeraf62ae122016-10-11 11:47:09 +0200152 def add_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300153 return self.add_dot1q_layer(packet, self.vlan)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200154
Eyal Bari284293a2017-06-06 14:18:55 +0300155 # called on received packet to "reverse" the add call
Klement Sekeraf62ae122016-10-11 11:47:09 +0200156 def remove_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300157 return self.remove_dot1q_layer(packet, self.vlan)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200158
159
160class VppDot1ADSubint(VppSubInterface):
161
162 @property
163 def outer_vlan(self):
164 """Outer VLAN tag"""
165 return self._outer_vlan
166
167 @property
168 def inner_vlan(self):
169 """Inner VLAN tag"""
170 return self._inner_vlan
171
172 def __init__(self, test, parent, sub_id, outer_vlan, inner_vlan):
Klement Sekerab9ef2732018-06-24 22:49:33 +0200173 super(VppDot1ADSubint, self).__init__(test, parent, sub_id)
Ole Troana5b2eec2019-03-11 19:23:25 +0100174 r = test.vapi.create_subif(sw_if_index=parent.sw_if_index,
175 sub_id=sub_id, outer_vlan_id=outer_vlan,
176 inner_vlan_id=inner_vlan, two_tags=1,
177 dot1ad=1, exact_match=1)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200178 self.set_sw_if_index(r.sw_if_index)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200179 self._outer_vlan = outer_vlan
180 self._inner_vlan = inner_vlan
Klement Sekeraf62ae122016-10-11 11:47:09 +0200181
182 def create_arp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100183 packet = VppPGInterface.create_arp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200184 return self.add_dot1_layer(packet)
185
186 def create_ndp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100187 packet = VppPGInterface.create_ndp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200188 return self.add_dot1_layer(packet)
189
190 def add_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300191 return self.add_dot1ad_layer(packet, self.outer_vlan, self.inner_vlan)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200192
193 def remove_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300194 return self.remove_dot1ad_layer(packet, self.outer_vlan,
195 self.inner_vlan)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200196
197
198class VppP2PSubint(VppSubInterface):
199
200 def __init__(self, test, parent, sub_id, remote_mac):
Klement Sekerab9ef2732018-06-24 22:49:33 +0200201 super(VppP2PSubint, self).__init__(test, parent, sub_id)
Ole Troane1ade682019-03-04 23:55:43 +0100202 r = test.vapi.p2p_ethernet_add(parent.sw_if_index,
203 remote_mac, sub_id)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200204 self.set_sw_if_index(r.sw_if_index)
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700205 self.parent_sw_if_index = parent.sw_if_index
206 self.p2p_remote_mac = remote_mac
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200207
208 def add_dot1_layer(self, packet):
209 return packet
210
211 def remove_dot1_layer(self, packet):
212 return packet
213
214 def create_arp_req(self):
215 packet = VppPGInterface.create_arp_req(self)
216 return packet
217
218 def create_ndp_req(self):
219 packet = VppPGInterface.create_ndp_req(self)
220 return packet