diff options
Diffstat (limited to 'net/dccp/ipv4.c')
-rw-r--r-- | net/dccp/ipv4.c | 140 |
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 | */ |
288 | void dccp_v4_err(struct sk_buff *skb, u32 info) | 290 | static 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 | ||
644 | EXPORT_SYMBOL_GPL(dccp_v4_checksum); | ||
645 | |||
642 | static int dccp_v4_verify_checksum(struct sk_buff *skb, | 646 | static 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) | |||
871 | EXPORT_SYMBOL_GPL(dccp_invalid_packet); | 875 | EXPORT_SYMBOL_GPL(dccp_invalid_packet); |
872 | 876 | ||
873 | /* this is called when real data arrives */ | 877 | /* this is called when real data arrives */ |
874 | int dccp_v4_rcv(struct sk_buff *skb) | 878 | static 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 | ||
981 | struct inet_connection_sock_af_ops dccp_ipv4_af_ops = { | 985 | static 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 | ||
1021 | struct proto dccp_prot = { | 1025 | struct 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 | ||
1047 | EXPORT_SYMBOL_GPL(dccp_prot); | 1051 | static struct net_protocol dccp_v4_protocol = { |
1052 | .handler = dccp_v4_rcv, | ||
1053 | .err_handler = dccp_v4_err, | ||
1054 | .no_policy = 1, | ||
1055 | }; | ||
1056 | |||
1057 | static 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 | |||
1080 | static 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 | */ | ||
1095 | struct socket *dccp_ctl_socket; | ||
1096 | |||
1097 | static char dccp_ctl_socket_err_msg[] __initdata = | ||
1098 | KERN_ERR "DCCP: Failed to create the control socket.\n"; | ||
1099 | |||
1100 | static 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 | ||
1121 | void 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 | |||
1129 | EXPORT_SYMBOL_GPL(dccp_ctl_sock_exit); | ||
1130 | #endif | ||
1131 | |||
1132 | static 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; | ||
1148 | out: | ||
1149 | return err; | ||
1150 | out_unregister_protosw: | ||
1151 | inet_unregister_protosw(&dccp_v4_protosw); | ||
1152 | inet_del_protocol(&dccp_v4_protocol, IPPROTO_DCCP); | ||
1153 | out_proto_unregister: | ||
1154 | proto_unregister(&dccp_v4_prot); | ||
1155 | goto out; | ||
1156 | } | ||
1157 | |||
1158 | static 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 | |||
1165 | module_init(dccp_v4_init); | ||
1166 | module_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 | */ | ||
1173 | MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-33-type-6"); | ||
1174 | MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-0-type-6"); | ||
1175 | MODULE_LICENSE("GPL"); | ||
1176 | MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>"); | ||
1177 | MODULE_DESCRIPTION("DCCP - Datagram Congestion Controlled Protocol"); | ||