The Linux Foundation - arphttp://www.linuxfoundation.org/taxonomy/term/1256/0
enneighboring subsystem by Rami Rosenhttp://www.linuxfoundation.org/collaborate/workgroups/networking/neighboringsubsystem
<p><a name="Linux_Kernel_Neighboring_Subsystem_Overview_by_Rami_Rosen"></a></p>
<h2><a name="Linux_Kernel_Neighboring_Subsystem_Overview_by_Rami_Rosen"></a></h2>
<h2>Linux Kernel Neighboring Subsystem Overview by Rami Rosen</h2>
<p><strong>&nbsp;</strong></p>
<p><strong><img src="http://static.wix.com/media/295986_ba454dff2981d37103dfe5feb4fa0555.jpg_srz_96_96_75_22_0.50_1.20_0.00_jpg_srz" alt="Rami Rosen pic" width="96" height="96" /></strong></p>
<p>&nbsp;</p>
<p>&nbsp;<strong><strong>&nbsp;Last updated: 2.12.12</strong></strong></p>
<p><strong>This wiki is based on a my practical experience with Linux&nbsp;<strong>kernel networking</strong>&nbsp;and a series of lectures I gave in the Technion:<br />See:&nbsp;<br /><a title="Rami Rosen lectures" href="http://www.haifux.org/rami_rosen.html" target="_blank">Rami Rosen lectures</a></strong></p>
<h2>Please feel free send any feedback or question to Rami Rosen by sending&nbsp;email to:&nbsp;<strong><a href="mailto:ramirose@gmail.com">ramirose@gmail.com</a></strong></h2>
<h2>&nbsp;</h2>
<p><strong>Introduction</strong></p>
<p>● Why do we need the neighboring subsystem&nbsp;?</p>
<p>● “The world is a jungle in general, and the networking game contributes many animals.” (from <a class="external" title="http://www.ietf.org/rfc/rfc826.txt" href="http://www.ietf.org/rfc/rfc826.txt">RFC 826</a>, ARP, 1982)</p>
<p>● Most known protocol: <strong>ARP</strong> (in IPv6: ND, neighbour discovery)</p>
<p>● Ethernet header is 14 bytes long:</p>
<p>● Source Mac address and destination Mac address are 6 bytes each.</p>
<p>– Type (2 bytes). For example, (include/linux/if_ether.h)</p>
<p>● 0x0800 is the type for IP packet <strong>(ETH_P_IP)</strong></p>
<p>● 0x0806 is the type for ARP packet <strong>(ETH_P_ARP)</strong></p>
<p>● 0X8035 is the type for RARP packet <strong>(ETH_P_RARP)</strong></p>
<p><strong>Neighboring Subsystem – struct neighbour</strong></p>
<p>● neighbour (instance of struct neighbour) is embedded in dst, which is in turn is embedded in sk_buff:</p>
<p>● Implementation: important data structures</p>
<p>●<strong> struct neighbour</strong> (<a href="http://lxr.free-electrons.com/source/include/net/neighbour.h" target="_blank">include/net/neighbour.h</a>)</p>
<p>– ha is the hardware address (MAC address when dealing with Ethernet) of the neighbour. This field is filled when an ARP response arrives.</p>
<ul>
<li>&nbsp;primary_key – The IP address (L3) of the neighbour.</li>
</ul>
<p>● lookup in the arp table is done with the primary_key.</p>
<ul>
<li>&nbsp;nud_state represents the Network Unreachability Detection state of the neighbor. (for example, NUD_REACHABLE).</li>
</ul>
<p>● int <strong>(*output)(struct sk_buff *skb)</strong>;</p>
<p>– output() can be assigned to different methods according to the state of the neighbour. For example, neigh_resolve_output() and neigh_connected_output().</p>
<p>Initially, it is <em><strong>neigh_blackhole().</strong></em></p>
<p>– When a state changes, than also the output function may be assigned to a different function.</p>
<p>● refcnt incremented by <em><strong>neigh_hold()</strong></em>; decremented by <em><strong>neigh_release()</strong></em>.</p>
<p>We don't free a neighbour when the refcnt is higher than 1;instead, we set dead(a member of neighbour) to 1.</p>
<p>● timer (The callback method is neigh_timer_handler()).</p>
<p>● struct hh_cache *hh (defined in include/linux/netdevice.h)</p>
<p>● confirmed – confirmation timestamp.</p>
<p>&nbsp;– Confirmation can be also done from L4 (transport layer). – For example, dst_confirm() calls neigh_confirm(). – dst_confirm() is called from tcp_ack()</p>
<p>&nbsp;(net/ipv4/tcp_input.c) – and by udp_sendmsg() (net/ipv4/udp.c) and more. –</p>
<p><em><strong> neigh_confirm()</strong></em> does NOT change the state</p>
<p>– it is the job of <em><strong>neigh_timer_handler()</strong></em>.</p>
<p>● dev (net_device)</p>
<p>● arp_queue – every neighbour has a small arp queue of itself. – There can be only 3 elements by default in an arp_queue.</p>
<p>– This is configurable:<em><strong>/proc/sys/net/ipv4/neigh/default/unres_qlen</strong></em></p>
<p><strong>struct neigh_table</strong></p>
<p>● struct <strong>neigh_table</strong> represents a neighboring table – (/include/net/neighbour.h)</p>
<p>– The arp table (arp_tbl) is a neigh_table. (<a href="http://lxr.free-electrons.com/source/include/net/arp.h" target="_blank">include/net/arp.h</a>)</p>
<p>– In IPv6, nd_tbl (Neighbor Discovery table ) is a neigh_table also (<a href="http://lxr.free-electrons.com/source/include/net/ndisc.h" target="_blank">include/net/ndisc.h</a>) – There is also dn_neigh_table (DEcnet ) (linux/net/decnet/dn_neigh.c) and clip_tbl (for ATM) (net/atm/clip.c) –</p>
<p>gc_timer: neigh_periodic_timer() is the callback for garbage collection. – neigh_periodic_timer() deletes FAILED entries from the ARP table. Neighboring Subsystem arp</p>
<p>● When there is no entry in the ARP cache for the destination IP address of a packet, a broadcast is sent (ARP request, <strong>ARPOP_REQUEST</strong>: who has IP address x.y.z...). This is done by a method called arp_solicit().(<a href="http://lxr.free-electrons.com/source/net/ipv4/arp.c" target="_blank">net/ipv4/arp.c</a>) – In IPv6, the parallel mechanism is called ND (Neighbor discovery) and is implemented as part of ICMPv6. – A multicast is sent in IPv6 (and not a broadcast).</p>
<p>● If there is no answer in time to this arp request, then we will end up with sending back an ICMP error (Destination Host Unreachable).</p>
<p>● This is done by <em><strong>arp_error_report</strong></em>() , which indirectly calls <em><strong>ipv4_link_failure</strong></em>()&nbsp;; see <a href="http://lxr.free-electrons.com/source/net/ipv4/route.c" target="_blank">net/ipv4/route.c</a>.</p>
<p>● You can see the contents of the arp table by running: “<em><strong>cat /proc/net/arp</strong></em>” or by running the “arp” from a command line.</p>
<ul>
<li>You can view statistics of arp cache (IPV4) by: <strong><em>cat /proc/net/stat/arp_cache</em></strong></li>
<li>You can view statistics of ndisc cache (IPV6) by: <strong><em>cat</em></strong> <strong>/proc/net/stat/ndisc_cache</strong></li>
</ul>
<p>● <em><strong>"ip neigh show"</strong></em> is the new method to show arp (from IPROUTE2)</p>
<ul>
<li>In IPv6 it is "<em><strong>ip -6 neigh show</strong></em>".</li>
</ul>
<p>● You can delete and add entries to the arp table; see <strong><em>man arp/man ip.</em></strong></p>
<p>● When using “ip<em><strong> neigh add</strong></em>” you can specify the state of the entry which you are adding (like permanent, stale, reachable, etc).</p>
<p>● arp command does not show reachability states except the incomplete state and permanent state: Permanent entries are marked with M in Flags:</p>
<p><strong>example&nbsp;: arp output</strong></p>
<p>Address HWtype HWaddress Flags Mask Iface 10.0.0.2 (incomplete) eth0 10.0.0.3 ether 00:01:02:03:04:05 CM eth0 10.0.0.138 ether 00:20:8F:0C:68:03 C eth0</p>
<p>Neighboring Subsystem – ip neigh show.</p>
<p>● We can see the current neighbour states:</p>
<p>● Example&nbsp;:</p>
<p>● <em><strong>ip neigh show</strong></em></p>
<p>192.168.0.254 dev eth0 lladdr 00:03:27:f1:a1:31 REACHABLE 192.168.0.152 dev eth0 lladdr 00:00:00:cc:bb:aa STALE 192.168.0.121 dev eth0 lladdr 00:10:18:1b:1c:14 PERMANENT 192.168.0.54 dev eth0 lladdr aa:ab:ac:ad:ae:af STALE</p>
<p>● <em><strong>arp_process</strong>()</em> handles both ARP requests and ARP responses. – <a href="http://lxr.free-electrons.com/source/net/ipv4/arp.c" target="_blank">net/ipv4/arp.c</a></p>
<p>– If the target ip (tip) address in the arp header is the loopback then <em><strong>arp_process()</strong></em> drops it since loopback does not need ARP</p>
<p>. ... if (LOOPBACK(tip) || MULTICAST(tip))</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;goto out;</p>
<p>out:</p>
<p>... kfree_skb(skb); return 0;</p>
<p>(see: #define LOOPBACK(x) (((x) &amp; htonl(0xff000000)) == htonl(0x7f000000)) in linux/in.h</p>
<p>● If it is an ARP request (ARPOP_REQUEST) we call ip_route_input().</p>
<p>● Why&nbsp;?</p>
<p>● In case it is for us, (RTN_LOCAL) we send and ARP reply. – arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha ,dev&gt; dev_addr,sha); – We also update our arp table with the sender entry (ip/mac).</p>
<p>● Special case: ARP proxy server.</p>
<p>● In case we receive an ARP reply – (ARPOP_REPLY) –</p>
<p>We perform a lookup in the arp table. (by calling __neigh_lookup()) – If we find an entry, we update the arp table by neigh_update().</p>
<p>● If there is no entry and there is NO support for unsolicited ARP we don't create an entry in the arp table. – Support for unsolicited ARP by setting /proc/sys/net/ipv4/conf/all/arp_accept to 1. – The corresponding macro is: IPV4_DEVCONF_ALL(ARP_ACCEPT)) – In older kernels, support for unsolicited ARP was done by: – CONFIG_IP_ACCEPT_UNSOLICITED_ARP Neighboring Subsystem – lookup</p>
<p>● Lookup in the neighboring subsystem is done via: neigh_lookup() parameters: – neigh_table (arp_tbl) – pkey (ip address, the primary_key of neighbour struct) – dev (net_device) – There are 2 wrappers: – __neigh_lookup()</p>
<p>● just one more parameter: creat (a flag: to create a neighbor by neigh_create() or not))</p>
<p>● and __neigh_lookup_errno()</p>
<p><strong>Neighboring Subsystem – static entries</strong></p>
<p>● Adding a static entry is done by:</p>
<p><em><strong> arp -s ipAddress MacAddress</strong></em></p>
<p>● Alternatively, this can be done by:</p>
<p><em><strong> ip neigh add ipAddress dev eth0 lladdr MacAddress nud permanent</strong></em></p>
<p>● The state (nud_state) of this entry will be <strong>NUD_PERMANENT</strong></p>
<ul>
<li><em><strong>ip neigh show</strong></em> will show it as PERMANENT.</li>
</ul>
<p>● Why do we need PERMANENT entries&nbsp;?</p>
<p>arp_bind_neighbour() method</p>
<p>● Suppose we are sending a packet to a host for the first time.</p>
<p>● a dst_entry is added to the routing cache by rt_intern_hash().</p>
<p>● We should know the L2 address of that host. – so rt_intern_hash() calls arp_bind_neighbour().</p>
<p>● only for RTN_UNICAST (not for multicast/broadcast). – arp_bind_neighbour(): net/ipv4/arp.c – dst-&gt; neighbour=NULL, so it calls__neigh_lookup_errno(). – There is no such entry in the arp table. – So we will create a neighbour with neigh_create() and add it to the arp table.</p>
<p>● <em><strong>neigh_create</strong>()</em> creates a neighbour with <strong>NUD_NONE</strong> state</p>
<p>– setting nud_state to NUD_NONE is done in neigh_alloc()</p>
<p><strong>The IFF_NOARP flag</strong></p>
<p>● Disabling and enabling arp</p>
<p>●<em><strong> ifconfig eth1 -arp</strong></em></p>
<p>– You will see the <strong>NOARP</strong> flag now in ifconfig a</p>
<p>● <strong><em>ifconfig eth1 arp</em></strong> (to enable arp of the device)</p>
<p>● In fact, this sets the <strong>IFF_NOARP</strong> flag of net_device.</p>
<p>● There are cases where the interface by default is with the <em><strong>IFF_NOARP</strong></em> flag (for example, ppp interface, see <em><strong>ppp_setup()</strong> </em>(drivers/net/ppp_generic.c)</p>
<p><strong>Changing IP address</strong></p>
<p>● Suppose we try to set eth1 to an IP address of a different machine on the LAN:</p>
<p>● First, we will set an ip for eth1 in (in Fedora Core 8,for example)</p>
<p>● /etc/sysconfig/networkscripts/ifcfg-eth1</p>
<p>● ... IPADDR=192.168.0.122 ...</p>
<p>and than run:</p>
<p>●<em><strong>ifup eth1</strong></em></p>
<p>● we will get:</p>
<ul>
<li><strong>Error, some other host already uses address 192.168.0.122.</strong></li>
</ul>
<p>● But:</p>
<p>● <em><strong>ifconfig eth0 192.168.0.122</strong></em></p>
<p>● works ok&nbsp;!</p>
<p>● Why is it so&nbsp;?</p>
<p><strong>Duplicate Address Detection (DAD)</strong></p>
<p>● Duplicate Address Detection mode (DAD)</p>
<p>● arping I eth0 D 192.168.0.10</p>
<p>– sends a broadcast packet whose source address is 0.0.0.0.</p>
<p>0.0.0.0 is not a valid IP address (for example, you cannot set an ip address to 0.0.0.0 with ifconfig)</p>
<p>● The mac address of the sender is the real one.</p>
<p>● -D flag is for Duplicate Address Detection mode.</p>
<p>Code: (from <strong><em>arp_process()</em></strong>&nbsp;; see /net/ipv4/arp.c) /* Special case: IPv4 duplicate address detection packet (RFC2131)*/ if (sip == 0) { if (arp&gt; ar_op == htons(ARPOP_REQUEST) &amp;&amp;</p>
<p>inet_addr_type(tip) == RTN_LOCAL &amp;&amp;&nbsp;!arp_ignore(in_dev,dev,sip,tip)) arp_send(ARPOP_REPLY,ETH_P_ARP,tip,dev,tip,sha,dev-&gt;dev_addr,dev&gt; dev_addr);</p>
<p>goto out;</p>
<p>}</p>
<p><strong>Neighboring Subsystem – Garbage Collection</strong></p>
<p>● Garbage Collection – neigh_periodic_timer() – neigh_timer_handler() – neigh_periodic_timer() removes entires which are in NUD_FAILED state. This is done by setting dead to 1, and calling neigh_release(). The refcnt must be 1 to ensure no one else uses this neighbour. Also expired entries are removed.</p>
<p>● <strong>NUD_FAILED </strong>entries don't have MAC address&nbsp;; see ip neigh show) Neighboring Subsystem – Asynchronous Garbage Collection</p>
<p>● neigh_forced_gc() performs asynchronous Garbage Collection.</p>
<p>● It is called from neigh_alloc() when the number of the entries in the arp table exceeds a (configurable) limit.</p>
<p>● This limit is configurable (gc_thresh2,gc_thresh3) <em><strong>/proc/sys/net/ipv4/neigh/default/gc_thresh2 </strong></em></p>
<p><em><strong>/proc/sys/net/ipv4/neigh/default/gc_thresh3</strong></em></p>
<p>– The default for gc_thresh3 is 1024.</p>
<p>&nbsp;Candidates for cleanup: Entries which their reference count is 1, or which their state is NOT permanent.</p>
<p>● Changing the neighbour state is done only in <em><strong>neigh_timer_handler()</strong></em>.</p>
<p><strong>LVS (Linux Virtual Sever)</strong></p>
<p>● <a class="external free" title="http://www.linuxvirtualserver.org/" href="http://www.linuxvirtualserver.org/" rel="nofollow">http://www.linuxvirtualserver.org/</a></p>
<p>● Integrated into the Linux kernel (in 2.4 kernel it was a patch).</p>
<p>● Located in: <a href="http://lxr.free-electrons.com/source/net/netfilter/ipvs/" target="_blank">net/netfilter/ipvs</a>&nbsp;in the kernel tree.</p>
<p>● LVS has eight scheduling algorithms.</p>
<p>● LVS/DR is LVS with direct routing (a load balancing solution).</p>
<p>● <em><strong>ipvsadm</strong></em> is the user space management tools (available in most distros).</p>
<p>● Direct Routing is the packet forwarding method.</p>
<p>● -g, gatewaying =&gt; Use gatewaying (direct routing)</p>
<p>● see man ipvsadm.</p>
<p><strong>LVS/DR</strong></p>
<p>● Example: 3 Real Servers and the Director all have the same VirtualIP (VIP).</p>
<p>● There is an ARP problem in this configuration.</p>
<p>● When you send an ARP broadcast, and the receiving machine has two or more NICs, each of them responds to this ARP request. Example: a machine with two NICs&nbsp;;</p>
<p>● eth0 is 192.168.0.151 and eth1 is 192.168.0.152.</p>
<p><strong>LVS and ARP</strong></p>
<p>● Solutions</p>
<p>1) Set ARP_IGNORE to 1:</p>
<ul>
<li><strong>echo “1” &gt; /proc/sys/net/ipv4/conf/eth0/arp_ignore</strong></li>
<li><strong>echo “1” &gt; /proc/sys/net/ipv4/conf/eth1/arp_ignore</strong></li>
</ul>
<p>2) Use arptables. – There are 3 points in the arp walkthrough: (include/linux/netfilter_arp.h) – NF_ARP_IN (in arp_rcv() , net/ipv4/arp.c). – NF_ARP_OUT (in arp_xmit()),net/ipv4/arp.c) – NF_ARP_FORWARD ( in br_nf_forward_arp(), net/bridge/br_netfilter.c)</p>
<p>● <a class="external free" title="http://ebtables.sourceforge.net/download.html" href="http://ebtables.sourceforge.net/download.html" rel="nofollow">http://ebtables.sourceforge.net/download.html</a></p>
<p>– <strong>Ebtables</strong> is in fact the parallel of netfilter but in L2.</p>
<p><strong>LVS example (ipvsadm)</strong></p>
<p>● An example for setting LVS/DR on TCP port 80 with three real servers:</p>
<p>● ipvsadm C // clear the LVS table</p>
<p>● ipvsadm A t DirectorIPAddress:80</p>
<p>● ipvsadm -a t DirectorIPAddress:80 r RealServer1 g</p>
<p>● ipvsadm -a t DirectorIPAddress:80 r RealServer2 g</p>
<p>● ipvsadm -a t DirectorIPAddress:80 r RealServer3 g</p>
<p>● This example deals with tcp connections (for udp connection we should use u instead of t in the last 3 lines).</p>
<p><strong>LVS example:</strong></p>
<p>● ipvsadm -Ln // list the LVS table</p>
<p>● <strong><em>/proc/sys/net/ipv4/ip_forward</em></strong> should be set to 1</p>
<p>● In this example, packets sent to VIP will be sent to the load balancer; it will delegate them to the real server according to its scheduler. The dest MAC address in L2 header will be the MAC address of the real server to which the packet will be sent. The dest IP header will be VIP.</p>
<p>● This is done with NF_IP_LOCAL_IN.</p>
<p><strong>ARPD&nbsp;</strong>– <strong>arp user space daemon</strong></p>
<p>● ARPD is a user space daemon; it can be used if we want to remove some work from the kernel.</p>
<p>● The user space daemon is part of iproute2 (/misc/arpd.c)</p>
<p>● ARPD has support for negative entries and for dead hosts.</p>
<p>– The kernel arp code does NOT support these type of entries!</p>
<p>● The kernel by default is not compiled with ARPD support; we should set CONFIG_ARPD for using it:</p>
<p>● Networking Support-&gt; Networking Options-&gt; IP: ARP daemon support.</p>
<p>● see: /usr/share/doc/iproute2.6.22/arpd.ps (Alexey Kuznetsov).&nbsp;</p>
<p>● We should also set app_probes to a value greater than 0 by setting – /proc/sys/net/ipv4/neigh/eth0/app_solicit – This can be done also by the a (active_probes) parameter. – The value of this parameter tells how many ARP requests to send before that neighbour is considered dead.</p>
<p>● The k parameter tells the kernel not to send ARP broadcast; in such case, the arpd daemon is not only listening to ARP requests, but also send ARP broadcasts.</p>
<p>● Activation:</p>
<p>● arpd a 1 k eth0 &amp;</p>
<p>● On some distros, you will get the error db_open: No such file or directory unless you simply run mkdir /var/lib/arpd/ before (for the arpd.db file).</p>
<p>● Pay attention: you can start arpd daemon when there is no support in the kernel(CONFIG_ARPD is not set).</p>
<p>● In this case you, arp packets are still caught by arpd daemon get_arp_pkt()</p>
<pre> (misc/arpd.c)
</pre><p>● But you don't get messages from the kernel.</p>
<p>● get_arp_pkt() is not called.(misc/arpd.c)</p>
<p>● Tip: to check if CONFIG_ARPD is set, simply see if there are any results from</p>
<p>– cat /proc/kallsyms | grep neigh_app</p>
<p><strong>Mac addresses</strong></p>
<p>● MAC address (Media Access Control)</p>
<p>● According to specs, MAC address should be unique.</p>
<p>● The 3 first bytes specify a hw manufacturer of the card.</p>
<p>● Allocated by IANA.</p>
<p>&nbsp;There are exceptions to this rule.&nbsp;</p>
<p>&nbsp;– Ethernet HWaddr 00:16:3E:3F:6E:5D&nbsp;</p>
<p><strong>ARPwatch (detect ARP cache poisoning)</strong></p>
<p>● Changing MAC address can be as a result of some security attack (ARP cache poisoning).</p>
<p>● Arpwatch can help detect such an attack.</p>
<p>● Activation: arpwatch d i eth0 (output to stderr)</p>
<p>● Arpwatch keeps a table of ip/mac addresses and senses when there is a change.</p>
<p>● d is for redirecting the log to stderr (no syslog, no mail).</p>
<p>● In case someone changed MAC address on the same network, you will get a message like this: <strong>ARPwatch Example</strong></p>
<p>From: root (Arpwatch) To: root Subject: changed ethernet address (jupiter) hostname: jupiter ip address: 192.168.0.54 ethernet address: aa:bb:cc:dd:ee:ff ethernet vendor: &lt;unknown&gt; old ethernet address: 0:20:18:61:e5:e0 old ethernet vendor: ...</p>
<p><strong>Neighbour states</strong></p>
<p>● neighbour states</p>
<p><strong>neigh_alloc()</strong> Reachable Incomplete None Stale Delay Probe Neighboring Subsystem</p>
<p>●– NUD_NONE</p>
<p>– NUD_REACHABLE</p>
<p>– NUD_STALE</p>
<p>– NUD_DELAY</p>
<p>– NUD_PROBE</p>
<p>– NUD_FAILED</p>
<p>– NUD_INCOMPLETE</p>
<p>● Special states:</p>
<p>● NUD_NOARP</p>
<p>● NUD_PERMANENT</p>
<p>● No state transitions are allowed from these states to another state.</p>
<p><strong>Neighboring Subsystem – states</strong></p>
<p>● NUD state combinations:</p>
<p>● NUD_IN_TIMER (NUD_INCOMPLETE|NUD_REACHABLE| NUD_DELAY|NUD_PROBE)</p>
<p>● NUD_VALID (NUD_PERMANENT|NUD_NOARP| NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY)</p>
<p>● NUD_CONNECTED (NUD_PERMANENT|NUD_NOARP| NUD_REACHABLE)</p>
<p>● When a neighbour is in a STALE state it will remain in this state until one of the two will occur – a packet is sent to this neighbour. – Its state changes to FAILED.</p>
<p>● <strong><em>neigh_resolve_output()</em></strong> and <em><strong>neigh_connected_output()</strong></em>.</p>
<p>● <a href="http://lxr.free-electrons.com/source/net/core/neighbour.c" target="_blank">net/core/neighbour.c</a></p>
<p>● A neighbour in INCOMPLETE state does not have MAC address set yet (ha member of neighbour)</p>
<p>● So when<em><strong> neigh_resolve_output()</strong></em> is called, the neighbour state is changed to INCOMPLETE.</p>
<p>● When <em><strong>neigh_connected_output()</strong></em> is called, the MAC address of the neighbour is known; so we end up with calling <em><strong>dev_queue_xmit()</strong></em>, which calls the <strong><em>ndo_start_xmit()</em></strong>&nbsp;callback method of the NIC device driver.&nbsp;</p>
<p>● The <strong><em>ndo_start_xmit()</em></strong>&nbsp;method actually puts the frame on the wire.</p>
<p><strong>Change of IP address/Mac address</strong></p>
<p>● Change of IP address does not trigger notifying its neighbours.</p>
<p>● Change of MAC address , <strong>NETDEV_CHANGEADDR</strong> ,also does not trigger notifying its neighbours.</p>
<p>● It does update the local arp table by <strong><em>neigh_changeaddr()</em></strong>.</p>
<p>– Exception to this is irlan eth: irlan_eth_send_gratuitous_arp() – (net/irda/irlan/irlan_eth.c) – Some nics don't permit changing of MAC address – you get: SIOCSIFHWADDR: Device or resource busy.</p>
<p><strong> Flushing the arp table</strong></p>
<p>● Flushing the arp table:</p>
<p>● ip statistics neigh flush dev eth0</p>
<p>●</p>
<ul>
<li>
<ul>
<li>
<ul>
<li>Round 1, deleting 7 entries ***</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>●</p>
<ul>
<li>
<ul>
<li>
<ul>
<li>Flush is complete after 1 round ***</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>● Specifying twice statistics will also show which entries were deleted, their mac addresses, etc...</p>
<p>● <strong>ip statistics statistics neigh flush dev eth0</strong></p>
<p>● 192.168.0.254 lladdr 00:04:27:fd:ad:30 ref 17 used 0/0/0 REACHABLE ●</p>
<p>● *** Round 1, deleting 1 entries ***</p>
<p>● *** Flush is complete after 1 round ***</p>
<p>● calls <em><strong>neigh_delete()</strong></em> in net/core/neighbour.c</p>
<p>● Changes the state to <strong>NUD_FAILED</strong></p>
arpARP cache poisoningarp tableARPwatcharp_queueDADDuplicate Address DetectionNDneighbour discoveryNETDEV_CHANGEADDRnetworkingNUD_DELAYNUD_FAILEDNUD_PROBENUD_REACHABLERami RosenNetworkingThu, 19 Nov 2009 18:23:47 +0000Linux Foundation Administrator5279 at http://www.linuxfoundation.orgLinux Kernel Networking by Rami Rosen (slides of lectures I gave)http://www.linuxfoundation.org/collaborate/workgroups/networking/networkoverview
<p>&nbsp;</p>
<p><a name="NetworkNamespaces"></a></p>
<p><strong>Please look in this link, for slides of lectures I gave about Linux Kernel Networking:</strong></p>
<p><a href="http://ramirose.wix.com/ramirosen" title="http://ramirose.wix.com/ramirosen">http://ramirose.wix.com/ramirosen</a></p>
<p>&nbsp;<strong>by Rami Rosen :&nbsp;</strong><strong>ramirose@gmail.com</strong></p>
<p><strong><img src="http://static.wix.com/media/295986_ba454dff2981d37103dfe5feb4fa0555.jpg_srz_96_96_75_22_0.50_1.20_0.00_jpg_srz" alt="Rami Rosen pic" width="96" height="96" /><br /></strong></p>
<p><strong><strong><a title="Rami Rosen website" href="http://ramirose.wix.com/ramirosen" target="_blank">Rami Rosen website</a></strong></strong></p>
<h2><strong>&nbsp;</strong></h2>
arpbluetoothBlueZBridgingbtCBQCLONE_NEWNETDNATdunduplicate ACKs.ECNethtooleth_toolExplicit Congestion NotificationFibfib_triegetsockopt()GREGROGSOhciattachhcidumphcitoolhcitool scanhiddhostapdHTBhw_featuresIGMPIGMPv2ingress_mapInternet Group Managementip maddrip maddr addiproute2IPSecIPv4IPv6IPv6 NATIP_ADD_MEMBERSHIPip_mr_inputISCANL2CAPLACPlibteamlinux bluetoothLinux Kernel Networkingmac80211Multicast RoutingmultiqueueNAPNATneighboring subsystemnet-nextnetfilterNETIF_FNETIF_F_LLTXNETIF_F_VLAN_CHALLENGEDnetnsnetworkingnfcnoqueue_qdiscobexOpen vSwitchopenobexopenvpnpandpimdpimregPMTU discoverypppPPP over L2TPpppoePPPoL2TPProtocol Independent MulticastqdiscRami RosenReceive Packet SteeringReverse Path FilterRFCOMMRFCOMMCREATEDEVroutingrpsrp_filterSCOSCTPSKBSNATTAPtc classtc filtertcpTCP Congestion ControlteamTIMTPROXYTUNNetworkingThu, 19 Nov 2009 18:23:47 +0000Linux Foundation Administrator5274 at http://www.linuxfoundation.org