fix(native): repost RX queue before waiting for relay ACK
This commit is contained in:
parent
a995d3660c
commit
f7a6dd2f19
4 changed files with 49 additions and 4 deletions
|
|
@ -962,12 +962,17 @@ ghal_net_icmp_exchange_once:
|
|||
add r12, 4095
|
||||
and r12, -4096
|
||||
movzx r8d, word [rel ghal_net_rx_next_index]
|
||||
mov byte [rel ghal_net_resident_retry_count], 0
|
||||
|
||||
.post_receive:
|
||||
mov rdi, VIRTIO_NET_RX_BUFFER
|
||||
xor eax, eax
|
||||
mov ecx, VIRTIO_NET_BUFFER_SIZE / 8
|
||||
rep stosq
|
||||
mov eax, r10d
|
||||
shl eax, 4
|
||||
mov ebx, VIRTIO_NET_RX_QUEUE
|
||||
add rbx, rax
|
||||
mov eax, r8d
|
||||
dec eax
|
||||
mov ecx, r10d
|
||||
|
|
@ -1085,6 +1090,7 @@ ghal_net_icmp_exchange_once:
|
|||
.request_complete:
|
||||
inc word [rel ghal_net_tx_next_index]
|
||||
|
||||
.reset_receive_wait:
|
||||
mov ecx, 0x80000000
|
||||
.wait_receive:
|
||||
cmp word [r12 + 2], r8w
|
||||
|
|
@ -1092,12 +1098,15 @@ ghal_net_icmp_exchange_once:
|
|||
pause
|
||||
loop .wait_receive
|
||||
%ifdef GHOS_NATIVE_RESIDENT
|
||||
inc byte [rel ghal_net_resident_retry_count]
|
||||
cmp byte [rel ghal_net_resident_retry_count], 3
|
||||
jae .receive_timeout
|
||||
jmp .send_request
|
||||
%else
|
||||
%endif
|
||||
.receive_timeout:
|
||||
mov byte [rel physical_proof_error_code], 0x54
|
||||
stc
|
||||
ret
|
||||
%endif
|
||||
|
||||
.packet_received:
|
||||
mov eax, r8d
|
||||
|
|
@ -1180,7 +1189,29 @@ ghal_net_icmp_exchange_once:
|
|||
|
||||
.ignore_packet:
|
||||
inc r8w
|
||||
jnz .post_receive
|
||||
jz .receive_index_exhausted
|
||||
mov rdi, VIRTIO_NET_RX_BUFFER
|
||||
xor eax, eax
|
||||
mov ecx, VIRTIO_NET_BUFFER_SIZE / 8
|
||||
rep stosq
|
||||
mov eax, r10d
|
||||
shl eax, 4
|
||||
mov ebx, VIRTIO_NET_RX_QUEUE
|
||||
add rbx, rax
|
||||
mov eax, r8d
|
||||
dec eax
|
||||
mov ecx, r10d
|
||||
dec ecx
|
||||
and eax, ecx
|
||||
mov word [rbx + rax * 2 + 4], 0
|
||||
mov word [rbx + 2], r8w
|
||||
sfence
|
||||
mov dx, [rel ghal_net_io_base]
|
||||
add dx, VIRTIO_QUEUE_NOTIFY
|
||||
xor ax, ax
|
||||
out dx, ax
|
||||
jmp .reset_receive_wait
|
||||
.receive_index_exhausted:
|
||||
mov byte [rel physical_proof_error_code], 0x57
|
||||
stc
|
||||
ret
|
||||
|
|
@ -1248,6 +1279,7 @@ ghal_net_expected_magic: dq ghal_login_magic
|
|||
ghal_net_command_kind: db 0
|
||||
ghal_net_matched_kind: db 0
|
||||
ghal_net_expected_sequence: db 1
|
||||
ghal_net_resident_retry_count: db 0
|
||||
|
||||
msg_ghal_net_discovered: db "GHOS_GHAL_VIRTIO_NET=DISCOVERED", 13, 10, 0
|
||||
msg_ghal_block_discovered: db "GHOS_GHAL_VIRTIO_BLOCK=DISCOVERED", 13, 10, 0
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ def verified_request(frame: bytes, sequence: int, magic: bytes) -> None:
|
|||
assert checksum(frame[34:82]) == 0
|
||||
|
||||
|
||||
def authenticated_reply(frame: bytes, magic: bytes) -> bytes:
|
||||
def ordinary_reply(frame: bytes) -> bytes:
|
||||
reply = bytearray(frame)
|
||||
reply[0:6] = GUEST_MAC
|
||||
reply[6:12] = PEER_MAC
|
||||
|
|
@ -74,6 +74,13 @@ def authenticated_reply(frame: bytes, magic: bytes) -> bytes:
|
|||
reply[24:26] = struct.pack("!H", checksum(bytes(reply[14:34])))
|
||||
reply[34] = 0
|
||||
reply[36:38] = b"\0\0"
|
||||
reply[36:38] = struct.pack("!H", checksum(bytes(reply[34:82])))
|
||||
return bytes(reply)
|
||||
|
||||
|
||||
def authenticated_reply(frame: bytes, magic: bytes) -> bytes:
|
||||
reply = bytearray(ordinary_reply(frame))
|
||||
reply[36:38] = b"\0\0"
|
||||
reply[66:82] = NATIVE_ACK_MAGIC
|
||||
reply[36:38] = struct.pack("!H", checksum(bytes(reply[34:82])))
|
||||
return bytes(reply)
|
||||
|
|
@ -137,6 +144,8 @@ def main() -> None:
|
|||
else:
|
||||
raise AssertionError(f"unexpected native sequence {sequence}")
|
||||
verified_request(frame, sequence, magic)
|
||||
peer.sendto(ordinary_reply(frame), qemu)
|
||||
time.sleep(0.05)
|
||||
peer.sendto(authenticated_reply(frame, magic), qemu)
|
||||
|
||||
terminal_sequence = 3 if args.login_only else (16 if args.resident else 5)
|
||||
|
|
@ -147,6 +156,7 @@ def main() -> None:
|
|||
"arp_gateway_reply: VERIFIED\n"
|
||||
"handshake_direction: NATIVE_INITIATED_OUTBOUND_ICMP\n"
|
||||
"authenticated_relay_reply: VERIFIED\n"
|
||||
"ordinary_echo_reply_ignored: true\n"
|
||||
"icmp_login_request_sent: true\n"
|
||||
"icmp_login_reply_verified: true\n"
|
||||
f"icmp_login_reply_count: {login_count}\n"
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ peer_pid=
|
|||
grep -q '^handshake_direction: NATIVE_INITIATED_OUTBOUND_ICMP$' \
|
||||
"${test_root}/peer.hldp"
|
||||
grep -q '^authenticated_relay_reply: VERIFIED$' "${test_root}/peer.hldp"
|
||||
grep -q '^ordinary_echo_reply_ignored: true$' "${test_root}/peer.hldp"
|
||||
grep -q '^icmp_login_reply_count: 3$' "${test_root}/peer.hldp"
|
||||
grep -q '^code_commit_reply_verified: true$' "${test_root}/peer.hldp"
|
||||
grep -q '^branch_move_reply_verified: true$' "${test_root}/peer.hldp"
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ handshake:
|
|||
response_delay_reason: ALLOW_KERNEL_NAT_REPLY_THEN_NATIVE_RX_REPOST
|
||||
expected_sequences: 1-16
|
||||
ordinary_echo_action: IGNORE
|
||||
ordinary_echo_follow_up: REPOST_RX_AND_WAIT_WITHOUT_RETRANSMIT
|
||||
receive_timeout_action: RETRY_THREE_TIMES_THEN_WRITE_FAIL_PROOF_AND_RESET
|
||||
stale_sequence_action: IGNORE_WITHOUT_STATE_ADVANCE
|
||||
future_sequence_action: IGNORE_WITHOUT_STATE_ADVANCE
|
||||
accepted_sequence_action: ADVANCE_EXACTLY_ONCE
|
||||
|
|
|
|||
Loading…
Reference in a new issue