arp: Implement gateway selection

This commit is contained in:
Markus Koch 2023-01-21 20:20:24 +01:00
parent 2190f146a0
commit cef4d3f114

View File

@ -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_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_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_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_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_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 signal arp_rx_spa : ip_addr_t; -- The IP address of the reply sender, valid with arp_rx_reply
begin begin
resolver : block resolver : block
type resolver_state_t is (IDLE, QUERY_MAC); type resolver_state_t is (IDLE, QUERY_MAC);
@ -72,8 +71,10 @@ begin
signal replied_ip : ip_addr_t; signal replied_ip : ip_addr_t;
signal replied_mac : mac_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 arp_resolver_main : process(rst, clk) is
begin begin
if rst then if rst then
@ -96,7 +97,7 @@ begin
case state is case state is
when IDLE => when IDLE =>
if arp_in.arp_query_stb then if arp_query_stb then
if query_mac_found then if query_mac_found then
arp_out.arp_ok_stb <= '1'; arp_out.arp_ok_stb <= '1';
else else
@ -118,9 +119,21 @@ begin
end if; end if;
end process arp_resolver_main; end process arp_resolver_main;
query_mac_found <= '1' when (arp_tx_request_tpa = replied_ip) else '0'; 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_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 timeout_timer_inst : entity work.timer
generic map( generic map(