ch02s06.html 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. <html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Send-to-self Patch</title><meta name="generator" content="DocBook XSL Stylesheets V1.76.1"><meta name="keywords" content="Intellon, Atheros, Qualcomm, HomePlug, powerline, communications, INT6000, INT6300, INT6400, AR7400, AR7420"><link rel="home" href="index.html" title="Qualcomm Atheros Open Powerline Toolkit"><link rel="up" href="ch02.html" title="Chapter 2.  Hardware"><link rel="prev" href="ch02s05.html" title="Powerline Workstations"><link rel="next" href="ch03.html" title="Chapter 3.  Software"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">
  2. Send-to-self Patch
  3. </th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch02s05.html">Prev</a> </td><th width="60%" align="center">Chapter 2. 
  4. Hardware
  5. </th><td width="20%" align="right"> <a accesskey="n" href="ch03.html">Next</a></td></tr></table><hr></div><div class="section" title="Send-to-self Patch"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="hardware-send-to-self"></a>
  6. Send-to-self Patch
  7. </h2></div></div></div><p>
  8. One advantage of <span class="productname">Linux</span>™ powerline workstations is the ability to control the low-level networking environment. ISO Layer 2 traffic can be easily directed from one Ethernet interface to another on the same host but Layer 3 traffic is a different matter because routing software merely routes this type of traffic internally.
  9. </p><p>
  10. A <span class="productname">Linux</span>™ kernel <a class="ulink" href="http://www.ssi.bg/~ja/#loop" target="_top">patch</a> is available that will allow ISO Layer 3 traffic to be routed from one Ethernet interface to another on the same host. With this patch, multiple instances of a traffic generator, like <span class="application">ttcp</span> or <span class="application">iperf</span>, can be effectively deployed on the same host without modification.
  11. </p><p>
  12. This patch is useful for testing on a closed network but it could pose a security risk to the local host when connected to a public network. Kernels having this patch installed should have a special designation such as <span class="quote">“<span class="quote">linux-2.6.28-send-to-self</span>”</span> so that users are aware that the patch is installed.
  13. </p><div class="example"><a name="idp20601280"></a><p class="title"><b>Example 2.1. 
  14. <span class="quote">“<span class="quote">send-to-self</span>”</span> Patch Description
  15. </b></p><div class="example-contents"><p>
  16. The following is the full, original patch description.
  17. </p><pre class="programlisting">
  18. Send-To-Self interface flag
  19. Julian Anastasov &lt;ja@ssi.bg&gt;, July 2003
  20. Patches for different kernels:
  21. send-to-self-2.4.21-1.diff
  22. send-to-self-2.5.73-1.diff
  23. The presented patch implements routing of traffic between local
  24. IP addresses externally via ethernet interfaces. This patch is basically
  25. the Ben Greear's send-to-self work but reimplemented entirely on routing
  26. level. The idea is to return output route via external interfaces if
  27. path between two local IP addresses is requested and they are configured
  28. on different interfaces with /proc/sys/net/ipv4/conf/DEVNAME/loop set to
  29. 1. As result, arp_filter (if enabled - the recommended value)
  30. automatically accepts the ARP requests on the right interface. The
  31. rp_filter check is modified to accept traffic from such interfaces with
  32. local IP as sender, so using loop=1 for interfaces attached to insecure
  33. mediums is not recommended.
  34. Pros:
  35. - it can be used from all existing applications without change
  36. - it is not limited to 2 interfaces
  37. - you can use it with many IP addresses
  38. - does not depend on the rp_filter and arp_filter states, they
  39. can be set to 1
  40. - the packets are not altered in any way, useful for QoS testings
  41. - the routing result is cached, the routing checks are not per packet
  42. Cons:
  43. - not possible to use it for interfaces attached to insecure
  44. mediums (the rp_filter protection allows saddr to be local IP).
  45. By design. Use at your own risk.
  46. The usage is simple:
  47. # Connect two or more interfaces to same hub or via crossover cable
  48. # Enable loopback mode for eth0 and eth1. This even can be
  49. # default mode without breaking any other talks. By this way
  50. # we allow external routing only between local IPs configured
  51. # on the specified interfaces.
  52. echo 1 &gt; /proc/sys/net/ipv4/conf/eth0/loop
  53. echo 1 &gt; /proc/sys/net/ipv4/conf/eth1/loop
  54. # Add some IP addresses for testing, eg. client and server IP
  55. ip address add 192.168.1.1 dev eth0
  56. ip address add 192.168.2.1 dev eth1
  57. # Testing with applications that are aware of this binding.
  58. # The main thing the apps need to know is what src and dst IP
  59. # addresses to use. The client app needs to bind to the src IP
  60. # and by this way to request output route to the dst IP. There
  61. # is no specific configuration for the server app listening on
  62. # 192.168.2.1
  63. ping -I 192.168.1.1 192.168.2.1
  64. # Note that specifying the output device (SO_BINDTODEVICE is
  65. # not recommended)
  66. # Testing with applications that are not aware of this feature:
  67. # for 192.168.1.1 client (the same for the server is not needed).
  68. # Note that by default, in local routes the kernel uses the local
  69. # IPs as preferred source. This is the safe default mode (if loop=1)
  70. # for applications that do not care what src IP will be used
  71. # for their talks with local IPs. We try to change that and to
  72. # use IPs from different interfaces.
  73. ip route replace local 192.168.2.1 dev eth1 scope host src 192.168.1.1 proto kernel
  74. # but for any case, here it is and for the "server":
  75. ip route replace local 192.168.1.1 dev eth0 scope host src 192.168.2.1 proto kernel
  76. # Testing it:
  77. ping 192.168.2.1
  78. ping -I 192.168.1.1 192.168.2.1
  79. telnet 192.168.2.1
  80. # Note that by replacing the local route's preferred source IP address
  81. # we help the IP address autoselection to select proper IP to the
  82. # target, in our case, route via eth
  83. </pre></div></div><br class="example-break"><div class="example"><a name="idp20602424"></a><p class="title"><b>Example 2.2. 
  84. <span class="quote">“<span class="quote">send-to-self</span>”</span> Patch Application
  85. </b></p><div class="example-contents"><p>
  86. The following example illustrates how to use <span class="application">iperf</span> to perform <acronym class="acronym">TCP</acronym> and <acronym class="acronym">UDP</acronym> traffic measurements once this patch is installed. We illustrate the use of <span class="application">iperf</span> but do not necessarily endorse it for traffic measurement. We also illustrate the use of two interfaces but the <span class="quote">“<span class="quote">send-to-self</span>”</span> patch will support additional interfaces. We also illustrate the use of environment variables so that procedures can execute on different hosts without modification but these environment variables are not required.
  87. </p><p>
  88. First, we define environment variables, <code class="varname">IF1</code> and <code class="varname">IF2</code>, for each Ethernet interface and, <code class="varname">IP1</code> and <code class="varname">IP2</code>, for their IP addresses. Each interface must be on a separate IP subnet. We export definitions here so that they are accessible to this process and any subprocesses, such as shell scripts. Do whatever is appropriate for your environment.
  89. </p><pre class="screen">
  90. export IF1=eth1
  91. export IF2=eth2
  92. export IP1=192.168.1.1
  93. export IP2=192.168.2.2
  94. </pre><p>
  95. Next, we assign the IP addresses to the interfaces using program <span class="application">ifconfig</span>. There are other ways to do this. Observe that we reference our environment variables on the command line.
  96. </p><pre class="screen">
  97. ifconfig ${IF1} ${IP1}
  98. ifconfig ${IF2} ${IP2}
  99. </pre><p>
  100. Next, we suppress internal routing between local interfaces. The <code class="varname">loop</code> propery only exists on kernels that have the <span class="quote">“<span class="quote">send-to-self</span>”</span> patch installed and have the <code class="filename">/proc</code> filesystem mounted. Some systems may not mount this file system.
  101. </p><pre class="screen">
  102. echo 1 &gt; /proc/sys/net/ipv4/conf/${IF1}/loop
  103. echo 1 &gt; /proc/sys/net/ipv4/conf/${IF2}/loop
  104. </pre><p>
  105. Alternately, you could edit file <code class="filename">/etc/sysctl.conf</code>, as follows, to set the <code class="varname">loop</code> property for each interface during system startup. Again, the <code class="varname">loop</code> propery only exists on kernels that have the <span class="quote">“<span class="quote">send-to-self</span>”</span> patch installed and so errors will occur if you boot another kernel that does not have it installed.
  106. </p><pre class="programlisting">
  107. net.ipv4.conf.eth1.loop = 1
  108. net.ipv4.conf.eth2.loop = 1
  109. </pre><p>
  110. Open a console window and start <span class="application">iperf</span> as a server. Option <strong class="userinput"><code>-s</code></strong> identifies this instance of <span class="application">iperf</span> as the server. Option <strong class="userinput"><code>-B</code></strong> binds this instance to one host interface by IP address, in this case <code class="varname">IP1</code> defined earlier.
  111. </p><pre class="screen">
  112. iperf -B ${IP1} -s
  113. ------------------------------------------------------------
  114. Server listening on TCP port 5001
  115. Binding to local address 192.168.1.1
  116. TCP window size: 85.3 KByte (default)
  117. ------------------------------------------------------------
  118. </pre><p>
  119. Open a second console window and start <span class="application">iperf</span> as a client. Option <strong class="userinput"><code>-c</code></strong> identifies this instance of <span class="application">iperf</span> as a client. Option <strong class="userinput"><code>-B</code></strong> binds this instance to the one interface by IP address, in this case <code class="varname">IP2</code> defined earlier. The server address must also be specified, in this case <code class="varname">IP1</code> bound to the server in the last step.
  120. </p><pre class="screen">
  121. iperf -B ${IP2} -c ${IP1}
  122. ------------------------------------------------------------
  123. Client connecting to 192.168.1.1, TCP port 5001
  124. Binding to local address 192.168.2.1
  125. TCP window size: 16.0 KByte (default)
  126. ------------------------------------------------------------
  127. [ 3] local 192.168.2.1 port 5001 connected with 192.168.1.1 port 5001
  128. [ ID] Interval Transfer Bandwidth
  129. [ 3] 0.0-10.0 sec 31.1 MBytes 26.0 Mbits/sec
  130. </pre></div></div><br class="example-break"><div class="example"><a name="idp20620152"></a><p class="title"><b>Example 2.3. 
  131. <span class="quote">“<span class="quote">send-to-self</span>”</span> Patch Installation
  132. </b></p><div class="example-contents"><p>
  133. The <span class="quote">“<span class="quote">send-to-self</span>”</span> patch exists for several recent <span class="productname">Linux</span>™ kernel versions but not all versions. Assuming you have obtained the correct kernel archive and the correct patch version, the following script illustrates the steps needed to apply the patch on <span class="productname">Ubuntu 9.04</span>™ and recompile the kernel. Observe that, in this case, the patch version does not match the kernel version because a patch has not been published for that kernel version.
  134. </p><p>
  135. The following script can be used on a Ubuntu Linux distribution to download kernel source, the send-to-self patch, apply the patch then compile and install the resulting kernal image. When the <span class="application">menuconfig</span> screen appears:
  136. </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
  137. Select <strong class="userinput"><code>General Setup</code></strong> on the <span class="quote">“<span class="quote">Linux Kernel Configuration</span>”</span> screen.
  138. </p></li><li class="listitem"><p>
  139. Select <strong class="userinput"><code>Local version - append to kernel release</code></strong> on the <span class="quote">“<span class="quote">General Setup</span>”</span> screen.
  140. </p></li><li class="listitem"><p>
  141. Enter the version suffix <span class="quote">“<span class="quote">-send-to-self</span>”</span>.
  142. </p></li><li class="listitem"><p>
  143. Select <strong class="userinput"><code>ok</code></strong> to return to the <span class="quote">“<span class="quote">General Setup</span>”</span> screen.
  144. </p></li><li class="listitem"><p>
  145. Select <strong class="userinput"><code>Automatically append version information to the version string</code></strong> on the <span class="quote">“<span class="quote">General Setup</span>”</span> screen.
  146. </p></li><li class="listitem"><p>
  147. Select <strong class="userinput"><code>exit</code></strong> to return to the <span class="quote">“<span class="quote">Linux Kernel Configuration</span>”</span> screen.
  148. </p></li><li class="listitem"><p>
  149. Select <strong class="userinput"><code>exit</code></strong> to close the <span class="application">menuconfig</span> program.
  150. </p></li><li class="listitem"><p>
  151. Select <strong class="userinput"><code>yes</code></strong> if prompted to save your new kernel configuration. This message does not appear each time.
  152. </p></li></ol></div><pre class="programlisting">
  153. #!/bin/bash
  154. # file: patches/send-to-self-2.6.28.sh
  155. # ====================================================================
  156. # environment variables;
  157. # --------------------------------------------------------------------
  158. VERSION=2.6.28
  159. CURRENT=9
  160. VARIANT=send-to-self
  161. PACKAGE=linux-source-${VERSION}
  162. ARCHIVE=${PACKAGE}.tar.bz2
  163. PATCH=send-to-self-2.6.26-1.diff
  164. # ====================================================================
  165. # extend version string;
  166. # --------------------------------------------------------------------
  167. if [ ! -z ${CURRENT} ]; then
  168. VERSION+=.${CURRENT}
  169. fi
  170. if [ ! -z ${VARIANT} ]; then
  171. VERSION+=-${VARIANT}
  172. fi
  173. # ====================================================================
  174. # install required software;
  175. # --------------------------------------------------------------------
  176. if [ ! -f ${ARCHIVE} ]; then
  177. wget http://www.ssi.bg/~ja/${PATCH}
  178. apt-get install ${PACKAGE}
  179. # apt-get install ${PACKAGE} --reinstall
  180. apt-get install binutils patch gcc g++
  181. apt-get install ncurses-dev
  182. mv /usr/src/${ARCHIVE} .
  183. fi
  184. # ====================================================================
  185. # confirm archive file exists;
  186. # --------------------------------------------------------------------
  187. if [ ! -f ${ARCHIVE} ]; then
  188. echo "File ${ARCHIVE} is missing or misplaced"
  189. exit 1
  190. fi
  191. # ====================================================================
  192. # confirm patch file exists;
  193. # --------------------------------------------------------------------
  194. if [ ! -f ${PATCH} ]; then
  195. echo "File ${PATCH} is missing or misplaced"
  196. exit 1
  197. fi
  198. # ====================================================================
  199. # remove old kernel source if present;
  200. # --------------------------------------------------------------------
  201. if [ -d ${PACKAGE} ]; then
  202. echo "Removing old source ..."
  203. rm -fr ${PACKAGE}
  204. fi
  205. # ====================================================================
  206. # extract kernel source;
  207. # --------------------------------------------------------------------
  208. tar -vjxf ${ARCHIVE}
  209. if [ ! -d ${PACKAGE} ]; then
  210. echo "Folder ${PACKAGE} does not exist"
  211. exit 1
  212. fi
  213. cd ${PACKAGE}
  214. # ====================================================================
  215. # patch kernel source;
  216. # --------------------------------------------------------------------
  217. patch -p1 &lt; ../${PATCH}
  218. # ====================================================================
  219. # compile kernel source;
  220. # --------------------------------------------------------------------
  221. make mrproper
  222. make menuconfig
  223. make
  224. # ====================================================================
  225. # install kernel source;
  226. # --------------------------------------------------------------------
  227. make modules_install
  228. make install
  229. # ====================================================================
  230. # install kernel source;
  231. # --------------------------------------------------------------------
  232. mkinitramfs -o /boot/initrd.img-${VERSION} ${VERSION}
  233. ln -fs config-${VERSION} /boot/config
  234. ln -fs initrd.img-${VERSION} /boot/initrd.img
  235. ln -fs System.map-${VERSION} /boot/System.map
  236. ln -fs vmlinuz-${VERSION} /boot/vmlinuz
  237. </pre></div></div><br class="example-break"><div class="note" title="In case you don't know ..." style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">
  238. In case you don't know ...
  239. </h3><p>
  240. apt-get --reinstall
  241. </p><p>
  242. The <span class="application">apt-get</span> program is only available on Debian-based distributions. If you do not use a Debian-based system then you must find another way to obtain the necessary packages. Option <strong class="userinput"><code>--reinstall</code></strong> instructs <span class="application">apt-get</span> to download the kernel even though it has been installed before. It is not needed on the first script execution but may be needed on subsequent script executions if you have deleted the kernel archive file.
  243. </p><p>
  244. mkinitramfs
  245. </p><p>
  246. This script uses <span class="application">mkinitramfs</span> instead of the <span class="application">mkinitrd</span>. This may differ on other distributions. The kernel source package used here has <span class="productname">Ubuntu</span>™ modifications that result in a minor version being appended to the kernel version. This may not happen with other distributions or with kernels obtained directly from kernel.org.
  247. </p><p>
  248. cut-and-paste
  249. </p><p>
  250. This script, or some like it, are included in the <code class="filename">./patches</code> folder of the toolkit. You can also copy and paste this script but remember to edit the environment variables at the top, remove all carriage returns and set correct file permissions with <strong class="userinput"><code>chmod 0755</code></strong> before executing it on your <span class="productname">Linux</span>™ host. Run the script as <code class="varname">root</code> user. </p><p>
  251. grub/menu.lst
  252. </p><p>
  253. If your system uses <span class="application">grub</span> then edit file <code class="filename">/boot/grub/menu.lst</code> and add a new reference to the new <code class="filename">initrd.img</code>, <code class="filename">System.map</code> and <code class="filename">vmlinuz</code> files installed in folder <code class="filename">/boot</code> by this script. We recommend adding these references as the last ones in the file so that the new kernel does not start by default. Once you are confident that everything works, you can then move the references to the first entry. We also recommend setting the <code class="varname">timeout</code> value to <code class="constant">10</code> for now.
  254. </p></div><div class="example"><a name="idp20653016"></a><p class="title"><b>Example 2.4. 
  255. <span class="quote">“<span class="quote">send-to-self</span>”</span> Patch Listing
  256. </b></p><div class="example-contents"><p>
  257. The following <span class="quote">“<span class="quote">send-to-self</span>”</span> patch is specifically for <span class="productname">Linux</span>™ kernel 2.6.30 and is provided for information only. For practical purposes, the patch has not changed much from version to version but the line numbers have changed. Some recent <span class="quote">“<span class="quote">send-to-self</span>”</span> patches are included in the toolkit <code class="filename">./patches</code> folder.
  258. </p><pre class="programlisting">
  259. diff -urp v2.6.30/linux/Documentation/networking/ip-sysctl.txt linux/Documentation/networking/ip-sysctl.txt
  260. --- v2.6.30/linux/Documentation/networking/ip-sysctl.txt 2009-06-13 10:53:29.000000000 +0300
  261. +++ linux/Documentation/networking/ip-sysctl.txt 2009-06-13 15:54:15.000000000 +0300
  262. @@ -637,6 +637,13 @@ accept_redirects - BOOLEAN
  263. forwarding - BOOLEAN
  264. Enable IP forwarding on this interface.
  265. +loop - BOOLEAN
  266. + By default (loop=0) the traffic between local IP addresses
  267. + is routed via interface "lo". Setting this flag for two
  268. + interfaces allows traffic between their IP addresses to
  269. + be looped externally. This is useful for setups where the
  270. + interfaces are attached to same broadcast medium.
  271. +
  272. mc_forwarding - BOOLEAN
  273. Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE
  274. and a multicast routing daemon is required.
  275. diff -urp v2.6.30/linux/include/linux/inetdevice.h linux/include/linux/inetdevice.h
  276. --- v2.6.30/linux/include/linux/inetdevice.h 2009-06-13 10:53:56.000000000 +0300
  277. +++ linux/include/linux/inetdevice.h 2009-06-13 15:54:15.000000000 +0300
  278. @@ -106,6 +106,7 @@ static inline void ipv4_devconf_setall(s
  279. IN_DEV_ORCONF((in_dev), ACCEPT_REDIRECTS)))
  280. #define IN_DEV_ARPFILTER(in_dev) IN_DEV_ORCONF((in_dev), ARPFILTER)
  281. +#define IN_DEV_LOOP(in_dev) IN_DEV_CONF_GET(in_dev, LOOP)
  282. #define IN_DEV_ARP_ANNOUNCE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_ANNOUNCE)
  283. #define IN_DEV_ARP_IGNORE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_IGNORE)
  284. #define IN_DEV_ARP_NOTIFY(in_dev) IN_DEV_MAXCONF((in_dev), ARP_NOTIFY)
  285. diff -urp v2.6.30/linux/include/linux/sysctl.h linux/include/linux/sysctl.h
  286. --- v2.6.30/linux/include/linux/sysctl.h 2009-06-13 10:53:56.000000000 +0300
  287. +++ linux/include/linux/sysctl.h 2009-06-13 15:54:40.000000000 +0300
  288. @@ -491,6 +491,7 @@ enum
  289. NET_IPV4_CONF_PROMOTE_SECONDARIES=20,
  290. NET_IPV4_CONF_ARP_ACCEPT=21,
  291. NET_IPV4_CONF_ARP_NOTIFY=22,
  292. + NET_IPV4_CONF_LOOP=23,
  293. __NET_IPV4_CONF_MAX
  294. };
  295. diff -urp v2.6.30/linux/kernel/sysctl_check.c linux/kernel/sysctl_check.c
  296. --- v2.6.30/linux/kernel/sysctl_check.c 2009-06-13 10:53:57.000000000 +0300
  297. +++ linux/kernel/sysctl_check.c 2009-06-13 15:55:00.000000000 +0300
  298. @@ -220,6 +220,7 @@ static const struct trans_ctl_table tran
  299. { NET_IPV4_CONF_PROMOTE_SECONDARIES, "promote_secondaries" },
  300. { NET_IPV4_CONF_ARP_ACCEPT, "arp_accept" },
  301. { NET_IPV4_CONF_ARP_NOTIFY, "arp_notify" },
  302. + { NET_IPV4_CONF_LOOP, "loop" },
  303. {}
  304. };
  305. diff -urp v2.6.30/linux/net/ipv4/devinet.c linux/net/ipv4/devinet.c
  306. --- v2.6.30/linux/net/ipv4/devinet.c 2009-06-13 10:53:58.000000000 +0300
  307. +++ linux/net/ipv4/devinet.c 2009-06-13 15:55:22.000000000 +0300
  308. @@ -1449,6 +1449,7 @@ static struct devinet_sysctl_table {
  309. DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
  310. DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"),
  311. DEVINET_SYSCTL_RW_ENTRY(ARP_NOTIFY, "arp_notify"),
  312. + DEVINET_SYSCTL_RW_ENTRY(LOOP, "loop"),
  313. DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
  314. DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
  315. diff -urp v2.6.30/linux/net/ipv4/fib_frontend.c linux/net/ipv4/fib_frontend.c
  316. --- v2.6.30/linux/net/ipv4/fib_frontend.c 2009-06-13 10:53:58.000000000 +0300
  317. +++ linux/net/ipv4/fib_frontend.c 2009-06-13 15:54:15.000000000 +0300
  318. @@ -239,16 +239,17 @@ int fib_validate_source(__be32 src, __be
  319. .tos = tos } },
  320. .iif = oif };
  321. struct fib_result res;
  322. - int no_addr, rpf;
  323. + int no_addr, rpf, loop;
  324. int ret;
  325. struct net *net;
  326. - no_addr = rpf = 0;
  327. + no_addr = rpf = loop = 0;
  328. rcu_read_lock();
  329. in_dev = __in_dev_get_rcu(dev);
  330. if (in_dev) {
  331. no_addr = in_dev-&gt;ifa_list == NULL;
  332. rpf = IN_DEV_RPFILTER(in_dev);
  333. + loop = IN_DEV_LOOP(in_dev);
  334. }
  335. rcu_read_unlock();
  336. @@ -258,6 +259,11 @@ int fib_validate_source(__be32 src, __be
  337. net = dev_net(dev);
  338. if (fib_lookup(net, &amp;fl, &amp;res))
  339. goto last_resort;
  340. + if (loop &amp;&amp; res.type == RTN_LOCAL) {
  341. + *spec_dst = FIB_RES_PREFSRC(res);
  342. + fib_res_put(&amp;res);
  343. + return 0;
  344. + }
  345. if (res.type != RTN_UNICAST)
  346. goto e_inval_res;
  347. *spec_dst = FIB_RES_PREFSRC(res);
  348. diff -urp v2.6.30/linux/net/ipv4/route.c linux/net/ipv4/route.c
  349. --- v2.6.30/linux/net/ipv4/route.c 2009-06-13 10:53:58.000000000 +0300
  350. +++ linux/net/ipv4/route.c 2009-06-13 15:54:15.000000000 +0300
  351. @@ -2521,6 +2521,11 @@ static int ip_route_output_slow(struct n
  352. dev_put(dev_out);
  353. goto out; /* Wrong error code */
  354. }
  355. + err = -ENETDOWN;
  356. + if (!(dev_out-&gt;flags&amp;IFF_UP)) {
  357. + dev_put(dev_out);
  358. + goto out;
  359. + }
  360. if (ipv4_is_local_multicast(oldflp-&gt;fl4_dst) ||
  361. oldflp-&gt;fl4_dst == htonl(0xFFFFFFFF)) {
  362. @@ -2588,10 +2593,41 @@ static int ip_route_output_slow(struct n
  363. free_res = 1;
  364. if (res.type == RTN_LOCAL) {
  365. - if (!fl.fl4_src)
  366. - fl.fl4_src = fl.fl4_dst;
  367. + struct in_device *in_dev;
  368. + __be32 src;
  369. +
  370. if (dev_out)
  371. dev_put(dev_out);
  372. + dev_out = FIB_RES_DEV(res);
  373. + in_dev = in_dev_get(dev_out);
  374. + src = fl.fl4_src? : FIB_RES_PREFSRC(res);
  375. + if (in_dev &amp;&amp; IN_DEV_LOOP(in_dev) &amp;&amp; src) {
  376. + struct net_device *dev_src;
  377. +
  378. + in_dev_put(in_dev);
  379. + in_dev = NULL;
  380. + dev_src = ip_dev_find(net, src);
  381. + if (dev_src &amp;&amp; dev_src != dev_out &amp;&amp;
  382. + (in_dev = in_dev_get(dev_src)) &amp;&amp;
  383. + IN_DEV_LOOP(in_dev)) {
  384. + in_dev_put(in_dev);
  385. + dev_out = dev_src;
  386. + fl.fl4_src = src;
  387. + fl.oif = dev_out-&gt;ifindex;
  388. + res.type = RTN_UNICAST;
  389. + if (res.fi) {
  390. + fib_info_put(res.fi);
  391. + res.fi = NULL;
  392. + }
  393. + goto make_route;
  394. + }
  395. + if (dev_src)
  396. + dev_put(dev_src);
  397. + }
  398. + if (in_dev)
  399. + in_dev_put(in_dev);
  400. + if (!fl.fl4_src)
  401. + fl.fl4_src = fl.fl4_dst;
  402. dev_out = net-&gt;loopback_dev;
  403. dev_hold(dev_out);
  404. fl.oif = dev_out-&gt;ifindex;
  405. </pre></div></div><br class="example-break"></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch02s05.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ch02.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ch03.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">
  406. Powerline Workstations
  407.  </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 3. 
  408. Software
  409. </td></tr></table></div></body></html>