/* * IPv6 BSD socket options interface * Linux INET6 implementation * * Authors: * Pedro Roque <roque@di.fc.ul.pt> * * Based on linux/net/ipv4/ip_sockglue.c * * 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 Truncate getsockopt returns * o Return an optlen of the truncated length if need be * * Changes: * David L Stevens <dlstevens@us.ibm.com>: * - added multicast source filtering API for MLDv2 */#include<linux/module.h>#include<linux/capability.h>#include<linux/errno.h>#include<linux/types.h>#include<linux/socket.h>#include<linux/sockios.h>#include<linux/net.h>#include<linux/in6.h>#include<linux/mroute6.h>#include<linux/netdevice.h>#include<linux/if_arp.h>#include<linux/init.h>#include<linux/sysctl.h>#include<linux/netfilter.h>#include<linux/slab.h>#include<net/sock.h>#include<net/snmp.h>#include<net/ipv6.h>#include<net/ndisc.h>#include<net/protocol.h>#include<net/transp_v6.h>#include<net/ip6_route.h>#include<net/addrconf.h>#include<net/inet_common.h>#include<net/tcp.h>#include<net/udp.h>#include<net/udplite.h>#include<net/xfrm.h>#include<net/compat.h>#include<asm/uaccess.h>structip6_ra_chain*ip6_ra_chain;DEFINE_RWLOCK(ip6_ra_lock);intip6_ra_control(structsock*sk,intsel){structip6_ra_chain*ra,*new_ra,**rap;/* RA packet may be delivered ONLY to IPPROTO_RAW socket */if(sk->sk_type!=SOCK_RAW||inet_sk(sk)->inet_num!=IPPROTO_RAW)return-ENOPROTOOPT;new_ra=(sel>=0)?kmalloc(sizeof(*new_ra),GFP_KERNEL):NULL;write_lock_bh(&ip6_ra_lock);for(rap=&ip6_ra_chain;(ra=*rap)!=NULL;rap=&ra->next){if(ra->sk==sk){if(sel>=0){write_unlock_bh(&ip6_ra_lock);kfree(new_ra);return-EADDRINUSE;}*rap=ra->next;write_unlock_bh(&ip6_ra_lock);sock_put(sk);kfree(ra);return0;}}if(new_ra==NULL){write_unlock_bh(&ip6_ra_lock);return-ENOBUFS;}new_ra->sk=sk;new_ra->sel=sel;new_ra->next=ra;*rap=new_ra;sock_hold(sk);write_unlock_bh(&ip6_ra_lock);return0;}staticstructipv6_txoptions*ipv6_update_options