aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ipv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/ipv4.c')
-rw-r--r--net/dccp/ipv4.c65
1 files changed, 29 insertions, 36 deletions
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 3fe958eb4bf3..f53bce590ade 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -32,6 +32,13 @@
32#include "dccp.h" 32#include "dccp.h"
33#include "feat.h" 33#include "feat.h"
34 34
35/*
36 * This is the global socket data structure used for responding to
37 * the Out-of-the-blue (OOTB) packets. A control sock will be created
38 * for this socket at the initialization time.
39 */
40static struct socket *dccp_v4_ctl_socket;
41
35static int dccp_v4_get_port(struct sock *sk, const unsigned short snum) 42static int dccp_v4_get_port(struct sock *sk, const unsigned short snum)
36{ 43{
37 return inet_csk_get_port(&dccp_hashinfo, sk, snum, 44 return inet_csk_get_port(&dccp_hashinfo, sk, snum,
@@ -226,11 +233,11 @@ static void dccp_v4_ctl_send_ack(struct sk_buff *rxskb)
226 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), 233 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb),
227 DCCP_SKB_CB(rxskb)->dccpd_seq); 234 DCCP_SKB_CB(rxskb)->dccpd_seq);
228 235
229 bh_lock_sock(dccp_ctl_socket->sk); 236 bh_lock_sock(dccp_v4_ctl_socket->sk);
230 err = ip_build_and_send_pkt(skb, dccp_ctl_socket->sk, 237 err = ip_build_and_send_pkt(skb, dccp_v4_ctl_socket->sk,
231 rxskb->nh.iph->daddr, 238 rxskb->nh.iph->daddr,
232 rxskb->nh.iph->saddr, NULL); 239 rxskb->nh.iph->saddr, NULL);
233 bh_unlock_sock(dccp_ctl_socket->sk); 240 bh_unlock_sock(dccp_v4_ctl_socket->sk);
234 241
235 if (err == NET_XMIT_CN || err == 0) { 242 if (err == NET_XMIT_CN || err == 0) {
236 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS); 243 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
@@ -704,7 +711,7 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
704 if (((struct rtable *)rxskb->dst)->rt_type != RTN_LOCAL) 711 if (((struct rtable *)rxskb->dst)->rt_type != RTN_LOCAL)
705 return; 712 return;
706 713
707 dst = dccp_v4_route_skb(dccp_ctl_socket->sk, rxskb); 714 dst = dccp_v4_route_skb(dccp_v4_ctl_socket->sk, rxskb);
708 if (dst == NULL) 715 if (dst == NULL)
709 return; 716 return;
710 717
@@ -741,11 +748,11 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
741 dh->dccph_checksum = dccp_v4_checksum(skb, rxskb->nh.iph->saddr, 748 dh->dccph_checksum = dccp_v4_checksum(skb, rxskb->nh.iph->saddr,
742 rxskb->nh.iph->daddr); 749 rxskb->nh.iph->daddr);
743 750
744 bh_lock_sock(dccp_ctl_socket->sk); 751 bh_lock_sock(dccp_v4_ctl_socket->sk);
745 err = ip_build_and_send_pkt(skb, dccp_ctl_socket->sk, 752 err = ip_build_and_send_pkt(skb, dccp_v4_ctl_socket->sk,
746 rxskb->nh.iph->daddr, 753 rxskb->nh.iph->daddr,
747 rxskb->nh.iph->saddr, NULL); 754 rxskb->nh.iph->saddr, NULL);
748 bh_unlock_sock(dccp_ctl_socket->sk); 755 bh_unlock_sock(dccp_v4_ctl_socket->sk);
749 756
750 if (err == NET_XMIT_CN || err == 0) { 757 if (err == NET_XMIT_CN || err == 0) {
751 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS); 758 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
@@ -997,10 +1004,15 @@ static struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
997 1004
998static int dccp_v4_init_sock(struct sock *sk) 1005static int dccp_v4_init_sock(struct sock *sk)
999{ 1006{
1000 const int err = dccp_init_sock(sk); 1007 static __u8 dccp_v4_ctl_sock_initialized;
1008 int err = dccp_init_sock(sk, dccp_v4_ctl_sock_initialized);
1001 1009
1002 if (err == 0) 1010 if (err == 0) {
1011 if (unlikely(!dccp_v4_ctl_sock_initialized))
1012 dccp_v4_ctl_sock_initialized = 1;
1003 inet_csk(sk)->icsk_af_ops = &dccp_ipv4_af_ops; 1013 inet_csk(sk)->icsk_af_ops = &dccp_ipv4_af_ops;
1014 }
1015
1004 return err; 1016 return err;
1005} 1017}
1006 1018
@@ -1087,48 +1099,29 @@ static struct inet_protosw dccp_v4_protosw = {
1087 .flags = INET_PROTOSW_ICSK, 1099 .flags = INET_PROTOSW_ICSK,
1088}; 1100};
1089 1101
1090/* 1102static char dccp_v4_ctl_socket_err_msg[] __initdata =
1091 * This is the global socket data structure used for responding to
1092 * the Out-of-the-blue (OOTB) packets. A control sock will be created
1093 * for this socket at the initialization time.
1094 */
1095struct socket *dccp_ctl_socket;
1096
1097static char dccp_ctl_socket_err_msg[] __initdata =
1098 KERN_ERR "DCCP: Failed to create the control socket.\n"; 1103 KERN_ERR "DCCP: Failed to create the control socket.\n";
1099 1104
1100static int __init dccp_ctl_sock_init(void) 1105static int __init dccp_v4_ctl_sock_init(void)
1101{ 1106{
1102 int rc = sock_create_kern(PF_INET, SOCK_DCCP, IPPROTO_DCCP, 1107 int rc = sock_create_kern(PF_INET, SOCK_DCCP, IPPROTO_DCCP,
1103 &dccp_ctl_socket); 1108 &dccp_v4_ctl_socket);
1104 if (rc < 0) 1109 if (rc < 0)
1105 printk(dccp_ctl_socket_err_msg); 1110 printk(dccp_v4_ctl_socket_err_msg);
1106 else { 1111 else {
1107 dccp_ctl_socket->sk->sk_allocation = GFP_ATOMIC; 1112 dccp_v4_ctl_socket->sk->sk_allocation = GFP_ATOMIC;
1108 inet_sk(dccp_ctl_socket->sk)->uc_ttl = -1; 1113 inet_sk(dccp_v4_ctl_socket->sk)->uc_ttl = -1;
1109 1114
1110 /* Unhash it so that IP input processing does not even 1115 /* Unhash it so that IP input processing does not even
1111 * see it, we do not wish this socket to see incoming 1116 * see it, we do not wish this socket to see incoming
1112 * packets. 1117 * packets.
1113 */ 1118 */
1114 dccp_ctl_socket->sk->sk_prot->unhash(dccp_ctl_socket->sk); 1119 dccp_v4_ctl_socket->sk->sk_prot->unhash(dccp_v4_ctl_socket->sk);
1115 } 1120 }
1116 1121
1117 return rc; 1122 return rc;
1118} 1123}
1119 1124
1120#ifdef CONFIG_IP_DCCP_UNLOAD_HACK
1121void dccp_ctl_sock_exit(void)
1122{
1123 if (dccp_ctl_socket != NULL) {
1124 sock_release(dccp_ctl_socket);
1125 dccp_ctl_socket = NULL;
1126 }
1127}
1128
1129EXPORT_SYMBOL_GPL(dccp_ctl_sock_exit);
1130#endif
1131
1132static int __init dccp_v4_init(void) 1125static int __init dccp_v4_init(void)
1133{ 1126{
1134 int err = proto_register(&dccp_v4_prot, 1); 1127 int err = proto_register(&dccp_v4_prot, 1);
@@ -1142,7 +1135,7 @@ static int __init dccp_v4_init(void)
1142 1135
1143 inet_register_protosw(&dccp_v4_protosw); 1136 inet_register_protosw(&dccp_v4_protosw);
1144 1137
1145 err = dccp_ctl_sock_init(); 1138 err = dccp_v4_ctl_sock_init();
1146 if (err) 1139 if (err)
1147 goto out_unregister_protosw; 1140 goto out_unregister_protosw;
1148out: 1141out: