+ #
+ # out of window are dropped
+ # this is Case B. So VPP will consider this to be a high seq num wrap
+ # and so the decrypt attempt will fail
+ #
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=17))
+ self.send_and_assert_no_replies(self.tra_if, pkt * 17)
+
+ if use_esn:
+ # an out of window error with ESN looks like a high sequence
+ # wrap. but since it isn't then the verify will fail.
+ hash_failed_count += 17
+ self.assert_error_counter_equal(hash_failed_node_name,
+ hash_failed_count)
+
+ else:
+ replay_count += 17
+ self.assert_error_counter_equal(replay_node_name,
+ replay_count)
+
+ # valid packet moves the window over to 258
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=258))
+ rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
+ decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
+
+ #
+ # move VPP's SA TX seq-num to just before the seq-number wrap.
+ # then fire in a packet that VPP should drop on TX because it
+ # causes the TX seq number to wrap; unless we're using extened sequence
+ # numbers.
+ #
+ self.vapi.cli("test ipsec sa %d seq 0xffffffff" % p.scapy_tra_sa_id)
+ self.logger.info(self.vapi.ppcli("show ipsec sa 0"))
+ self.logger.info(self.vapi.ppcli("show ipsec sa 1"))
+
+ pkts = [(Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=seq))
+ for seq in range(259, 280)]
+
+ if use_esn:
+ rxs = self.send_and_expect(self.tra_if, pkts, self.tra_if)
+
+ #
+ # in order for scapy to decrypt its SA's high order number needs
+ # to wrap
+ #
+ p.vpp_tra_sa.seq_num = 0x100000000
+ for rx in rxs:
+ decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
+
+ #
+ # wrap scapy's TX high sequence number. VPP is in case B, so it
+ # will consider this a high seq wrap also.
+ # The low seq num we set it to will place VPP's RX window in Case A
+ #
+ p.scapy_tra_sa.seq_num = 0x100000005
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=0x100000005))
+ rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
+ decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
+
+ #
+ # A packet that has seq num between (2^32-64) and 5 is within
+ # the window
+ #
+ p.scapy_tra_sa.seq_num = 0xfffffffd
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=0xfffffffd))
+ rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
+ decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
+
+ #
+ # While in case A we cannot wrap the high sequence number again
+ # becuase VPP will consider this packet to be one that moves the
+ # window forward
+ #
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=0x200000999))
+ self.send_and_assert_no_replies(self.tra_if, [pkt], self.tra_if)
+
+ hash_failed_count += 1
+ self.assert_error_counter_equal(hash_failed_node_name,
+ hash_failed_count)
+
+ #
+ # but if we move the wondow forward to case B, then we can wrap
+ # again
+ #
+ p.scapy_tra_sa.seq_num = 0x100000555
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=0x100000555))
+ rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
+ decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
+
+ p.scapy_tra_sa.seq_num = 0x200000444
+ pkt = (Ether(src=self.tra_if.remote_mac,
+ dst=self.tra_if.local_mac) /
+ p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
+ dst=self.tra_if.local_ip4) /
+ ICMP(),
+ seq_num=0x200000444))
+ rx = self.send_and_expect(self.tra_if, [pkt], self.tra_if)
+ decrypted = p.vpp_tra_sa.decrypt(rx[0][IP])
+
+ else:
+ #
+ # without ESN TX sequence numbers can't wrap and packets are
+ # dropped from here on out.
+ #
+ self.send_and_assert_no_replies(self.tra_if, pkts)
+ seq_cycle_count += len(pkts)
+ self.assert_error_counter_equal(seq_cycle_node_name,
+ seq_cycle_count)
+