16
16
#include <linux/skbuff.h>
17
17
#include <linux/dccp.h>
18
18
19
+ #include <net/net_namespace.h>
20
+ #include <net/netns/generic.h>
21
+
19
22
#include <linux/netfilter/nfnetlink_conntrack.h>
20
23
#include <net/netfilter/nf_conntrack.h>
21
24
#include <net/netfilter/nf_conntrack_l4proto.h>
22
25
#include <net/netfilter/nf_log.h>
23
26
24
27
static DEFINE_RWLOCK (dccp_lock );
25
28
26
- static int nf_ct_dccp_loose __read_mostly = 1 ;
27
-
28
29
/* Timeouts are based on values from RFC4340:
29
30
*
30
31
* - REQUEST:
@@ -72,16 +73,6 @@ static int nf_ct_dccp_loose __read_mostly = 1;
72
73
73
74
#define DCCP_MSL (2 * 60 * HZ)
74
75
75
- static unsigned int dccp_timeout [CT_DCCP_MAX + 1 ] __read_mostly = {
76
- [CT_DCCP_REQUEST ] = 2 * DCCP_MSL ,
77
- [CT_DCCP_RESPOND ] = 4 * DCCP_MSL ,
78
- [CT_DCCP_PARTOPEN ] = 4 * DCCP_MSL ,
79
- [CT_DCCP_OPEN ] = 12 * 3600 * HZ ,
80
- [CT_DCCP_CLOSEREQ ] = 64 * HZ ,
81
- [CT_DCCP_CLOSING ] = 64 * HZ ,
82
- [CT_DCCP_TIMEWAIT ] = 2 * DCCP_MSL ,
83
- };
84
-
85
76
static const char * const dccp_state_names [] = {
86
77
[CT_DCCP_NONE ] = "NONE" ,
87
78
[CT_DCCP_REQUEST ] = "REQUEST" ,
@@ -393,6 +384,22 @@ dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] =
393
384
},
394
385
};
395
386
387
+ /* this module per-net specifics */
388
+ static int dccp_net_id ;
389
+ struct dccp_net {
390
+ int dccp_loose ;
391
+ unsigned int dccp_timeout [CT_DCCP_MAX + 1 ];
392
+ #ifdef CONFIG_SYSCTL
393
+ struct ctl_table_header * sysctl_header ;
394
+ struct ctl_table * sysctl_table ;
395
+ #endif
396
+ };
397
+
398
+ static inline struct dccp_net * dccp_pernet (struct net * net )
399
+ {
400
+ return net_generic (net , dccp_net_id );
401
+ }
402
+
396
403
static bool dccp_pkt_to_tuple (const struct sk_buff * skb , unsigned int dataoff ,
397
404
struct nf_conntrack_tuple * tuple )
398
405
{
@@ -419,6 +426,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
419
426
unsigned int dataoff )
420
427
{
421
428
struct net * net = nf_ct_net (ct );
429
+ struct dccp_net * dn ;
422
430
struct dccp_hdr _dh , * dh ;
423
431
const char * msg ;
424
432
u_int8_t state ;
@@ -429,7 +437,8 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
429
437
state = dccp_state_table [CT_DCCP_ROLE_CLIENT ][dh -> dccph_type ][CT_DCCP_NONE ];
430
438
switch (state ) {
431
439
default :
432
- if (nf_ct_dccp_loose == 0 ) {
440
+ dn = dccp_pernet (net );
441
+ if (dn -> dccp_loose == 0 ) {
433
442
msg = "nf_ct_dccp: not picking up existing connection " ;
434
443
goto out_invalid ;
435
444
}
@@ -465,6 +474,7 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
465
474
u_int8_t pf , unsigned int hooknum )
466
475
{
467
476
struct net * net = nf_ct_net (ct );
477
+ struct dccp_net * dn ;
468
478
enum ip_conntrack_dir dir = CTINFO2DIR (ctinfo );
469
479
struct dccp_hdr _dh , * dh ;
470
480
u_int8_t type , old_state , new_state ;
@@ -542,7 +552,9 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
542
552
ct -> proto .dccp .last_pkt = type ;
543
553
ct -> proto .dccp .state = new_state ;
544
554
write_unlock_bh (& dccp_lock );
545
- nf_ct_refresh_acct (ct , ctinfo , skb , dccp_timeout [new_state ]);
555
+
556
+ dn = dccp_pernet (net );
557
+ nf_ct_refresh_acct (ct , ctinfo , skb , dn -> dccp_timeout [new_state ]);
546
558
547
559
return NF_ACCEPT ;
548
560
}
@@ -660,70 +672,61 @@ static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
660
672
#endif
661
673
662
674
#ifdef CONFIG_SYSCTL
663
- static unsigned int dccp_sysctl_table_users ;
664
- static struct ctl_table_header * dccp_sysctl_header ;
665
- static ctl_table dccp_sysctl_table [] = {
675
+ /* template, data assigned later */
676
+ static struct ctl_table dccp_sysctl_table [] = {
666
677
{
667
678
.ctl_name = CTL_UNNUMBERED ,
668
679
.procname = "nf_conntrack_dccp_timeout_request" ,
669
- .data = & dccp_timeout [CT_DCCP_REQUEST ],
670
680
.maxlen = sizeof (unsigned int ),
671
681
.mode = 0644 ,
672
682
.proc_handler = proc_dointvec_jiffies ,
673
683
},
674
684
{
675
685
.ctl_name = CTL_UNNUMBERED ,
676
686
.procname = "nf_conntrack_dccp_timeout_respond" ,
677
- .data = & dccp_timeout [CT_DCCP_RESPOND ],
678
687
.maxlen = sizeof (unsigned int ),
679
688
.mode = 0644 ,
680
689
.proc_handler = proc_dointvec_jiffies ,
681
690
},
682
691
{
683
692
.ctl_name = CTL_UNNUMBERED ,
684
693
.procname = "nf_conntrack_dccp_timeout_partopen" ,
685
- .data = & dccp_timeout [CT_DCCP_PARTOPEN ],
686
694
.maxlen = sizeof (unsigned int ),
687
695
.mode = 0644 ,
688
696
.proc_handler = proc_dointvec_jiffies ,
689
697
},
690
698
{
691
699
.ctl_name = CTL_UNNUMBERED ,
692
700
.procname = "nf_conntrack_dccp_timeout_open" ,
693
- .data = & dccp_timeout [CT_DCCP_OPEN ],
694
701
.maxlen = sizeof (unsigned int ),
695
702
.mode = 0644 ,
696
703
.proc_handler = proc_dointvec_jiffies ,
697
704
},
698
705
{
699
706
.ctl_name = CTL_UNNUMBERED ,
700
707
.procname = "nf_conntrack_dccp_timeout_closereq" ,
701
- .data = & dccp_timeout [CT_DCCP_CLOSEREQ ],
702
708
.maxlen = sizeof (unsigned int ),
703
709
.mode = 0644 ,
704
710
.proc_handler = proc_dointvec_jiffies ,
705
711
},
706
712
{
707
713
.ctl_name = CTL_UNNUMBERED ,
708
714
.procname = "nf_conntrack_dccp_timeout_closing" ,
709
- .data = & dccp_timeout [CT_DCCP_CLOSING ],
710
715
.maxlen = sizeof (unsigned int ),
711
716
.mode = 0644 ,
712
717
.proc_handler = proc_dointvec_jiffies ,
713
718
},
714
719
{
715
720
.ctl_name = CTL_UNNUMBERED ,
716
721
.procname = "nf_conntrack_dccp_timeout_timewait" ,
717
- .data = & dccp_timeout [CT_DCCP_TIMEWAIT ],
718
722
.maxlen = sizeof (unsigned int ),
719
723
.mode = 0644 ,
720
724
.proc_handler = proc_dointvec_jiffies ,
721
725
},
722
726
{
723
727
.ctl_name = CTL_UNNUMBERED ,
724
728
.procname = "nf_conntrack_dccp_loose" ,
725
- .data = & nf_ct_dccp_loose ,
726
- .maxlen = sizeof (nf_ct_dccp_loose ),
729
+ .maxlen = sizeof (int ),
727
730
.mode = 0644 ,
728
731
.proc_handler = proc_dointvec ,
729
732
},
@@ -751,11 +754,6 @@ static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = {
751
754
.nlattr_to_tuple = nf_ct_port_nlattr_to_tuple ,
752
755
.nla_policy = nf_ct_port_nla_policy ,
753
756
#endif
754
- #ifdef CONFIG_SYSCTL
755
- .ctl_table_users = & dccp_sysctl_table_users ,
756
- .ctl_table_header = & dccp_sysctl_header ,
757
- .ctl_table = dccp_sysctl_table ,
758
- #endif
759
757
};
760
758
761
759
static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = {
@@ -776,34 +774,107 @@ static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = {
776
774
.nlattr_to_tuple = nf_ct_port_nlattr_to_tuple ,
777
775
.nla_policy = nf_ct_port_nla_policy ,
778
776
#endif
777
+ };
778
+
779
+ static __net_init int dccp_net_init (struct net * net )
780
+ {
781
+ struct dccp_net * dn ;
782
+ int err ;
783
+
784
+ dn = kmalloc (sizeof (* dn ), GFP_KERNEL );
785
+ if (!dn )
786
+ return - ENOMEM ;
787
+
788
+ /* default values */
789
+ dn -> dccp_loose = 1 ;
790
+ dn -> dccp_timeout [CT_DCCP_REQUEST ] = 2 * DCCP_MSL ;
791
+ dn -> dccp_timeout [CT_DCCP_RESPOND ] = 4 * DCCP_MSL ;
792
+ dn -> dccp_timeout [CT_DCCP_PARTOPEN ] = 4 * DCCP_MSL ;
793
+ dn -> dccp_timeout [CT_DCCP_OPEN ] = 12 * 3600 * HZ ;
794
+ dn -> dccp_timeout [CT_DCCP_CLOSEREQ ] = 64 * HZ ;
795
+ dn -> dccp_timeout [CT_DCCP_CLOSING ] = 64 * HZ ;
796
+ dn -> dccp_timeout [CT_DCCP_TIMEWAIT ] = 2 * DCCP_MSL ;
797
+
798
+ err = net_assign_generic (net , dccp_net_id , dn );
799
+ if (err )
800
+ goto out ;
801
+
779
802
#ifdef CONFIG_SYSCTL
780
- .ctl_table_users = & dccp_sysctl_table_users ,
781
- .ctl_table_header = & dccp_sysctl_header ,
782
- .ctl_table = dccp_sysctl_table ,
803
+ err = - ENOMEM ;
804
+ dn -> sysctl_table = kmemdup (dccp_sysctl_table ,
805
+ sizeof (dccp_sysctl_table ), GFP_KERNEL );
806
+ if (!dn -> sysctl_table )
807
+ goto out ;
808
+
809
+ dn -> sysctl_table [0 ].data = & dn -> dccp_timeout [CT_DCCP_REQUEST ];
810
+ dn -> sysctl_table [1 ].data = & dn -> dccp_timeout [CT_DCCP_RESPOND ];
811
+ dn -> sysctl_table [2 ].data = & dn -> dccp_timeout [CT_DCCP_PARTOPEN ];
812
+ dn -> sysctl_table [3 ].data = & dn -> dccp_timeout [CT_DCCP_OPEN ];
813
+ dn -> sysctl_table [4 ].data = & dn -> dccp_timeout [CT_DCCP_CLOSEREQ ];
814
+ dn -> sysctl_table [5 ].data = & dn -> dccp_timeout [CT_DCCP_CLOSING ];
815
+ dn -> sysctl_table [6 ].data = & dn -> dccp_timeout [CT_DCCP_TIMEWAIT ];
816
+ dn -> sysctl_table [7 ].data = & dn -> dccp_loose ;
817
+
818
+ dn -> sysctl_header = register_net_sysctl_table (net ,
819
+ nf_net_netfilter_sysctl_path , dn -> sysctl_table );
820
+ if (!dn -> sysctl_header ) {
821
+ kfree (dn -> sysctl_table );
822
+ goto out ;
823
+ }
783
824
#endif
825
+
826
+ return 0 ;
827
+
828
+ out :
829
+ kfree (dn );
830
+ return err ;
831
+ }
832
+
833
+ static __net_exit void dccp_net_exit (struct net * net )
834
+ {
835
+ struct dccp_net * dn = dccp_pernet (net );
836
+ #ifdef CONFIG_SYSCTL
837
+ unregister_net_sysctl_table (dn -> sysctl_header );
838
+ kfree (dn -> sysctl_table );
839
+ #endif
840
+ kfree (dn );
841
+
842
+ net_assign_generic (net , dccp_net_id , NULL );
843
+ }
844
+
845
+ static struct pernet_operations dccp_net_ops = {
846
+ .init = dccp_net_init ,
847
+ .exit = dccp_net_exit ,
784
848
};
785
849
786
850
static int __init nf_conntrack_proto_dccp_init (void )
787
851
{
788
852
int err ;
789
853
790
- err = nf_conntrack_l4proto_register ( & dccp_proto4 );
854
+ err = register_pernet_gen_subsys ( & dccp_net_id , & dccp_net_ops );
791
855
if (err < 0 )
792
856
goto err1 ;
793
857
794
- err = nf_conntrack_l4proto_register (& dccp_proto6 );
858
+ err = nf_conntrack_l4proto_register (& dccp_proto4 );
795
859
if (err < 0 )
796
860
goto err2 ;
861
+
862
+ err = nf_conntrack_l4proto_register (& dccp_proto6 );
863
+ if (err < 0 )
864
+ goto err3 ;
797
865
return 0 ;
798
866
799
- err2 :
867
+ err3 :
800
868
nf_conntrack_l4proto_unregister (& dccp_proto4 );
869
+ err2 :
870
+ unregister_pernet_gen_subsys (dccp_net_id , & dccp_net_ops );
801
871
err1 :
802
872
return err ;
803
873
}
804
874
805
875
static void __exit nf_conntrack_proto_dccp_fini (void )
806
876
{
877
+ unregister_pernet_gen_subsys (dccp_net_id , & dccp_net_ops );
807
878
nf_conntrack_l4proto_unregister (& dccp_proto6 );
808
879
nf_conntrack_l4proto_unregister (& dccp_proto4 );
809
880
}
0 commit comments