# 2021-01-17 #「GitLab」- Requests to the local network are not allowed

本文介绍了解决在配置Webhook过程中遇到的Requeststothelocalnetworkarenotallowed错误的方法。此问题通常出现在尝试从Webhook访问未经过认证的内部服务时。文章详细说明了如何通过管理员后台进行设置来允许此类请求。

问题描述

在添加Webhook时,产生了该错误:

	Requests to the local network are not allowed

问题原因

原因在官方「Webhooks and insecure internal web services」文章已经解释,是为了防止内部无认证的服务被恶意请求。

解决方案

如果要解决这个问题,在管理员后台设置即可。以管理员帐号登录:

	Admin Area
		-> Settings
			-> Network
				-> Outbound requests
					-> Allow requests to the local network from hooks and services

勾选「Allow requests to the local network from hooks and services」即可。

参考文献

WikiNotes/Requests to the local network are not allowed
gitlab使用webhook向jenkins发送请求,报错 Requests to the local network are not allowed
Webhooks and insecure internal web services

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity PING_10G is generic ( IPv6_ENABLED: std_logic := &#39;0&#39;; -- 0 to minimize size, 1 to allow IPv6 in addition to IPv4 (larger size) MAX_PING_SIZE: std_logic_vector(7 downto 0) := x"FE" -- maximum IP/ICMP size (excluding Ethernet/MAC, but including the IP/ICMP header) in 64-bit words. Larger echo requests will be ignored. -- The ping buffer contains up to 18Kbits total (for a queued IP/ICMP response waiting for the tx path -- to become available) ); Port ( --// CLK, RESET CLK: in std_logic; -- Must be a global clock. No BUFG instantiation within this component. SYNC_RESET: in std_logic; --// ICMP frame received IP_RX_DATA: in std_logic_vector(63 downto 0); IP_RX_DATA_VALID: in std_logic_vector(7 downto 0); IP_RX_SOF: in std_logic; IP_RX_EOF: in std_logic; IP_RX_WORD_COUNT: in std_logic_vector(10 downto 0); --// Partial checks (done in PACKET_PARSING common code) --// basic IP validity check IP_RX_FRAME_VALID2: in std_logic; -- The received IP frame is presumed valid until proven otherwise. -- IP frame validity checks include: -- (a) protocol is IP -- (b) unicast or multicast destination IP address matches -- (c) correct IP header checksum (IPv4 only) -- (d) allowed IPv6 -- (e) Ethernet frame is valid (correct FCS, dest address) -- Also compute IP_RX_FRAME_VALID2 (no IP destination check) -- Ready at IP_RX_VALID_D (= MAC_RX_DATA_VALID_D3) VALID_UNICAST_DEST_IP: in std_logic; VALID_DEST_IP_RDY : in std_logic; -- Unicast destination address verification RX_SOURCE_MAC_ADDR: in std_logic_vector(47 downto 0); RX_SOURCE_IP_ADDR: in std_logic_vector(127 downto 0); -- Packet origin, already parsed in PACKET_PARSING (shared code) --// Configuration data: IP address, MAC address MAC_ADDR: in std_logic_vector(47 downto 0); -- MAC address. Unique for each network interface card. -- Natural byte order: (MSB) 0x000102030405 (LSB) -- as transmitted in the Ethernet packet. IPv4_ADDR: in std_logic_vector(31 downto 0); IPv6_ADDR: in std_logic_vector(127 downto 0); -- local IP address. 4 bytes for IPv4, 16 bytes for IPv6 -- Natural order (MSB) 172.16.1.128 (LSB) as transmitted in the IP frame. --// IP type, already parsed in PACKET_PARSING (shared code) RX_IPv4_6n: in std_logic; -- IP version. 4 or 6 RX_IP_PROTOCOL: in std_logic_vector(7 downto 0); -- read between RX_IP_PROTOCOL_RDY (inclusive)(i.e. before IP_PAYLOAD_SOF) and IP_PAYLOAD_EOF (inclusive) -- most common protocols: -- 0 = unknown, 1 = ICMP, 2 = IGMP, 6 = TCP, 17 = UDP, 41 = IPv6 encapsulation, 89 = OSPF, 132 = SCTP RX_IP_PROTOCOL_RDY: in std_logic; -- 1 CLK wide pulse. --// USER -> Transmit MAC Interface -- 32-bit CRC is automatically appended. User should not supply it. -- Synchonous with CLK MAC_TX_DATA: out std_logic_vector(63 downto 0); -- MAC reads the data at the rising edge of CLK when MAC_TX_DATA_VALID /= 0 MAC_TX_DATA_VALID: out std_logic_vector(7 downto 0); -- data valid MAC_TX_EOF: out std_logic; -- &#39;1&#39; when sending the last byte in a packet to be transmitted. -- Aligned with MAC_TX_DATA_VALID MAC_TX_CTS: in std_logic; -- MAC-generated Clear To Send flow control signal. The user should check that this -- signal is high before sending the next MAC_TX_DATA byte. RTS: out std_logic; -- &#39;1&#39; when a full or partial packet is ready to be read. -- &#39;0&#39; when output buffer is empty. -- When the user starts reading the output buffer, it is expected that it will be -- read until empty. -- Test Points TP: out std_logic_vector(10 downto 1) ); end entity; architecture Behavioral of PING_10G is -------------------------------------------------------- -- COMPONENTS -------------------------------------------------------- COMPONENT BRAM_DP2 GENERIC( DATA_WIDTHA: integer; ADDR_WIDTHA: integer; DATA_WIDTHB: integer; ADDR_WIDTHB: integer ); PORT( CLKA : in std_logic; CSA: in std_logic; WEA : in std_logic; OEA : in std_logic; ADDRA : in std_logic_vector(ADDR_WIDTHA-1 downto 0); DIA : in std_logic_vector(DATA_WIDTHA-1 downto 0); DOA : out std_logic_vector(DATA_WIDTHA-1 downto 0); CLKB : in std_logic; CSB: in std_logic; WEB : in std_logic; OEB : in std_logic; ADDRB : in std_logic_vector(ADDR_WIDTHB-1 downto 0); DIB : in std_logic_vector(DATA_WIDTHB-1 downto 0); DOB : out std_logic_vector(DATA_WIDTHB-1 downto 0) ); END COMPONENT; -------------------------------------------------------- -- SIGNALS -------------------------------------------------------- --// STATE MACHINE ------------------ signal STATE: unsigned(0 downto 0) := (others => &#39;0&#39;); signal INPUT_ENABLED: std_logic := &#39;1&#39;; signal IP_RX_WORD_VALID: std_logic := &#39;0&#39;; signal RX_IPv4_6n0: std_logic := &#39;0&#39;; signal IP_RX_DATA_PREVIOUS: std_logic_vector(63 downto 0) := (others => &#39;0&#39;); signal IP_RX_DATA_MOD: std_logic_vector(63 downto 0) := (others => &#39;0&#39;); signal REPLY_CHECKSUM: unsigned(15 downto 0) := (others => &#39;0&#39;); signal IP_RX_DATA_VALID_D: std_logic_vector(7 downto 0) := (others => &#39;0&#39;); signal IP_RX_EOF_D: std_logic := &#39;0&#39;; --// ELASTIC BUFFER ---------------------- signal WPTR: unsigned(7 downto 0) := (others => &#39;0&#39;); signal WPTR_CONFIRMED: unsigned(7 downto 0) := (others => &#39;0&#39;); signal WEA: std_logic := &#39;0&#39;; signal DIA: std_logic_vector(72 downto 0) := (others => &#39;0&#39;); signal DOB: std_logic_vector(72 downto 0) := (others => &#39;0&#39;); signal DOB_PREVIOUS: std_logic_vector(72 downto 0) := (others => &#39;0&#39;); signal RPTR: unsigned(7 downto 0) := (others => &#39;1&#39;); signal BUF_SIZE: unsigned(7 downto 0) := (others => &#39;0&#39;); --// VALIDATE PING REQUEST ----------- signal VALID_PING_REQ0: std_logic := &#39;0&#39;; signal VALID_PING_REQ: std_logic := &#39;0&#39;; --// OUTPUT SECTION ------------------- signal TX_SEQUENCE_CNTR: unsigned(7 downto 0) := (others => &#39;0&#39;); signal TX_SEQUENCE_CNTR_D: unsigned(7 downto 0) := (others => &#39;0&#39;); signal DOB_SAMPLE_CLK_E: std_logic := &#39;0&#39;; signal DOB_SAMPLE_CLK: std_logic := &#39;0&#39;; signal MAC_TX_CTS_D: std_logic := &#39;0&#39;; signal MAC_TX_CTS_D2: std_logic := &#39;0&#39;; signal MAC_TX_EOF_local: std_logic := &#39;0&#39;; signal MAC_TX_DATA_VALID_local: std_logic_vector(7 downto 0) := (others => &#39;0&#39;); signal RTS_local: std_logic := &#39;0&#39;; -------------------------------------------------------- -- IMPLEMENTATION -------------------------------------------------------- begin --// STATE MACHINE ------------------ -- A state machine is needed as this process is memoryless. -- State 0 = idle or incoming IP frame being processed. -- State 1 = valid ping request. tx packet waiting for tx capacity. Incoming IP frames are discarded. STATE_GEN_001: process(CLK) begin if rising_edge(CLK) then if(SYNC_RESET = &#39;1&#39;) then STATE <= (others => &#39;0&#39;); elsif(IP_RX_EOF_D = &#39;1&#39;) and (VALID_PING_REQ = &#39;1&#39;) then -- event = valid PING request. Ready to send PING reply when tx channel opens. -- In the mean time, incoming IP frames are discarded. STATE <= "1"; elsif(MAC_TX_EOF_local = &#39;1&#39;) then -- event = successfully sent PING reply. Reopen input STATE <= "0"; end if; end if; end process; INPUT_ENABLED <= &#39;1&#39; when (STATE = 0) else &#39;0&#39;; -- save previous IP word (needed information to swap fields) IN_001: process(CLK) begin if rising_edge(CLK) then if(SYNC_RESET = &#39;1&#39;) then IP_RX_DATA_PREVIOUS <= (others => &#39;0&#39;); elsif(IP_RX_DATA_VALID /= x"00") then IP_RX_DATA_PREVIOUS <= IP_RX_DATA; end if; end if; end process; --// freeze some parameters at the end of the packet -- Reason: we don&#39;t want subsequent packets to change this information while we are waiting -- to send the echo . FREEZE_001: process(CLK) begin if rising_edge(CLK) then if(IP_RX_EOF = &#39;1&#39;) and (INPUT_ENABLED = &#39;1&#39;) then RX_IPv4_6n0 <= RX_IPv4_6n; end if; end if; end process; --// FIELDS ALTERATIONS -------------------- -- Modify the incoming words on the fly before temporary storage into elastic buffer IN_002: process(CLK) begin if rising_edge(CLK) then IP_RX_EOF_D <= IP_RX_EOF; IP_RX_DATA_VALID_D <= IP_RX_DATA_VALID; if(SYNC_RESET = &#39;1&#39;) or (INPUT_ENABLED = &#39;0&#39;) then IP_RX_DATA_MOD <= (others => &#39;0&#39;); elsif(RX_IPv4_6n = &#39;1&#39;) then if(unsigned(IP_RX_WORD_COUNT) = 2) then IP_RX_DATA_MOD(63 downto 32) <= IP_RX_DATA(63 downto 32); IP_RX_DATA_MOD(31 downto 0) <= IPv4_ADDR; -- source is our IP address elsif(unsigned(IP_RX_WORD_COUNT) = 3) then IP_RX_DATA_MOD(63 downto 32) <= IP_RX_DATA_PREVIOUS(31 downto 0); -- swap source/dest IP addresses in response IP_RX_DATA_MOD(31 downto 24) <= x"00"; -- ICMP echo reply IPv4 type IP_RX_DATA_MOD(23 downto 16) <= IP_RX_DATA(23 downto 16); -- ICMP echo reply IPv4 code IP_RX_DATA_MOD(15 downto 0) <= std_logic_vector(REPLY_CHECKSUM); -- ICMP echo reply IPv4 checksum elsif(IP_RX_DATA_VALID /= x"00") then IP_RX_DATA_MOD <= IP_RX_DATA; end if; elsif(IPv6_ENABLED = &#39;1&#39;) and (RX_IPv4_6n = &#39;0&#39;) then if(unsigned(IP_RX_WORD_COUNT) = 2) then IP_RX_DATA_MOD <= IPv6_ADDR(127 downto 64); -- source is our IP address elsif(unsigned(IP_RX_WORD_COUNT) = 3) then IP_RX_DATA_MOD <= IPv6_ADDR(63 downto 0); -- source is our IP address elsif(unsigned(IP_RX_WORD_COUNT) = 4) then IP_RX_DATA_MOD <= RX_SOURCE_IP_ADDR(127 downto 64); -- destination IP elsif(unsigned(IP_RX_WORD_COUNT) = 5) then IP_RX_DATA_MOD <= RX_SOURCE_IP_ADDR(63 downto 0); -- destination IP elsif(unsigned(IP_RX_WORD_COUNT) = 6) then IP_RX_DATA_MOD <= x"8100" & std_logic_vector(REPLY_CHECKSUM) & IP_RX_DATA(31 downto 0); -- modify the ICMP checksum elsif(IP_RX_DATA_VALID /= x"00") then IP_RX_DATA_MOD <= IP_RX_DATA; end if; end if; end if; end process; REPLY_CHECKSUM_GEN: process(IP_RX_DATA, RX_IPv4_6n) variable CKSUM: unsigned(16 downto 0); begin if(RX_IPv4_6n = &#39;1&#39;) then -- IPv4 CKSUM := resize(unsigned(IP_RX_DATA(15 downto 0)),17); CKSUM := CKSUM + x"0800"; else -- IPv6 CKSUM := resize(unsigned(IP_RX_DATA(47 downto 32)),17); CKSUM := CKSUM - x"0100"; end if; if(CKSUM(16) = &#39;1&#39;) then CKSUM := CKSUM + 1; end if; REPLY_CHECKSUM <= CKSUM(15 downto 0); end process; --// ELASTIC BUFFER ---------------------- -- Stores the IP/ICMP frame until validity check is complete and transmission path is open WEA_GEN_001: process(CLK) begin if rising_edge(CLK) then if(SYNC_RESET = &#39;1&#39;) then WEA <= &#39;0&#39;; elsif(unsigned(IP_RX_DATA_VALID) /= 0) and (INPUT_ENABLED = &#39;1&#39;) then WEA <= &#39;1&#39;; else WEA <= &#39;0&#39;; end if; end if; end process; -- write pointer management WPTR_GEN_001: process(CLK) begin if rising_edge(CLK) then if(SYNC_RESET = &#39;1&#39;) then WPTR <= (others => &#39;0&#39;); elsif(IP_RX_SOF = &#39;1&#39;) then -- rewind write pointer WPTR <= (others => &#39;0&#39;); elsif(WEA = &#39;1&#39;) then WPTR <= WPTR + 1; end if; end if; end process; -- confirm WPTR when valid IP/ICMP request WPTR_CONFIRMED_GEN_001: process(CLK) begin if rising_edge(CLK) then if(SYNC_RESET = &#39;1&#39;) or (MAC_TX_EOF_local = &#39;1&#39;) then WPTR_CONFIRMED <= (others => &#39;0&#39;); elsif(IP_RX_EOF_D = &#39;1&#39;) and (VALID_PING_REQ = &#39;1&#39;) then WPTR_CONFIRMED <= WPTR+1; end if; end if; end process; -- elastic buffer. -- 18Kbit buffer(s) DIA <= IP_RX_EOF_D & IP_RX_DATA_VALID_D & IP_RX_DATA_MOD; BRAM_DP2_001: BRAM_DP2 GENERIC MAP( DATA_WIDTHA => 73, ADDR_WIDTHA => 8, DATA_WIDTHB => 73, ADDR_WIDTHB => 8 ) PORT MAP( CSA => &#39;1&#39;, CLKA => CLK, WEA => WEA, -- Port A Write Enable Input ADDRA => std_logic_vector(WPTR), -- Port A 8-bit Address Input DIA => DIA, -- Port A 65-bit Data Input OEA => &#39;0&#39;, DOA => open, CSB => &#39;1&#39;, CLKB => CLK, WEB => &#39;0&#39;, ADDRB => std_logic_vector(RPTR), -- Port B 8-bit Address Input DIB => (others => &#39;0&#39;), -- Port B 65-bit Data Input OEB => &#39;1&#39;, DOB => DOB -- Port B 65-bit Data Output ); -- occupied buffer space, in bytes BUF_SIZE <= WPTR_CONFIRMED + (not RPTR); --// VALIDATE PING REQUEST ----------- -- The ping echo generation is immediately cancelled if -- (a) the received packet type is not an IP datagram or IPv6 is not allowed -- (b) the received IP type is not ICMP/ICMP6 -- (c) invalid unicast destination IP (IPv4 or IPv6) -- (d) packet size is greater than MAX_PING_SIZE (units = 64-bit words, including IP/ICMP headers) -- (e) ICMP incoming packet is not an echo request (ICMP type /= x"0800") or (ICMP6 type /= 128) -- (f) incorrect IP header checksum (IPv4 only) -- (g) erroneous MAC frame (incorrect FCS, wrong dest MAC address) IP_RX_WORD_VALID <= &#39;1&#39; when (unsigned(IP_RX_DATA_VALID) /= 0) else &#39;0&#39;; VALIDITY_CHECK_001: process(CLK) begin if rising_edge(CLK) then if(SYNC_RESET = &#39;1&#39;) then VALID_PING_REQ0 <= &#39;1&#39;; elsif(IP_RX_SOF = &#39;1&#39;) then -- just received first word in an IP frame. Assume validity VALID_PING_REQ0 <= &#39;1&#39;; else if(RX_IP_PROTOCOL_RDY = &#39;1&#39;) and (unsigned(RX_IP_PROTOCOL) /= 1) and (unsigned(RX_IP_PROTOCOL) /= 58) then -- (b) not ICMP nor ICMPv6 VALID_PING_REQ0 <= &#39;0&#39;; end if; if(IP_RX_WORD_VALID = &#39;1&#39;) and (unsigned(IP_RX_WORD_COUNT) = 3) and (RX_IPv4_6n = &#39;1&#39;) and (IP_RX_DATA(31 downto 16) /= x"0800") then -- (e) IPv4 and ICMP incoming packet is not an echo request (ICMP type /= 8) VALID_PING_REQ0 <= &#39;0&#39;; end if; if(VALID_DEST_IP_RDY = &#39;1&#39;) and (VALID_UNICAST_DEST_IP = &#39;0&#39;) then -- (c) invalid destination IP (IPv4 or IPv6) VALID_PING_REQ0 <= &#39;0&#39;; end if; if(IP_RX_WORD_VALID = &#39;1&#39;) and (unsigned(IP_RX_WORD_COUNT) = 6) and (RX_IPv4_6n = &#39;0&#39;) and ((IP_RX_DATA(63 downto 48) /= x"8000") or (IPv6_ENABLED = &#39;0&#39;)) then -- (e) IPv6 and ICMP6 incoming packet is not an echo request (ICMP6 type /= 128) VALID_PING_REQ0 <= &#39;0&#39;; end if; if(IP_RX_WORD_VALID = &#39;1&#39;) and (unsigned(IP_RX_WORD_COUNT(MAX_PING_SIZE&#39;left downto 0)) > unsigned(MAX_PING_SIZE)) then -- (d) packet size is greater than MAX_PING_SIZE (units = 64-bit words, including IP/ICMP headers) VALID_PING_REQ0 <= &#39;0&#39;; end if; end if; end if; end process; VALID_PING_REQ <= VALID_PING_REQ0 and IP_RX_FRAME_VALID2; -- combine with the other checks done in parsing.vhd --// OUTPUT SECTION ------------------- -- send request to send when a valid IP/ICMP echo response is ready RTS_local <= &#39;1&#39; when (BUF_SIZE /= 0) else &#39;0&#39;; RTS <= RTS_local; -- Output MAC frame generation RPTR_GEN_001: process(CLK) begin if rising_edge(CLK) then DOB_SAMPLE_CLK <= DOB_SAMPLE_CLK_E; -- latency to read from RAM TX_SEQUENCE_CNTR_D <= TX_SEQUENCE_CNTR; MAC_TX_CTS_D <= MAC_TX_CTS; MAC_TX_CTS_D2 <= MAC_TX_CTS_D; if(SYNC_RESET = &#39;1&#39;) or (MAC_TX_EOF_local = &#39;1&#39;) then TX_SEQUENCE_CNTR <= (others => &#39;0&#39;); RPTR <= (others => &#39;1&#39;); DOB_SAMPLE_CLK_E <= &#39;0&#39;; elsif(RTS_local = &#39;1&#39;) and (MAC_TX_CTS = &#39;1&#39;) then -- buffer is not empty and MAC requests another byte TX_SEQUENCE_CNTR <= TX_SEQUENCE_CNTR + 1; DOB_SAMPLE_CLK_E <= &#39;1&#39;; if(TX_SEQUENCE_CNTR > 0) then RPTR <= RPTR + 1; end if; else DOB_SAMPLE_CLK_E <= &#39;0&#39;; end if; end if; end process; -- remember previous word DOB_PREVIOUS_GEN_001: process(CLK) begin if rising_edge(CLK) then if(DOB_SAMPLE_CLK = &#39;1&#39;) then DOB_PREVIOUS <= DOB; end if; end if; end process; MAC_TX_DATA_GEN_001: process(CLK) begin if rising_edge(CLK) then case TX_SEQUENCE_CNTR_D is when x"01" => MAC_TX_DATA(63 downto 16) <= RX_SOURCE_MAC_ADDR; -- source <-> destination MAC MAC_TX_DATA(15 downto 0) <= MAC_ADDR(47 downto 32); when x"02" => MAC_TX_DATA(63 downto 32) <= MAC_ADDR(31 downto 0); -- source <-> destination MAC if(RX_IPv4_6n0 = &#39;1&#39;) then MAC_TX_DATA(31 downto 16) <= x"0800"; -- IPv4 else MAC_TX_DATA(31 downto 16) <= x"86dd"; -- IPv6 end if; MAC_TX_DATA(15 downto 0) <= DOB(63 downto 48); when others => MAC_TX_DATA(63 downto 16) <= DOB_PREVIOUS(47 downto 0); MAC_TX_DATA(15 downto 0) <= DOB(63 downto 48); end case; end if; end process; MAC_TX_DATA_VALID_GEN_001: process(CLK) begin if rising_edge(CLK) then if(SYNC_RESET = &#39;1&#39;) or (MAC_TX_EOF_local = &#39;1&#39;) or (STATE = "0") then MAC_TX_DATA_VALID_local <= x"00"; elsif(DOB_SAMPLE_CLK = &#39;1&#39;) then if(unsigned(TX_SEQUENCE_CNTR_D) < 3) then MAC_TX_DATA_VALID_local <= x"FF"; else MAC_TX_DATA_VALID_local(7 downto 2) <= DOB_PREVIOUS(69 downto 64); MAC_TX_DATA_VALID_local(1 downto 0) <= DOB(71 downto 70); end if; elsif(MAC_TX_CTS_D2 = &#39;1&#39;) and (unsigned(DOB_PREVIOUS(69 downto 64)) /= 0) then -- flush last bytes MAC_TX_DATA_VALID_local(7 downto 2) <= DOB_PREVIOUS(69 downto 64); MAC_TX_DATA_VALID_local(1 downto 0) <= "00"; else MAC_TX_DATA_VALID_local <= x"00"; end if; end if; end process; MAC_TX_DATA_VALID <= MAC_TX_DATA_VALID_local; MAC_TX_EOF_GEN_001: process(CLK) begin if rising_edge(CLK) then if(SYNC_RESET = &#39;1&#39;) or (MAC_TX_EOF_local = &#39;1&#39;) or (STATE = "0") then MAC_TX_EOF_local <= &#39;0&#39;; elsif(DOB_SAMPLE_CLK = &#39;1&#39;) then if (DOB_SAMPLE_CLK_E = &#39;0&#39;) and (BUF_SIZE = 0) and (unsigned(DOB(69 downto 64)) = 0) then MAC_TX_EOF_local <= &#39;1&#39;; end if; elsif(DOB_SAMPLE_CLK = &#39;0&#39;) and (MAC_TX_CTS_D2 = &#39;1&#39;) and (unsigned(DOB_PREVIOUS(69 downto 64)) /= 0) then -- flush last bytes MAC_TX_EOF_local <= &#39;1&#39;; else MAC_TX_EOF_local <= &#39;0&#39;; end if; end if; end process; MAC_TX_EOF <= MAC_TX_EOF_local; --// TEST POINTS -------------------------- TP(1) <= IP_RX_EOF_D and VALID_PING_REQ; --TP(1) <= IP_RX_SOF; TP(2) <= &#39;1&#39; when (IP_RX_DATA_VALID /= x"00") else &#39;0&#39;; TP(3) <= IP_RX_EOF; TP(4) <= VALID_PING_REQ0; TP(5) <= VALID_UNICAST_DEST_IP and VALID_DEST_IP_RDY; TP(6) <= IP_RX_FRAME_VALID2; TP(7) <= DOB_SAMPLE_CLK; TP(8) <= MAC_TX_EOF_local; TP(9) <= &#39;1&#39; when (MAC_TX_DATA_VALID_local /= x"00") else &#39;0&#39;; TP(10)<= MAC_TX_CTS; end Behavioral;
最新发布
11-15
`PING_10G` 实体用于 10G 以太网环境下实现 ICMP(Internet Control Message Protocol)的 PING 功能,用于测试两台设备之间的连通性。以下是对其具体功能和作用的详细分析: ### 输入处理 - **IP 帧接收**:通过 `IP_RX_DATA`、`IP_RX_DATA_VALID`、`IP_RX_SOF`、`IP_RX_EOF` 和 `IP_RX_WORD_COUNT` 等信号接收 IP 帧数据,并进行有效性检查。 ```vhdl if rising_edge(CLK) then if(SYNC_RESET = &#39;1&#39;) then IP_RX_DATA_PREVIOUS <= (others => &#39;0&#39;); elsif(IP_RX_DATA_VALID /= x"00") then IP_RX_DATA_PREVIOUS <= IP_RX_DATA; end if; end if; ``` - **IP 类型和协议解析**:借助 `RX_IPv4_6n` 和 `RX_IP_PROTOCOL` 信号解析 IP 版本和协议类型,判断是否为 ICMP 协议。 ```vhdl if(RX_IP_PROTOCOL_RDY = &#39;1&#39;) and (unsigned(RX_IP_PROTOCOL) /= 1) and (unsigned(RX_IP_PROTOCOL) /= 58) then -- (b) not ICMP nor ICMPv6 VALID_PING_REQ0 <= &#39;0&#39;; end if; ``` - **IP 地址和 MAC 地址处理**:使用 `MAC_ADDR`、`IPv4_ADDR` 和 `IPv6_ADDR` 配置本地 MAC 地址和 IP 地址,同时通过 `RX_SOURCE_MAC_ADDR` 和 `RX_SOURCE_IP_ADDR` 获取源 MAC 地址和 IP 地址。 ### 状态机管理 使用状态机控制整个流程,状态 `0` 表示空闲或正在处理传入 IP 帧,状态 `1` 表示有有效的 PING 请求,等待发送 PING 回复。 ```vhdl if rising_edge(CLK) then if(SYNC_RESET = &#39;1&#39;) then STATE <= (others => &#39;0&#39;); elsif(IP_RX_EOF_D = &#39;1&#39;) and (VALID_PING_REQ = &#39;1&#39;) then -- event = valid PING request. Ready to send PING reply when tx channel opens. -- In the mean time, incoming IP frames are discarded. STATE <= "1"; elsif(MAC_TX_EOF_local = &#39;1&#39;) then -- event = successfully sent PING reply. Reopen input STATE <= "0"; end if; end if; ``` ### 数据处理和校验 - **数据修改**:在将 IP 数据存入弹性缓冲区之前,对其进行修改,如交换源 IP 地址和目的 IP 地址,修改 ICMP 类型和校验和。 ```vhdl if(unsigned(IP_RX_WORD_COUNT) = 2) then IP_RX_DATA_MOD(63 downto 32) <= IP_RX_DATA(63 downto 32); IP_RX_DATA_MOD(31 downto 0) <= IPv4_ADDR; -- source is our IP address elsif(unsigned(IP_RX_WORD_COUNT) = 3) then IP_RX_DATA_MOD(63 downto 32) <= IP_RX_DATA_PREVIOUS(31 downto 0); -- swap source/dest IP addresses in response IP_RX_DATA_MOD(31 downto 24) <= x"00"; -- ICMP echo reply IPv4 type IP_RX_DATA_MOD(23 downto 16) <= IP_RX_DATA(23 downto 16); -- ICMP echo reply IPv4 code IP_RX_DATA_MOD(15 downto 0) <= std_logic_vector(REPLY_CHECKSUM); -- ICMP echo reply IPv4 checksum end if; ``` - **校验和计算**:根据 IP 版本计算 ICMP 回复的校验和。 ```vhdl if(RX_IPv4_6n = &#39;1&#39;) then -- IPv4 CKSUM := resize(unsigned(IP_RX_DATA(15 downto 0)),17); CKSUM := CKSUM + x"0800"; else -- IPv6 CKSUM := resize(unsigned(IP_RX_DATA(47 downto 32)),17); CKSUM := CKSUM - x"0100"; end if; if(CKSUM(16) = &#39;1&#39;) then CKSUM := CKSUM + 1; end if; REPLY_CHECKSUM <= CKSUM(15 downto 0); ``` ### 弹性缓冲区 使用双端口 RAM 实现弹性缓冲区,存储 IP/ICMP 帧,直到有效性检查完成且传输路径可用。 ```vhdl BRAM_DP2_001: BRAM_DP2 GENERIC MAP( DATA_WIDTHA => 73, ADDR_WIDTHA => 8, DATA_WIDTHB => 73, ADDR_WIDTHB => 8 ) PORT MAP( CSA => &#39;1&#39;, CLKA => CLK, WEA => WEA, -- Port A Write Enable Input ADDRA => std_logic_vector(WPTR), -- Port A 8-bit Address Input DIA => DIA, -- Port A 65-bit Data Input OEA => &#39;0&#39;, DOA => open, CSB => &#39;1&#39;, CLKB => CLK, WEB => &#39;0&#39;, ADDRB => std_logic_vector(RPTR), -- Port B 8-bit Address Input DIB => (others => &#39;0&#39;), -- Port B 65-bit Data Input OEB => &#39;1&#39;, DOB => DOB -- Port B 65-bit Data Output ); ``` ### 输出处理 - **请求发送**:当有有效的 IP/ICMP 回显响应准备好时,通过 `RTS` 信号请求发送。 ```vhdl RTS_local <= &#39;1&#39; when (BUF_SIZE /= 0) else &#39;0&#39;; RTS <= RTS_local; ``` - **MAC 帧生成**:根据弹性缓冲区的数据生成要发送的 MAC 帧,通过 `MAC_TX_DATA`、`MAC_TX_DATA_VALID` 和 `MAC_TX_EOF` 信号发送。 ```vhdl case TX_SEQUENCE_CNTR_D is when x"01" => MAC_TX_DATA(63 downto 16) <= RX_SOURCE_MAC_ADDR; -- source <-> destination MAC MAC_TX_DATA(15 downto 0) <= MAC_ADDR(47 downto 32); when x"02" => MAC_TX_DATA(63 downto 32) <= MAC_ADDR(31 downto 0); -- source <-> destination MAC if(RX_IPv4_6n0 = &#39;1&#39;) then MAC_TX_DATA(31 downto 16) <= x"0800"; -- IPv4 else MAC_TX_DATA(31 downto 16) <= x"86dd"; -- IPv6 end if; MAC_TX_DATA(15 downto 0) <= DOB(63 downto 48); when others => MAC_TX_DATA(63 downto 16) <= DOB_PREVIOUS(47 downto 0); MAC_TX_DATA(15 downto 0) <= DOB(63 downto 48); end case; ``` ### 测试点 通过 `TP` 信号输出一些关键状态和信号,方便调试和测试。 ```vhdl TP(1) <= IP_RX_EOF_D and VALID_PING_REQ; TP(2) <= &#39;1&#39; when (IP_RX_DATA_VALID /= x"00") else &#39;0&#39;; TP(3) <= IP_RX_EOF; ``` ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值