patch-2.1.120 linux/net/ipv6/raw.c
Next file: linux/net/ipv6/reassembly.c
Previous file: linux/net/ipv6/proc.c
Back to the patch index
Back to the overall index
- Lines: 191
- Date:
Thu Aug 27 19:33:09 1998
- Orig file:
v2.1.119/linux/net/ipv6/raw.c
- Orig date:
Thu Aug 27 19:56:31 1998
diff -u --recursive --new-file v2.1.119/linux/net/ipv6/raw.c linux/net/ipv6/raw.c
@@ -7,7 +7,7 @@
*
* Adapted from linux/net/ipv4/raw.c
*
- * $Id: raw.c,v 1.20 1998/07/15 05:05:41 davem Exp $
+ * $Id: raw.c,v 1.21 1998/08/26 12:05:13 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -156,9 +156,8 @@
/* Check if the address belongs to the host. */
if (addr_type == IPV6_ADDR_MAPPED) {
- v4addr = addr->sin6_addr.s6_addr32[3];
- if (inet_addr_type(v4addr) != RTN_LOCAL)
- return(-EADDRNOTAVAIL);
+ /* Raw sockets are IPv6 only */
+ return(-EADDRNOTAVAIL);
} else {
if (addr_type != IPV6_ADDR_ANY) {
/* ipv4 addr of the socket is invalid. Only the
@@ -182,10 +181,11 @@
return 0;
}
-void rawv6_err(struct sock *sk, int type, int code, unsigned char *buff,
- struct in6_addr *saddr, struct in6_addr *daddr)
+void rawv6_err(struct sock *sk, struct sk_buff *skb, struct ipv6hdr *hdr,
+ struct inet6_skb_parm *opt,
+ int type, int code, unsigned char *buff, u32 info)
{
- if (sk == NULL)
+ if (sk == NULL)
return;
}
@@ -193,12 +193,12 @@
{
/* Charge it to the socket. */
if (sock_queue_rcv_skb(sk,skb)<0) {
- /* ip_statistics.IpInDiscards++; */
+ ipv6_statistics.Ip6InDiscards++;
kfree_skb(skb);
return 0;
}
- /* ip_statistics.IpInDelivers++; */
+ ipv6_statistics.Ip6InDelivers++;
return 0;
}
@@ -209,22 +209,11 @@
* maybe we could have the network decide uppon a hint if it
* should call raw_rcv for demultiplexing
*/
-int rawv6_rcv(struct sk_buff *skb, struct device *dev,
- struct in6_addr *saddr, struct in6_addr *daddr,
- struct ipv6_options *opt, unsigned short len)
+int rawv6_rcv(struct sock *sk, struct sk_buff *skb, unsigned long len)
{
- struct sock *sk;
-
- sk = skb->sk;
-
if (sk->ip_hdrincl)
skb->h.raw = skb->nh.raw;
- if (atomic_read(&sk->sock_readers)) {
- __skb_queue_tail(&sk->back_log, skb);
- return 0;
- }
-
rawv6_rcv_skb(sk, skb);
return 0;
}
@@ -255,8 +244,12 @@
if (!skb)
goto out;
- copied = min(len, skb->tail - skb->h.raw);
-
+ copied = skb->tail - skb->h.raw;
+ if (copied > len) {
+ copied = len;
+ msg->msg_flags |= MSG_TRUNC;
+ }
+
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
sk->stamp=skb->stamp;
if (err)
@@ -269,7 +262,7 @@
sizeof(struct in6_addr));
}
- if (msg->msg_controllen)
+ if (sk->net_pinfo.af_inet6.rxopt.all)
datagram_recv_ctl(sk, msg, skb);
err = copied;
@@ -332,11 +325,9 @@
csum = (__u16 *) (buff + opt->offset);
*csum = hdr->cksum;
} else {
- /*
- * FIXME
- * signal an error to user via sk->err
- */
- printk(KERN_DEBUG "icmp: cksum offset too big\n");
+ if (net_ratelimit())
+ printk(KERN_DEBUG "icmp: cksum offset too big\n");
+ return -EINVAL;
}
}
return 0;
@@ -345,10 +336,10 @@
static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, int len)
{
- struct ipv6_options opt_space;
+ struct ipv6_txoptions opt_space;
struct sockaddr_in6 * sin6 = (struct sockaddr_in6 *) msg->msg_name;
struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
- struct ipv6_options *opt = NULL;
+ struct ipv6_txoptions *opt = NULL;
struct in6_addr *saddr = NULL;
struct flowi fl;
int addr_len = msg->msg_namelen;
@@ -360,11 +351,8 @@
/* Rough check on arithmetic overflow,
better check is made in ip6_build_xmit
-
- When jumbo header will be implemeted we will remove it
- at all (len will be size_t)
*/
- if (len < 0 || len > 0xFFFF)
+ if (len < 0)
return -EMSGSIZE;
/* Mirror BSD error message compatibility */
@@ -394,14 +382,6 @@
return(-EINVAL);
daddr = &sin6->sin6_addr;
-
- /* BUGGGG If route is not cloned, this check always
- fails, hence dst_cache only slows down tramsmission --ANK
- */
- if (sk->dst_cache && ipv6_addr_cmp(daddr, &np->daddr)) {
- dst_release(sk->dst_cache);
- sk->dst_cache = NULL;
- }
} else {
if (sk->state != TCP_ESTABLISHED)
return(-EINVAL);
@@ -422,12 +402,14 @@
if (msg->msg_controllen) {
opt = &opt_space;
- memset(opt, 0, sizeof(struct ipv6_options));
+ memset(opt, 0, sizeof(struct ipv6_txoptions));
err = datagram_send_ctl(msg, &fl.oif, &saddr, opt, &hlimit);
if (err < 0)
return err;
}
+ if (opt == NULL || !(opt->opt_nflen|opt->opt_flen))
+ opt = np->opt;
raw_opt = &sk->tp_pinfo.tp_raw;
@@ -594,8 +576,9 @@
static void rawv6_close(struct sock *sk, unsigned long timeout)
{
+ /* See for explanation: raw_close in ipv4/raw.c */
sk->state = TCP_CLOSE;
- ipv6_sock_mc_close(sk);
+ raw_v6_unhash(sk);
if (sk->num == IPPROTO_RAW)
ip6_ra_control(sk, -1, NULL);
sk->dead = 1;
@@ -619,7 +602,7 @@
datagram_poll, /* poll */
NULL, /* ioctl */
rawv6_init_sk, /* init */
- NULL, /* destroy */
+ inet6_destroy_sock, /* destroy */
NULL, /* shutdown */
rawv6_setsockopt, /* setsockopt */
rawv6_getsockopt, /* getsockopt */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov