@@ -632,6 +632,7 @@ def verify_udp(self, udp):
632632 def get_ike_header (self , packet ):
633633 try :
634634 ih = packet [ikev2 .IKEv2 ]
635+ ih = self .verify_and_remove_non_esp_marker (ih )
635636 except IndexError as e :
636637 # this is a workaround for getting IKEv2 layer as both ikev2 and
637638 # ipsec register for port 4500
@@ -933,6 +934,8 @@ def verify_nat_detection(self, packet):
933934 self .assertEqual (s .load , dst_sha )
934935
935936 def verify_sa_init_request (self , packet ):
937+ udp = packet [UDP ]
938+ self .sa .dport = udp .sport
936939 ih = packet [ikev2 .IKEv2 ]
937940 self .assertNotEqual (ih .init_SPI , 8 * b'\x00 ' )
938941 self .assertEqual (ih .exch_type , 34 ) # SA_INIT
@@ -974,6 +977,8 @@ def update_esp_transforms(self, trans, sa):
974977 trans = trans .payload
975978
976979 def verify_sa_auth_req (self , packet ):
980+ udp = packet [UDP ]
981+ self .sa .dport = udp .sport
977982 ih = self .get_ike_header (packet )
978983 self .assertEqual (ih .resp_SPI , self .sa .rspi )
979984 self .assertEqual (ih .init_SPI , self .sa .ispi )
@@ -1009,18 +1014,32 @@ def send_init_response(self):
10091014 transform_id = self .sa .ike_dh ))
10101015 props = (ikev2 .IKEv2_payload_Proposal (proposal = 1 , proto = 'IKEv2' ,
10111016 trans_nb = 4 , trans = trans ))
1017+
1018+ src_address = inet_pton (socket .AF_INET , self .pg0 .remote_ip4 )
1019+ if self .sa .natt :
1020+ dst_address = b'\x0a \x0a \x0a \x0a '
1021+ else :
1022+ dst_address = inet_pton (socket .AF_INET , self .pg0 .local_ip4 )
1023+ src_nat = self .sa .compute_nat_sha1 (src_address , self .sa .sport )
1024+ dst_nat = self .sa .compute_nat_sha1 (dst_address , self .sa .dport )
1025+
10121026 self .sa .init_resp_packet = (
10131027 ikev2 .IKEv2 (init_SPI = self .sa .ispi , resp_SPI = self .sa .rspi ,
10141028 exch_type = 'IKE_SA_INIT' , flags = 'Response' ) /
10151029 ikev2 .IKEv2_payload_SA (next_payload = 'KE' , prop = props ) /
10161030 ikev2 .IKEv2_payload_KE (next_payload = 'Nonce' ,
10171031 group = self .sa .ike_dh ,
10181032 load = self .sa .my_dh_pub_key ) /
1019- ikev2 .IKEv2_payload_Nonce (load = self .sa .r_nonce ))
1033+ ikev2 .IKEv2_payload_Nonce (load = self .sa .r_nonce ,
1034+ next_payload = 'Notify' ) /
1035+ ikev2 .IKEv2_payload_Notify (
1036+ type = 'NAT_DETECTION_SOURCE_IP' , load = src_nat ,
1037+ next_payload = 'Notify' ) / ikev2 .IKEv2_payload_Notify (
1038+ type = 'NAT_DETECTION_DESTINATION_IP' , load = dst_nat ))
10201039
10211040 ike_msg = self .create_packet (self .pg0 , self .sa .init_resp_packet ,
10221041 self .sa .sport , self .sa .dport ,
1023- self . sa . natt , self .ip6 )
1042+ False , self .ip6 )
10241043 self .pg_send (self .pg0 , ike_msg )
10251044 capture = self .pg0 .get_capture (1 )
10261045 self .verify_sa_auth_req (capture [0 ])
@@ -1588,6 +1607,31 @@ def verify_profile(self, ap, cp):
15881607 self .assertEqual (ap .tun_itf , 0xffffffff )
15891608
15901609
1610+ class TestInitiatorNATT (TemplateInitiator , Ikev2Params ):
1611+ """ test ikev2 initiator - NAT traversal (intitiator behind NAT) """
1612+
1613+ def config_tc (self ):
1614+ self .config_params ({
1615+ 'natt' : True ,
1616+ 'is_initiator' : False , # seen from test case perspective
1617+ # thus vpp is initiator
1618+ 'responder' : {'sw_if_index' : self .pg0 .sw_if_index ,
1619+ 'addr' : self .pg0 .remote_ip4 },
1620+ 'ike-crypto' : ('AES-GCM-16ICV' , 32 ),
1621+ 'ike-integ' : 'NULL' ,
1622+ 'ike-dh' : '3072MODPgr' ,
1623+ 'ike_transforms' : {
1624+ 'crypto_alg' : 20 , # "aes-gcm-16"
1625+ 'crypto_key_size' : 256 ,
1626+ 'dh_group' : 15 , # "modp-3072"
1627+ },
1628+ 'esp_transforms' : {
1629+ 'crypto_alg' : 12 , # "aes-cbc"
1630+ 'crypto_key_size' : 256 ,
1631+ # "hmac-sha2-256-128"
1632+ 'integ_alg' : 12 }})
1633+
1634+
15911635class TestInitiatorPsk (TemplateInitiator , Ikev2Params ):
15921636 """ test ikev2 initiator - pre shared key auth """
15931637
0 commit comments