summaryrefslogtreecommitdiffstats
path: root/net/ipv6/ipv6_sockglue.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-04-29 21:13:14 +0000
committer <ralf@linux-mips.org>1997-04-29 21:13:14 +0000
commit19c9bba94152148523ba0f7ef7cffe3d45656b11 (patch)
tree40b1cb534496a7f1ca0f5c314a523c69f1fee464 /net/ipv6/ipv6_sockglue.c
parent7206675c40394c78a90e74812bbdbf8cf3cca1be (diff)
Import of Linux/MIPS 2.1.36
Diffstat (limited to 'net/ipv6/ipv6_sockglue.c')
-rw-r--r--net/ipv6/ipv6_sockglue.c120
1 files changed, 47 insertions, 73 deletions
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 7ae830876..88920bb73 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -7,14 +7,21 @@
*
* Based on linux/net/ipv4/ip_sockglue.c
*
- * $Id: ipv6_sockglue.c,v 1.12 1996/10/29 22:45:53 roque Exp $
+ * $Id: ipv6_sockglue.c,v 1.11 1997/04/20 09:44:33 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
+ *
+ * FIXME: Make the setsockopt code POSIX compliant: That is
+ *
+ * o Return -EINVAL for setsockopt of short lengths
+ * o Truncate getsockopt returns
+ * o Return an optlen of the truncated length if need be
*/
+#include <linux/config.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
@@ -34,7 +41,7 @@
#include <net/ndisc.h>
#include <net/protocol.h>
#include <net/transp_v6.h>
-#include <net/ipv6_route.h>
+#include <net/ip6_route.h>
#include <net/addrconf.h>
#include <net/inet_common.h>
#include <net/sit.h>
@@ -46,7 +53,7 @@
struct ipv6_mib ipv6_statistics={0, };
struct packet_type ipv6_packet_type =
{
- 0,
+ __constant_htons(ETH_P_IPV6),
NULL, /* All devices */
ipv6_rcv,
NULL,
@@ -67,17 +74,14 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
{
struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
int val, err;
- int retv = -EOPNOTSUPP;
+ int retv = -ENOPROTOOPT;
if(level!=SOL_IPV6)
goto out;
- if (optval == NULL)
- {
+ if (optval == NULL) {
val=0;
- }
- else
- {
+ } else {
err = get_user(val, (int *) optval);
if(err)
return err;
@@ -87,42 +91,33 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
switch (optname) {
case IPV6_ADDRFORM:
- if (val == PF_INET)
- {
+ if (val == PF_INET) {
if (sk->protocol != IPPROTO_UDP &&
sk->protocol != IPPROTO_TCP)
- {
goto out;
- }
- if (sk->state != TCP_ESTABLISHED)
- {
+ if (sk->state != TCP_ESTABLISHED) {
retv = ENOTCONN;
goto out;
}
- if (!(ipv6_addr_type(&np->daddr) & IPV6_ADDR_MAPPED))
- {
+ if (!(ipv6_addr_type(&np->daddr) & IPV6_ADDR_MAPPED)) {
retv = -EADDRNOTAVAIL;
goto out;
}
- if (sk->protocol == IPPROTO_TCP)
- {
+ if (sk->protocol == IPPROTO_TCP) {
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
sk->prot = &tcp_prot;
tp->af_specific = &ipv4_specific;
- }
- else
- {
+ sk->socket->ops = &inet_stream_ops;
+ } else {
sk->prot = &udp_prot;
+ sk->socket->ops = &inet_dgram_ops;
}
- sk->socket->ops = &inet_proto_ops;
retv = 0;
- }
- else
- {
+ } else {
retv = -EINVAL;
}
break;
@@ -132,13 +127,15 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
retv = 0;
break;
+ case IPV6_HOPLIMIT:
+ np->rxhlim = val;
+ retv = 0;
+ break;
+
case IPV6_UNICAST_HOPS:
if (val > 255)
- {
retv = -EINVAL;
- }
- else
- {
+ else {
np->hop_limit = val;
retv = 0;
}
@@ -146,11 +143,8 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
case IPV6_MULTICAST_HOPS:
if (val > 255)
- {
retv = -EINVAL;
- }
- else
- {
+ else {
np->mcast_hops = val;
retv = 0;
}
@@ -168,23 +162,19 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
if(err)
return -EFAULT;
- if (ipv6_addr_any(&addr))
- {
- np->mc_if = NULL;
- }
- else
- {
+ if (ipv6_addr_any(&addr)) {
+ np->oif = NULL;
+ } else {
struct inet6_ifaddr *ifp;
ifp = ipv6_chk_addr(&addr);
- if (ifp == NULL)
- {
+ if (ifp == NULL) {
retv = -EADDRNOTAVAIL;
break;
}
- np->mc_if = ifp->idev->dev;
+ np->oif = ifp->idev->dev;
}
retv = 0;
break;
@@ -200,8 +190,8 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
if(err)
return -EFAULT;
- if (mreq.ipv6mr_ifindex == 0)
- {
+ if (mreq.ipv6mr_ifindex == 0) {
+#if 0
struct in6_addr mcast;
struct dest_entry *dc;
@@ -214,34 +204,22 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
dev = dc->rt.rt_dev;
ipv6_dst_unlock(dc);
}
- }
- else
- {
- struct inet6_dev *idev;
-
- if ((idev = ipv6_dev_by_index(mreq.ipv6mr_ifindex)))
- {
- dev = idev->dev;
- }
+#endif
+ } else {
+ dev = dev_get_by_index(mreq.ipv6mr_ifindex);
}
if (dev == NULL)
- {
return -ENODEV;
- }
if (optname == IPV6_ADD_MEMBERSHIP)
- {
retv = ipv6_sock_mc_join(sk, dev, &mreq.ipv6mr_multiaddr);
- }
else
- {
retv = ipv6_sock_mc_drop(sk, dev, &mreq.ipv6mr_multiaddr);
- }
- }
}
+ };
- out:
+out:
return retv;
}
@@ -251,7 +229,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname, char *optval,
return 0;
}
-#ifdef MODULE
+#if defined(MODULE) && defined(CONFIG_SYSCTL)
/*
* sysctl registration functions defined in sysctl_net_ipv6.c
@@ -263,17 +241,15 @@ extern void ipv6_sysctl_unregister(void);
void ipv6_init(void)
{
- ipv6_packet_type.type = ntohs(ETH_P_IPV6);
-
dev_add_pack(&ipv6_packet_type);
-#ifdef MODULE
+#if defined(MODULE) && defined(CONFIG_SYSCTL)
ipv6_sysctl_register();
#endif
register_netdevice_notifier(&ipv6_dev_notf);
- ipv6_route_init();
+ ip6_route_init();
}
#ifdef MODULE
@@ -281,15 +257,13 @@ void ipv6_cleanup(void)
{
unregister_netdevice_notifier(&ipv6_dev_notf);
dev_remove_pack(&ipv6_packet_type);
+#ifdef CONFIG_SYSCTL
ipv6_sysctl_unregister();
- ipv6_route_cleanup();
+#endif
+ ip6_route_cleanup();
ndisc_cleanup();
addrconf_cleanup();
}
#endif
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O6 -m486 -c ipv6_sockglue.c"
- * End:
- */
+