diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 38 | ||||
-rw-r--r-- | net/ipv6/addrlabel.c | 11 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 2 | ||||
-rw-r--r-- | net/ipv6/anycast.c | 12 | ||||
-rw-r--r-- | net/ipv6/inet6_connection_sock.c | 23 | ||||
-rw-r--r-- | net/ipv6/inet6_hashtables.c | 58 | ||||
-rw-r--r-- | net/ipv6/ip6_flowlabel.c | 3 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 6 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 4 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 32 | ||||
-rw-r--r-- | net/ipv6/mcast.c | 36 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 8 | ||||
-rw-r--r-- | net/ipv6/netfilter/Kconfig | 18 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_reject_ipv6.c | 37 | ||||
-rw-r--r-- | net/ipv6/ping.c | 3 | ||||
-rw-r--r-- | net/ipv6/raw.c | 10 | ||||
-rw-r--r-- | net/ipv6/route.c | 18 | ||||
-rw-r--r-- | net/ipv6/syncookies.c | 13 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 59 | ||||
-rw-r--r-- | net/ipv6/tcpv6_offload.c | 4 | ||||
-rw-r--r-- | net/ipv6/udp.c | 26 | ||||
-rw-r--r-- | net/ipv6/udp_impl.h | 7 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 1 |
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 | ||
2467 | static 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 | */ |
31 | struct ip6addrlbl_entry { | 31 | struct 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 */ |
130 | static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p) | 128 | static 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 | ||
132 | error: | 133 | error: |
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 | ||
115 | struct request_sock *inet6_csk_search_req(const struct sock *sk, | 115 | struct 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 | } |
146 | EXPORT_SYMBOL_GPL(inet6_csk_search_req); | 145 | EXPORT_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 | ||
26 | static unsigned int inet6_ehashfn(struct net *net, | 26 | u32 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 | ||
47 | static 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 | |||
59 | int __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 | } | ||
93 | EXPORT_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 | } |
325 | EXPORT_SYMBOL_GPL(inet6_hash_connect); | 275 | EXPORT_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"); | |||
64 | MODULE_ALIAS_RTNL_LINK("ip6tnl"); | 64 | MODULE_ALIAS_RTNL_LINK("ip6tnl"); |
65 | MODULE_ALIAS_NETDEV("ip6tnl0"); | 65 | MODULE_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 | ||
57 | struct mr6_table { | 57 | struct 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 | ||
120 | static 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 | |||
120 | static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | 139 | static 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 | ||
843 | e_inval: | 867 | e_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 | } |
202 | EXPORT_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 | } |
246 | EXPORT_SYMBOL(ipv6_sock_mc_drop); | ||
249 | 247 | ||
250 | /* called with rcu_read_lock() */ | 248 | /* called with rcu_read_lock() */ |
251 | static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net, | 249 | static 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; |
2913 | out: | ||
2914 | return err; | ||
2915 | 2919 | ||
2920 | return 0; | ||
2921 | |||
2922 | out_sock_create_autojoin: | ||
2923 | inet_ctl_sock_destroy(net->ipv6.mc_autojoin_sk); | ||
2916 | out_sock_create: | 2924 | out_sock_create: |
2917 | inet_ctl_sock_destroy(net->ipv6.igmp_sk); | 2925 | inet_ctl_sock_destroy(net->ipv6.igmp_sk); |
2918 | goto out; | 2926 | out: |
2927 | return err; | ||
2919 | } | 2928 | } |
2920 | 2929 | ||
2921 | static void __net_exit igmp6_net_exit(struct net *net) | 2930 | static 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 { \ | |||
84 | static u32 ndisc_hash(const void *pkey, | 84 | static 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); |
87 | static bool ndisc_key_eq(const struct neighbour *neigh, const void *pkey); | ||
87 | static int ndisc_constructor(struct neighbour *neigh); | 88 | static int ndisc_constructor(struct neighbour *neigh); |
88 | static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb); | 89 | static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb); |
89 | static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb); | 90 | static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb); |
@@ -117,7 +118,9 @@ static const struct neigh_ops ndisc_direct_ops = { | |||
117 | struct neigh_table nd_tbl = { | 118 | struct 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 | ||
300 | static bool ndisc_key_eq(const struct neighbour *n, const void *pkey) | ||
301 | { | ||
302 | return neigh_key_eq128(n, pkey); | ||
303 | } | ||
304 | |||
297 | static int ndisc_constructor(struct neighbour *neigh) | 305 | static 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 | ||
28 | if NF_TABLES | ||
29 | |||
28 | config NF_TABLES_IPV6 | 30 | config 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 | ||
35 | if NF_TABLES_IPV6 | ||
36 | |||
34 | config NFT_CHAIN_ROUTE_IPV6 | 37 | config 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 | ||
43 | config NF_REJECT_IPV6 | ||
44 | tristate "IPv6 packet rejection" | ||
45 | default m if NETFILTER_ADVANCED=n | ||
46 | |||
47 | config NFT_REJECT_IPV6 | 45 | config 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 | ||
50 | endif # NF_TABLES_IPV6 | ||
51 | endif # NF_TABLES | ||
52 | |||
53 | config NF_REJECT_IPV6 | ||
54 | tristate "IPv6 packet rejection" | ||
55 | default m if NETFILTER_ADVANCED=n | ||
56 | |||
53 | config NF_LOG_IPV6 | 57 | config 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 | ||
66 | struct ipv6hdr *nf_reject_ip6hdr_put(struct sk_buff *nskb, | 66 | struct 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 | } |
209 | EXPORT_SYMBOL_GPL(nf_send_reset6); | 209 | EXPORT_SYMBOL_GPL(nf_send_reset6); |
210 | 210 | ||
211 | static 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 | |||
233 | void 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 | } | ||
244 | EXPORT_SYMBOL_GPL(nf_send_unreach6); | ||
245 | |||
211 | MODULE_LICENSE("GPL"); | 246 | MODULE_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 | ||
80 | int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | 80 | int 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 | ||
459 | static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, | 459 | static 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 | ||
733 | static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | 732 | static 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 | ||
195 | static struct dst_ops ip6_dst_ops_template = { | 195 | static 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 | ||
237 | static struct dst_ops ip6_dst_blackhole_ops = { | 236 | static 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 | ||
2405 | static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, | 2404 | static 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; |
2486 | errout: | 2494 | errout: |
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 | ||
2591 | static int rt6_fill_node(struct net *net, | 2600 | static 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 | ||
107 | static 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 | |||
120 | static __u32 tcp_v6_init_sequence(const struct sk_buff *skb) | 107 | static __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 | ||
754 | static struct dst_entry *tcp_v6_route_req(struct sock *sk, struct flowi *fl, | 739 | static 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 | ||
998 | static struct sock *tcp_v6_hnd_req(struct sock *sk, struct sk_buff *skb) | 983 | static 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. */ |
1691 | static void get_openreq6(struct seq_file *seq, | 1674 | static 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 | } |
1833 | out: | 1816 | out: |
@@ -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 | ||
44 | struct sk_buff *tcp6_gso_segment(struct sk_buff *skb, | 44 | static 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 | ||
56 | static unsigned int udp6_ehashfn(struct net *net, | 56 | static 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 | ||
107 | static unsigned int udp6_portaddr_hash(struct net *net, | 107 | static 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 | ||
394 | int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, | 394 | int 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 | ||
1104 | int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, | 1103 | int 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, | |||
1164 | do_udp_sendmsg: | 1162 | do_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, | |||
23 | int compat_udpv6_getsockopt(struct sock *sk, int level, int optname, | 23 | int 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 |
26 | int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | 26 | int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len); |
27 | size_t len); | 27 | int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock, |
28 | int 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); | ||
30 | int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); | 29 | int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); |
31 | void udpv6_destroy_sock(struct sock *sk); | 30 | void 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 | ||
294 | static struct dst_ops xfrm6_dst_ops = { | 294 | static 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, |