aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c38
-rw-r--r--net/ipv6/addrlabel.c11
-rw-r--r--net/ipv6/af_inet6.c2
-rw-r--r--net/ipv6/anycast.c12
-rw-r--r--net/ipv6/inet6_connection_sock.c23
-rw-r--r--net/ipv6/inet6_hashtables.c58
-rw-r--r--net/ipv6/ip6_flowlabel.c3
-rw-r--r--net/ipv6/ip6_tunnel.c6
-rw-r--r--net/ipv6/ip6mr.c4
-rw-r--r--net/ipv6/ipv6_sockglue.c32
-rw-r--r--net/ipv6/mcast.c36
-rw-r--r--net/ipv6/ndisc.c8
-rw-r--r--net/ipv6/netfilter/Kconfig18
-rw-r--r--net/ipv6/netfilter/nf_reject_ipv6.c37
-rw-r--r--net/ipv6/ping.c3
-rw-r--r--net/ipv6/raw.c10
-rw-r--r--net/ipv6/route.c18
-rw-r--r--net/ipv6/syncookies.c13
-rw-r--r--net/ipv6/tcp_ipv6.c59
-rw-r--r--net/ipv6/tcpv6_offload.c4
-rw-r--r--net/ipv6/udp.c26
-rw-r--r--net/ipv6/udp_impl.h7
-rw-r--r--net/ipv6/xfrm6_policy.c1
23 files changed, 232 insertions, 197 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index b6030025f411..158378e73f0a 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2464,6 +2464,23 @@ err_exit:
2464 return err; 2464 return err;
2465} 2465}
2466 2466
2467static int ipv6_mc_config(struct sock *sk, bool join,
2468 const struct in6_addr *addr, int ifindex)
2469{
2470 int ret;
2471
2472 ASSERT_RTNL();
2473
2474 lock_sock(sk);
2475 if (join)
2476 ret = ipv6_sock_mc_join(sk, ifindex, addr);
2477 else
2478 ret = ipv6_sock_mc_drop(sk, ifindex, addr);
2479 release_sock(sk);
2480
2481 return ret;
2482}
2483
2467/* 2484/*
2468 * Manual configuration of address on an interface 2485 * Manual configuration of address on an interface
2469 */ 2486 */
@@ -2476,10 +2493,10 @@ static int inet6_addr_add(struct net *net, int ifindex,
2476 struct inet6_ifaddr *ifp; 2493 struct inet6_ifaddr *ifp;
2477 struct inet6_dev *idev; 2494 struct inet6_dev *idev;
2478 struct net_device *dev; 2495 struct net_device *dev;
2496 unsigned long timeout;
2497 clock_t expires;
2479 int scope; 2498 int scope;
2480 u32 flags; 2499 u32 flags;
2481 clock_t expires;
2482 unsigned long timeout;
2483 2500
2484 ASSERT_RTNL(); 2501 ASSERT_RTNL();
2485 2502
@@ -2501,6 +2518,14 @@ static int inet6_addr_add(struct net *net, int ifindex,
2501 if (IS_ERR(idev)) 2518 if (IS_ERR(idev))
2502 return PTR_ERR(idev); 2519 return PTR_ERR(idev);
2503 2520
2521 if (ifa_flags & IFA_F_MCAUTOJOIN) {
2522 int ret = ipv6_mc_config(net->ipv6.mc_autojoin_sk,
2523 true, pfx, ifindex);
2524
2525 if (ret < 0)
2526 return ret;
2527 }
2528
2504 scope = ipv6_addr_scope(pfx); 2529 scope = ipv6_addr_scope(pfx);
2505 2530
2506 timeout = addrconf_timeout_fixup(valid_lft, HZ); 2531 timeout = addrconf_timeout_fixup(valid_lft, HZ);
@@ -2542,6 +2567,9 @@ static int inet6_addr_add(struct net *net, int ifindex,
2542 in6_ifa_put(ifp); 2567 in6_ifa_put(ifp);
2543 addrconf_verify_rtnl(); 2568 addrconf_verify_rtnl();
2544 return 0; 2569 return 0;
2570 } else if (ifa_flags & IFA_F_MCAUTOJOIN) {
2571 ipv6_mc_config(net->ipv6.mc_autojoin_sk,
2572 false, pfx, ifindex);
2545 } 2573 }
2546 2574
2547 return PTR_ERR(ifp); 2575 return PTR_ERR(ifp);
@@ -2578,6 +2606,10 @@ static int inet6_addr_del(struct net *net, int ifindex, u32 ifa_flags,
2578 jiffies); 2606 jiffies);
2579 ipv6_del_addr(ifp); 2607 ipv6_del_addr(ifp);
2580 addrconf_verify_rtnl(); 2608 addrconf_verify_rtnl();
2609 if (ipv6_addr_is_multicast(pfx)) {
2610 ipv6_mc_config(net->ipv6.mc_autojoin_sk,
2611 false, pfx, dev->ifindex);
2612 }
2581 return 0; 2613 return 0;
2582 } 2614 }
2583 } 2615 }
@@ -3945,7 +3977,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
3945 3977
3946 /* We ignore other flags so far. */ 3978 /* We ignore other flags so far. */
3947 ifa_flags &= IFA_F_NODAD | IFA_F_HOMEADDRESS | IFA_F_MANAGETEMPADDR | 3979 ifa_flags &= IFA_F_NODAD | IFA_F_HOMEADDRESS | IFA_F_MANAGETEMPADDR |
3948 IFA_F_NOPREFIXROUTE; 3980 IFA_F_NOPREFIXROUTE | IFA_F_MCAUTOJOIN;
3949 3981
3950 ifa = ipv6_get_ifaddr(net, pfx, dev, 1); 3982 ifa = ipv6_get_ifaddr(net, pfx, dev, 1);
3951 if (ifa == NULL) { 3983 if (ifa == NULL) {
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index e43e79d0a612..3cc50e2d3bf5 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -29,9 +29,7 @@
29 * Policy Table 29 * Policy Table
30 */ 30 */
31struct ip6addrlbl_entry { 31struct ip6addrlbl_entry {
32#ifdef CONFIG_NET_NS 32 possible_net_t lbl_net;
33 struct net *lbl_net;
34#endif
35 struct in6_addr prefix; 33 struct in6_addr prefix;
36 int prefixlen; 34 int prefixlen;
37 int ifindex; 35 int ifindex;
@@ -129,9 +127,6 @@ static const __net_initconst struct ip6addrlbl_init_table
129/* Object management */ 127/* Object management */
130static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p) 128static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p)
131{ 129{
132#ifdef CONFIG_NET_NS
133 release_net(p->lbl_net);
134#endif
135 kfree(p); 130 kfree(p);
136} 131}
137 132
@@ -240,9 +235,7 @@ static struct ip6addrlbl_entry *ip6addrlbl_alloc(struct net *net,
240 newp->addrtype = addrtype; 235 newp->addrtype = addrtype;
241 newp->label = label; 236 newp->label = label;
242 INIT_HLIST_NODE(&newp->list); 237 INIT_HLIST_NODE(&newp->list);
243#ifdef CONFIG_NET_NS 238 write_pnet(&newp->lbl_net, net);
244 newp->lbl_net = hold_net(net);
245#endif
246 atomic_set(&newp->refcnt, 1); 239 atomic_set(&newp->refcnt, 1);
247 return newp; 240 return newp;
248} 241}
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index e8c4400f23e9..6bafcc2c79e3 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -824,7 +824,7 @@ static int __init inet6_init(void)
824 struct list_head *r; 824 struct list_head *r;
825 int err = 0; 825 int err = 0;
826 826
827 BUILD_BUG_ON(sizeof(struct inet6_skb_parm) > FIELD_SIZEOF(struct sk_buff, cb)); 827 sock_skb_cb_check_size(sizeof(struct inet6_skb_parm));
828 828
829 /* Register the socket-side information for inet6_create. */ 829 /* Register the socket-side information for inet6_create. */
830 for (r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) 830 for (r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r)
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index baf2742d1ec4..9e6b0ee563f0 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -60,6 +60,8 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
60 int ishost = !net->ipv6.devconf_all->forwarding; 60 int ishost = !net->ipv6.devconf_all->forwarding;
61 int err = 0; 61 int err = 0;
62 62
63 ASSERT_RTNL();
64
63 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 65 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
64 return -EPERM; 66 return -EPERM;
65 if (ipv6_addr_is_multicast(addr)) 67 if (ipv6_addr_is_multicast(addr))
@@ -73,7 +75,6 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
73 pac->acl_next = NULL; 75 pac->acl_next = NULL;
74 pac->acl_addr = *addr; 76 pac->acl_addr = *addr;
75 77
76 rtnl_lock();
77 if (ifindex == 0) { 78 if (ifindex == 0) {
78 struct rt6_info *rt; 79 struct rt6_info *rt;
79 80
@@ -130,7 +131,6 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
130 } 131 }
131 132
132error: 133error:
133 rtnl_unlock();
134 if (pac) 134 if (pac)
135 sock_kfree_s(sk, pac, sizeof(*pac)); 135 sock_kfree_s(sk, pac, sizeof(*pac));
136 return err; 136 return err;
@@ -146,7 +146,8 @@ int ipv6_sock_ac_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
146 struct ipv6_ac_socklist *pac, *prev_pac; 146 struct ipv6_ac_socklist *pac, *prev_pac;
147 struct net *net = sock_net(sk); 147 struct net *net = sock_net(sk);
148 148
149 rtnl_lock(); 149 ASSERT_RTNL();
150
150 prev_pac = NULL; 151 prev_pac = NULL;
151 for (pac = np->ipv6_ac_list; pac; pac = pac->acl_next) { 152 for (pac = np->ipv6_ac_list; pac; pac = pac->acl_next) {
152 if ((ifindex == 0 || pac->acl_ifindex == ifindex) && 153 if ((ifindex == 0 || pac->acl_ifindex == ifindex) &&
@@ -154,10 +155,8 @@ int ipv6_sock_ac_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
154 break; 155 break;
155 prev_pac = pac; 156 prev_pac = pac;
156 } 157 }
157 if (!pac) { 158 if (!pac)
158 rtnl_unlock();
159 return -ENOENT; 159 return -ENOENT;
160 }
161 if (prev_pac) 160 if (prev_pac)
162 prev_pac->acl_next = pac->acl_next; 161 prev_pac->acl_next = pac->acl_next;
163 else 162 else
@@ -166,7 +165,6 @@ int ipv6_sock_ac_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
166 dev = __dev_get_by_index(net, pac->acl_ifindex); 165 dev = __dev_get_by_index(net, pac->acl_ifindex);
167 if (dev) 166 if (dev)
168 ipv6_dev_ac_dec(dev, &pac->acl_addr); 167 ipv6_dev_ac_dec(dev, &pac->acl_addr);
169 rtnl_unlock();
170 168
171 sock_kfree_s(sk, pac, sizeof(*pac)); 169 sock_kfree_s(sk, pac, sizeof(*pac));
172 return 0; 170 return 0;
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 29b32206e494..2f3bbe569e8f 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -112,22 +112,20 @@ static u32 inet6_synq_hash(const struct in6_addr *raddr, const __be16 rport,
112 return c & (synq_hsize - 1); 112 return c & (synq_hsize - 1);
113} 113}
114 114
115struct request_sock *inet6_csk_search_req(const struct sock *sk, 115struct request_sock *inet6_csk_search_req(struct sock *sk,
116 struct request_sock ***prevp,
117 const __be16 rport, 116 const __be16 rport,
118 const struct in6_addr *raddr, 117 const struct in6_addr *raddr,
119 const struct in6_addr *laddr, 118 const struct in6_addr *laddr,
120 const int iif) 119 const int iif)
121{ 120{
122 const struct inet_connection_sock *icsk = inet_csk(sk); 121 struct inet_connection_sock *icsk = inet_csk(sk);
123 struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt; 122 struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
124 struct request_sock *req, **prev; 123 struct request_sock *req;
124 u32 hash = inet6_synq_hash(raddr, rport, lopt->hash_rnd,
125 lopt->nr_table_entries);
125 126
126 for (prev = &lopt->syn_table[inet6_synq_hash(raddr, rport, 127 write_lock(&icsk->icsk_accept_queue.syn_wait_lock);
127 lopt->hash_rnd, 128 for (req = lopt->syn_table[hash]; req != NULL; req = req->dl_next) {
128 lopt->nr_table_entries)];
129 (req = *prev) != NULL;
130 prev = &req->dl_next) {
131 const struct inet_request_sock *ireq = inet_rsk(req); 129 const struct inet_request_sock *ireq = inet_rsk(req);
132 130
133 if (ireq->ir_rmt_port == rport && 131 if (ireq->ir_rmt_port == rport &&
@@ -135,13 +133,14 @@ struct request_sock *inet6_csk_search_req(const struct sock *sk,
135 ipv6_addr_equal(&ireq->ir_v6_rmt_addr, raddr) && 133 ipv6_addr_equal(&ireq->ir_v6_rmt_addr, raddr) &&
136 ipv6_addr_equal(&ireq->ir_v6_loc_addr, laddr) && 134 ipv6_addr_equal(&ireq->ir_v6_loc_addr, laddr) &&
137 (!ireq->ir_iif || ireq->ir_iif == iif)) { 135 (!ireq->ir_iif || ireq->ir_iif == iif)) {
136 atomic_inc(&req->rsk_refcnt);
138 WARN_ON(req->sk != NULL); 137 WARN_ON(req->sk != NULL);
139 *prevp = prev; 138 break;
140 return req;
141 } 139 }
142 } 140 }
141 write_unlock(&icsk->icsk_accept_queue.syn_wait_lock);
143 142
144 return NULL; 143 return req;
145} 144}
146EXPORT_SYMBOL_GPL(inet6_csk_search_req); 145EXPORT_SYMBOL_GPL(inet6_csk_search_req);
147 146
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 051dffb49c90..033f17816ef4 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -23,11 +23,9 @@
23#include <net/secure_seq.h> 23#include <net/secure_seq.h>
24#include <net/ip.h> 24#include <net/ip.h>
25 25
26static unsigned int inet6_ehashfn(struct net *net, 26u32 inet6_ehashfn(const struct net *net,
27 const struct in6_addr *laddr, 27 const struct in6_addr *laddr, const u16 lport,
28 const u16 lport, 28 const struct in6_addr *faddr, const __be16 fport)
29 const struct in6_addr *faddr,
30 const __be16 fport)
31{ 29{
32 static u32 inet6_ehash_secret __read_mostly; 30 static u32 inet6_ehash_secret __read_mostly;
33 static u32 ipv6_hash_secret __read_mostly; 31 static u32 ipv6_hash_secret __read_mostly;
@@ -44,54 +42,6 @@ static unsigned int inet6_ehashfn(struct net *net,
44 inet6_ehash_secret + net_hash_mix(net)); 42 inet6_ehash_secret + net_hash_mix(net));
45} 43}
46 44
47static int inet6_sk_ehashfn(const struct sock *sk)
48{
49 const struct inet_sock *inet = inet_sk(sk);
50 const struct in6_addr *laddr = &sk->sk_v6_rcv_saddr;
51 const struct in6_addr *faddr = &sk->sk_v6_daddr;
52 const __u16 lport = inet->inet_num;
53 const __be16 fport = inet->inet_dport;
54 struct net *net = sock_net(sk);
55
56 return inet6_ehashfn(net, laddr, lport, faddr, fport);
57}
58
59int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw)
60{
61 struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo;
62 int twrefcnt = 0;
63
64 WARN_ON(!sk_unhashed(sk));
65
66 if (sk->sk_state == TCP_LISTEN) {
67 struct inet_listen_hashbucket *ilb;
68
69 ilb = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
70 spin_lock(&ilb->lock);
71 __sk_nulls_add_node_rcu(sk, &ilb->head);
72 spin_unlock(&ilb->lock);
73 } else {
74 unsigned int hash;
75 struct hlist_nulls_head *list;
76 spinlock_t *lock;
77
78 sk->sk_hash = hash = inet6_sk_ehashfn(sk);
79 list = &inet_ehash_bucket(hashinfo, hash)->chain;
80 lock = inet_ehash_lockp(hashinfo, hash);
81 spin_lock(lock);
82 __sk_nulls_add_node_rcu(sk, list);
83 if (tw) {
84 WARN_ON(sk->sk_hash != tw->tw_hash);
85 twrefcnt = inet_twsk_unhash(tw);
86 }
87 spin_unlock(lock);
88 }
89
90 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
91 return twrefcnt;
92}
93EXPORT_SYMBOL(__inet6_hash);
94
95/* 45/*
96 * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so 46 * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so
97 * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM 47 * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM
@@ -320,6 +270,6 @@ int inet6_hash_connect(struct inet_timewait_death_row *death_row,
320 struct sock *sk) 270 struct sock *sk)
321{ 271{
322 return __inet_hash_connect(death_row, sk, inet6_sk_port_offset(sk), 272 return __inet_hash_connect(death_row, sk, inet6_sk_port_offset(sk),
323 __inet6_check_established, __inet6_hash); 273 __inet6_check_established);
324} 274}
325EXPORT_SYMBOL_GPL(inet6_hash_connect); 275EXPORT_SYMBOL_GPL(inet6_hash_connect);
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index f45d6db50a45..457303886fd4 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -100,7 +100,6 @@ static void fl_free(struct ip6_flowlabel *fl)
100 if (fl) { 100 if (fl) {
101 if (fl->share == IPV6_FL_S_PROCESS) 101 if (fl->share == IPV6_FL_S_PROCESS)
102 put_pid(fl->owner.pid); 102 put_pid(fl->owner.pid);
103 release_net(fl->fl_net);
104 kfree(fl->opt); 103 kfree(fl->opt);
105 kfree_rcu(fl, rcu); 104 kfree_rcu(fl, rcu);
106 } 105 }
@@ -403,7 +402,7 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
403 } 402 }
404 } 403 }
405 404
406 fl->fl_net = hold_net(net); 405 fl->fl_net = net;
407 fl->expires = jiffies; 406 fl->expires = jiffies;
408 err = fl6_renew(fl, freq->flr_linger, freq->flr_expires); 407 err = fl6_renew(fl, freq->flr_linger, freq->flr_expires);
409 if (err) 408 if (err)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index ddd94eca19b3..41f84f76ad9d 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -64,12 +64,6 @@ MODULE_LICENSE("GPL");
64MODULE_ALIAS_RTNL_LINK("ip6tnl"); 64MODULE_ALIAS_RTNL_LINK("ip6tnl");
65MODULE_ALIAS_NETDEV("ip6tnl0"); 65MODULE_ALIAS_NETDEV("ip6tnl0");
66 66
67#ifdef IP6_TNL_DEBUG
68#define IP6_TNL_TRACE(x...) pr_debug("%s:" x "\n", __func__)
69#else
70#define IP6_TNL_TRACE(x...) do {;} while(0)
71#endif
72
73#define HASH_SIZE_SHIFT 5 67#define HASH_SIZE_SHIFT 5
74#define HASH_SIZE (1 << HASH_SIZE_SHIFT) 68#define HASH_SIZE (1 << HASH_SIZE_SHIFT)
75 69
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 34b682617f50..4b9315aa273e 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -56,9 +56,7 @@
56 56
57struct mr6_table { 57struct mr6_table {
58 struct list_head list; 58 struct list_head list;
59#ifdef CONFIG_NET_NS 59 possible_net_t net;
60 struct net *net;
61#endif
62 u32 id; 60 u32 id;
63 struct sock *mroute6_sk; 61 struct sock *mroute6_sk;
64 struct timer_list ipmr_expire_timer; 62 struct timer_list ipmr_expire_timer;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 8d766d9100cb..9b2cb1444230 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -117,6 +117,25 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
117 return opt; 117 return opt;
118} 118}
119 119
120static bool setsockopt_needs_rtnl(int optname)
121{
122 switch (optname) {
123 case IPV6_ADD_MEMBERSHIP:
124 case IPV6_DROP_MEMBERSHIP:
125 case IPV6_JOIN_ANYCAST:
126 case IPV6_LEAVE_ANYCAST:
127 case MCAST_JOIN_GROUP:
128 case MCAST_LEAVE_GROUP:
129 case MCAST_JOIN_SOURCE_GROUP:
130 case MCAST_LEAVE_SOURCE_GROUP:
131 case MCAST_BLOCK_SOURCE:
132 case MCAST_UNBLOCK_SOURCE:
133 case MCAST_MSFILTER:
134 return true;
135 }
136 return false;
137}
138
120static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, 139static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
121 char __user *optval, unsigned int optlen) 140 char __user *optval, unsigned int optlen)
122{ 141{
@@ -124,6 +143,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
124 struct net *net = sock_net(sk); 143 struct net *net = sock_net(sk);
125 int val, valbool; 144 int val, valbool;
126 int retv = -ENOPROTOOPT; 145 int retv = -ENOPROTOOPT;
146 bool needs_rtnl = setsockopt_needs_rtnl(optname);
127 147
128 if (optval == NULL) 148 if (optval == NULL)
129 val = 0; 149 val = 0;
@@ -140,6 +160,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
140 if (ip6_mroute_opt(optname)) 160 if (ip6_mroute_opt(optname))
141 return ip6_mroute_setsockopt(sk, optname, optval, optlen); 161 return ip6_mroute_setsockopt(sk, optname, optval, optlen);
142 162
163 if (needs_rtnl)
164 rtnl_lock();
143 lock_sock(sk); 165 lock_sock(sk);
144 166
145 switch (optname) { 167 switch (optname) {
@@ -624,10 +646,10 @@ done:
624 psin6 = (struct sockaddr_in6 *)&greq.gr_group; 646 psin6 = (struct sockaddr_in6 *)&greq.gr_group;
625 if (optname == MCAST_JOIN_GROUP) 647 if (optname == MCAST_JOIN_GROUP)
626 retv = ipv6_sock_mc_join(sk, greq.gr_interface, 648 retv = ipv6_sock_mc_join(sk, greq.gr_interface,
627 &psin6->sin6_addr); 649 &psin6->sin6_addr);
628 else 650 else
629 retv = ipv6_sock_mc_drop(sk, greq.gr_interface, 651 retv = ipv6_sock_mc_drop(sk, greq.gr_interface,
630 &psin6->sin6_addr); 652 &psin6->sin6_addr);
631 break; 653 break;
632 } 654 }
633 case MCAST_JOIN_SOURCE_GROUP: 655 case MCAST_JOIN_SOURCE_GROUP:
@@ -660,7 +682,7 @@ done:
660 682
661 psin6 = (struct sockaddr_in6 *)&greqs.gsr_group; 683 psin6 = (struct sockaddr_in6 *)&greqs.gsr_group;
662 retv = ipv6_sock_mc_join(sk, greqs.gsr_interface, 684 retv = ipv6_sock_mc_join(sk, greqs.gsr_interface,
663 &psin6->sin6_addr); 685 &psin6->sin6_addr);
664 /* prior join w/ different source is ok */ 686 /* prior join w/ different source is ok */
665 if (retv && retv != -EADDRINUSE) 687 if (retv && retv != -EADDRINUSE)
666 break; 688 break;
@@ -837,11 +859,15 @@ pref_skip_coa:
837 } 859 }
838 860
839 release_sock(sk); 861 release_sock(sk);
862 if (needs_rtnl)
863 rtnl_unlock();
840 864
841 return retv; 865 return retv;
842 866
843e_inval: 867e_inval:
844 release_sock(sk); 868 release_sock(sk);
869 if (needs_rtnl)
870 rtnl_unlock();
845 return -EINVAL; 871 return -EINVAL;
846} 872}
847 873
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 5ce107c8aab3..cbb66fd3da6d 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -140,6 +140,8 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
140 struct net *net = sock_net(sk); 140 struct net *net = sock_net(sk);
141 int err; 141 int err;
142 142
143 ASSERT_RTNL();
144
143 if (!ipv6_addr_is_multicast(addr)) 145 if (!ipv6_addr_is_multicast(addr))
144 return -EINVAL; 146 return -EINVAL;
145 147
@@ -161,7 +163,6 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
161 mc_lst->next = NULL; 163 mc_lst->next = NULL;
162 mc_lst->addr = *addr; 164 mc_lst->addr = *addr;
163 165
164 rtnl_lock();
165 if (ifindex == 0) { 166 if (ifindex == 0) {
166 struct rt6_info *rt; 167 struct rt6_info *rt;
167 rt = rt6_lookup(net, addr, NULL, 0, 0); 168 rt = rt6_lookup(net, addr, NULL, 0, 0);
@@ -173,7 +174,6 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
173 dev = __dev_get_by_index(net, ifindex); 174 dev = __dev_get_by_index(net, ifindex);
174 175
175 if (dev == NULL) { 176 if (dev == NULL) {
176 rtnl_unlock();
177 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); 177 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
178 return -ENODEV; 178 return -ENODEV;
179 } 179 }
@@ -190,7 +190,6 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
190 err = ipv6_dev_mc_inc(dev, addr); 190 err = ipv6_dev_mc_inc(dev, addr);
191 191
192 if (err) { 192 if (err) {
193 rtnl_unlock();
194 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); 193 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
195 return err; 194 return err;
196 } 195 }
@@ -198,10 +197,9 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
198 mc_lst->next = np->ipv6_mc_list; 197 mc_lst->next = np->ipv6_mc_list;
199 rcu_assign_pointer(np->ipv6_mc_list, mc_lst); 198 rcu_assign_pointer(np->ipv6_mc_list, mc_lst);
200 199
201 rtnl_unlock();
202
203 return 0; 200 return 0;
204} 201}
202EXPORT_SYMBOL(ipv6_sock_mc_join);
205 203
206/* 204/*
207 * socket leave on multicast group 205 * socket leave on multicast group
@@ -213,10 +211,11 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
213 struct ipv6_mc_socklist __rcu **lnk; 211 struct ipv6_mc_socklist __rcu **lnk;
214 struct net *net = sock_net(sk); 212 struct net *net = sock_net(sk);
215 213
214 ASSERT_RTNL();
215
216 if (!ipv6_addr_is_multicast(addr)) 216 if (!ipv6_addr_is_multicast(addr))
217 return -EINVAL; 217 return -EINVAL;
218 218
219 rtnl_lock();
220 for (lnk = &np->ipv6_mc_list; 219 for (lnk = &np->ipv6_mc_list;
221 (mc_lst = rtnl_dereference(*lnk)) != NULL; 220 (mc_lst = rtnl_dereference(*lnk)) != NULL;
222 lnk = &mc_lst->next) { 221 lnk = &mc_lst->next) {
@@ -235,17 +234,16 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
235 __ipv6_dev_mc_dec(idev, &mc_lst->addr); 234 __ipv6_dev_mc_dec(idev, &mc_lst->addr);
236 } else 235 } else
237 (void) ip6_mc_leave_src(sk, mc_lst, NULL); 236 (void) ip6_mc_leave_src(sk, mc_lst, NULL);
238 rtnl_unlock();
239 237
240 atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc); 238 atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc);
241 kfree_rcu(mc_lst, rcu); 239 kfree_rcu(mc_lst, rcu);
242 return 0; 240 return 0;
243 } 241 }
244 } 242 }
245 rtnl_unlock();
246 243
247 return -EADDRNOTAVAIL; 244 return -EADDRNOTAVAIL;
248} 245}
246EXPORT_SYMBOL(ipv6_sock_mc_drop);
249 247
250/* called with rcu_read_lock() */ 248/* called with rcu_read_lock() */
251static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net, 249static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net,
@@ -438,7 +436,7 @@ done:
438 read_unlock_bh(&idev->lock); 436 read_unlock_bh(&idev->lock);
439 rcu_read_unlock(); 437 rcu_read_unlock();
440 if (leavegroup) 438 if (leavegroup)
441 return ipv6_sock_mc_drop(sk, pgsr->gsr_interface, group); 439 err = ipv6_sock_mc_drop(sk, pgsr->gsr_interface, group);
442 return err; 440 return err;
443} 441}
444 442
@@ -2907,20 +2905,32 @@ static int __net_init igmp6_net_init(struct net *net)
2907 2905
2908 inet6_sk(net->ipv6.igmp_sk)->hop_limit = 1; 2906 inet6_sk(net->ipv6.igmp_sk)->hop_limit = 1;
2909 2907
2908 err = inet_ctl_sock_create(&net->ipv6.mc_autojoin_sk, PF_INET6,
2909 SOCK_RAW, IPPROTO_ICMPV6, net);
2910 if (err < 0) {
2911 pr_err("Failed to initialize the IGMP6 autojoin socket (err %d)\n",
2912 err);
2913 goto out_sock_create;
2914 }
2915
2910 err = igmp6_proc_init(net); 2916 err = igmp6_proc_init(net);
2911 if (err) 2917 if (err)
2912 goto out_sock_create; 2918 goto out_sock_create_autojoin;
2913out:
2914 return err;
2915 2919
2920 return 0;
2921
2922out_sock_create_autojoin:
2923 inet_ctl_sock_destroy(net->ipv6.mc_autojoin_sk);
2916out_sock_create: 2924out_sock_create:
2917 inet_ctl_sock_destroy(net->ipv6.igmp_sk); 2925 inet_ctl_sock_destroy(net->ipv6.igmp_sk);
2918 goto out; 2926out:
2927 return err;
2919} 2928}
2920 2929
2921static void __net_exit igmp6_net_exit(struct net *net) 2930static void __net_exit igmp6_net_exit(struct net *net)
2922{ 2931{
2923 inet_ctl_sock_destroy(net->ipv6.igmp_sk); 2932 inet_ctl_sock_destroy(net->ipv6.igmp_sk);
2933 inet_ctl_sock_destroy(net->ipv6.mc_autojoin_sk);
2924 igmp6_proc_exit(net); 2934 igmp6_proc_exit(net);
2925} 2935}
2926 2936
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 471ed24aabae..247ad7c298f7 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -84,6 +84,7 @@ do { \
84static u32 ndisc_hash(const void *pkey, 84static u32 ndisc_hash(const void *pkey,
85 const struct net_device *dev, 85 const struct net_device *dev,
86 __u32 *hash_rnd); 86 __u32 *hash_rnd);
87static bool ndisc_key_eq(const struct neighbour *neigh, const void *pkey);
87static int ndisc_constructor(struct neighbour *neigh); 88static int ndisc_constructor(struct neighbour *neigh);
88static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb); 89static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb);
89static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb); 90static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb);
@@ -117,7 +118,9 @@ static const struct neigh_ops ndisc_direct_ops = {
117struct neigh_table nd_tbl = { 118struct neigh_table nd_tbl = {
118 .family = AF_INET6, 119 .family = AF_INET6,
119 .key_len = sizeof(struct in6_addr), 120 .key_len = sizeof(struct in6_addr),
121 .protocol = cpu_to_be16(ETH_P_IPV6),
120 .hash = ndisc_hash, 122 .hash = ndisc_hash,
123 .key_eq = ndisc_key_eq,
121 .constructor = ndisc_constructor, 124 .constructor = ndisc_constructor,
122 .pconstructor = pndisc_constructor, 125 .pconstructor = pndisc_constructor,
123 .pdestructor = pndisc_destructor, 126 .pdestructor = pndisc_destructor,
@@ -294,6 +297,11 @@ static u32 ndisc_hash(const void *pkey,
294 return ndisc_hashfn(pkey, dev, hash_rnd); 297 return ndisc_hashfn(pkey, dev, hash_rnd);
295} 298}
296 299
300static bool ndisc_key_eq(const struct neighbour *n, const void *pkey)
301{
302 return neigh_key_eq128(n, pkey);
303}
304
297static int ndisc_constructor(struct neighbour *neigh) 305static int ndisc_constructor(struct neighbour *neigh)
298{ 306{
299 struct in6_addr *addr = (struct in6_addr *)&neigh->primary_key; 307 struct in6_addr *addr = (struct in6_addr *)&neigh->primary_key;
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index a069822936e6..ca6998345b42 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -25,14 +25,16 @@ config NF_CONNTRACK_IPV6
25 25
26 To compile it as a module, choose M here. If unsure, say N. 26 To compile it as a module, choose M here. If unsure, say N.
27 27
28if NF_TABLES
29
28config NF_TABLES_IPV6 30config NF_TABLES_IPV6
29 depends on NF_TABLES
30 tristate "IPv6 nf_tables support" 31 tristate "IPv6 nf_tables support"
31 help 32 help
32 This option enables the IPv6 support for nf_tables. 33 This option enables the IPv6 support for nf_tables.
33 34
35if NF_TABLES_IPV6
36
34config NFT_CHAIN_ROUTE_IPV6 37config NFT_CHAIN_ROUTE_IPV6
35 depends on NF_TABLES_IPV6
36 tristate "IPv6 nf_tables route chain support" 38 tristate "IPv6 nf_tables route chain support"
37 help 39 help
38 This option enables the "route" chain for IPv6 in nf_tables. This 40 This option enables the "route" chain for IPv6 in nf_tables. This
@@ -40,16 +42,18 @@ config NFT_CHAIN_ROUTE_IPV6
40 fields such as the source, destination, flowlabel, hop-limit and 42 fields such as the source, destination, flowlabel, hop-limit and
41 the packet mark. 43 the packet mark.
42 44
43config NF_REJECT_IPV6
44 tristate "IPv6 packet rejection"
45 default m if NETFILTER_ADVANCED=n
46
47config NFT_REJECT_IPV6 45config NFT_REJECT_IPV6
48 depends on NF_TABLES_IPV6
49 select NF_REJECT_IPV6 46 select NF_REJECT_IPV6
50 default NFT_REJECT 47 default NFT_REJECT
51 tristate 48 tristate
52 49
50endif # NF_TABLES_IPV6
51endif # NF_TABLES
52
53config NF_REJECT_IPV6
54 tristate "IPv6 packet rejection"
55 default m if NETFILTER_ADVANCED=n
56
53config NF_LOG_IPV6 57config NF_LOG_IPV6
54 tristate "IPv6 packet logging" 58 tristate "IPv6 packet logging"
55 default m if NETFILTER_ADVANCED=n 59 default m if NETFILTER_ADVANCED=n
diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c
index d05b36440e8b..3afdce03d94e 100644
--- a/net/ipv6/netfilter/nf_reject_ipv6.c
+++ b/net/ipv6/netfilter/nf_reject_ipv6.c
@@ -65,7 +65,7 @@ EXPORT_SYMBOL_GPL(nf_reject_ip6_tcphdr_get);
65 65
66struct ipv6hdr *nf_reject_ip6hdr_put(struct sk_buff *nskb, 66struct ipv6hdr *nf_reject_ip6hdr_put(struct sk_buff *nskb,
67 const struct sk_buff *oldskb, 67 const struct sk_buff *oldskb,
68 __be16 protocol, int hoplimit) 68 __u8 protocol, int hoplimit)
69{ 69{
70 struct ipv6hdr *ip6h; 70 struct ipv6hdr *ip6h;
71 const struct ipv6hdr *oip6h = ipv6_hdr(oldskb); 71 const struct ipv6hdr *oip6h = ipv6_hdr(oldskb);
@@ -208,4 +208,39 @@ void nf_send_reset6(struct net *net, struct sk_buff *oldskb, int hook)
208} 208}
209EXPORT_SYMBOL_GPL(nf_send_reset6); 209EXPORT_SYMBOL_GPL(nf_send_reset6);
210 210
211static bool reject6_csum_ok(struct sk_buff *skb, int hook)
212{
213 const struct ipv6hdr *ip6h = ipv6_hdr(skb);
214 int thoff;
215 __be16 fo;
216 u8 proto;
217
218 if (skb->csum_bad)
219 return false;
220
221 if (skb_csum_unnecessary(skb))
222 return true;
223
224 proto = ip6h->nexthdr;
225 thoff = ipv6_skip_exthdr(skb, ((u8*)(ip6h+1) - skb->data), &proto, &fo);
226
227 if (thoff < 0 || thoff >= skb->len || (fo & htons(~0x7)) != 0)
228 return false;
229
230 return nf_ip6_checksum(skb, hook, thoff, proto) == 0;
231}
232
233void nf_send_unreach6(struct net *net, struct sk_buff *skb_in,
234 unsigned char code, unsigned int hooknum)
235{
236 if (!reject6_csum_ok(skb_in, hooknum))
237 return;
238
239 if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL)
240 skb_in->dev = net->loopback_dev;
241
242 icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0);
243}
244EXPORT_SYMBOL_GPL(nf_send_unreach6);
245
211MODULE_LICENSE("GPL"); 246MODULE_LICENSE("GPL");
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index a2dfff6ff227..263a5164a6f5 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -77,8 +77,7 @@ static int dummy_ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
77 return 0; 77 return 0;
78} 78}
79 79
80int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, 80int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
81 size_t len)
82{ 81{
83 struct inet_sock *inet = inet_sk(sk); 82 struct inet_sock *inet = inet_sk(sk);
84 struct ipv6_pinfo *np = inet6_sk(sk); 83 struct ipv6_pinfo *np = inet6_sk(sk);
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index dae7f1a1e464..a5287b3582a4 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -32,7 +32,7 @@
32#include <linux/netfilter_ipv6.h> 32#include <linux/netfilter_ipv6.h>
33#include <linux/skbuff.h> 33#include <linux/skbuff.h>
34#include <linux/compat.h> 34#include <linux/compat.h>
35#include <asm/uaccess.h> 35#include <linux/uaccess.h>
36#include <asm/ioctls.h> 36#include <asm/ioctls.h>
37 37
38#include <net/net_namespace.h> 38#include <net/net_namespace.h>
@@ -456,9 +456,8 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
456 * we return it, otherwise we block. 456 * we return it, otherwise we block.
457 */ 457 */
458 458
459static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, 459static int rawv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
460 struct msghdr *msg, size_t len, 460 int noblock, int flags, int *addr_len)
461 int noblock, int flags, int *addr_len)
462{ 461{
463 struct ipv6_pinfo *np = inet6_sk(sk); 462 struct ipv6_pinfo *np = inet6_sk(sk);
464 DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); 463 DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
@@ -730,8 +729,7 @@ static int raw6_getfrag(void *from, char *to, int offset, int len, int odd,
730 return ip_generic_getfrag(rfv->msg, to, offset, len, odd, skb); 729 return ip_generic_getfrag(rfv->msg, to, offset, len, odd, skb);
731} 730}
732 731
733static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, 732static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
734 struct msghdr *msg, size_t len)
735{ 733{
736 struct ipv6_txoptions opt_space; 734 struct ipv6_txoptions opt_space;
737 DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); 735 DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 4688bd4d7f59..58c0e6a4d15d 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -194,7 +194,6 @@ static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst,
194 194
195static struct dst_ops ip6_dst_ops_template = { 195static struct dst_ops ip6_dst_ops_template = {
196 .family = AF_INET6, 196 .family = AF_INET6,
197 .protocol = cpu_to_be16(ETH_P_IPV6),
198 .gc = ip6_dst_gc, 197 .gc = ip6_dst_gc,
199 .gc_thresh = 1024, 198 .gc_thresh = 1024,
200 .check = ip6_dst_check, 199 .check = ip6_dst_check,
@@ -236,7 +235,6 @@ static u32 *ip6_rt_blackhole_cow_metrics(struct dst_entry *dst,
236 235
237static struct dst_ops ip6_dst_blackhole_ops = { 236static struct dst_ops ip6_dst_blackhole_ops = {
238 .family = AF_INET6, 237 .family = AF_INET6,
239 .protocol = cpu_to_be16(ETH_P_IPV6),
240 .destroy = ip6_dst_destroy, 238 .destroy = ip6_dst_destroy,
241 .check = ip6_dst_check, 239 .check = ip6_dst_check,
242 .mtu = ip6_blackhole_mtu, 240 .mtu = ip6_blackhole_mtu,
@@ -2400,6 +2398,7 @@ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
2400 [RTA_PRIORITY] = { .type = NLA_U32 }, 2398 [RTA_PRIORITY] = { .type = NLA_U32 },
2401 [RTA_METRICS] = { .type = NLA_NESTED }, 2399 [RTA_METRICS] = { .type = NLA_NESTED },
2402 [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) }, 2400 [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) },
2401 [RTA_PREF] = { .type = NLA_U8 },
2403}; 2402};
2404 2403
2405static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, 2404static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -2407,6 +2406,7 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
2407{ 2406{
2408 struct rtmsg *rtm; 2407 struct rtmsg *rtm;
2409 struct nlattr *tb[RTA_MAX+1]; 2408 struct nlattr *tb[RTA_MAX+1];
2409 unsigned int pref;
2410 int err; 2410 int err;
2411 2411
2412 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy); 2412 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
@@ -2482,6 +2482,14 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
2482 cfg->fc_mp_len = nla_len(tb[RTA_MULTIPATH]); 2482 cfg->fc_mp_len = nla_len(tb[RTA_MULTIPATH]);
2483 } 2483 }
2484 2484
2485 if (tb[RTA_PREF]) {
2486 pref = nla_get_u8(tb[RTA_PREF]);
2487 if (pref != ICMPV6_ROUTER_PREF_LOW &&
2488 pref != ICMPV6_ROUTER_PREF_HIGH)
2489 pref = ICMPV6_ROUTER_PREF_MEDIUM;
2490 cfg->fc_flags |= RTF_PREF(pref);
2491 }
2492
2485 err = 0; 2493 err = 0;
2486errout: 2494errout:
2487 return err; 2495 return err;
@@ -2585,7 +2593,8 @@ static inline size_t rt6_nlmsg_size(void)
2585 + nla_total_size(4) /* RTA_PRIORITY */ 2593 + nla_total_size(4) /* RTA_PRIORITY */
2586 + RTAX_MAX * nla_total_size(4) /* RTA_METRICS */ 2594 + RTAX_MAX * nla_total_size(4) /* RTA_METRICS */
2587 + nla_total_size(sizeof(struct rta_cacheinfo)) 2595 + nla_total_size(sizeof(struct rta_cacheinfo))
2588 + nla_total_size(TCP_CA_NAME_MAX); /* RTAX_CC_ALGO */ 2596 + nla_total_size(TCP_CA_NAME_MAX) /* RTAX_CC_ALGO */
2597 + nla_total_size(1); /* RTA_PREF */
2589} 2598}
2590 2599
2591static int rt6_fill_node(struct net *net, 2600static int rt6_fill_node(struct net *net,
@@ -2726,6 +2735,9 @@ static int rt6_fill_node(struct net *net,
2726 if (rtnl_put_cacheinfo(skb, &rt->dst, 0, expires, rt->dst.error) < 0) 2735 if (rtnl_put_cacheinfo(skb, &rt->dst, 0, expires, rt->dst.error) < 0)
2727 goto nla_put_failure; 2736 goto nla_put_failure;
2728 2737
2738 if (nla_put_u8(skb, RTA_PREF, IPV6_EXTRACT_PREF(rt->rt6i_flags)))
2739 goto nla_put_failure;
2740
2729 nlmsg_end(skb, nlh); 2741 nlmsg_end(skb, nlh);
2730 return 0; 2742 return 0;
2731 2743
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 7337fc7947e2..2819137fc87d 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -49,11 +49,12 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
49 struct sock *child; 49 struct sock *child;
50 50
51 child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst); 51 child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst);
52 if (child) 52 if (child) {
53 atomic_set(&req->rsk_refcnt, 1);
53 inet_csk_reqsk_queue_add(sk, req, child); 54 inet_csk_reqsk_queue_add(sk, req, child);
54 else 55 } else {
55 reqsk_free(req); 56 reqsk_free(req);
56 57 }
57 return child; 58 return child;
58} 59}
59 60
@@ -189,13 +190,14 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
189 goto out; 190 goto out;
190 191
191 ret = NULL; 192 ret = NULL;
192 req = inet_reqsk_alloc(&tcp6_request_sock_ops); 193 req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk);
193 if (!req) 194 if (!req)
194 goto out; 195 goto out;
195 196
196 ireq = inet_rsk(req); 197 ireq = inet_rsk(req);
197 treq = tcp_rsk(req); 198 treq = tcp_rsk(req);
198 treq->listener = NULL; 199 treq->tfo_listener = false;
200 ireq->ireq_family = AF_INET6;
199 201
200 if (security_inet_conn_request(sk, skb, req)) 202 if (security_inet_conn_request(sk, skb, req))
201 goto out_free; 203 goto out_free;
@@ -220,7 +222,6 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
220 222
221 ireq->ir_mark = inet_request_mark(sk, skb); 223 ireq->ir_mark = inet_request_mark(sk, skb);
222 224
223 req->expires = 0UL;
224 req->num_retrans = 0; 225 req->num_retrans = 0;
225 ireq->snd_wscale = tcp_opt.snd_wscale; 226 ireq->snd_wscale = tcp_opt.snd_wscale;
226 ireq->sack_ok = tcp_opt.sack_ok; 227 ireq->sack_ok = tcp_opt.sack_ok;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 5d46832c6f72..6e3f90db038c 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -104,19 +104,6 @@ static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
104 } 104 }
105} 105}
106 106
107static void tcp_v6_hash(struct sock *sk)
108{
109 if (sk->sk_state != TCP_CLOSE) {
110 if (inet_csk(sk)->icsk_af_ops == &ipv6_mapped) {
111 tcp_prot.hash(sk);
112 return;
113 }
114 local_bh_disable();
115 __inet6_hash(sk, NULL);
116 local_bh_enable();
117 }
118}
119
120static __u32 tcp_v6_init_sequence(const struct sk_buff *skb) 107static __u32 tcp_v6_init_sequence(const struct sk_buff *skb)
121{ 108{
122 return secure_tcpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, 109 return secure_tcpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32,
@@ -233,11 +220,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
233 tp->af_specific = &tcp_sock_ipv6_specific; 220 tp->af_specific = &tcp_sock_ipv6_specific;
234#endif 221#endif
235 goto failure; 222 goto failure;
236 } else {
237 ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr);
238 ipv6_addr_set_v4mapped(inet->inet_rcv_saddr,
239 &sk->sk_v6_rcv_saddr);
240 } 223 }
224 np->saddr = sk->sk_v6_rcv_saddr;
241 225
242 return err; 226 return err;
243 } 227 }
@@ -419,13 +403,13 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
419 403
420 /* Might be for an request_sock */ 404 /* Might be for an request_sock */
421 switch (sk->sk_state) { 405 switch (sk->sk_state) {
422 struct request_sock *req, **prev; 406 struct request_sock *req;
423 case TCP_LISTEN: 407 case TCP_LISTEN:
424 if (sock_owned_by_user(sk)) 408 if (sock_owned_by_user(sk))
425 goto out; 409 goto out;
426 410
427 /* Note : We use inet6_iif() here, not tcp_v6_iif() */ 411 /* Note : We use inet6_iif() here, not tcp_v6_iif() */
428 req = inet6_csk_search_req(sk, &prev, th->dest, &hdr->daddr, 412 req = inet6_csk_search_req(sk, th->dest, &hdr->daddr,
429 &hdr->saddr, inet6_iif(skb)); 413 &hdr->saddr, inet6_iif(skb));
430 if (!req) 414 if (!req)
431 goto out; 415 goto out;
@@ -437,11 +421,13 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
437 421
438 if (seq != tcp_rsk(req)->snt_isn) { 422 if (seq != tcp_rsk(req)->snt_isn) {
439 NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); 423 NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
424 reqsk_put(req);
440 goto out; 425 goto out;
441 } 426 }
442 427
443 inet_csk_reqsk_queue_drop(sk, req, prev); 428 inet_csk_reqsk_queue_drop(sk, req);
444 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); 429 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
430 reqsk_put(req);
445 goto out; 431 goto out;
446 432
447 case TCP_SYN_SENT: 433 case TCP_SYN_SENT:
@@ -734,8 +720,6 @@ static void tcp_v6_init_req(struct request_sock *req, struct sock *sk,
734 ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr; 720 ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr;
735 ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr; 721 ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr;
736 722
737 ireq->ir_iif = sk->sk_bound_dev_if;
738
739 /* So that link locals have meaning */ 723 /* So that link locals have meaning */
740 if (!sk->sk_bound_dev_if && 724 if (!sk->sk_bound_dev_if &&
741 ipv6_addr_type(&ireq->ir_v6_rmt_addr) & IPV6_ADDR_LINKLOCAL) 725 ipv6_addr_type(&ireq->ir_v6_rmt_addr) & IPV6_ADDR_LINKLOCAL)
@@ -749,6 +733,7 @@ static void tcp_v6_init_req(struct request_sock *req, struct sock *sk,
749 atomic_inc(&skb->users); 733 atomic_inc(&skb->users);
750 ireq->pktopts = skb; 734 ireq->pktopts = skb;
751 } 735 }
736 ireq->ireq_family = AF_INET6;
752} 737}
753 738
754static struct dst_entry *tcp_v6_route_req(struct sock *sk, struct flowi *fl, 739static struct dst_entry *tcp_v6_route_req(struct sock *sk, struct flowi *fl,
@@ -997,17 +982,19 @@ static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
997 982
998static struct sock *tcp_v6_hnd_req(struct sock *sk, struct sk_buff *skb) 983static struct sock *tcp_v6_hnd_req(struct sock *sk, struct sk_buff *skb)
999{ 984{
1000 struct request_sock *req, **prev;
1001 const struct tcphdr *th = tcp_hdr(skb); 985 const struct tcphdr *th = tcp_hdr(skb);
986 struct request_sock *req;
1002 struct sock *nsk; 987 struct sock *nsk;
1003 988
1004 /* Find possible connection requests. */ 989 /* Find possible connection requests. */
1005 req = inet6_csk_search_req(sk, &prev, th->source, 990 req = inet6_csk_search_req(sk, th->source,
1006 &ipv6_hdr(skb)->saddr, 991 &ipv6_hdr(skb)->saddr,
1007 &ipv6_hdr(skb)->daddr, tcp_v6_iif(skb)); 992 &ipv6_hdr(skb)->daddr, tcp_v6_iif(skb));
1008 if (req) 993 if (req) {
1009 return tcp_check_req(sk, skb, req, prev, false); 994 nsk = tcp_check_req(sk, skb, req, false);
1010 995 reqsk_put(req);
996 return nsk;
997 }
1011 nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo, 998 nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo,
1012 &ipv6_hdr(skb)->saddr, th->source, 999 &ipv6_hdr(skb)->saddr, th->source,
1013 &ipv6_hdr(skb)->daddr, ntohs(th->dest), 1000 &ipv6_hdr(skb)->daddr, ntohs(th->dest),
@@ -1079,11 +1066,7 @@ static struct sock *tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1079 1066
1080 memcpy(newnp, np, sizeof(struct ipv6_pinfo)); 1067 memcpy(newnp, np, sizeof(struct ipv6_pinfo));
1081 1068
1082 ipv6_addr_set_v4mapped(newinet->inet_daddr, &newsk->sk_v6_daddr); 1069 newnp->saddr = newsk->sk_v6_rcv_saddr;
1083
1084 ipv6_addr_set_v4mapped(newinet->inet_saddr, &newnp->saddr);
1085
1086 newsk->sk_v6_rcv_saddr = newnp->saddr;
1087 1070
1088 inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; 1071 inet_csk(newsk)->icsk_af_ops = &ipv6_mapped;
1089 newsk->sk_backlog_rcv = tcp_v4_do_rcv; 1072 newsk->sk_backlog_rcv = tcp_v4_do_rcv;
@@ -1232,7 +1215,7 @@ static struct sock *tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1232 tcp_done(newsk); 1215 tcp_done(newsk);
1233 goto out; 1216 goto out;
1234 } 1217 }
1235 __inet6_hash(newsk, NULL); 1218 __inet_hash(newsk, NULL);
1236 1219
1237 return newsk; 1220 return newsk;
1238 1221
@@ -1584,7 +1567,7 @@ static void tcp_v6_early_demux(struct sk_buff *skb)
1584 if (sk) { 1567 if (sk) {
1585 skb->sk = sk; 1568 skb->sk = sk;
1586 skb->destructor = sock_edemux; 1569 skb->destructor = sock_edemux;
1587 if (sk->sk_state != TCP_TIME_WAIT) { 1570 if (sk_fullsock(sk)) {
1588 struct dst_entry *dst = sk->sk_rx_dst; 1571 struct dst_entry *dst = sk->sk_rx_dst;
1589 1572
1590 if (dst) 1573 if (dst)
@@ -1689,9 +1672,9 @@ static void tcp_v6_destroy_sock(struct sock *sk)
1689#ifdef CONFIG_PROC_FS 1672#ifdef CONFIG_PROC_FS
1690/* Proc filesystem TCPv6 sock list dumping. */ 1673/* Proc filesystem TCPv6 sock list dumping. */
1691static void get_openreq6(struct seq_file *seq, 1674static void get_openreq6(struct seq_file *seq,
1692 const struct sock *sk, struct request_sock *req, int i, kuid_t uid) 1675 struct request_sock *req, int i, kuid_t uid)
1693{ 1676{
1694 int ttd = req->expires - jiffies; 1677 long ttd = req->rsk_timer.expires - jiffies;
1695 const struct in6_addr *src = &inet_rsk(req)->ir_v6_loc_addr; 1678 const struct in6_addr *src = &inet_rsk(req)->ir_v6_loc_addr;
1696 const struct in6_addr *dest = &inet_rsk(req)->ir_v6_rmt_addr; 1679 const struct in6_addr *dest = &inet_rsk(req)->ir_v6_rmt_addr;
1697 1680
@@ -1827,7 +1810,7 @@ static int tcp6_seq_show(struct seq_file *seq, void *v)
1827 get_tcp6_sock(seq, v, st->num); 1810 get_tcp6_sock(seq, v, st->num);
1828 break; 1811 break;
1829 case TCP_SEQ_STATE_OPENREQ: 1812 case TCP_SEQ_STATE_OPENREQ:
1830 get_openreq6(seq, st->syn_wait_sk, v, st->num, st->uid); 1813 get_openreq6(seq, v, st->num, st->uid);
1831 break; 1814 break;
1832 } 1815 }
1833out: 1816out:
@@ -1891,7 +1874,7 @@ struct proto tcpv6_prot = {
1891 .sendpage = tcp_sendpage, 1874 .sendpage = tcp_sendpage,
1892 .backlog_rcv = tcp_v6_do_rcv, 1875 .backlog_rcv = tcp_v6_do_rcv,
1893 .release_cb = tcp_release_cb, 1876 .release_cb = tcp_release_cb,
1894 .hash = tcp_v6_hash, 1877 .hash = inet_hash,
1895 .unhash = inet_unhash, 1878 .unhash = inet_unhash,
1896 .get_port = inet_csk_get_port, 1879 .get_port = inet_csk_get_port,
1897 .enter_memory_pressure = tcp_enter_memory_pressure, 1880 .enter_memory_pressure = tcp_enter_memory_pressure,
diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c
index c1ab77105b4c..d883c9204c01 100644
--- a/net/ipv6/tcpv6_offload.c
+++ b/net/ipv6/tcpv6_offload.c
@@ -41,8 +41,8 @@ static int tcp6_gro_complete(struct sk_buff *skb, int thoff)
41 return tcp_gro_complete(skb); 41 return tcp_gro_complete(skb);
42} 42}
43 43
44struct sk_buff *tcp6_gso_segment(struct sk_buff *skb, 44static struct sk_buff *tcp6_gso_segment(struct sk_buff *skb,
45 netdev_features_t features) 45 netdev_features_t features)
46{ 46{
47 struct tcphdr *th; 47 struct tcphdr *th;
48 48
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index d048d46779fc..7fe0329c0d37 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -53,11 +53,11 @@
53#include <trace/events/skb.h> 53#include <trace/events/skb.h>
54#include "udp_impl.h" 54#include "udp_impl.h"
55 55
56static unsigned int udp6_ehashfn(struct net *net, 56static u32 udp6_ehashfn(const struct net *net,
57 const struct in6_addr *laddr, 57 const struct in6_addr *laddr,
58 const u16 lport, 58 const u16 lport,
59 const struct in6_addr *faddr, 59 const struct in6_addr *faddr,
60 const __be16 fport) 60 const __be16 fport)
61{ 61{
62 static u32 udp6_ehash_secret __read_mostly; 62 static u32 udp6_ehash_secret __read_mostly;
63 static u32 udp_ipv6_hash_secret __read_mostly; 63 static u32 udp_ipv6_hash_secret __read_mostly;
@@ -104,9 +104,9 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
104 return 0; 104 return 0;
105} 105}
106 106
107static unsigned int udp6_portaddr_hash(struct net *net, 107static u32 udp6_portaddr_hash(const struct net *net,
108 const struct in6_addr *addr6, 108 const struct in6_addr *addr6,
109 unsigned int port) 109 unsigned int port)
110{ 110{
111 unsigned int hash, mix = net_hash_mix(net); 111 unsigned int hash, mix = net_hash_mix(net);
112 112
@@ -391,8 +391,7 @@ EXPORT_SYMBOL_GPL(udp6_lib_lookup);
391 * return it, otherwise we block. 391 * return it, otherwise we block.
392 */ 392 */
393 393
394int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, 394int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
395 struct msghdr *msg, size_t len,
396 int noblock, int flags, int *addr_len) 395 int noblock, int flags, int *addr_len)
397{ 396{
398 struct ipv6_pinfo *np = inet6_sk(sk); 397 struct ipv6_pinfo *np = inet6_sk(sk);
@@ -1101,8 +1100,7 @@ out:
1101 return err; 1100 return err;
1102} 1101}
1103 1102
1104int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, 1103int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
1105 struct msghdr *msg, size_t len)
1106{ 1104{
1107 struct ipv6_txoptions opt_space; 1105 struct ipv6_txoptions opt_space;
1108 struct udp_sock *up = udp_sk(sk); 1106 struct udp_sock *up = udp_sk(sk);
@@ -1164,12 +1162,12 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
1164do_udp_sendmsg: 1162do_udp_sendmsg:
1165 if (__ipv6_only_sock(sk)) 1163 if (__ipv6_only_sock(sk))
1166 return -ENETUNREACH; 1164 return -ENETUNREACH;
1167 return udp_sendmsg(iocb, sk, msg, len); 1165 return udp_sendmsg(sk, msg, len);
1168 } 1166 }
1169 } 1167 }
1170 1168
1171 if (up->pending == AF_INET) 1169 if (up->pending == AF_INET)
1172 return udp_sendmsg(iocb, sk, msg, len); 1170 return udp_sendmsg(sk, msg, len);
1173 1171
1174 /* Rough check on arithmetic overflow, 1172 /* Rough check on arithmetic overflow,
1175 better check is made in ip6_append_data(). 1173 better check is made in ip6_append_data().
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
index c779c3c90b9d..0682c031ccdc 100644
--- a/net/ipv6/udp_impl.h
+++ b/net/ipv6/udp_impl.h
@@ -23,10 +23,9 @@ int compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
23int compat_udpv6_getsockopt(struct sock *sk, int level, int optname, 23int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
24 char __user *optval, int __user *optlen); 24 char __user *optval, int __user *optlen);
25#endif 25#endif
26int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, 26int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len);
27 size_t len); 27int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
28int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, 28 int flags, int *addr_len);
29 size_t len, int noblock, int flags, int *addr_len);
30int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); 29int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
31void udpv6_destroy_sock(struct sock *sk); 30void udpv6_destroy_sock(struct sock *sk);
32 31
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 8d2d01b4800a..11dbcc1790d2 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -293,7 +293,6 @@ static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
293 293
294static struct dst_ops xfrm6_dst_ops = { 294static struct dst_ops xfrm6_dst_ops = {
295 .family = AF_INET6, 295 .family = AF_INET6,
296 .protocol = cpu_to_be16(ETH_P_IPV6),
297 .gc = xfrm6_garbage_collect, 296 .gc = xfrm6_garbage_collect,
298 .update_pmtu = xfrm6_update_pmtu, 297 .update_pmtu = xfrm6_update_pmtu,
299 .redirect = xfrm6_redirect, 298 .redirect = xfrm6_redirect,