summaryrefslogtreecommitdiffstats
path: root/src/plugins/nat/test/test_nat44_ei.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/nat/test/test_nat44_ei.py')
-rw-r--r--src/plugins/nat/test/test_nat44_ei.py211
1 files changed, 119 insertions, 92 deletions
diff --git a/src/plugins/nat/test/test_nat44_ei.py b/src/plugins/nat/test/test_nat44_ei.py
index cd1941a7f12..04ed9a33e01 100644
--- a/src/plugins/nat/test/test_nat44_ei.py
+++ b/src/plugins/nat/test/test_nat44_ei.py
@@ -632,9 +632,9 @@ class MethodHolder(VppTestCase):
""" Verify that there is no NAT44EI user """
users = self.vapi.nat44_ei_user_dump()
self.assertEqual(len(users), 0)
- users = self.statistics.get_counter('/nat44-ei/total-users')
+ users = self.statistics['/nat44-ei/total-users']
self.assertEqual(users[0][0], 0)
- sessions = self.statistics.get_counter('/nat44-ei/total-sessions')
+ sessions = self.statistics['/nat44-ei/total-sessions']
self.assertEqual(sessions[0][0], 0)
def verify_syslog_apmap(self, data, is_add=True):
@@ -852,6 +852,16 @@ class MethodHolder(VppTestCase):
self.assertEqual(data, p[Raw].load)
+def get_nat44_ei_in2out_worker_index(ip, vpp_worker_count):
+ if 0 == vpp_worker_count:
+ return 0
+ numeric = socket.inet_aton(ip)
+ numeric = struct.unpack("!L", numeric)[0]
+ numeric = socket.htonl(numeric)
+ h = numeric + (numeric >> 8) + (numeric >> 16) + (numeric >> 24)
+ return 1 + h % vpp_worker_count
+
+
@tag_fixme_vpp_workers
class TestNAT44EI(MethodHolder):
""" NAT44EI Test Cases """
@@ -963,14 +973,14 @@ class TestNAT44EI(MethodHolder):
capture = self.pg1.get_capture(len(pkts))
self.verify_capture_out(capture)
- sessions = self.statistics.get_counter('/nat44-ei/total-sessions')
- self.assertTrue(sessions[0][0] > 0)
+ sessions = self.statistics['/nat44-ei/total-sessions']
+ self.assertGreater(sessions[:, 0].sum(), 0, "Session count invalid")
self.logger.info("sessions before clearing: %s" % sessions[0][0])
self.vapi.cli("clear nat44 ei sessions")
- sessions = self.statistics.get_counter('/nat44-ei/total-sessions')
- self.assertEqual(sessions[0][0], 0)
+ sessions = self.statistics['/nat44-ei/total-sessions']
+ self.assertEqual(sessions[:, 0].sum(), 0, "Session count invalid")
self.logger.info("sessions after clearing: %s" % sessions[0][0])
def test_dynamic(self):
@@ -985,12 +995,10 @@ class TestNAT44EI(MethodHolder):
is_add=1)
# in2out
- tcpn = self.statistics.get_counter('/nat44-ei/in2out/slowpath/tcp')[0]
- udpn = self.statistics.get_counter('/nat44-ei/in2out/slowpath/udp')[0]
- icmpn = self.statistics.get_counter(
- '/nat44-ei/in2out/slowpath/icmp')[0]
- drops = self.statistics.get_counter(
- '/nat44-ei/in2out/slowpath/drops')[0]
+ tcpn = self.statistics['/nat44-ei/in2out/slowpath/tcp']
+ udpn = self.statistics['/nat44-ei/in2out/slowpath/udp']
+ icmpn = self.statistics['/nat44-ei/in2out/slowpath/icmp']
+ drops = self.statistics['/nat44-ei/in2out/slowpath/drops']
pkts = self.create_stream_in(self.pg0, self.pg1)
self.pg0.add_stream(pkts)
@@ -1000,22 +1008,20 @@ class TestNAT44EI(MethodHolder):
self.verify_capture_out(capture)
if_idx = self.pg0.sw_if_index
- cnt = self.statistics.get_counter('/nat44-ei/in2out/slowpath/tcp')[0]
- self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
- cnt = self.statistics.get_counter('/nat44-ei/in2out/slowpath/udp')[0]
- self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
- cnt = self.statistics.get_counter('/nat44-ei/in2out/slowpath/icmp')[0]
- self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
- cnt = self.statistics.get_counter('/nat44-ei/in2out/slowpath/drops')[0]
- self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
+ cnt = self.statistics['/nat44-ei/in2out/slowpath/tcp']
+ self.assertEqual(cnt[:, if_idx].sum() - tcpn[:, if_idx].sum(), 2)
+ cnt = self.statistics['/nat44-ei/in2out/slowpath/udp']
+ self.assertEqual(cnt[:, if_idx].sum() - udpn[:, if_idx].sum(), 1)
+ cnt = self.statistics['/nat44-ei/in2out/slowpath/icmp']
+ self.assertEqual(cnt[:, if_idx].sum() - icmpn[:, if_idx].sum(), 1)
+ cnt = self.statistics['/nat44-ei/in2out/slowpath/drops']
+ self.assertEqual(cnt[:, if_idx].sum() - drops[:, if_idx].sum(), 0)
# out2in
- tcpn = self.statistics.get_counter('/nat44-ei/out2in/slowpath/tcp')[0]
- udpn = self.statistics.get_counter('/nat44-ei/out2in/slowpath/udp')[0]
- icmpn = self.statistics.get_counter(
- '/nat44-ei/out2in/slowpath/icmp')[0]
- drops = self.statistics.get_counter(
- '/nat44-ei/out2in/slowpath/drops')[0]
+ tcpn = self.statistics['/nat44-ei/out2in/slowpath/tcp']
+ udpn = self.statistics['/nat44-ei/out2in/slowpath/udp']
+ icmpn = self.statistics['/nat44-ei/out2in/slowpath/icmp']
+ drops = self.statistics['/nat44-ei/out2in/slowpath/drops']
pkts = self.create_stream_out(self.pg1)
self.pg1.add_stream(pkts)
@@ -1025,19 +1031,19 @@ class TestNAT44EI(MethodHolder):
self.verify_capture_in(capture, self.pg0)
if_idx = self.pg1.sw_if_index
- cnt = self.statistics.get_counter('/nat44-ei/out2in/slowpath/tcp')[0]
- self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
- cnt = self.statistics.get_counter('/nat44-ei/out2in/slowpath/udp')[0]
- self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
- cnt = self.statistics.get_counter('/nat44-ei/out2in/slowpath/icmp')[0]
- self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
- cnt = self.statistics.get_counter('/nat44-ei/out2in/slowpath/drops')[0]
- self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
-
- users = self.statistics.get_counter('/nat44-ei/total-users')
- self.assertEqual(users[0][0], 1)
- sessions = self.statistics.get_counter('/nat44-ei/total-sessions')
- self.assertEqual(sessions[0][0], 3)
+ cnt = self.statistics['/nat44-ei/out2in/slowpath/tcp']
+ self.assertEqual(cnt[:, if_idx].sum() - tcpn[:, if_idx].sum(), 2)
+ cnt = self.statistics['/nat44-ei/out2in/slowpath/udp']
+ self.assertEqual(cnt[:, if_idx].sum() - udpn[:, if_idx].sum(), 1)
+ cnt = self.statistics['/nat44-ei/out2in/slowpath/icmp']
+ self.assertEqual(cnt[:, if_idx].sum() - icmpn[:, if_idx].sum(), 1)
+ cnt = self.statistics['/nat44-ei/out2in/slowpath/drops']
+ self.assertEqual(cnt[:, if_idx].sum() - drops[:, if_idx].sum(), 0)
+
+ users = self.statistics['/nat44-ei/total-users']
+ self.assertEqual(users[:, 0].sum(), 1)
+ sessions = self.statistics['/nat44-ei/total-sessions']
+ self.assertEqual(sessions[:, 0].sum(), 3)
def test_dynamic_icmp_errors_in2out_ttl_1(self):
""" NAT44EI handling of client packets with TTL=1 """
@@ -1828,7 +1834,7 @@ class TestNAT44EI(MethodHolder):
server_in_port, server_out_port,
proto=IP_PROTOS.tcp)
- cnt = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
+ cnt = self.statistics['/nat44-ei/hairpinning']
# send packet from host to server
p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
IP(src=host.ip4, dst=self.nat_addr) /
@@ -1851,9 +1857,9 @@ class TestNAT44EI(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
- after = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
+ after = self.statistics['/nat44-ei/hairpinning']
if_idx = self.pg0.sw_if_index
- self.assertEqual(after[if_idx] - cnt[if_idx], 1)
+ self.assertEqual(after[:, if_idx].sum() - cnt[:, if_idx].sum(), 1)
# send reply from server to host
p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
@@ -1876,9 +1882,10 @@ class TestNAT44EI(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
- after = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
+ after = self.statistics['/nat44-ei/hairpinning']
if_idx = self.pg0.sw_if_index
- self.assertEqual(after[if_idx] - cnt[if_idx], 2)
+ self.assertEqual(after[:, if_idx].sum() - cnt[:, if_idx].sum(),
+ 2+(1 if self.vpp_worker_count > 0 else 0))
def test_hairpinning2(self):
""" NAT44EI hairpinning - 1:1 NAT"""
@@ -2086,7 +2093,7 @@ class TestNAT44EI(MethodHolder):
self.pg_start()
# Here VPP used to crash due to an infinite loop
- cnt = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
+ cnt = self.statistics['/nat44-ei/hairpinning']
# send packet from host to server
p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
IP(src=host.ip4, dst=self.nat_addr) /
@@ -2109,9 +2116,9 @@ class TestNAT44EI(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
- after = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
+ after = self.statistics['/nat44-ei/hairpinning']
if_idx = self.pg0.sw_if_index
- self.assertEqual(after[if_idx] - cnt[if_idx], 1)
+ self.assertEqual(after[:, if_idx].sum() - cnt[:, if_idx].sum(), 1)
# send reply from server to host
p = (Ether(src=server.mac, dst=self.pg0.local_mac) /
@@ -2134,9 +2141,10 @@ class TestNAT44EI(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
- after = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
+ after = self.statistics['/nat44-ei/hairpinning']
if_idx = self.pg0.sw_if_index
- self.assertEqual(after[if_idx] - cnt[if_idx], 2)
+ self.assertEqual(after[:, if_idx].sum() - cnt[:, if_idx].sum(),
+ 2+(1 if self.vpp_worker_count > 0 else 0))
def test_interface_addr(self):
""" NAT44EI acquire addresses from interface """
@@ -2368,7 +2376,8 @@ class TestNAT44EI(MethodHolder):
sw_if_index=self.pg1.sw_if_index,
is_add=1)
- max_sessions = self.max_translations
+ max_sessions_per_thread = self.max_translations
+ max_sessions = max(1, self.vpp_worker_count) * max_sessions_per_thread
pkts = []
for i in range(0, max_sessions):
@@ -2416,7 +2425,7 @@ class TestNAT44EI(MethodHolder):
for p in capture:
if p.haslayer(Data):
data = ipfix.decode_data_set(p.getlayer(Set))
- self.verify_ipfix_max_sessions(data, max_sessions)
+ self.verify_ipfix_max_sessions(data, max_sessions_per_thread)
def test_syslog_apmap(self):
""" NAT44EI syslog address and port mapping creation and deletion """
@@ -3400,8 +3409,8 @@ class TestNAT44EI(MethodHolder):
self.verify_capture_out(capture)
# active send HA events
self.vapi.nat44_ei_ha_flush()
- stats = self.statistics.get_counter('/nat44-ei/ha/add-event-send')
- self.assertEqual(stats[0][0], 3)
+ stats = self.statistics['/nat44-ei/ha/add-event-send']
+ self.assertEqual(stats[:, 0].sum(), 3)
capture = self.pg3.get_capture(1)
p = capture[0]
self.assert_packet_checksums_valid(p)
@@ -3418,7 +3427,7 @@ class TestNAT44EI(MethodHolder):
self.assertEqual(udp.sport, 12345)
self.assertEqual(udp.dport, 12346)
self.assertEqual(hanat.version, 1)
- self.assertEqual(hanat.thread_index, 0)
+ # self.assertEqual(hanat.thread_index, 0)
self.assertEqual(hanat.count, 3)
seq = hanat.sequence_number
for event in hanat.events:
@@ -3431,11 +3440,12 @@ class TestNAT44EI(MethodHolder):
ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
UDP(sport=12346, dport=12345) /
- HANATStateSync(sequence_number=seq, flags='ACK'))
+ HANATStateSync(sequence_number=seq, flags='ACK',
+ thread_index=hanat.thread_index))
self.pg3.add_stream(ack)
self.pg_start()
- stats = self.statistics.get_counter('/nat44-ei/ha/ack-recv')
- self.assertEqual(stats[0][0], 1)
+ stats = self.statistics['/nat44-ei/ha/ack-recv']
+ self.assertEqual(stats[:, 0].sum(), 1)
# delete one session
self.pg_enable_capture(self.pg_interfaces)
@@ -3443,8 +3453,8 @@ class TestNAT44EI(MethodHolder):
address=self.pg0.remote_ip4, port=self.tcp_port_in,
protocol=IP_PROTOS.tcp, flags=self.config_flags.NAT44_EI_IF_INSIDE)
self.vapi.nat44_ei_ha_flush()
- stats = self.statistics.get_counter('/nat44-ei/ha/del-event-send')
- self.assertEqual(stats[0][0], 1)
+ stats = self.statistics['/nat44-ei/ha/del-event-send']
+ self.assertEqual(stats[:, 0].sum(), 1)
capture = self.pg3.get_capture(1)
p = capture[0]
try:
@@ -3458,10 +3468,10 @@ class TestNAT44EI(MethodHolder):
# do not send ACK, active retry send HA event again
self.pg_enable_capture(self.pg_interfaces)
sleep(12)
- stats = self.statistics.get_counter('/nat44-ei/ha/retry-count')
- self.assertEqual(stats[0][0], 3)
- stats = self.statistics.get_counter('/nat44-ei/ha/missed-count')
- self.assertEqual(stats[0][0], 1)
+ stats = self.statistics['/nat44-ei/ha/retry-count']
+ self.assertEqual(stats[:, 0].sum(), 3)
+ stats = self.statistics['/nat44-ei/ha/missed-count']
+ self.assertEqual(stats[:, 0].sum(), 1)
capture = self.pg3.get_capture(3)
for packet in capture:
self.assertEqual(packet, p)
@@ -3473,8 +3483,8 @@ class TestNAT44EI(MethodHolder):
self.pg_start()
self.pg0.get_capture(2)
self.vapi.nat44_ei_ha_flush()
- stats = self.statistics.get_counter('/nat44-ei/ha/refresh-event-send')
- self.assertEqual(stats[0][0], 2)
+ stats = self.statistics['/nat44-ei/ha/refresh-event-send']
+ self.assertEqual(stats[:, 0].sum(), 2)
capture = self.pg3.get_capture(1)
p = capture[0]
self.assert_packet_checksums_valid(p)
@@ -3500,14 +3510,16 @@ class TestNAT44EI(MethodHolder):
self.assertEqual(event.total_pkts, 2)
self.assertGreater(event.total_bytes, 0)
+ stats = self.statistics['/nat44-ei/ha/ack-recv']
ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) /
UDP(sport=12346, dport=12345) /
- HANATStateSync(sequence_number=seq, flags='ACK'))
+ HANATStateSync(sequence_number=seq, flags='ACK',
+ thread_index=hanat.thread_index))
self.pg3.add_stream(ack)
self.pg_start()
- stats = self.statistics.get_counter('/nat44-ei/ha/ack-recv')
- self.assertEqual(stats[0][0], 2)
+ stats = self.statistics['/nat44-ei/ha/ack-recv']
+ self.assertEqual(stats[:, 0].sum(), 2)
def test_ha_recv(self):
""" NAT44EI Receive HA session synchronization events (passive) """
@@ -3523,8 +3535,23 @@ class TestNAT44EI(MethodHolder):
port=12345, path_mtu=512)
bind_layers(UDP, HANATStateSync, sport=12345)
- self.tcp_port_out = random.randint(1025, 65535)
- self.udp_port_out = random.randint(1025, 65535)
+ # this is a bit tricky - HA dictates thread index due to how it's
+ # designed, but once we use HA to create a session, we also want
+ # to pass a packet through said session. so the session must end
+ # up on the correct thread from both directions - in2out (based on
+ # IP address) and out2in (based on outside port)
+
+ # first choose a thread index which is correct for IP
+ thread_index = get_nat44_ei_in2out_worker_index(self.pg0.remote_ip4,
+ self.vpp_worker_count)
+
+ # now pick a port which is correct for given thread
+ port_per_thread = int((0xffff-1024) / max(1, self.vpp_worker_count))
+ self.tcp_port_out = 1024 + random.randint(1, port_per_thread)
+ self.udp_port_out = 1024 + random.randint(1, port_per_thread)
+ if self.vpp_worker_count > 0:
+ self.tcp_port_out += port_per_thread * (thread_index - 1)
+ self.udp_port_out += port_per_thread * (thread_index - 1)
# send HA session add events to failover/passive
p = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) /
@@ -3544,7 +3571,8 @@ class TestNAT44EI(MethodHolder):
eh_addr=self.pg1.remote_ip4,
ehn_addr=self.pg1.remote_ip4,
eh_port=self.udp_external_port,
- ehn_port=self.udp_external_port, fib_index=0)]))
+ ehn_port=self.udp_external_port, fib_index=0)],
+ thread_index=thread_index))
self.pg3.add_stream(p)
self.pg_enable_capture(self.pg_interfaces)
@@ -3561,15 +3589,15 @@ class TestNAT44EI(MethodHolder):
self.assertEqual(hanat.sequence_number, 1)
self.assertEqual(hanat.flags, 'ACK')
self.assertEqual(hanat.version, 1)
- self.assertEqual(hanat.thread_index, 0)
- stats = self.statistics.get_counter('/nat44-ei/ha/ack-send')
- self.assertEqual(stats[0][0], 1)
- stats = self.statistics.get_counter('/nat44-ei/ha/add-event-recv')
- self.assertEqual(stats[0][0], 2)
- users = self.statistics.get_counter('/nat44-ei/total-users')
- self.assertEqual(users[0][0], 1)
- sessions = self.statistics.get_counter('/nat44-ei/total-sessions')
- self.assertEqual(sessions[0][0], 2)
+ self.assertEqual(hanat.thread_index, thread_index)
+ stats = self.statistics['/nat44-ei/ha/ack-send']
+ self.assertEqual(stats[:, 0].sum(), 1)
+ stats = self.statistics['/nat44-ei/ha/add-event-recv']
+ self.assertEqual(stats[:, 0].sum(), 2)
+ users = self.statistics['/nat44-ei/total-users']
+ self.assertEqual(users[:, 0].sum(), 1)
+ sessions = self.statistics['/nat44-ei/total-sessions']
+ self.assertEqual(sessions[:, 0].sum(), 2)
users = self.vapi.nat44_ei_user_dump()
self.assertEqual(len(users), 1)
self.assertEqual(str(users[0].ip_address),
@@ -3600,7 +3628,8 @@ class TestNAT44EI(MethodHolder):
eh_addr=self.pg1.remote_ip4,
ehn_addr=self.pg1.remote_ip4,
eh_port=self.udp_external_port,
- ehn_port=self.udp_external_port, fib_index=0)]))
+ ehn_port=self.udp_external_port, fib_index=0)],
+ thread_index=thread_index))
self.pg3.add_stream(p)
self.pg_enable_capture(self.pg_interfaces)
@@ -3625,8 +3654,8 @@ class TestNAT44EI(MethodHolder):
sessions = self.vapi.nat44_ei_user_session_dump(users[0].ip_address,
users[0].vrf_id)
self.assertEqual(len(sessions), 1)
- stats = self.statistics.get_counter('/nat44-ei/ha/del-event-recv')
- self.assertEqual(stats[0][0], 1)
+ stats = self.statistics['/nat44-ei/ha/del-event-recv']
+ self.assertEqual(stats[:, 0].sum(), 1)
stats = self.statistics.get_err_counter(
'/err/nat44-ei-ha/pkts-processed')
@@ -3644,7 +3673,8 @@ class TestNAT44EI(MethodHolder):
ehn_addr=self.pg1.remote_ip4,
eh_port=self.tcp_external_port,
ehn_port=self.tcp_external_port, fib_index=0,
- total_bytes=1024, total_pkts=2)]))
+ total_bytes=1024, total_pkts=2)],
+ thread_index=thread_index))
self.pg3.add_stream(p)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
@@ -3670,9 +3700,8 @@ class TestNAT44EI(MethodHolder):
session = sessions[0]
self.assertEqual(session.total_bytes, 1024)
self.assertEqual(session.total_pkts, 2)
- stats = self.statistics.get_counter(
- '/nat44-ei/ha/refresh-event-recv')
- self.assertEqual(stats[0][0], 1)
+ stats = self.statistics['/nat44-ei/ha/refresh-event-recv']
+ self.assertEqual(stats[:, 0].sum(), 1)
stats = self.statistics.get_err_counter(
'/err/nat44-ei-ha/pkts-processed')
@@ -3898,9 +3927,7 @@ class TestNAT44Out2InDPO(MethodHolder):
class TestNAT44EIMW(MethodHolder):
""" NAT44EI Test Cases (multiple workers) """
-
vpp_worker_count = 2
-
max_translations = 10240
max_users = 10240
@@ -4013,7 +4040,7 @@ class TestNAT44EIMW(MethodHolder):
server_in_port, server_out_port,
proto=IP_PROTOS.tcp)
- cnt = self.statistics.get_counter('/nat44-ei/hairpinning')
+ cnt = self.statistics['/nat44-ei/hairpinning']
# send packet from host to server
p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
IP(src=host.ip4, dst=self.nat_addr) /
@@ -4036,7 +4063,7 @@ class TestNAT44EIMW(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
- after = self.statistics.get_counter('/nat44-ei/hairpinning')
+ after = self.statistics['/nat44-ei/hairpinning']
if_idx = self.pg0.sw_if_index
self.assertEqual(after[worker_2][if_idx] - cnt[worker_1][if_idx], 1)
@@ -4062,7 +4089,7 @@ class TestNAT44EIMW(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
- after = self.statistics.get_counter('/nat44-ei/hairpinning')
+ after = self.statistics['/nat44-ei/hairpinning']
if_idx = self.pg0.sw_if_index
self.assertEqual(after[worker_1][if_idx] - cnt[worker_1][if_idx], 1)
self.assertEqual(after[worker_2][if_idx] - cnt[worker_2][if_idx], 2)