patch-2.1.112 linux/net/ipv6/ipv6_sockglue.c
Next file: linux/net/ipv6/raw.c
Previous file: linux/net/ipv6/ip6_output.c
Back to the patch index
Back to the overall index
- Lines: 90
- Date:
Sun Jul 26 23:35:57 1998
- Orig file:
v2.1.111/linux/net/ipv6/ipv6_sockglue.c
- Orig date:
Thu May 14 19:47:45 1998
diff -u --recursive --new-file v2.1.111/linux/net/ipv6/ipv6_sockglue.c linux/net/ipv6/ipv6_sockglue.c
@@ -7,7 +7,7 @@
*
* Based on linux/net/ipv4/ip_sockglue.c
*
- * $Id: ipv6_sockglue.c,v 1.21 1998/05/07 15:43:13 davem Exp $
+ * $Id: ipv6_sockglue.c,v 1.22 1998/07/15 05:05:39 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -67,6 +67,45 @@
0
};
+struct ip6_ra_chain *ip6_ra_chain;
+
+int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *))
+{
+ struct ip6_ra_chain *ra, *new_ra, **rap;
+
+ /* RA packet may be delivered ONLY to IPPROTO_RAW socket */
+ if (sk->type != SOCK_RAW || sk->num != IPPROTO_RAW)
+ return -EINVAL;
+
+ new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL;
+
+ for (rap = &ip6_ra_chain; (ra=*rap) != NULL; rap = &ra->next) {
+ if (ra->sk == sk) {
+ if (sel>=0) {
+ if (new_ra)
+ kfree(new_ra);
+ return -EADDRINUSE;
+ }
+ *rap = ra->next;
+ if (ra->destructor)
+ ra->destructor(sk);
+ kfree(ra);
+ return 0;
+ }
+ }
+ if (new_ra == NULL)
+ return -ENOBUFS;
+ new_ra->sk = sk;
+ new_ra->sel = sel;
+ new_ra->destructor = destructor;
+ start_bh_atomic();
+ new_ra->next = ra;
+ *rap = new_ra;
+ end_bh_atomic();
+ return 0;
+}
+
+
int ipv6_setsockopt(struct sock *sk, int level, int optname, char *optval,
int optlen)
{
@@ -74,6 +113,9 @@
int val, err;
int retv = -ENOPROTOOPT;
+ if(level==SOL_IP && sk->type != SOCK_RAW)
+ return udp_prot.setsockopt(sk, level, optname, optval, optlen);
+
if(level!=SOL_IPV6)
goto out;
@@ -197,7 +239,11 @@
retv = ipv6_sock_mc_join(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
else
retv = ipv6_sock_mc_drop(sk, mreq.ipv6mr_ifindex, &mreq.ipv6mr_multiaddr);
+ break;
}
+ case IPV6_ROUTER_ALERT:
+ retv = ip6_ra_control(sk, val, NULL);
+ break;
};
out:
@@ -207,7 +253,11 @@
int ipv6_getsockopt(struct sock *sk, int level, int optname, char *optval,
int *optlen)
{
- return 0;
+ if(level==SOL_IP && sk->type != SOCK_RAW)
+ return udp_prot.getsockopt(sk, level, optname, optval, optlen);
+ if(level!=SOL_IPV6)
+ return -ENOPROTOOPT;
+ return -EINVAL;
}
#if defined(MODULE) && defined(CONFIG_SYSCTL)
FUNET's LINUX-ADM group, [email protected]
TCL-scripts by Sam Shen, [email protected]