aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/ipv6.c')
-rw-r--r--net/dccp/ipv6.c44
1 files changed, 40 insertions, 4 deletions
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 904967bf2fe9..3c9f0836404f 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -33,6 +33,9 @@
33#include "dccp.h" 33#include "dccp.h"
34#include "ipv6.h" 34#include "ipv6.h"
35 35
36/* Socket used for sending RSTs and ACKs */
37static struct socket *dccp_v6_ctl_socket;
38
36static void dccp_v6_ctl_send_reset(struct sk_buff *skb); 39static void dccp_v6_ctl_send_reset(struct sk_buff *skb);
37static void dccp_v6_reqsk_send_ack(struct sk_buff *skb, 40static void dccp_v6_reqsk_send_ack(struct sk_buff *skb,
38 struct request_sock *req); 41 struct request_sock *req);
@@ -568,7 +571,7 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
568 /* sk = NULL, but it is safe for now. RST socket required. */ 571 /* sk = NULL, but it is safe for now. RST socket required. */
569 if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) { 572 if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
570 if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) { 573 if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
571 ip6_xmit(NULL, skb, &fl, NULL, 0); 574 ip6_xmit(dccp_v6_ctl_socket->sk, skb, &fl, NULL, 0);
572 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS); 575 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
573 DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS); 576 DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS);
574 return; 577 return;
@@ -623,7 +626,7 @@ static void dccp_v6_ctl_send_ack(struct sk_buff *rxskb)
623 626
624 if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) { 627 if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
625 if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) { 628 if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
626 ip6_xmit(NULL, skb, &fl, NULL, 0); 629 ip6_xmit(dccp_v6_ctl_socket->sk, skb, &fl, NULL, 0);
627 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS); 630 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
628 return; 631 return;
629 } 632 }
@@ -1146,10 +1149,14 @@ static struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
1146 */ 1149 */
1147static int dccp_v6_init_sock(struct sock *sk) 1150static int dccp_v6_init_sock(struct sock *sk)
1148{ 1151{
1149 int err = dccp_init_sock(sk); 1152 static __u8 dccp_v6_ctl_sock_initialized;
1153 int err = dccp_init_sock(sk, dccp_v6_ctl_sock_initialized);
1150 1154
1151 if (err == 0) 1155 if (err == 0) {
1156 if (unlikely(!dccp_v6_ctl_sock_initialized))
1157 dccp_v6_ctl_sock_initialized = 1;
1152 inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops; 1158 inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops;
1159 }
1153 1160
1154 return err; 1161 return err;
1155} 1162}
@@ -1222,6 +1229,29 @@ static struct inet_protosw dccp_v6_protosw = {
1222 .flags = INET_PROTOSW_ICSK, 1229 .flags = INET_PROTOSW_ICSK,
1223}; 1230};
1224 1231
1232static char dccp_v6_ctl_socket_err_msg[] __initdata =
1233 KERN_ERR "DCCP: Failed to create the control socket.\n";
1234
1235static int __init dccp_v6_ctl_sock_init(void)
1236{
1237 int rc = sock_create_kern(PF_INET6, SOCK_DCCP, IPPROTO_DCCP,
1238 &dccp_v6_ctl_socket);
1239 if (rc < 0)
1240 printk(dccp_v6_ctl_socket_err_msg);
1241 else {
1242 dccp_v6_ctl_socket->sk->sk_allocation = GFP_ATOMIC;
1243 inet_sk(dccp_v6_ctl_socket->sk)->uc_ttl = -1;
1244
1245 /* Unhash it so that IP input processing does not even
1246 * see it, we do not wish this socket to see incoming
1247 * packets.
1248 */
1249 dccp_v6_ctl_socket->sk->sk_prot->unhash(dccp_v6_ctl_socket->sk);
1250 }
1251
1252 return rc;
1253}
1254
1225static int __init dccp_v6_init(void) 1255static int __init dccp_v6_init(void)
1226{ 1256{
1227 int err = proto_register(&dccp_v6_prot, 1); 1257 int err = proto_register(&dccp_v6_prot, 1);
@@ -1234,8 +1264,14 @@ static int __init dccp_v6_init(void)
1234 goto out_unregister_proto; 1264 goto out_unregister_proto;
1235 1265
1236 inet6_register_protosw(&dccp_v6_protosw); 1266 inet6_register_protosw(&dccp_v6_protosw);
1267
1268 if (dccp_v6_ctl_sock_init() != 0)
1269 goto out_unregister_protosw;
1237out: 1270out:
1238 return err; 1271 return err;
1272out_unregister_protosw:
1273 inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
1274 inet6_unregister_protosw(&dccp_v6_protosw);
1239out_unregister_proto: 1275out_unregister_proto:
1240 proto_unregister(&dccp_v6_prot); 1276 proto_unregister(&dccp_v6_prot);
1241 goto out; 1277 goto out;