Line data Source code
1 : /* 2 : * ethernet/arp.c: IP v4 ARP node 3 : * 4 : * Copyright (c) 2010 Cisco and/or its affiliates. 5 : * Licensed under the Apache License, Version 2.0 (the "License"); 6 : * you may not use this file except in compliance with the License. 7 : * You may obtain a copy of the License at: 8 : * 9 : * http://www.apache.org/licenses/LICENSE-2.0 10 : * 11 : * Unless required by applicable law or agreed to in writing, software 12 : * distributed under the License is distributed on an "AS IS" BASIS, 13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 : * See the License for the specific language governing permissions and 15 : * limitations under the License. 16 : */ 17 : 18 : #ifndef __ARP_PACKET_H__ 19 : #define __ARP_PACKET_H__ 20 : 21 : #include <vnet/arp/arp.h> 22 : 23 : /* Either we drop the packet or we send a reply to the sender. */ 24 : typedef enum 25 : { 26 : ARP_REPLY_NEXT_DROP, 27 : ARP_REPLY_NEXT_REPLY_TX, 28 : ARP_REPLY_N_NEXT, 29 : } arp_reply_next_t; 30 : 31 : static_always_inline u32 32 1974 : arp_mk_reply (vnet_main_t * vnm, 33 : vlib_buffer_t * p0, 34 : u32 sw_if_index0, 35 : const ip4_address_t * if_addr0, 36 : ethernet_arp_header_t * arp0, ethernet_header_t * eth_rx) 37 : { 38 : vnet_hw_interface_t *hw_if0; 39 : u8 *rewrite0, rewrite0_len; 40 : ethernet_header_t *eth_tx; 41 : u32 next0; 42 : 43 : /* Send a reply. 44 : An adjacency to the sender is not always present, 45 : so we use the interface to build us a rewrite string 46 : which will contain all the necessary tags. */ 47 3948 : rewrite0 = ethernet_build_rewrite (vnm, sw_if_index0, 48 1974 : VNET_LINK_ARP, eth_rx->src_address); 49 1974 : rewrite0_len = vec_len (rewrite0); 50 : 51 : /* Figure out how much to rewind current data from adjacency. */ 52 1974 : vlib_buffer_advance (p0, -rewrite0_len); 53 1974 : eth_tx = vlib_buffer_get_current (p0); 54 : 55 1974 : vnet_buffer (p0)->sw_if_index[VLIB_TX] = sw_if_index0; 56 1974 : hw_if0 = vnet_get_sup_hw_interface (vnm, sw_if_index0); 57 : 58 : /* Send reply back through input interface */ 59 1974 : vnet_buffer (p0)->sw_if_index[VLIB_TX] = sw_if_index0; 60 1974 : next0 = ARP_REPLY_NEXT_REPLY_TX; 61 : 62 1974 : arp0->opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply); 63 : 64 1974 : arp0->ip4_over_ethernet[1] = arp0->ip4_over_ethernet[0]; 65 : 66 1974 : mac_address_from_bytes (&arp0->ip4_over_ethernet[0].mac, 67 1974 : hw_if0->hw_address); 68 1974 : clib_mem_unaligned (&arp0->ip4_over_ethernet[0].ip4.data_u32, u32) = 69 1974 : if_addr0->data_u32; 70 : 71 1974 : p0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED; 72 : 73 : /* Hardware must be ethernet-like. */ 74 1974 : ASSERT (vec_len (hw_if0->hw_address) == 6); 75 : 76 : /* the rx nd tx ethernet headers wil overlap in the case 77 : * when we received a tagged VLAN=0 packet, but we are sending 78 : * back untagged */ 79 1974 : clib_memcpy_fast (eth_tx, rewrite0, vec_len (rewrite0)); 80 1974 : vec_free (rewrite0); 81 : 82 1974 : return (next0); 83 : } 84 : 85 : #endif 86 : 87 : /* 88 : * fd.io coding-style-patch-verification: ON 89 : * 90 : * Local Variables: 91 : * eval: (c-set-style "gnu") 92 : * End: 93 : */