patch-2.1.21 linux/net/ipv6/datagram.c
Next file: linux/net/ipv6/icmp.c
Previous file: linux/net/ipv4/ip_masq_raudio.c
Back to the patch index
Back to the overall index
- Lines: 127
- Date:
Tue Jan 14 08:16:49 1997
- Orig file:
v2.1.20/linux/net/ipv6/datagram.c
- Orig date:
Thu Dec 12 19:37:30 1996
diff -u --recursive --new-file v2.1.20/linux/net/ipv6/datagram.c linux/net/ipv6/datagram.c
@@ -65,6 +65,22 @@
cmsg = (struct cmsghdr *)((u8*) cmsg + cmsg->cmsg_len);
}
+ if (np->rxhlim && (len >= sizeof(struct cmsghdr) + sizeof(int)))
+ {
+ int *hlim;
+
+ cmsg->cmsg_len = (sizeof(struct cmsghdr) + sizeof(int));
+ cmsg->cmsg_level = SOL_IPV6;
+ cmsg->cmsg_type = IPV6_HOPLIMIT;
+
+ hlim = (int *) cmsg->cmsg_data;
+ *hlim = skb->nh.ipv6h->hop_limit;
+
+ len -= cmsg->cmsg_len;
+ msg->msg_controllen += cmsg->cmsg_len;
+ cmsg = (struct cmsghdr *)((u8*) cmsg + cmsg->cmsg_len);
+ }
+
if (opt->srcrt)
{
int hdrlen = sizeof(struct rt0_hdr) + (opt->srcrt->hdrlen << 3);
@@ -90,14 +106,15 @@
int datagram_send_ctl(struct msghdr *msg, struct device **src_dev,
- struct in6_addr **src_addr, struct ipv6_options *opt)
+ struct in6_addr **src_addr, struct ipv6_options *opt,
+ int *hlimit)
{
struct inet6_dev *in6_dev = NULL;
struct in6_pktinfo *src_info;
struct cmsghdr *cmsg;
struct ipv6_rt_hdr *rthdr;
int len;
- int err = -EINVAL;
+ int err = 0;
for (cmsg = msg->msg_control; cmsg; cmsg = cmsg_nxthdr(msg, cmsg))
{
@@ -113,6 +130,7 @@
if (cmsg->cmsg_len < (sizeof(struct cmsghdr) +
sizeof(struct in6_pktinfo)))
{
+ err = -EINVAL;
goto exit_f;
}
@@ -123,6 +141,7 @@
in6_dev = ipv6_dev_by_index(src_info->ipi6_ifindex);
if (in6_dev == NULL)
{
+ err = -ENODEV;
goto exit_f;
}
@@ -137,11 +156,11 @@
if ( ifp == NULL)
{
+ err = -EINVAL;
goto exit_f;
}
*src_addr = &src_info->ipi6_addr;
- err = 0;
}
break;
@@ -155,6 +174,7 @@
/* validate option length */
if (len < sizeof(struct ipv6_rt_hdr))
{
+ err = -EINVAL;
goto exit_f;
}
@@ -165,28 +185,46 @@
*/
if (rthdr->type)
{
+ err = -EINVAL;
goto exit_f;
}
if (((rthdr->hdrlen + 1) << 3) < len)
- {
+ {
+ err = -EINVAL;
goto exit_f;
}
/* segments left must also match */
if ((rthdr->hdrlen >> 1) != rthdr->segments_left)
{
+ err = -EINVAL;
goto exit_f;
}
opt->opt_nflen += ((rthdr->hdrlen + 1) << 3);
opt->srcrt = rthdr;
- err = 0;
break;
+
+ case IPV6_HOPLIMIT:
+
+ len = cmsg->cmsg_len;
+ len -= sizeof(struct cmsghdr);
+
+ if (len < sizeof(int))
+ {
+ err = -EINVAL;
+ goto exit_f;
+ }
+
+ *hlimit = *((int *) cmsg->cmsg_data);
+ break;
+
default:
printk(KERN_DEBUG "invalid cmsg type: %d\n",
cmsg->cmsg_type);
+ err = -EINVAL;
break;
}
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov