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.c73
1 files changed, 34 insertions, 39 deletions
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 9f69a67a4b01..3108c9d464f7 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -46,11 +46,13 @@ static void dccp_v4_hash(struct sock *sk)
46 inet_hash(&dccp_hashinfo, sk); 46 inet_hash(&dccp_hashinfo, sk);
47} 47}
48 48
49static void dccp_v4_unhash(struct sock *sk) 49void dccp_unhash(struct sock *sk)
50{ 50{
51 inet_unhash(&dccp_hashinfo, sk); 51 inet_unhash(&dccp_hashinfo, sk);
52} 52}
53 53
54EXPORT_SYMBOL_GPL(dccp_unhash);
55
54/* called with local bh disabled */ 56/* called with local bh disabled */
55static int __dccp_v4_check_established(struct sock *sk, const __u16 lport, 57static int __dccp_v4_check_established(struct sock *sk, const __u16 lport,
56 struct inet_timewait_sock **twp) 58 struct inet_timewait_sock **twp)
@@ -209,8 +211,7 @@ out:
209 } 211 }
210} 212}
211 213
212static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, 214int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
213 int addr_len)
214{ 215{
215 struct inet_sock *inet = inet_sk(sk); 216 struct inet_sock *inet = inet_sk(sk);
216 struct dccp_sock *dp = dccp_sk(sk); 217 struct dccp_sock *dp = dccp_sk(sk);
@@ -288,16 +289,6 @@ static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
288 usin->sin_port); 289 usin->sin_port);
289 dccp_update_gss(sk, dp->dccps_iss); 290 dccp_update_gss(sk, dp->dccps_iss);
290 291
291 /*
292 * SWL and AWL are initially adjusted so that they are not less than
293 * the initial Sequence Numbers received and sent, respectively:
294 * SWL := max(GSR + 1 - floor(W/4), ISR),
295 * AWL := max(GSS - W' + 1, ISS).
296 * These adjustments MUST be applied only at the beginning of the
297 * connection.
298 */
299 dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss));
300
301 inet->id = dp->dccps_iss ^ jiffies; 292 inet->id = dp->dccps_iss ^ jiffies;
302 293
303 err = dccp_connect(sk); 294 err = dccp_connect(sk);
@@ -317,6 +308,8 @@ failure:
317 goto out; 308 goto out;
318} 309}
319 310
311EXPORT_SYMBOL_GPL(dccp_v4_connect);
312
320/* 313/*
321 * This routine does path mtu discovery as defined in RFC1191. 314 * This routine does path mtu discovery as defined in RFC1191.
322 */ 315 */
@@ -608,7 +601,7 @@ out:
608} 601}
609 602
610/* This routine computes an IPv4 DCCP checksum. */ 603/* This routine computes an IPv4 DCCP checksum. */
611static void dccp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb) 604void dccp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
612{ 605{
613 const struct inet_sock *inet = inet_sk(sk); 606 const struct inet_sock *inet = inet_sk(sk);
614 struct dccp_hdr *dh = dccp_hdr(skb); 607 struct dccp_hdr *dh = dccp_hdr(skb);
@@ -616,6 +609,8 @@ static void dccp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
616 dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr, inet->daddr); 609 dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr, inet->daddr);
617} 610}
618 611
612EXPORT_SYMBOL_GPL(dccp_v4_send_check);
613
619int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code) 614int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code)
620{ 615{
621 struct sk_buff *skb; 616 struct sk_buff *skb;
@@ -651,16 +646,6 @@ static inline u64 dccp_v4_init_sequence(const struct sock *sk,
651 dccp_hdr(skb)->dccph_sport); 646 dccp_hdr(skb)->dccph_sport);
652} 647}
653 648
654static inline int dccp_bad_service_code(const struct sock *sk,
655 const __u32 service)
656{
657 const struct dccp_sock *dp = dccp_sk(sk);
658
659 if (dp->dccps_service == service)
660 return 0;
661 return !dccp_list_has_service(dp->dccps_service_list, service);
662}
663
664int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) 649int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
665{ 650{
666 struct inet_request_sock *ireq; 651 struct inet_request_sock *ireq;
@@ -672,7 +657,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
672 const __u32 service = dccp_hdr_request(skb)->dccph_req_service; 657 const __u32 service = dccp_hdr_request(skb)->dccph_req_service;
673 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); 658 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
674 __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY; 659 __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
675 struct dst_entry *dst = NULL;
676 660
677 /* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */ 661 /* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */
678 if (((struct rtable *)skb->dst)->rt_flags & 662 if (((struct rtable *)skb->dst)->rt_flags &
@@ -713,7 +697,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
713 ireq = inet_rsk(req); 697 ireq = inet_rsk(req);
714 ireq->loc_addr = daddr; 698 ireq->loc_addr = daddr;
715 ireq->rmt_addr = saddr; 699 ireq->rmt_addr = saddr;
716 /* FIXME: Merge Aristeu's option parsing code when ready */
717 req->rcv_wnd = 100; /* Fake, option parsing will get the 700 req->rcv_wnd = 100; /* Fake, option parsing will get the
718 right value */ 701 right value */
719 ireq->opt = NULL; 702 ireq->opt = NULL;
@@ -731,7 +714,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
731 dreq->dreq_iss = dccp_v4_init_sequence(sk, skb); 714 dreq->dreq_iss = dccp_v4_init_sequence(sk, skb);
732 dreq->dreq_service = service; 715 dreq->dreq_service = service;
733 716
734 if (dccp_v4_send_response(sk, req, dst)) 717 if (dccp_v4_send_response(sk, req, NULL))
735 goto drop_and_free; 718 goto drop_and_free;
736 719
737 inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT); 720 inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
@@ -748,6 +731,8 @@ drop:
748 return -1; 731 return -1;
749} 732}
750 733
734EXPORT_SYMBOL_GPL(dccp_v4_conn_request);
735
751/* 736/*
752 * The three way handshake has completed - we got a valid ACK or DATAACK - 737 * The three way handshake has completed - we got a valid ACK or DATAACK -
753 * now create the new socket. 738 * now create the new socket.
@@ -802,6 +787,8 @@ exit:
802 return NULL; 787 return NULL;
803} 788}
804 789
790EXPORT_SYMBOL_GPL(dccp_v4_request_recv_sock);
791
805static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) 792static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
806{ 793{
807 const struct dccp_hdr *dh = dccp_hdr(skb); 794 const struct dccp_hdr *dh = dccp_hdr(skb);
@@ -1021,7 +1008,9 @@ discard:
1021 return 0; 1008 return 0;
1022} 1009}
1023 1010
1024static inline int dccp_invalid_packet(struct sk_buff *skb) 1011EXPORT_SYMBOL_GPL(dccp_v4_do_rcv);
1012
1013int dccp_invalid_packet(struct sk_buff *skb)
1025{ 1014{
1026 const struct dccp_hdr *dh; 1015 const struct dccp_hdr *dh;
1027 1016
@@ -1075,17 +1064,11 @@ static inline int dccp_invalid_packet(struct sk_buff *skb)
1075 return 1; 1064 return 1;
1076 } 1065 }
1077 1066
1078 /* If the header checksum is incorrect, drop packet and return */
1079 if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr,
1080 skb->nh.iph->daddr) < 0) {
1081 LIMIT_NETDEBUG(KERN_WARNING "DCCP: header checksum is "
1082 "incorrect\n");
1083 return 1;
1084 }
1085
1086 return 0; 1067 return 0;
1087} 1068}
1088 1069
1070EXPORT_SYMBOL_GPL(dccp_invalid_packet);
1071
1089/* this is called when real data arrives */ 1072/* this is called when real data arrives */
1090int dccp_v4_rcv(struct sk_buff *skb) 1073int dccp_v4_rcv(struct sk_buff *skb)
1091{ 1074{
@@ -1098,6 +1081,14 @@ int dccp_v4_rcv(struct sk_buff *skb)
1098 if (dccp_invalid_packet(skb)) 1081 if (dccp_invalid_packet(skb))
1099 goto discard_it; 1082 goto discard_it;
1100 1083
1084 /* If the header checksum is incorrect, drop packet and return */
1085 if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr,
1086 skb->nh.iph->daddr) < 0) {
1087 LIMIT_NETDEBUG(KERN_WARNING "%s: incorrect header checksum\n",
1088 __FUNCTION__);
1089 goto discard_it;
1090 }
1091
1101 dh = dccp_hdr(skb); 1092 dh = dccp_hdr(skb);
1102 1093
1103 DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb); 1094 DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb);
@@ -1217,7 +1208,7 @@ struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
1217 .sockaddr_len = sizeof(struct sockaddr_in), 1208 .sockaddr_len = sizeof(struct sockaddr_in),
1218}; 1209};
1219 1210
1220static int dccp_v4_init_sock(struct sock *sk) 1211int dccp_v4_init_sock(struct sock *sk)
1221{ 1212{
1222 struct dccp_sock *dp = dccp_sk(sk); 1213 struct dccp_sock *dp = dccp_sk(sk);
1223 static int dccp_ctl_socket_init = 1; 1214 static int dccp_ctl_socket_init = 1;
@@ -1270,7 +1261,9 @@ static int dccp_v4_init_sock(struct sock *sk)
1270 return 0; 1261 return 0;
1271} 1262}
1272 1263
1273static int dccp_v4_destroy_sock(struct sock *sk) 1264EXPORT_SYMBOL_GPL(dccp_v4_init_sock);
1265
1266int dccp_v4_destroy_sock(struct sock *sk)
1274{ 1267{
1275 struct dccp_sock *dp = dccp_sk(sk); 1268 struct dccp_sock *dp = dccp_sk(sk);
1276 1269
@@ -1303,6 +1296,8 @@ static int dccp_v4_destroy_sock(struct sock *sk)
1303 return 0; 1296 return 0;
1304} 1297}
1305 1298
1299EXPORT_SYMBOL_GPL(dccp_v4_destroy_sock);
1300
1306static void dccp_v4_reqsk_destructor(struct request_sock *req) 1301static void dccp_v4_reqsk_destructor(struct request_sock *req)
1307{ 1302{
1308 kfree(inet_rsk(req)->opt); 1303 kfree(inet_rsk(req)->opt);
@@ -1331,7 +1326,7 @@ struct proto dccp_prot = {
1331 .recvmsg = dccp_recvmsg, 1326 .recvmsg = dccp_recvmsg,
1332 .backlog_rcv = dccp_v4_do_rcv, 1327 .backlog_rcv = dccp_v4_do_rcv,
1333 .hash = dccp_v4_hash, 1328 .hash = dccp_v4_hash,
1334 .unhash = dccp_v4_unhash, 1329 .unhash = dccp_unhash,
1335 .accept = inet_csk_accept, 1330 .accept = inet_csk_accept,
1336 .get_port = dccp_v4_get_port, 1331 .get_port = dccp_v4_get_port,
1337 .shutdown = dccp_shutdown, 1332 .shutdown = dccp_shutdown,