patch-2.1.22 linux/net/ipv6/sit.c
Next file: linux/net/ipv6/udp.c
Previous file: linux/net/ipv6/raw.c
Back to the patch index
Back to the overall index
- Lines: 169
- Date:
Sun Jan 19 15:47:28 1997
- Orig file:
v2.1.21/linux/net/ipv6/sit.c
- Orig date:
Thu Dec 12 19:37:31 1996
diff -u --recursive --new-file v2.1.21/linux/net/ipv6/sit.c linux/net/ipv6/sit.c
@@ -208,7 +208,7 @@
dev->hard_header_len = MAX_HEADER;
dev->mtu = 1500 - sizeof(struct iphdr);
dev->addr_len = 0;
- dev->tx_queue_len = 2;
+ dev->tx_queue_len = 0;
memset(dev->broadcast, 0, MAX_ADDR_LEN);
memset(dev->dev_addr, 0, MAX_ADDR_LEN);
@@ -415,31 +415,19 @@
struct enet_statistics *stats;
struct sit_mtu_info *minfo;
struct in6_addr *addr6;
- unsigned long flags;
struct rtable *rt;
struct iphdr *iph;
__u32 saddr;
__u32 daddr;
- __u32 raddr;
int addr_type;
int mtu;
- int len;
+ int headroom;
/*
* Make sure we are not busy (check lock variable)
*/
stats = (struct enet_statistics *)dev->priv;
- save_flags(flags);
- cli();
- if (dev->tbusy != 0)
- {
- restore_flags(flags);
- printk(KERN_DEBUG "sit_xmit: busy\n");
- return(1);
- }
- dev->tbusy = 1;
- restore_flags(flags);
daddr = dev->pa_dstaddr;
if (daddr == 0)
@@ -470,79 +458,57 @@
daddr = addr6->s6_addr32[3];
}
- len = skb->tail - (skb->data + sizeof(struct ipv6hdr));
-
- skb_orphan(skb);
-
- iph = (struct iphdr *) skb_push(skb, sizeof(struct iphdr));
-
- skb->protocol = htons(ETH_P_IP);
-
- /* get route */
-
if (ip_route_output(&rt, daddr, 0, 0, NULL)) {
printk(KERN_DEBUG "sit: no route to host\n");
goto on_error;
}
- skb->dst = dst_clone(&rt->u.dst);
minfo = sit_mtu_lookup(daddr);
+ /* IP should calculate pmtu correctly,
+ * let's check it...
+ */
+#if 0
if (minfo)
mtu = minfo->mtu;
else
- mtu = rt->u.dst.dev->mtu;
+#endif
+ mtu = rt->u.dst.pmtu;
- if (mtu > 576 && len > mtu)
+ if (mtu > 576 && skb->tail - (skb->data + sizeof(struct ipv6hdr)) > mtu)
{
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
+ ip_rt_put(rt);
goto on_error;
}
- saddr = rt->rt_src;
- skb->dev = rt->u.dst.dev;
- raddr = rt->rt_gateway;
-
- if (raddr == 0)
- raddr = daddr;
-
- /* now for the device header */
-
- skb->arp = 1;
-
- if (skb->dev->hard_header_len)
- {
- int mac;
+ headroom = ((rt->u.dst.dev->hard_header_len+15)&~15)+sizeof(struct iphdr);
- if (skb->data - skb->head < skb->dev->hard_header_len)
- {
- printk(KERN_DEBUG "sit: space at head < dev header\n");
+ if (skb_headroom(skb) < headroom || skb_shared(skb)) {
+ struct sk_buff *new_skb = skb_realloc_headroom(skb, headroom);
+ if (!new_skb) {
+ ip_rt_put(rt);
goto on_error;
}
-
- if (skb->dev->hard_header)
- {
- mac = skb->dev->hard_header(skb, skb->dev, ETH_P_IP,
- NULL, NULL, len);
-
- if (mac < 0)
- skb->arp = 0;
-
- }
-
+ dev_kfree_skb(skb, FREE_WRITE);
+ skb = new_skb;
}
+
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
- ip_rt_put(rt);
+ iph = (struct iphdr *) skb_push(skb, sizeof(struct iphdr));
+ skb->nh.iph = iph;
+ saddr = rt->rt_src;
+ dst_release(skb->dst);
+ skb->dst = &rt->u.dst;
iph->version = 4;
iph->ihl = 5;
iph->tos = 0; /* tos set to 0... */
if (mtu > 576)
- {
iph->frag_off = htons(IP_DF);
- }
else
iph->frag_off = 0;
@@ -550,20 +516,18 @@
iph->saddr = saddr;
iph->daddr = daddr;
iph->protocol = IPPROTO_IPV6;
- skb->nh.iph = iph;
-
+ iph->tot_len = htons(skb->len);
+ iph->id = htons(ip_id_count++);
ip_send_check(iph);
- ip_queue_xmit(skb);
+ ip_send(skb);
stats->tx_packets++;
- dev->tbusy=0;
return 0;
on_error:
- kfree_skb(skb, FREE_WRITE);
- dev->tbusy=0;
+ dev_kfree_skb(skb, FREE_WRITE);
stats->tx_errors++;
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov