patch-2.0.8 linux/net/ipv4/ip_forward.c
Next file: linux/net/ipv4/ip_fragment.c
Previous file: linux/net/ipv4/Config.in
Back to the patch index
Back to the overall index
- Lines: 148
- Date:
Fri Jul 19 19:48:43 1996
- Orig file:
v2.0.7/linux/net/ipv4/ip_forward.c
- Orig date:
Wed Jul 3 22:05:23 1996
diff -u --recursive --new-file v2.0.7/linux/net/ipv4/ip_forward.c linux/net/ipv4/ip_forward.c
@@ -39,7 +39,7 @@
#include <net/checksum.h>
#include <linux/route.h>
#include <net/route.h>
-
+
#ifdef CONFIG_IP_FORWARD
#ifdef CONFIG_IP_MROUTE
@@ -57,8 +57,11 @@
* Firstly push down and install the IPIP header.
*/
struct iphdr *iph=(struct iphdr *)skb_push(skb,sizeof(struct iphdr));
+
if(len>65515)
len=65515;
+
+
iph->version = 4;
iph->tos = skb->ip_hdr->tos;
iph->ttl = skb->ip_hdr->ttl;
@@ -67,17 +70,26 @@
iph->saddr = out->pa_addr;
iph->protocol = IPPROTO_IPIP;
iph->ihl = 5;
- iph->tot_len = htons(skb->len);
+ iph->tot_len = htons(skb->len + len); /* Anand, ernet */
iph->id = htons(ip_id_count++);
ip_send_check(iph);
skb->dev = out;
skb->arp = 1;
- skb->raddr=daddr;
+ skb->raddr=daddr; /* Router address is not destination address. The
+ * correct value is given eventually. I have not
+ * removed this statement. But could have.
+ * Anand, ernet.
+ */
/*
* Now add the physical header (driver will push it down).
*/
- if (out->hard_header && out->hard_header(skb, out, ETH_P_IP, NULL, NULL, len)<0)
+
+ /* The last parameter of out->hard_header() needed skb->len + len.
+ * Anand, ernet.
+ */
+ if (out->hard_header && out->hard_header(skb, out, ETH_P_IP, NULL, NULL,
+ skb->len + len)<0)
skb->arp=0;
/*
* Read to queue for transmission.
@@ -121,18 +133,22 @@
*/
iph = skb->h.iph;
- iph->ttl--;
+ if (!(is_frag&IPFWD_NOTTLDEC))
+ {
+ unsigned long checksum = iph->check;
+ iph->ttl--;
/*
* Re-compute the IP header checksum.
- * This is inefficient. We know what has happened to the header
- * and could thus adjust the checksum as Phil Karn does in KA9Q
+ * This is efficient. We know what has happened to the header
+ * and can thus adjust the checksum as Phil Karn does in KA9Q
+ * except we do this in "network byte order".
*/
-
- iph->check = ntohs(iph->check) + 0x0100;
- if ((iph->check & 0xFF00) == 0)
- iph->check++; /* carry overflow */
- iph->check = htons(iph->check);
+ checksum += htons(0x0100);
+ /* carry overflow? */
+ checksum += checksum >> 16;
+ iph->check = checksum;
+ }
if (iph->ttl <= 0)
{
@@ -141,8 +157,14 @@
return -1;
}
+ /* If IPFWD_MULTITUNNEL flag is set, then we have to perform routing
+ * decision so as to reach the other end of the tunnel. This condition
+ * also means that we are dealing with a unicast IP packet "in a way".
+ * Anand, ernet.
+ */
+
#ifdef CONFIG_IP_MROUTE
- if(!(is_frag&IPFWD_MULTICASTING))
+ if(!(is_frag&IPFWD_MULTICASTING) || (is_frag&IPFWD_MULTITUNNEL))
{
#endif
/*
@@ -205,6 +227,12 @@
icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev);
#endif
#ifdef CONFIG_IP_MROUTE
+
+ /* This is for ip encap. Anand, ernet.*/
+
+ if (is_frag&IPFWD_MULTITUNNEL) {
+ encap=20;
+ }
}
else
{
@@ -327,7 +355,20 @@
if(is_frag&IPFWD_MULTITUNNEL)
{
skb_reserve(skb2,(encap+dev2->hard_header_len+15)&~15); /* 16 byte aligned IP headers are good */
- ip_encap(skb2,skb->len, dev2, raddr);
+
+/* We need to pass on IP information of the incoming packet to ip_encap()
+ * to fillin ttl, and tos fields.The destination should be target_addr.
+ * Anand, ernet.
+ */
+
+ skb2->ip_hdr = skb->ip_hdr;
+
+ ip_encap(skb2,skb->len, dev2, target_addr);
+
+/* The router address is got earlier that to take us to the remote tunnel
+ * Anand, ernet.
+ */
+ skb2->raddr = rt->rt_gateway;
}
else
#endif
@@ -341,7 +382,6 @@
ptr = skb_put(skb2,skb->len);
skb2->free = 1;
skb2->h.raw = ptr;
-
/*
* Copy the packet data into the new buffer.
*/
@@ -517,3 +557,6 @@
#endif
+
+
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov