TEST: IPSEC NAT-T with UDP header
[vpp.git] / test / test_ipsec_esp.py
1 import socket
2 import unittest
3 from scapy.layers.ipsec import ESP
4 from scapy.layers.inet import UDP
5
6 from framework import VppTestRunner
7 from template_ipsec import IpsecTra46Tests, IpsecTun46Tests, TemplateIpsec, \
8     IpsecTcpTests, IpsecTun4Tests, IpsecTra4Tests
9 from vpp_ipsec import VppIpsecSpd, VppIpsecSpdEntry, VppIpsecSA,\
10         VppIpsecSpdItfBinding
11 from vpp_ip_route import VppIpRoute, VppRoutePath
12 from vpp_ip import DpoProto
13 from vpp_papi import VppEnum
14
15
16 def config_esp_tun(test, params):
17     addr_type = params.addr_type
18     scapy_tun_sa_id = params.scapy_tun_sa_id
19     scapy_tun_spi = params.scapy_tun_spi
20     vpp_tun_sa_id = params.vpp_tun_sa_id
21     vpp_tun_spi = params.vpp_tun_spi
22     auth_algo_vpp_id = params.auth_algo_vpp_id
23     auth_key = params.auth_key
24     crypt_algo_vpp_id = params.crypt_algo_vpp_id
25     crypt_key = params.crypt_key
26     remote_tun_if_host = params.remote_tun_if_host
27     addr_any = params.addr_any
28     addr_bcast = params.addr_bcast
29     e = VppEnum.vl_api_ipsec_spd_action_t
30
31     params.tun_sa_in = VppIpsecSA(test, scapy_tun_sa_id, scapy_tun_spi,
32                                   auth_algo_vpp_id, auth_key,
33                                   crypt_algo_vpp_id, crypt_key,
34                                   test.vpp_esp_protocol,
35                                   test.tun_if.local_addr[addr_type],
36                                   test.tun_if.remote_addr[addr_type])
37     params.tun_sa_in.add_vpp_config()
38     params.tun_sa_out = VppIpsecSA(test, vpp_tun_sa_id, vpp_tun_spi,
39                                    auth_algo_vpp_id, auth_key,
40                                    crypt_algo_vpp_id, crypt_key,
41                                    test.vpp_esp_protocol,
42                                    test.tun_if.remote_addr[addr_type],
43                                    test.tun_if.local_addr[addr_type])
44     params.tun_sa_out.add_vpp_config()
45
46     params.spd_policy_in_any = VppIpsecSpdEntry(test, test.tun_spd,
47                                                 scapy_tun_sa_id,
48                                                 addr_any, addr_bcast,
49                                                 addr_any, addr_bcast,
50                                                 socket.IPPROTO_ESP)
51     params.spd_policy_in_any.add_vpp_config()
52     params.spd_policy_out_any = VppIpsecSpdEntry(test, test.tun_spd,
53                                                  scapy_tun_sa_id,
54                                                  addr_any, addr_bcast,
55                                                  addr_any, addr_bcast,
56                                                  socket.IPPROTO_ESP,
57                                                  is_outbound=0)
58     params.spd_policy_out_any.add_vpp_config()
59
60     VppIpsecSpdEntry(test, test.tun_spd, vpp_tun_sa_id,
61                      remote_tun_if_host, remote_tun_if_host,
62                      test.pg1.remote_addr[addr_type],
63                      test.pg1.remote_addr[addr_type],
64                      0,
65                      priority=10,
66                      policy=e.IPSEC_API_SPD_ACTION_PROTECT,
67                      is_outbound=0).add_vpp_config()
68     VppIpsecSpdEntry(test, test.tun_spd, scapy_tun_sa_id,
69                      test.pg1.remote_addr[addr_type],
70                      test.pg1.remote_addr[addr_type],
71                      remote_tun_if_host, remote_tun_if_host,
72                      0,
73                      policy=e.IPSEC_API_SPD_ACTION_PROTECT,
74                      priority=10).add_vpp_config()
75
76     VppIpsecSpdEntry(test, test.tun_spd, vpp_tun_sa_id,
77                      remote_tun_if_host, remote_tun_if_host,
78                      test.pg0.local_addr[addr_type],
79                      test.pg0.local_addr[addr_type],
80                      0,
81                      priority=20,
82                      policy=e.IPSEC_API_SPD_ACTION_PROTECT,
83                      is_outbound=0).add_vpp_config()
84     VppIpsecSpdEntry(test, test.tun_spd, scapy_tun_sa_id,
85                      test.pg0.local_addr[addr_type],
86                      test.pg0.local_addr[addr_type],
87                      remote_tun_if_host, remote_tun_if_host,
88                      0,
89                      policy=e.IPSEC_API_SPD_ACTION_PROTECT,
90                      priority=20).add_vpp_config()
91
92
93 def config_esp_tra(test, params):
94     addr_type = params.addr_type
95     scapy_tra_sa_id = params.scapy_tra_sa_id
96     scapy_tra_spi = params.scapy_tra_spi
97     vpp_tra_sa_id = params.vpp_tra_sa_id
98     vpp_tra_spi = params.vpp_tra_spi
99     auth_algo_vpp_id = params.auth_algo_vpp_id
100     auth_key = params.auth_key
101     crypt_algo_vpp_id = params.crypt_algo_vpp_id
102     crypt_key = params.crypt_key
103     addr_any = params.addr_any
104     addr_bcast = params.addr_bcast
105     flags = (VppEnum.vl_api_ipsec_sad_flags_t.
106              IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY)
107     e = VppEnum.vl_api_ipsec_spd_action_t
108     flags = params.flags | flags
109
110     params.tra_sa_in = VppIpsecSA(test, scapy_tra_sa_id, scapy_tra_spi,
111                                   auth_algo_vpp_id, auth_key,
112                                   crypt_algo_vpp_id, crypt_key,
113                                   test.vpp_esp_protocol,
114                                   flags=flags)
115     params.tra_sa_in.add_vpp_config()
116     params.tra_sa_out = VppIpsecSA(test, vpp_tra_sa_id, vpp_tra_spi,
117                                    auth_algo_vpp_id, auth_key,
118                                    crypt_algo_vpp_id, crypt_key,
119                                    test.vpp_esp_protocol,
120                                    flags=flags)
121     params.tra_sa_out.add_vpp_config()
122
123     VppIpsecSpdEntry(test, test.tra_spd, vpp_tra_sa_id,
124                      addr_any, addr_bcast,
125                      addr_any, addr_bcast,
126                      socket.IPPROTO_ESP).add_vpp_config()
127     VppIpsecSpdEntry(test, test.tra_spd, vpp_tra_sa_id,
128                      addr_any, addr_bcast,
129                      addr_any, addr_bcast,
130                      socket.IPPROTO_ESP,
131                      is_outbound=0).add_vpp_config()
132
133     VppIpsecSpdEntry(test, test.tra_spd, vpp_tra_sa_id,
134                      test.tra_if.local_addr[addr_type],
135                      test.tra_if.local_addr[addr_type],
136                      test.tra_if.remote_addr[addr_type],
137                      test.tra_if.remote_addr[addr_type],
138                      0, priority=10,
139                      policy=e.IPSEC_API_SPD_ACTION_PROTECT,
140                      is_outbound=0).add_vpp_config()
141     VppIpsecSpdEntry(test, test.tra_spd, scapy_tra_sa_id,
142                      test.tra_if.local_addr[addr_type],
143                      test.tra_if.local_addr[addr_type],
144                      test.tra_if.remote_addr[addr_type],
145                      test.tra_if.remote_addr[addr_type],
146                      0, policy=e.IPSEC_API_SPD_ACTION_PROTECT,
147                      priority=10).add_vpp_config()
148
149
150 class TemplateIpsecEsp(TemplateIpsec):
151     """
152     Basic test for ipsec esp sanity - tunnel and transport modes.
153
154     Below 4 cases are covered as part of this test
155     1) ipsec esp v4 transport basic test  - IPv4 Transport mode
156         scenario using HMAC-SHA1-96 intergrity algo
157     2) ipsec esp v4 transport burst test
158         Above test for 257 pkts
159     3) ipsec esp 4o4 tunnel basic test    - IPv4 Tunnel mode
160         scenario using HMAC-SHA1-96 intergrity algo
161     4) ipsec esp 4o4 tunnel burst test
162         Above test for 257 pkts
163
164     TRANSPORT MODE:
165
166      ---   encrypt   ---
167     |pg2| <-------> |VPP|
168      ---   decrypt   ---
169
170     TUNNEL MODE:
171
172      ---   encrypt   ---   plain   ---
173     |pg0| <-------  |VPP| <------ |pg1|
174      ---             ---           ---
175
176      ---   decrypt   ---   plain   ---
177     |pg0| ------->  |VPP| ------> |pg1|
178      ---             ---           ---
179     """
180     config_esp_tun = config_esp_tun
181     config_esp_tra = config_esp_tra
182
183     def setUp(self):
184         super(TemplateIpsecEsp, self).setUp()
185         self.encryption_type = ESP
186         self.tun_if = self.pg0
187         self.tra_if = self.pg2
188         self.logger.info(self.vapi.ppcli("show int addr"))
189
190         self.tra_spd = VppIpsecSpd(self, self.tra_spd_id)
191         self.tra_spd.add_vpp_config()
192         VppIpsecSpdItfBinding(self, self.tra_spd,
193                               self.tra_if).add_vpp_config()
194
195         for _, p in self.params.items():
196             self.config_esp_tra(p)
197             self.configure_sa_tra(p)
198         self.logger.info(self.vapi.ppcli("show ipsec"))
199
200         self.tun_spd = VppIpsecSpd(self, self.tun_spd_id)
201         self.tun_spd.add_vpp_config()
202         VppIpsecSpdItfBinding(self, self.tun_spd,
203                               self.tun_if).add_vpp_config()
204
205         for _, p in self.params.items():
206             self.config_esp_tun(p)
207         self.logger.info(self.vapi.ppcli("show ipsec"))
208
209         for _, p in self.params.items():
210             d = DpoProto.DPO_PROTO_IP6 if p.is_ipv6 else DpoProto.DPO_PROTO_IP4
211             VppIpRoute(self,  p.remote_tun_if_host, p.addr_len,
212                        [VppRoutePath(self.tun_if.remote_addr[p.addr_type],
213                                      0xffffffff,
214                                      proto=d)],
215                        is_ip6=p.is_ipv6).add_vpp_config()
216
217     def tearDown(self):
218         super(TemplateIpsecEsp, self).tearDown()
219         if not self.vpp_dead:
220             self.vapi.cli("show hardware")
221
222
223 class TestIpsecEsp1(TemplateIpsecEsp, IpsecTra46Tests, IpsecTun46Tests):
224     """ Ipsec ESP - TUN & TRA tests """
225     tra4_encrypt_node_name = "esp4-encrypt"
226     tra4_decrypt_node_name = "esp4-decrypt"
227     tra6_encrypt_node_name = "esp6-encrypt"
228     tra6_decrypt_node_name = "esp6-decrypt"
229     tun4_encrypt_node_name = "esp4-encrypt"
230     tun4_decrypt_node_name = "esp4-decrypt"
231     tun6_encrypt_node_name = "esp6-encrypt"
232     tun6_decrypt_node_name = "esp6-decrypt"
233
234
235 class TestIpsecEsp2(TemplateIpsecEsp, IpsecTcpTests):
236     """ Ipsec ESP - TCP tests """
237     pass
238
239
240 class TemplateIpsecEspUdp(TemplateIpsec):
241     """
242     UDP encapped ESP
243     """
244     config_esp_tun = config_esp_tun
245     config_esp_tra = config_esp_tra
246
247     def setUp(self):
248         super(TemplateIpsecEspUdp, self).setUp()
249         self.encryption_type = ESP
250         self.tun_if = self.pg0
251         self.tra_if = self.pg2
252         self.logger.info(self.vapi.ppcli("show int addr"))
253
254         p = self.ipv4_params
255         p.flags = (VppEnum.vl_api_ipsec_sad_flags_t.
256                    IPSEC_API_SAD_FLAG_UDP_ENCAP)
257         p.nat_header = UDP(sport=5454, dport=4500)
258
259         self.tra_spd = VppIpsecSpd(self, self.tra_spd_id)
260         self.tra_spd.add_vpp_config()
261         VppIpsecSpdItfBinding(self, self.tra_spd,
262                               self.tra_if).add_vpp_config()
263
264         self.config_esp_tra(p)
265         self.configure_sa_tra(p)
266
267         self.tun_spd = VppIpsecSpd(self, self.tun_spd_id)
268         self.tun_spd.add_vpp_config()
269         VppIpsecSpdItfBinding(self, self.tun_spd,
270                               self.tun_if).add_vpp_config()
271
272         self.config_esp_tun(p)
273         self.logger.info(self.vapi.ppcli("show ipsec"))
274
275         d = DpoProto.DPO_PROTO_IP4
276         VppIpRoute(self,  p.remote_tun_if_host, p.addr_len,
277                    [VppRoutePath(self.tun_if.remote_addr[p.addr_type],
278                                  0xffffffff,
279                                  proto=d)]).add_vpp_config()
280
281     def tearDown(self):
282         super(TemplateIpsecEspUdp, self).tearDown()
283         if not self.vpp_dead:
284             self.vapi.cli("show hardware")
285
286
287 class TestIpsecEspUdp(TemplateIpsecEspUdp, IpsecTra4Tests, IpsecTun4Tests):
288     """ Ipsec NAT-T ESP UDP tests """
289     tra4_encrypt_node_name = "esp4-encrypt"
290     tra4_decrypt_node_name = "esp4-decrypt"
291     tun4_encrypt_node_name = "esp4-encrypt"
292     tun4_decrypt_node_name = "esp4-decrypt"
293     pass
294
295
296 if __name__ == '__main__':
297     unittest.main(testRunner=VppTestRunner)