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.c79
1 files changed, 48 insertions, 31 deletions
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index b33704415555..b348dd70c685 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -32,11 +32,10 @@
32#include "feat.h" 32#include "feat.h"
33 33
34/* 34/*
35 * This is the global socket data structure used for responding to 35 * The per-net dccp.v4_ctl_sk socket is used for responding to
36 * the Out-of-the-blue (OOTB) packets. A control sock will be created 36 * the Out-of-the-blue (OOTB) packets. A control sock will be created
37 * for this socket at the initialization time. 37 * for this socket at the initialization time.
38 */ 38 */
39static struct socket *dccp_v4_ctl_socket;
40 39
41int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) 40int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
42{ 41{
@@ -212,8 +211,9 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
212 return; 211 return;
213 } 212 }
214 213
215 sk = inet_lookup(&init_net, &dccp_hashinfo, iph->daddr, dh->dccph_dport, 214 sk = inet_lookup(dev_net(skb->dev), &dccp_hashinfo,
216 iph->saddr, dh->dccph_sport, inet_iif(skb)); 215 iph->daddr, dh->dccph_dport,
216 iph->saddr, dh->dccph_sport, inet_iif(skb));
217 if (sk == NULL) { 217 if (sk == NULL) {
218 ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); 218 ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
219 return; 219 return;
@@ -430,7 +430,7 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
430 if (req != NULL) 430 if (req != NULL)
431 return dccp_check_req(sk, skb, req, prev); 431 return dccp_check_req(sk, skb, req, prev);
432 432
433 nsk = inet_lookup_established(&init_net, &dccp_hashinfo, 433 nsk = inet_lookup_established(sock_net(sk), &dccp_hashinfo,
434 iph->saddr, dh->dccph_sport, 434 iph->saddr, dh->dccph_sport,
435 iph->daddr, dh->dccph_dport, 435 iph->daddr, dh->dccph_dport,
436 inet_iif(skb)); 436 inet_iif(skb));
@@ -446,11 +446,11 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
446 return sk; 446 return sk;
447} 447}
448 448
449static struct dst_entry* dccp_v4_route_skb(struct sock *sk, 449static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
450 struct sk_buff *skb) 450 struct sk_buff *skb)
451{ 451{
452 struct rtable *rt; 452 struct rtable *rt;
453 struct flowi fl = { .oif = ((struct rtable *)skb->dst)->rt_iif, 453 struct flowi fl = { .oif = skb->rtable->rt_iif,
454 .nl_u = { .ip4_u = 454 .nl_u = { .ip4_u =
455 { .daddr = ip_hdr(skb)->saddr, 455 { .daddr = ip_hdr(skb)->saddr,
456 .saddr = ip_hdr(skb)->daddr, 456 .saddr = ip_hdr(skb)->daddr,
@@ -463,7 +463,7 @@ static struct dst_entry* dccp_v4_route_skb(struct sock *sk,
463 }; 463 };
464 464
465 security_skb_classify_flow(skb, &fl); 465 security_skb_classify_flow(skb, &fl);
466 if (ip_route_output_flow(&init_net, &rt, &fl, sk, 0)) { 466 if (ip_route_output_flow(net, &rt, &fl, sk, 0)) {
467 IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); 467 IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES);
468 return NULL; 468 return NULL;
469 } 469 }
@@ -471,15 +471,14 @@ static struct dst_entry* dccp_v4_route_skb(struct sock *sk,
471 return &rt->u.dst; 471 return &rt->u.dst;
472} 472}
473 473
474static int dccp_v4_send_response(struct sock *sk, struct request_sock *req, 474static int dccp_v4_send_response(struct sock *sk, struct request_sock *req)
475 struct dst_entry *dst)
476{ 475{
477 int err = -1; 476 int err = -1;
478 struct sk_buff *skb; 477 struct sk_buff *skb;
478 struct dst_entry *dst;
479 479
480 /* First, grab a route. */ 480 dst = inet_csk_route_req(sk, req);
481 481 if (dst == NULL)
482 if (dst == NULL && (dst = inet_csk_route_req(sk, req)) == NULL)
483 goto out; 482 goto out;
484 483
485 skb = dccp_make_response(sk, dst, req); 484 skb = dccp_make_response(sk, dst, req);
@@ -506,19 +505,21 @@ static void dccp_v4_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
506 const struct iphdr *rxiph; 505 const struct iphdr *rxiph;
507 struct sk_buff *skb; 506 struct sk_buff *skb;
508 struct dst_entry *dst; 507 struct dst_entry *dst;
508 struct net *net = dev_net(rxskb->dst->dev);
509 struct sock *ctl_sk = net->dccp.v4_ctl_sk;
509 510
510 /* Never send a reset in response to a reset. */ 511 /* Never send a reset in response to a reset. */
511 if (dccp_hdr(rxskb)->dccph_type == DCCP_PKT_RESET) 512 if (dccp_hdr(rxskb)->dccph_type == DCCP_PKT_RESET)
512 return; 513 return;
513 514
514 if (((struct rtable *)rxskb->dst)->rt_type != RTN_LOCAL) 515 if (rxskb->rtable->rt_type != RTN_LOCAL)
515 return; 516 return;
516 517
517 dst = dccp_v4_route_skb(dccp_v4_ctl_socket->sk, rxskb); 518 dst = dccp_v4_route_skb(net, ctl_sk, rxskb);
518 if (dst == NULL) 519 if (dst == NULL)
519 return; 520 return;
520 521
521 skb = dccp_ctl_make_reset(dccp_v4_ctl_socket, rxskb); 522 skb = dccp_ctl_make_reset(ctl_sk, rxskb);
522 if (skb == NULL) 523 if (skb == NULL)
523 goto out; 524 goto out;
524 525
@@ -527,10 +528,10 @@ static void dccp_v4_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
527 rxiph->daddr); 528 rxiph->daddr);
528 skb->dst = dst_clone(dst); 529 skb->dst = dst_clone(dst);
529 530
530 bh_lock_sock(dccp_v4_ctl_socket->sk); 531 bh_lock_sock(ctl_sk);
531 err = ip_build_and_send_pkt(skb, dccp_v4_ctl_socket->sk, 532 err = ip_build_and_send_pkt(skb, ctl_sk,
532 rxiph->daddr, rxiph->saddr, NULL); 533 rxiph->daddr, rxiph->saddr, NULL);
533 bh_unlock_sock(dccp_v4_ctl_socket->sk); 534 bh_unlock_sock(ctl_sk);
534 535
535 if (net_xmit_eval(err) == 0) { 536 if (net_xmit_eval(err) == 0) {
536 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS); 537 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
@@ -563,8 +564,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
563 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); 564 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
564 565
565 /* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */ 566 /* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */
566 if (((struct rtable *)skb->dst)->rt_flags & 567 if (skb->rtable->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
567 (RTCF_BROADCAST | RTCF_MULTICAST))
568 return 0; /* discard, don't send a reset here */ 568 return 0; /* discard, don't send a reset here */
569 569
570 if (dccp_bad_service_code(sk, service)) { 570 if (dccp_bad_service_code(sk, service)) {
@@ -619,7 +619,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
619 dreq->dreq_iss = dccp_v4_init_sequence(skb); 619 dreq->dreq_iss = dccp_v4_init_sequence(skb);
620 dreq->dreq_service = service; 620 dreq->dreq_service = service;
621 621
622 if (dccp_v4_send_response(sk, req, NULL)) 622 if (dccp_v4_send_response(sk, req))
623 goto drop_and_free; 623 goto drop_and_free;
624 624
625 inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT); 625 inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
@@ -810,7 +810,7 @@ static int dccp_v4_rcv(struct sk_buff *skb)
810 810
811 /* Step 2: 811 /* Step 2:
812 * Look up flow ID in table and get corresponding socket */ 812 * Look up flow ID in table and get corresponding socket */
813 sk = __inet_lookup(&init_net, &dccp_hashinfo, 813 sk = __inet_lookup(dev_net(skb->dst->dev), &dccp_hashinfo,
814 iph->saddr, dh->dccph_sport, 814 iph->saddr, dh->dccph_sport,
815 iph->daddr, dh->dccph_dport, inet_iif(skb)); 815 iph->daddr, dh->dccph_dport, inet_iif(skb));
816 /* 816 /*
@@ -916,8 +916,6 @@ static struct timewait_sock_ops dccp_timewait_sock_ops = {
916 .twsk_obj_size = sizeof(struct inet_timewait_sock), 916 .twsk_obj_size = sizeof(struct inet_timewait_sock),
917}; 917};
918 918
919DEFINE_PROTO_INUSE(dccp_v4)
920
921static struct proto dccp_v4_prot = { 919static struct proto dccp_v4_prot = {
922 .name = "DCCP", 920 .name = "DCCP",
923 .owner = THIS_MODULE, 921 .owner = THIS_MODULE,
@@ -942,18 +940,18 @@ static struct proto dccp_v4_prot = {
942 .obj_size = sizeof(struct dccp_sock), 940 .obj_size = sizeof(struct dccp_sock),
943 .rsk_prot = &dccp_request_sock_ops, 941 .rsk_prot = &dccp_request_sock_ops,
944 .twsk_prot = &dccp_timewait_sock_ops, 942 .twsk_prot = &dccp_timewait_sock_ops,
945 .hashinfo = &dccp_hashinfo, 943 .h.hashinfo = &dccp_hashinfo,
946#ifdef CONFIG_COMPAT 944#ifdef CONFIG_COMPAT
947 .compat_setsockopt = compat_dccp_setsockopt, 945 .compat_setsockopt = compat_dccp_setsockopt,
948 .compat_getsockopt = compat_dccp_getsockopt, 946 .compat_getsockopt = compat_dccp_getsockopt,
949#endif 947#endif
950 REF_PROTO_INUSE(dccp_v4)
951}; 948};
952 949
953static struct net_protocol dccp_v4_protocol = { 950static struct net_protocol dccp_v4_protocol = {
954 .handler = dccp_v4_rcv, 951 .handler = dccp_v4_rcv,
955 .err_handler = dccp_v4_err, 952 .err_handler = dccp_v4_err,
956 .no_policy = 1, 953 .no_policy = 1,
954 .netns_ok = 1,
957}; 955};
958 956
959static const struct proto_ops inet_dccp_ops = { 957static const struct proto_ops inet_dccp_ops = {
@@ -993,6 +991,25 @@ static struct inet_protosw dccp_v4_protosw = {
993 .flags = INET_PROTOSW_ICSK, 991 .flags = INET_PROTOSW_ICSK,
994}; 992};
995 993
994static int dccp_v4_init_net(struct net *net)
995{
996 int err;
997
998 err = inet_ctl_sock_create(&net->dccp.v4_ctl_sk, PF_INET,
999 SOCK_DCCP, IPPROTO_DCCP, net);
1000 return err;
1001}
1002
1003static void dccp_v4_exit_net(struct net *net)
1004{
1005 inet_ctl_sock_destroy(net->dccp.v4_ctl_sk);
1006}
1007
1008static struct pernet_operations dccp_v4_ops = {
1009 .init = dccp_v4_init_net,
1010 .exit = dccp_v4_exit_net,
1011};
1012
996static int __init dccp_v4_init(void) 1013static int __init dccp_v4_init(void)
997{ 1014{
998 int err = proto_register(&dccp_v4_prot, 1); 1015 int err = proto_register(&dccp_v4_prot, 1);
@@ -1006,13 +1023,12 @@ static int __init dccp_v4_init(void)
1006 1023
1007 inet_register_protosw(&dccp_v4_protosw); 1024 inet_register_protosw(&dccp_v4_protosw);
1008 1025
1009 err = inet_csk_ctl_sock_create(&dccp_v4_ctl_socket, PF_INET, 1026 err = register_pernet_subsys(&dccp_v4_ops);
1010 SOCK_DCCP, IPPROTO_DCCP);
1011 if (err) 1027 if (err)
1012 goto out_unregister_protosw; 1028 goto out_destroy_ctl_sock;
1013out: 1029out:
1014 return err; 1030 return err;
1015out_unregister_protosw: 1031out_destroy_ctl_sock:
1016 inet_unregister_protosw(&dccp_v4_protosw); 1032 inet_unregister_protosw(&dccp_v4_protosw);
1017 inet_del_protocol(&dccp_v4_protocol, IPPROTO_DCCP); 1033 inet_del_protocol(&dccp_v4_protocol, IPPROTO_DCCP);
1018out_proto_unregister: 1034out_proto_unregister:
@@ -1022,6 +1038,7 @@ out_proto_unregister:
1022 1038
1023static void __exit dccp_v4_exit(void) 1039static void __exit dccp_v4_exit(void)
1024{ 1040{
1041 unregister_pernet_subsys(&dccp_v4_ops);
1025 inet_unregister_protosw(&dccp_v4_protosw); 1042 inet_unregister_protosw(&dccp_v4_protosw);
1026 inet_del_protocol(&dccp_v4_protocol, IPPROTO_DCCP); 1043 inet_del_protocol(&dccp_v4_protocol, IPPROTO_DCCP);
1027 proto_unregister(&dccp_v4_prot); 1044 proto_unregister(&dccp_v4_prot);