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.c140
1 files changed, 135 insertions, 5 deletions
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index a7332f0f85c4..033c3ab8fe33 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -18,8 +18,10 @@
18#include <linux/random.h> 18#include <linux/random.h>
19 19
20#include <net/icmp.h> 20#include <net/icmp.h>
21#include <net/inet_common.h>
21#include <net/inet_hashtables.h> 22#include <net/inet_hashtables.h>
22#include <net/inet_sock.h> 23#include <net/inet_sock.h>
24#include <net/protocol.h>
23#include <net/sock.h> 25#include <net/sock.h>
24#include <net/timewait_sock.h> 26#include <net/timewait_sock.h>
25#include <net/tcp_states.h> 27#include <net/tcp_states.h>
@@ -285,7 +287,7 @@ out:
285 * check at all. A more general error queue to queue errors for later handling 287 * check at all. A more general error queue to queue errors for later handling
286 * is probably better. 288 * is probably better.
287 */ 289 */
288void dccp_v4_err(struct sk_buff *skb, u32 info) 290static void dccp_v4_err(struct sk_buff *skb, u32 info)
289{ 291{
290 const struct iphdr *iph = (struct iphdr *)skb->data; 292 const struct iphdr *iph = (struct iphdr *)skb->data;
291 const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + 293 const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data +
@@ -639,6 +641,8 @@ int dccp_v4_checksum(const struct sk_buff *skb, const __be32 saddr,
639 IPPROTO_DCCP, tmp); 641 IPPROTO_DCCP, tmp);
640} 642}
641 643
644EXPORT_SYMBOL_GPL(dccp_v4_checksum);
645
642static int dccp_v4_verify_checksum(struct sk_buff *skb, 646static int dccp_v4_verify_checksum(struct sk_buff *skb,
643 const __be32 saddr, const __be32 daddr) 647 const __be32 saddr, const __be32 daddr)
644{ 648{
@@ -871,7 +875,7 @@ int dccp_invalid_packet(struct sk_buff *skb)
871EXPORT_SYMBOL_GPL(dccp_invalid_packet); 875EXPORT_SYMBOL_GPL(dccp_invalid_packet);
872 876
873/* this is called when real data arrives */ 877/* this is called when real data arrives */
874int dccp_v4_rcv(struct sk_buff *skb) 878static int dccp_v4_rcv(struct sk_buff *skb)
875{ 879{
876 const struct dccp_hdr *dh; 880 const struct dccp_hdr *dh;
877 struct sock *sk; 881 struct sock *sk;
@@ -978,7 +982,7 @@ do_time_wait:
978 goto no_dccp_socket; 982 goto no_dccp_socket;
979} 983}
980 984
981struct inet_connection_sock_af_ops dccp_ipv4_af_ops = { 985static struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
982 .queue_xmit = ip_queue_xmit, 986 .queue_xmit = ip_queue_xmit,
983 .send_check = dccp_v4_send_check, 987 .send_check = dccp_v4_send_check,
984 .rebuild_header = inet_sk_rebuild_header, 988 .rebuild_header = inet_sk_rebuild_header,
@@ -1018,7 +1022,7 @@ static struct timewait_sock_ops dccp_timewait_sock_ops = {
1018 .twsk_obj_size = sizeof(struct inet_timewait_sock), 1022 .twsk_obj_size = sizeof(struct inet_timewait_sock),
1019}; 1023};
1020 1024
1021struct proto dccp_prot = { 1025struct proto dccp_v4_prot = {
1022 .name = "DCCP", 1026 .name = "DCCP",
1023 .owner = THIS_MODULE, 1027 .owner = THIS_MODULE,
1024 .close = dccp_close, 1028 .close = dccp_close,
@@ -1044,4 +1048,130 @@ struct proto dccp_prot = {
1044 .twsk_prot = &dccp_timewait_sock_ops, 1048 .twsk_prot = &dccp_timewait_sock_ops,
1045}; 1049};
1046 1050
1047EXPORT_SYMBOL_GPL(dccp_prot); 1051static struct net_protocol dccp_v4_protocol = {
1052 .handler = dccp_v4_rcv,
1053 .err_handler = dccp_v4_err,
1054 .no_policy = 1,
1055};
1056
1057static const struct proto_ops inet_dccp_ops = {
1058 .family = PF_INET,
1059 .owner = THIS_MODULE,
1060 .release = inet_release,
1061 .bind = inet_bind,
1062 .connect = inet_stream_connect,
1063 .socketpair = sock_no_socketpair,
1064 .accept = inet_accept,
1065 .getname = inet_getname,
1066 /* FIXME: work on tcp_poll to rename it to inet_csk_poll */
1067 .poll = dccp_poll,
1068 .ioctl = inet_ioctl,
1069 /* FIXME: work on inet_listen to rename it to sock_common_listen */
1070 .listen = inet_dccp_listen,
1071 .shutdown = inet_shutdown,
1072 .setsockopt = sock_common_setsockopt,
1073 .getsockopt = sock_common_getsockopt,
1074 .sendmsg = inet_sendmsg,
1075 .recvmsg = sock_common_recvmsg,
1076 .mmap = sock_no_mmap,
1077 .sendpage = sock_no_sendpage,
1078};
1079
1080static struct inet_protosw dccp_v4_protosw = {
1081 .type = SOCK_DCCP,
1082 .protocol = IPPROTO_DCCP,
1083 .prot = &dccp_v4_prot,
1084 .ops = &inet_dccp_ops,
1085 .capability = -1,
1086 .no_check = 0,
1087 .flags = INET_PROTOSW_ICSK,
1088};
1089
1090/*
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";
1099
1100static int __init dccp_ctl_sock_init(void)
1101{
1102 int rc = sock_create_kern(PF_INET, SOCK_DCCP, IPPROTO_DCCP,
1103 &dccp_ctl_socket);
1104 if (rc < 0)
1105 printk(dccp_ctl_socket_err_msg);
1106 else {
1107 dccp_ctl_socket->sk->sk_allocation = GFP_ATOMIC;
1108 inet_sk(dccp_ctl_socket->sk)->uc_ttl = -1;
1109
1110 /* Unhash it so that IP input processing does not even
1111 * see it, we do not wish this socket to see incoming
1112 * packets.
1113 */
1114 dccp_ctl_socket->sk->sk_prot->unhash(dccp_ctl_socket->sk);
1115 }
1116
1117 return rc;
1118}
1119
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)
1133{
1134 int err = proto_register(&dccp_v4_prot, 1);
1135
1136 if (err != 0)
1137 goto out;
1138
1139 err = inet_add_protocol(&dccp_v4_protocol, IPPROTO_DCCP);
1140 if (err != 0)
1141 goto out_proto_unregister;
1142
1143 inet_register_protosw(&dccp_v4_protosw);
1144
1145 err = dccp_ctl_sock_init();
1146 if (err)
1147 goto out_unregister_protosw;
1148out:
1149 return err;
1150out_unregister_protosw:
1151 inet_unregister_protosw(&dccp_v4_protosw);
1152 inet_del_protocol(&dccp_v4_protocol, IPPROTO_DCCP);
1153out_proto_unregister:
1154 proto_unregister(&dccp_v4_prot);
1155 goto out;
1156}
1157
1158static void __exit dccp_v4_exit(void)
1159{
1160 inet_unregister_protosw(&dccp_v4_protosw);
1161 inet_del_protocol(&dccp_v4_protocol, IPPROTO_DCCP);
1162 proto_unregister(&dccp_v4_prot);
1163}
1164
1165module_init(dccp_v4_init);
1166module_exit(dccp_v4_exit);
1167
1168/*
1169 * __stringify doesn't likes enums, so use SOCK_DCCP (6) and IPPROTO_DCCP (33)
1170 * values directly, Also cover the case where the protocol is not specified,
1171 * i.e. net-pf-PF_INET-proto-0-type-SOCK_DCCP
1172 */
1173MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-33-type-6");
1174MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-0-type-6");
1175MODULE_LICENSE("GPL");
1176MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
1177MODULE_DESCRIPTION("DCCP - Datagram Congestion Controlled Protocol");