patch-2.1.10 linux/net/ipv6/ipv6_output.c
Next file: linux/net/ipv6/ipv6_sockglue.c
Previous file: linux/net/ipv6/icmp.c
Back to the patch index
Back to the overall index
- Lines: 133
- Date:
Thu Nov 14 18:26:17 1996
- Orig file:
v2.1.9/linux/net/ipv6/ipv6_output.c
- Orig date:
Tue Nov 12 15:56:16 1996
diff -u --recursive --new-file v2.1.9/linux/net/ipv6/ipv6_output.c linux/net/ipv6/ipv6_output.c
@@ -15,6 +15,11 @@
* 2 of the License, or (at your option) any later version.
*/
+/*
+ * Changes:
+ *
+ * Andi Kleen : exception handling
+ */
#include <linux/errno.h>
#include <linux/types.h>
@@ -440,7 +445,7 @@
int pktlength;
int pmtu = 0;
int rt_flags = 0;
-
+ int error;
if (opt && opt->srcrt)
{
@@ -568,8 +573,6 @@
if (pktlength <= pmtu)
{
- int error;
-
struct sk_buff *skb =
sock_alloc_send_skb(sk, pktlength+15+
dev->hard_header_len,
@@ -624,14 +627,22 @@
}
skb_put(skb, length);
- getfrag(data, &hdr->saddr,
- ((char *) hdr) + (pktlength - length), 0, length);
+ error = getfrag(data, &hdr->saddr,
+ ((char *) hdr) + (pktlength - length),
+ 0, length);
- ipv6_statistics.Ip6OutRequests++;
- (*output_method)(skb, (struct rt6_info *) dc);
+ if (!error)
+ {
+ ipv6_statistics.Ip6OutRequests++;
+ (*output_method)(skb, (struct rt6_info *) dc);
+ } else
+ {
+ error = -EFAULT;
+ kfree_skb(skb, FREE_WRITE);
+ }
dev_unlock_list();
- return 0;
+ return error;
}
else
{
@@ -763,31 +774,52 @@
fhdr_dist = (unsigned char *) fhdr - last_skb->data;
- getfrag(data, &hdr->saddr, last_skb->tail, nfrags * frag_len,
- last_len);
+ error = getfrag(data, &hdr->saddr, last_skb->tail,
+ nfrags * frag_len, last_len);
- while (nfrags--)
- {
- struct sk_buff *skb;
-
- struct frag_hdr *fhdr2;
-
- printk(KERN_DEBUG "sending frag %d\n", nfrags);
- skb = skb_copy(last_skb, sk->allocation);
-
- fhdr2 = (struct frag_hdr *) (skb->data + fhdr_dist);
- /* more flag on */
- fhdr2->frag_off = ntohs(nfrags * frag_len + 1);
-
- /* if (nfrags == 0)
- put rest of headers
- */
+ if (!error)
+ {
+ while (nfrags--)
+ {
+ struct sk_buff *skb;
+
+ struct frag_hdr *fhdr2;
+
+ printk(KERN_DEBUG "sending frag %d\n", nfrags);
+ skb = skb_copy(last_skb, sk->allocation);
+
+ fhdr2 = (struct frag_hdr *)
+ (skb->data + fhdr_dist);
+
+ /* more flag on */
+ fhdr2->frag_off = ntohs(nfrags * frag_len + 1);
+
+ /*
+ * FIXME:
+ * if (nfrags == 0)
+ * put rest of headers
+ */
+
+ error = getfrag(data, &hdr->saddr,
+ skb_put(skb, frag_len),
+ nfrags * frag_len, frag_len);
+
+ if (error)
+ {
+ kfree_skb(skb, FREE_WRITE);
+ break;
+ }
- getfrag(data, &hdr->saddr, skb_put(skb, frag_len),
- nfrags * frag_len, frag_len);
+ ipv6_statistics.Ip6OutRequests++;
+ (*output_method)(skb, (struct rt6_info *) dc);
+ }
+ }
- ipv6_statistics.Ip6OutRequests++;
- (*output_method)(skb, (struct rt6_info *) dc);
+ if (error)
+ {
+ kfree_skb(last_skb, FREE_WRITE);
+ dev_unlock_list();
+ return -EFAULT;
}
printk(KERN_DEBUG "sending last frag \n");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov