blob: 90989291c1fa9066f478f70b104bac5845c5c1a8 [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
Jakub Grajciare63325e2019-03-01 08:55:49 +01007from vpp_papi import VppEnum
Klement Sekeraf62ae122016-10-11 11:47:09 +02008
9
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080010@six.add_metaclass(abc.ABCMeta)
Matej Klotton0178d522016-11-04 11:11:44 +010011class VppSubInterface(VppPGInterface):
Klement Sekeraf62ae122016-10-11 11:47:09 +020012
13 @property
14 def parent(self):
15 """Parent interface for this sub-interface"""
16 return self._parent
17
18 @property
19 def sub_id(self):
20 """Sub-interface ID"""
21 return self._sub_id
22
Eyal Bari284293a2017-06-06 14:18:55 +030023 @property
24 def tag1(self):
25 return self._tag1
26
27 @property
28 def tag2(self):
29 return self._tag2
30
31 @property
32 def vtr(self):
33 return self._vtr
34
Klement Sekeraf62ae122016-10-11 11:47:09 +020035 def __init__(self, test, parent, sub_id):
Matej Klottonc5bf07f2016-11-23 15:27:17 +010036 VppInterface.__init__(self, test)
Klement Sekeraf62ae122016-10-11 11:47:09 +020037 self._parent = parent
38 self._parent.add_sub_if(self)
39 self._sub_id = sub_id
Eyal Bari284293a2017-06-06 14:18:55 +030040 self.DOT1AD_TYPE = 0x88A8
41 self.DOT1Q_TYPE = 0x8100
Klement Sekeraf62ae122016-10-11 11:47:09 +020042
Klement Sekerab9ef2732018-06-24 22:49:33 +020043 def set_sw_if_index(self, sw_if_index):
44 super(VppSubInterface, self).set_sw_if_index(sw_if_index)
45 self.set_vtr(L2_VTR_OP.L2_DISABLED)
46
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080047 @abc.abstractmethod
Klement Sekeraf62ae122016-10-11 11:47:09 +020048 def create_arp_req(self):
49 pass
50
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080051 @abc.abstractmethod
Klement Sekeraf62ae122016-10-11 11:47:09 +020052 def create_ndp_req(self):
53 pass
54
Klement Sekerabeaded52018-06-24 10:30:37 +020055 def resolve_arp(self):
56 super(VppSubInterface, self).resolve_arp(self.parent)
57
58 def resolve_ndp(self):
59 super(VppSubInterface, self).resolve_ndp(self.parent)
60
Paul Vinciguerra3bce8eb2018-11-24 21:46:05 -080061 @abc.abstractmethod
Klement Sekeraf62ae122016-10-11 11:47:09 +020062 def add_dot1_layer(self, pkt):
63 pass
64
Neale Ranns177bbdc2016-11-15 09:46:51 +000065 def remove_vpp_config(self):
Klement Sekerab9ef2732018-06-24 22:49:33 +020066 self.test.vapi.delete_subif(self.sw_if_index)
Neale Ranns177bbdc2016-11-15 09:46:51 +000067
Eyal Bari284293a2017-06-06 14:18:55 +030068 def _add_tag(self, packet, vlan, tag_type):
69 payload = packet.payload
70 inner_type = packet.type
71 packet.remove_payload()
72 packet.add_payload(Dot1Q(vlan=vlan) / payload)
73 packet.payload.type = inner_type
74 packet.payload.vlan = vlan
75 packet.type = tag_type
76 return packet
77
78 def _remove_tag(self, packet, vlan=None, tag_type=None):
79 if tag_type:
80 self.test.instance().assertEqual(packet.type, tag_type)
81
82 payload = packet.payload
83 if vlan:
84 self.test.instance().assertEqual(payload.vlan, vlan)
85 inner_type = payload.type
86 payload = payload.payload
87 packet.remove_payload()
88 packet.add_payload(payload)
89 packet.type = inner_type
90 return packet
91
92 def add_dot1q_layer(self, packet, vlan):
93 return self._add_tag(packet, vlan, self.DOT1Q_TYPE)
94
95 def add_dot1ad_layer(self, packet, outer, inner):
96 p = self._add_tag(packet, inner, self.DOT1Q_TYPE)
97 return self._add_tag(p, outer, self.DOT1AD_TYPE)
98
99 def remove_dot1q_layer(self, packet, vlan=None):
100 return self._remove_tag(packet, vlan, self.DOT1Q_TYPE)
101
102 def remove_dot1ad_layer(self, packet, outer=None, inner=None):
103 p = self._remove_tag(packet, outer, self.DOT1AD_TYPE)
104 return self._remove_tag(p, inner, self.DOT1Q_TYPE)
105
106 def set_vtr(self, vtr, push1q=0, tag=None, inner=None, outer=None):
107 self._tag1 = 0
108 self._tag2 = 0
109 self._push1q = 0
110
111 if (vtr == L2_VTR_OP.L2_PUSH_1 or
112 vtr == L2_VTR_OP.L2_TRANSLATE_1_1 or
113 vtr == L2_VTR_OP.L2_TRANSLATE_2_1):
114 self._tag1 = tag
115 self._push1q = push1q
116 if (vtr == L2_VTR_OP.L2_PUSH_2 or
117 vtr == L2_VTR_OP.L2_TRANSLATE_1_2 or
118 vtr == L2_VTR_OP.L2_TRANSLATE_2_2):
119 self._tag1 = outer
120 self._tag2 = inner
121 self._push1q = push1q
122
Ole Troane1ade682019-03-04 23:55:43 +0100123 self.test.vapi.l2_interface_vlan_tag_rewrite(
Ole Troana5b2eec2019-03-11 19:23:25 +0100124 sw_if_index=self.sw_if_index, vtr_op=vtr, push_dot1q=self._push1q,
Eyal Bari284293a2017-06-06 14:18:55 +0300125 tag1=self._tag1, tag2=self._tag2)
126 self._vtr = vtr
127
Klement Sekeraf62ae122016-10-11 11:47:09 +0200128
129class VppDot1QSubint(VppSubInterface):
130
131 @property
132 def vlan(self):
133 """VLAN tag"""
134 return self._vlan
135
136 def __init__(self, test, parent, sub_id, vlan=None):
Klement Sekerab9ef2732018-06-24 22:49:33 +0200137 super(VppDot1QSubint, self).__init__(test, parent, sub_id)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200138 if vlan is None:
139 vlan = sub_id
Klement Sekeraf62ae122016-10-11 11:47:09 +0200140 self._vlan = vlan
Matej Klottonc5bf07f2016-11-23 15:27:17 +0100141 r = test.vapi.create_vlan_subif(parent.sw_if_index, vlan)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200142 self.set_sw_if_index(r.sw_if_index)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200143
144 def create_arp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100145 packet = VppPGInterface.create_arp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200146 return self.add_dot1_layer(packet)
147
148 def create_ndp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100149 packet = VppPGInterface.create_ndp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200150 return self.add_dot1_layer(packet)
151
Eyal Bari284293a2017-06-06 14:18:55 +0300152 # called before sending packet
Klement Sekeraf62ae122016-10-11 11:47:09 +0200153 def add_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300154 return self.add_dot1q_layer(packet, self.vlan)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200155
Eyal Bari284293a2017-06-06 14:18:55 +0300156 # called on received packet to "reverse" the add call
Klement Sekeraf62ae122016-10-11 11:47:09 +0200157 def remove_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300158 return self.remove_dot1q_layer(packet, self.vlan)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200159
160
161class VppDot1ADSubint(VppSubInterface):
162
163 @property
164 def outer_vlan(self):
165 """Outer VLAN tag"""
166 return self._outer_vlan
167
168 @property
169 def inner_vlan(self):
170 """Inner VLAN tag"""
171 return self._inner_vlan
172
173 def __init__(self, test, parent, sub_id, outer_vlan, inner_vlan):
Klement Sekerab9ef2732018-06-24 22:49:33 +0200174 super(VppDot1ADSubint, self).__init__(test, parent, sub_id)
Jakub Grajciare63325e2019-03-01 08:55:49 +0100175 flags = (VppEnum.vl_api_sub_if_flags_t.SUB_IF_API_FLAG_DOT1AD |
176 VppEnum.vl_api_sub_if_flags_t.SUB_IF_API_FLAG_TWO_TAGS |
177 VppEnum.vl_api_sub_if_flags_t.SUB_IF_API_FLAG_EXACT_MATCH)
Ole Troana5b2eec2019-03-11 19:23:25 +0100178 r = test.vapi.create_subif(sw_if_index=parent.sw_if_index,
179 sub_id=sub_id, outer_vlan_id=outer_vlan,
Jakub Grajciare63325e2019-03-01 08:55:49 +0100180 inner_vlan_id=inner_vlan,
181 sub_if_flags=flags)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200182 self.set_sw_if_index(r.sw_if_index)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200183 self._outer_vlan = outer_vlan
184 self._inner_vlan = inner_vlan
Klement Sekeraf62ae122016-10-11 11:47:09 +0200185
186 def create_arp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100187 packet = VppPGInterface.create_arp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200188 return self.add_dot1_layer(packet)
189
190 def create_ndp_req(self):
Matej Klotton0178d522016-11-04 11:11:44 +0100191 packet = VppPGInterface.create_ndp_req(self)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200192 return self.add_dot1_layer(packet)
193
194 def add_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300195 return self.add_dot1ad_layer(packet, self.outer_vlan, self.inner_vlan)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200196
197 def remove_dot1_layer(self, packet):
Eyal Bari284293a2017-06-06 14:18:55 +0300198 return self.remove_dot1ad_layer(packet, self.outer_vlan,
199 self.inner_vlan)
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200200
201
202class VppP2PSubint(VppSubInterface):
203
204 def __init__(self, test, parent, sub_id, remote_mac):
Klement Sekerab9ef2732018-06-24 22:49:33 +0200205 super(VppP2PSubint, self).__init__(test, parent, sub_id)
Ole Troane1ade682019-03-04 23:55:43 +0100206 r = test.vapi.p2p_ethernet_add(parent.sw_if_index,
207 remote_mac, sub_id)
Klement Sekerab9ef2732018-06-24 22:49:33 +0200208 self.set_sw_if_index(r.sw_if_index)
Neale Ranns2ae2bc52018-03-16 03:22:39 -0700209 self.parent_sw_if_index = parent.sw_if_index
210 self.p2p_remote_mac = remote_mac
Pavel Kotucek15ac81c2017-06-20 14:00:26 +0200211
212 def add_dot1_layer(self, packet):
213 return packet
214
215 def remove_dot1_layer(self, packet):
216 return packet
217
218 def create_arp_req(self):
219 packet = VppPGInterface.create_arp_req(self)
220 return packet
221
222 def create_ndp_req(self):
223 packet = VppPGInterface.create_ndp_req(self)
224 return packet