From e4416635861d494f43c55ad32155fe86cda1c787 Mon Sep 17 00:00:00 2001 From: Markus Koch Date: Sat, 21 Jan 2023 20:20:24 +0100 Subject: [PATCH] arp: Implement gateway selection Fixes #17. --- trashernet/trashernet_arp.vhd | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/trashernet/trashernet_arp.vhd b/trashernet/trashernet_arp.vhd index c63d7c4..9f0a4d1 100644 --- a/trashernet/trashernet_arp.vhd +++ b/trashernet/trashernet_arp.vhd @@ -55,13 +55,12 @@ architecture rtl of trashernet_arp is signal arp_tx_reply_ack : std_logic; -- ARP reply has been latched and is being sent signal arp_tx_request_rq : std_logic; -- Request to transmit an ARP request - signal arp_tx_request_tpa : ip_addr_t; -- IP address that we want to know the MAC address of + signal arp_tx_request_tpa : ip_addr_t; -- IP address that we want to know the MAC address of, either real target or gateway signal arp_tx_request_ack : std_logic; -- ARP request has been latched and is being sent signal arp_rx_reply_stb : std_logic; -- An ARP reply was received (strobe) signal arp_rx_sha : mac_addr_t; -- The MAC address of the reply sender, valid with arp_rx_reply signal arp_rx_spa : ip_addr_t; -- The IP address of the reply sender, valid with arp_rx_reply - begin resolver : block type resolver_state_t is (IDLE, QUERY_MAC); @@ -72,8 +71,10 @@ begin signal replied_ip : ip_addr_t; signal replied_mac : mac_addr_t; - begin + signal arp_query_stb : std_logic; -- Pipelined version of arp_in.arp_query_stb + signal target_is_in_subnet : std_logic; -- Indicates whether the target IP is the subnet or whether to send this to the gateway + begin arp_resolver_main : process(rst, clk) is begin if rst then @@ -96,7 +97,7 @@ begin case state is when IDLE => - if arp_in.arp_query_stb then + if arp_query_stb then if query_mac_found then arp_out.arp_ok_stb <= '1'; else @@ -118,9 +119,21 @@ begin end if; end process arp_resolver_main; query_mac_found <= '1' when (arp_tx_request_tpa = replied_ip) else '0'; + target_is_in_subnet <= or((arp_in.arp_ip xor ip_config.gateway) and ip_config.subnet_mask); arp_out.arp_mac <= replied_mac; - arp_tx_request_tpa <= arp_in.arp_ip; + + -- Pipelines the start of query so that we get some additional time to evaluate the target+netmask. + pipeline : process (clk, rst) is + begin + if rst then + arp_tx_request_tpa <= (others => x"00"); + arp_query_stb <= '0'; + elsif rising_edge(clk) then + arp_tx_request_tpa <= arp_in.arp_ip when target_is_in_subnet else ip_config.gateway; + arp_query_stb <= arp_in.arp_query_stb; + end if; + end process pipeline; timeout_timer_inst : entity work.timer generic map(