Commit 2c352f444ccfa966a1aa4fd8e9ee29381c467448

Authored by Gao feng
Committed by Pablo Neira Ayuso
1 parent fdb694a01f

netfilter: nf_conntrack: prepare namespace support for l4 protocol trackers

This patch prepares the namespace support for layer 4 protocol trackers.
Basically, this modifies the following interfaces:

* nf_ct_[un]register_sysctl
* nf_conntrack_l4proto_[un]register

to include the namespace parameter. We still use init_net in this patch
to prepare the ground for follow-up patches for each layer 4 protocol
tracker.

We add a new net_id field to struct nf_conntrack_l4proto that is used
to store the pernet_operations id for each layer 4 protocol tracker.

Note that AF_INET6's protocols do not need to do sysctl compat. Thus,
we only register compat sysctl when l4proto.l3proto != AF_INET6.

Acked-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

Showing 9 changed files with 159 additions and 79 deletions Inline Diff

include/net/netfilter/nf_conntrack_l4proto.h
1 /* 1 /*
2 * Header for use in defining a given L4 protocol for connection tracking. 2 * Header for use in defining a given L4 protocol for connection tracking.
3 * 3 *
4 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> 4 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
5 * - generalized L3 protocol dependent part. 5 * - generalized L3 protocol dependent part.
6 * 6 *
7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_protcol.h 7 * Derived from include/linux/netfiter_ipv4/ip_conntrack_protcol.h
8 */ 8 */
9 9
10 #ifndef _NF_CONNTRACK_L4PROTO_H 10 #ifndef _NF_CONNTRACK_L4PROTO_H
11 #define _NF_CONNTRACK_L4PROTO_H 11 #define _NF_CONNTRACK_L4PROTO_H
12 #include <linux/netlink.h> 12 #include <linux/netlink.h>
13 #include <net/netlink.h> 13 #include <net/netlink.h>
14 #include <net/netfilter/nf_conntrack.h> 14 #include <net/netfilter/nf_conntrack.h>
15 #include <net/netns/generic.h>
15 16
16 struct seq_file; 17 struct seq_file;
17 18
18 struct nf_conntrack_l4proto { 19 struct nf_conntrack_l4proto {
19 /* L3 Protocol number. */ 20 /* L3 Protocol number. */
20 u_int16_t l3proto; 21 u_int16_t l3proto;
21 22
22 /* L4 Protocol number. */ 23 /* L4 Protocol number. */
23 u_int8_t l4proto; 24 u_int8_t l4proto;
24 25
25 /* Try to fill in the third arg: dataoff is offset past network protocol 26 /* Try to fill in the third arg: dataoff is offset past network protocol
26 hdr. Return true if possible. */ 27 hdr. Return true if possible. */
27 bool (*pkt_to_tuple)(const struct sk_buff *skb, unsigned int dataoff, 28 bool (*pkt_to_tuple)(const struct sk_buff *skb, unsigned int dataoff,
28 struct nf_conntrack_tuple *tuple); 29 struct nf_conntrack_tuple *tuple);
29 30
30 /* Invert the per-proto part of the tuple: ie. turn xmit into reply. 31 /* Invert the per-proto part of the tuple: ie. turn xmit into reply.
31 * Some packets can't be inverted: return 0 in that case. 32 * Some packets can't be inverted: return 0 in that case.
32 */ 33 */
33 bool (*invert_tuple)(struct nf_conntrack_tuple *inverse, 34 bool (*invert_tuple)(struct nf_conntrack_tuple *inverse,
34 const struct nf_conntrack_tuple *orig); 35 const struct nf_conntrack_tuple *orig);
35 36
36 /* Returns verdict for packet, or -1 for invalid. */ 37 /* Returns verdict for packet, or -1 for invalid. */
37 int (*packet)(struct nf_conn *ct, 38 int (*packet)(struct nf_conn *ct,
38 const struct sk_buff *skb, 39 const struct sk_buff *skb,
39 unsigned int dataoff, 40 unsigned int dataoff,
40 enum ip_conntrack_info ctinfo, 41 enum ip_conntrack_info ctinfo,
41 u_int8_t pf, 42 u_int8_t pf,
42 unsigned int hooknum, 43 unsigned int hooknum,
43 unsigned int *timeouts); 44 unsigned int *timeouts);
44 45
45 /* Called when a new connection for this protocol found; 46 /* Called when a new connection for this protocol found;
46 * returns TRUE if it's OK. If so, packet() called next. */ 47 * returns TRUE if it's OK. If so, packet() called next. */
47 bool (*new)(struct nf_conn *ct, const struct sk_buff *skb, 48 bool (*new)(struct nf_conn *ct, const struct sk_buff *skb,
48 unsigned int dataoff, unsigned int *timeouts); 49 unsigned int dataoff, unsigned int *timeouts);
49 50
50 /* Called when a conntrack entry is destroyed */ 51 /* Called when a conntrack entry is destroyed */
51 void (*destroy)(struct nf_conn *ct); 52 void (*destroy)(struct nf_conn *ct);
52 53
53 int (*error)(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb, 54 int (*error)(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb,
54 unsigned int dataoff, enum ip_conntrack_info *ctinfo, 55 unsigned int dataoff, enum ip_conntrack_info *ctinfo,
55 u_int8_t pf, unsigned int hooknum); 56 u_int8_t pf, unsigned int hooknum);
56 57
57 /* Print out the per-protocol part of the tuple. Return like seq_* */ 58 /* Print out the per-protocol part of the tuple. Return like seq_* */
58 int (*print_tuple)(struct seq_file *s, 59 int (*print_tuple)(struct seq_file *s,
59 const struct nf_conntrack_tuple *); 60 const struct nf_conntrack_tuple *);
60 61
61 /* Print out the private part of the conntrack. */ 62 /* Print out the private part of the conntrack. */
62 int (*print_conntrack)(struct seq_file *s, struct nf_conn *); 63 int (*print_conntrack)(struct seq_file *s, struct nf_conn *);
63 64
64 /* Return the array of timeouts for this protocol. */ 65 /* Return the array of timeouts for this protocol. */
65 unsigned int *(*get_timeouts)(struct net *net); 66 unsigned int *(*get_timeouts)(struct net *net);
66 67
67 /* convert protoinfo to nfnetink attributes */ 68 /* convert protoinfo to nfnetink attributes */
68 int (*to_nlattr)(struct sk_buff *skb, struct nlattr *nla, 69 int (*to_nlattr)(struct sk_buff *skb, struct nlattr *nla,
69 struct nf_conn *ct); 70 struct nf_conn *ct);
70 /* Calculate protoinfo nlattr size */ 71 /* Calculate protoinfo nlattr size */
71 int (*nlattr_size)(void); 72 int (*nlattr_size)(void);
72 73
73 /* convert nfnetlink attributes to protoinfo */ 74 /* convert nfnetlink attributes to protoinfo */
74 int (*from_nlattr)(struct nlattr *tb[], struct nf_conn *ct); 75 int (*from_nlattr)(struct nlattr *tb[], struct nf_conn *ct);
75 76
76 int (*tuple_to_nlattr)(struct sk_buff *skb, 77 int (*tuple_to_nlattr)(struct sk_buff *skb,
77 const struct nf_conntrack_tuple *t); 78 const struct nf_conntrack_tuple *t);
78 /* Calculate tuple nlattr size */ 79 /* Calculate tuple nlattr size */
79 int (*nlattr_tuple_size)(void); 80 int (*nlattr_tuple_size)(void);
80 int (*nlattr_to_tuple)(struct nlattr *tb[], 81 int (*nlattr_to_tuple)(struct nlattr *tb[],
81 struct nf_conntrack_tuple *t); 82 struct nf_conntrack_tuple *t);
82 const struct nla_policy *nla_policy; 83 const struct nla_policy *nla_policy;
83 84
84 size_t nla_size; 85 size_t nla_size;
85 86
86 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 87 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
87 struct { 88 struct {
88 size_t obj_size; 89 size_t obj_size;
89 int (*nlattr_to_obj)(struct nlattr *tb[], void *data); 90 int (*nlattr_to_obj)(struct nlattr *tb[], void *data);
90 int (*obj_to_nlattr)(struct sk_buff *skb, const void *data); 91 int (*obj_to_nlattr)(struct sk_buff *skb, const void *data);
91 92
92 unsigned int nlattr_max; 93 unsigned int nlattr_max;
93 const struct nla_policy *nla_policy; 94 const struct nla_policy *nla_policy;
94 } ctnl_timeout; 95 } ctnl_timeout;
95 #endif 96 #endif
96 97
97 #ifdef CONFIG_SYSCTL 98 #ifdef CONFIG_SYSCTL
98 struct ctl_table_header **ctl_table_header; 99 struct ctl_table_header **ctl_table_header;
99 struct ctl_table *ctl_table; 100 struct ctl_table *ctl_table;
100 unsigned int *ctl_table_users; 101 unsigned int *ctl_table_users;
101 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 102 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
102 struct ctl_table_header *ctl_compat_table_header; 103 struct ctl_table_header *ctl_compat_table_header;
103 struct ctl_table *ctl_compat_table; 104 struct ctl_table *ctl_compat_table;
104 #endif 105 #endif
105 #endif 106 #endif
107 int *net_id;
108 /* Init l4proto pernet data */
109 int (*init_net)(struct net *net);
110
106 /* Protocol name */ 111 /* Protocol name */
107 const char *name; 112 const char *name;
108 113
109 /* Module (if any) which this is connected to. */ 114 /* Module (if any) which this is connected to. */
110 struct module *me; 115 struct module *me;
111 }; 116 };
112 117
113 /* Existing built-in generic protocol */ 118 /* Existing built-in generic protocol */
114 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_generic; 119 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_generic;
115 120
116 #define MAX_NF_CT_PROTO 256 121 #define MAX_NF_CT_PROTO 256
117 122
118 extern struct nf_conntrack_l4proto * 123 extern struct nf_conntrack_l4proto *
119 __nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto); 124 __nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto);
120 125
121 extern struct nf_conntrack_l4proto * 126 extern struct nf_conntrack_l4proto *
122 nf_ct_l4proto_find_get(u_int16_t l3proto, u_int8_t l4proto); 127 nf_ct_l4proto_find_get(u_int16_t l3proto, u_int8_t l4proto);
123 extern void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p); 128 extern void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p);
124 129
125 /* Protocol registration. */ 130 /* Protocol registration. */
126 extern int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *proto); 131 extern int nf_conntrack_l4proto_register(struct net *net,
127 extern void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *proto); 132 struct nf_conntrack_l4proto *proto);
133 extern void nf_conntrack_l4proto_unregister(struct net *net,
134 struct nf_conntrack_l4proto *proto);
128 135
129 /* Generic netlink helpers */ 136 /* Generic netlink helpers */
130 extern int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb, 137 extern int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb,
131 const struct nf_conntrack_tuple *tuple); 138 const struct nf_conntrack_tuple *tuple);
132 extern int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[], 139 extern int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[],
133 struct nf_conntrack_tuple *t); 140 struct nf_conntrack_tuple *t);
134 extern int nf_ct_port_nlattr_tuple_size(void); 141 extern int nf_ct_port_nlattr_tuple_size(void);
135 extern const struct nla_policy nf_ct_port_nla_policy[]; 142 extern const struct nla_policy nf_ct_port_nla_policy[];
136 143
137 #ifdef CONFIG_SYSCTL 144 #ifdef CONFIG_SYSCTL
138 #ifdef DEBUG_INVALID_PACKETS 145 #ifdef DEBUG_INVALID_PACKETS
139 #define LOG_INVALID(net, proto) \ 146 #define LOG_INVALID(net, proto) \
140 ((net)->ct.sysctl_log_invalid == (proto) || \ 147 ((net)->ct.sysctl_log_invalid == (proto) || \
141 (net)->ct.sysctl_log_invalid == IPPROTO_RAW) 148 (net)->ct.sysctl_log_invalid == IPPROTO_RAW)
142 #else 149 #else
143 #define LOG_INVALID(net, proto) \ 150 #define LOG_INVALID(net, proto) \
144 (((net)->ct.sysctl_log_invalid == (proto) || \ 151 (((net)->ct.sysctl_log_invalid == (proto) || \
145 (net)->ct.sysctl_log_invalid == IPPROTO_RAW) \ 152 (net)->ct.sysctl_log_invalid == IPPROTO_RAW) \
146 && net_ratelimit()) 153 && net_ratelimit())
147 #endif 154 #endif
148 #else 155 #else
149 static inline int LOG_INVALID(struct net *net, int proto) { return 0; } 156 static inline int LOG_INVALID(struct net *net, int proto) { return 0; }
150 #endif /* CONFIG_SYSCTL */ 157 #endif /* CONFIG_SYSCTL */
151 158
152 #endif /*_NF_CONNTRACK_PROTOCOL_H*/ 159 #endif /*_NF_CONNTRACK_PROTOCOL_H*/
153 160
include/net/netns/conntrack.h
1 #ifndef __NETNS_CONNTRACK_H 1 #ifndef __NETNS_CONNTRACK_H
2 #define __NETNS_CONNTRACK_H 2 #define __NETNS_CONNTRACK_H
3 3
4 #include <linux/list.h> 4 #include <linux/list.h>
5 #include <linux/list_nulls.h> 5 #include <linux/list_nulls.h>
6 #include <linux/atomic.h> 6 #include <linux/atomic.h>
7 7
8 struct ctl_table_header; 8 struct ctl_table_header;
9 struct nf_conntrack_ecache; 9 struct nf_conntrack_ecache;
10 10
11 struct nf_proto_net {
12 #ifdef CONFIG_SYSCTL
13 struct ctl_table_header *ctl_table_header;
14 struct ctl_table *ctl_table;
15 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
16 struct ctl_table_header *ctl_compat_header;
17 struct ctl_table *ctl_compat_table;
18 #endif
19 #endif
20 unsigned int users;
21 };
22
11 struct netns_ct { 23 struct netns_ct {
12 atomic_t count; 24 atomic_t count;
13 unsigned int expect_count; 25 unsigned int expect_count;
14 unsigned int htable_size; 26 unsigned int htable_size;
15 struct kmem_cache *nf_conntrack_cachep; 27 struct kmem_cache *nf_conntrack_cachep;
16 struct hlist_nulls_head *hash; 28 struct hlist_nulls_head *hash;
17 struct hlist_head *expect_hash; 29 struct hlist_head *expect_hash;
18 struct hlist_nulls_head unconfirmed; 30 struct hlist_nulls_head unconfirmed;
19 struct hlist_nulls_head dying; 31 struct hlist_nulls_head dying;
20 struct ip_conntrack_stat __percpu *stat; 32 struct ip_conntrack_stat __percpu *stat;
21 struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb; 33 struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
22 struct nf_exp_event_notifier __rcu *nf_expect_event_cb; 34 struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
23 int sysctl_events; 35 int sysctl_events;
24 unsigned int sysctl_events_retry_timeout; 36 unsigned int sysctl_events_retry_timeout;
25 int sysctl_acct; 37 int sysctl_acct;
26 int sysctl_tstamp; 38 int sysctl_tstamp;
27 int sysctl_checksum; 39 int sysctl_checksum;
28 unsigned int sysctl_log_invalid; /* Log invalid packets */ 40 unsigned int sysctl_log_invalid; /* Log invalid packets */
29 int sysctl_auto_assign_helper; 41 int sysctl_auto_assign_helper;
30 bool auto_assign_helper_warned; 42 bool auto_assign_helper_warned;
31 #ifdef CONFIG_SYSCTL 43 #ifdef CONFIG_SYSCTL
32 struct ctl_table_header *sysctl_header; 44 struct ctl_table_header *sysctl_header;
33 struct ctl_table_header *acct_sysctl_header; 45 struct ctl_table_header *acct_sysctl_header;
34 struct ctl_table_header *tstamp_sysctl_header; 46 struct ctl_table_header *tstamp_sysctl_header;
35 struct ctl_table_header *event_sysctl_header; 47 struct ctl_table_header *event_sysctl_header;
36 struct ctl_table_header *helper_sysctl_header; 48 struct ctl_table_header *helper_sysctl_header;
37 #endif 49 #endif
38 char *slabname; 50 char *slabname;
39 }; 51 };
40 #endif 52 #endif
41 53
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
1 1
2 /* (C) 1999-2001 Paul `Rusty' Russell 2 /* (C) 1999-2001 Paul `Rusty' Russell
3 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 3 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 */ 8 */
9 9
10 #include <linux/types.h> 10 #include <linux/types.h>
11 #include <linux/ip.h> 11 #include <linux/ip.h>
12 #include <linux/netfilter.h> 12 #include <linux/netfilter.h>
13 #include <linux/module.h> 13 #include <linux/module.h>
14 #include <linux/skbuff.h> 14 #include <linux/skbuff.h>
15 #include <linux/icmp.h> 15 #include <linux/icmp.h>
16 #include <linux/sysctl.h> 16 #include <linux/sysctl.h>
17 #include <net/route.h> 17 #include <net/route.h>
18 #include <net/ip.h> 18 #include <net/ip.h>
19 19
20 #include <linux/netfilter_ipv4.h> 20 #include <linux/netfilter_ipv4.h>
21 #include <net/netfilter/nf_conntrack.h> 21 #include <net/netfilter/nf_conntrack.h>
22 #include <net/netfilter/nf_conntrack_helper.h> 22 #include <net/netfilter/nf_conntrack_helper.h>
23 #include <net/netfilter/nf_conntrack_l4proto.h> 23 #include <net/netfilter/nf_conntrack_l4proto.h>
24 #include <net/netfilter/nf_conntrack_l3proto.h> 24 #include <net/netfilter/nf_conntrack_l3proto.h>
25 #include <net/netfilter/nf_conntrack_zones.h> 25 #include <net/netfilter/nf_conntrack_zones.h>
26 #include <net/netfilter/nf_conntrack_core.h> 26 #include <net/netfilter/nf_conntrack_core.h>
27 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 27 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
28 #include <net/netfilter/nf_nat_helper.h> 28 #include <net/netfilter/nf_nat_helper.h>
29 #include <net/netfilter/ipv4/nf_defrag_ipv4.h> 29 #include <net/netfilter/ipv4/nf_defrag_ipv4.h>
30 #include <net/netfilter/nf_log.h> 30 #include <net/netfilter/nf_log.h>
31 31
32 int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, 32 int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
33 struct nf_conn *ct, 33 struct nf_conn *ct,
34 enum ip_conntrack_info ctinfo); 34 enum ip_conntrack_info ctinfo);
35 EXPORT_SYMBOL_GPL(nf_nat_seq_adjust_hook); 35 EXPORT_SYMBOL_GPL(nf_nat_seq_adjust_hook);
36 36
37 static bool ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, 37 static bool ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
38 struct nf_conntrack_tuple *tuple) 38 struct nf_conntrack_tuple *tuple)
39 { 39 {
40 const __be32 *ap; 40 const __be32 *ap;
41 __be32 _addrs[2]; 41 __be32 _addrs[2];
42 ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr), 42 ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr),
43 sizeof(u_int32_t) * 2, _addrs); 43 sizeof(u_int32_t) * 2, _addrs);
44 if (ap == NULL) 44 if (ap == NULL)
45 return false; 45 return false;
46 46
47 tuple->src.u3.ip = ap[0]; 47 tuple->src.u3.ip = ap[0];
48 tuple->dst.u3.ip = ap[1]; 48 tuple->dst.u3.ip = ap[1];
49 49
50 return true; 50 return true;
51 } 51 }
52 52
53 static bool ipv4_invert_tuple(struct nf_conntrack_tuple *tuple, 53 static bool ipv4_invert_tuple(struct nf_conntrack_tuple *tuple,
54 const struct nf_conntrack_tuple *orig) 54 const struct nf_conntrack_tuple *orig)
55 { 55 {
56 tuple->src.u3.ip = orig->dst.u3.ip; 56 tuple->src.u3.ip = orig->dst.u3.ip;
57 tuple->dst.u3.ip = orig->src.u3.ip; 57 tuple->dst.u3.ip = orig->src.u3.ip;
58 58
59 return true; 59 return true;
60 } 60 }
61 61
62 static int ipv4_print_tuple(struct seq_file *s, 62 static int ipv4_print_tuple(struct seq_file *s,
63 const struct nf_conntrack_tuple *tuple) 63 const struct nf_conntrack_tuple *tuple)
64 { 64 {
65 return seq_printf(s, "src=%pI4 dst=%pI4 ", 65 return seq_printf(s, "src=%pI4 dst=%pI4 ",
66 &tuple->src.u3.ip, &tuple->dst.u3.ip); 66 &tuple->src.u3.ip, &tuple->dst.u3.ip);
67 } 67 }
68 68
69 static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, 69 static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
70 unsigned int *dataoff, u_int8_t *protonum) 70 unsigned int *dataoff, u_int8_t *protonum)
71 { 71 {
72 const struct iphdr *iph; 72 const struct iphdr *iph;
73 struct iphdr _iph; 73 struct iphdr _iph;
74 74
75 iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph); 75 iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
76 if (iph == NULL) 76 if (iph == NULL)
77 return -NF_ACCEPT; 77 return -NF_ACCEPT;
78 78
79 /* Conntrack defragments packets, we might still see fragments 79 /* Conntrack defragments packets, we might still see fragments
80 * inside ICMP packets though. */ 80 * inside ICMP packets though. */
81 if (iph->frag_off & htons(IP_OFFSET)) 81 if (iph->frag_off & htons(IP_OFFSET))
82 return -NF_ACCEPT; 82 return -NF_ACCEPT;
83 83
84 *dataoff = nhoff + (iph->ihl << 2); 84 *dataoff = nhoff + (iph->ihl << 2);
85 *protonum = iph->protocol; 85 *protonum = iph->protocol;
86 86
87 /* Check bogus IP headers */ 87 /* Check bogus IP headers */
88 if (*dataoff > skb->len) { 88 if (*dataoff > skb->len) {
89 pr_debug("nf_conntrack_ipv4: bogus IPv4 packet: " 89 pr_debug("nf_conntrack_ipv4: bogus IPv4 packet: "
90 "nhoff %u, ihl %u, skblen %u\n", 90 "nhoff %u, ihl %u, skblen %u\n",
91 nhoff, iph->ihl << 2, skb->len); 91 nhoff, iph->ihl << 2, skb->len);
92 return -NF_ACCEPT; 92 return -NF_ACCEPT;
93 } 93 }
94 94
95 return NF_ACCEPT; 95 return NF_ACCEPT;
96 } 96 }
97 97
98 static unsigned int ipv4_confirm(unsigned int hooknum, 98 static unsigned int ipv4_confirm(unsigned int hooknum,
99 struct sk_buff *skb, 99 struct sk_buff *skb,
100 const struct net_device *in, 100 const struct net_device *in,
101 const struct net_device *out, 101 const struct net_device *out,
102 int (*okfn)(struct sk_buff *)) 102 int (*okfn)(struct sk_buff *))
103 { 103 {
104 struct nf_conn *ct; 104 struct nf_conn *ct;
105 enum ip_conntrack_info ctinfo; 105 enum ip_conntrack_info ctinfo;
106 const struct nf_conn_help *help; 106 const struct nf_conn_help *help;
107 const struct nf_conntrack_helper *helper; 107 const struct nf_conntrack_helper *helper;
108 unsigned int ret; 108 unsigned int ret;
109 109
110 /* This is where we call the helper: as the packet goes out. */ 110 /* This is where we call the helper: as the packet goes out. */
111 ct = nf_ct_get(skb, &ctinfo); 111 ct = nf_ct_get(skb, &ctinfo);
112 if (!ct || ctinfo == IP_CT_RELATED_REPLY) 112 if (!ct || ctinfo == IP_CT_RELATED_REPLY)
113 goto out; 113 goto out;
114 114
115 help = nfct_help(ct); 115 help = nfct_help(ct);
116 if (!help) 116 if (!help)
117 goto out; 117 goto out;
118 118
119 /* rcu_read_lock()ed by nf_hook_slow */ 119 /* rcu_read_lock()ed by nf_hook_slow */
120 helper = rcu_dereference(help->helper); 120 helper = rcu_dereference(help->helper);
121 if (!helper) 121 if (!helper)
122 goto out; 122 goto out;
123 123
124 ret = helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb), 124 ret = helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb),
125 ct, ctinfo); 125 ct, ctinfo);
126 if (ret != NF_ACCEPT) { 126 if (ret != NF_ACCEPT) {
127 nf_log_packet(NFPROTO_IPV4, hooknum, skb, in, out, NULL, 127 nf_log_packet(NFPROTO_IPV4, hooknum, skb, in, out, NULL,
128 "nf_ct_%s: dropping packet", helper->name); 128 "nf_ct_%s: dropping packet", helper->name);
129 return ret; 129 return ret;
130 } 130 }
131 131
132 /* adjust seqs for loopback traffic only in outgoing direction */ 132 /* adjust seqs for loopback traffic only in outgoing direction */
133 if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) && 133 if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) &&
134 !nf_is_loopback_packet(skb)) { 134 !nf_is_loopback_packet(skb)) {
135 typeof(nf_nat_seq_adjust_hook) seq_adjust; 135 typeof(nf_nat_seq_adjust_hook) seq_adjust;
136 136
137 seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook); 137 seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook);
138 if (!seq_adjust || !seq_adjust(skb, ct, ctinfo)) { 138 if (!seq_adjust || !seq_adjust(skb, ct, ctinfo)) {
139 NF_CT_STAT_INC_ATOMIC(nf_ct_net(ct), drop); 139 NF_CT_STAT_INC_ATOMIC(nf_ct_net(ct), drop);
140 return NF_DROP; 140 return NF_DROP;
141 } 141 }
142 } 142 }
143 out: 143 out:
144 /* We've seen it coming out the other side: confirm it */ 144 /* We've seen it coming out the other side: confirm it */
145 return nf_conntrack_confirm(skb); 145 return nf_conntrack_confirm(skb);
146 } 146 }
147 147
148 static unsigned int ipv4_conntrack_in(unsigned int hooknum, 148 static unsigned int ipv4_conntrack_in(unsigned int hooknum,
149 struct sk_buff *skb, 149 struct sk_buff *skb,
150 const struct net_device *in, 150 const struct net_device *in,
151 const struct net_device *out, 151 const struct net_device *out,
152 int (*okfn)(struct sk_buff *)) 152 int (*okfn)(struct sk_buff *))
153 { 153 {
154 return nf_conntrack_in(dev_net(in), PF_INET, hooknum, skb); 154 return nf_conntrack_in(dev_net(in), PF_INET, hooknum, skb);
155 } 155 }
156 156
157 static unsigned int ipv4_conntrack_local(unsigned int hooknum, 157 static unsigned int ipv4_conntrack_local(unsigned int hooknum,
158 struct sk_buff *skb, 158 struct sk_buff *skb,
159 const struct net_device *in, 159 const struct net_device *in,
160 const struct net_device *out, 160 const struct net_device *out,
161 int (*okfn)(struct sk_buff *)) 161 int (*okfn)(struct sk_buff *))
162 { 162 {
163 /* root is playing with raw sockets. */ 163 /* root is playing with raw sockets. */
164 if (skb->len < sizeof(struct iphdr) || 164 if (skb->len < sizeof(struct iphdr) ||
165 ip_hdrlen(skb) < sizeof(struct iphdr)) 165 ip_hdrlen(skb) < sizeof(struct iphdr))
166 return NF_ACCEPT; 166 return NF_ACCEPT;
167 return nf_conntrack_in(dev_net(out), PF_INET, hooknum, skb); 167 return nf_conntrack_in(dev_net(out), PF_INET, hooknum, skb);
168 } 168 }
169 169
170 /* Connection tracking may drop packets, but never alters them, so 170 /* Connection tracking may drop packets, but never alters them, so
171 make it the first hook. */ 171 make it the first hook. */
172 static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { 172 static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
173 { 173 {
174 .hook = ipv4_conntrack_in, 174 .hook = ipv4_conntrack_in,
175 .owner = THIS_MODULE, 175 .owner = THIS_MODULE,
176 .pf = NFPROTO_IPV4, 176 .pf = NFPROTO_IPV4,
177 .hooknum = NF_INET_PRE_ROUTING, 177 .hooknum = NF_INET_PRE_ROUTING,
178 .priority = NF_IP_PRI_CONNTRACK, 178 .priority = NF_IP_PRI_CONNTRACK,
179 }, 179 },
180 { 180 {
181 .hook = ipv4_conntrack_local, 181 .hook = ipv4_conntrack_local,
182 .owner = THIS_MODULE, 182 .owner = THIS_MODULE,
183 .pf = NFPROTO_IPV4, 183 .pf = NFPROTO_IPV4,
184 .hooknum = NF_INET_LOCAL_OUT, 184 .hooknum = NF_INET_LOCAL_OUT,
185 .priority = NF_IP_PRI_CONNTRACK, 185 .priority = NF_IP_PRI_CONNTRACK,
186 }, 186 },
187 { 187 {
188 .hook = ipv4_confirm, 188 .hook = ipv4_confirm,
189 .owner = THIS_MODULE, 189 .owner = THIS_MODULE,
190 .pf = NFPROTO_IPV4, 190 .pf = NFPROTO_IPV4,
191 .hooknum = NF_INET_POST_ROUTING, 191 .hooknum = NF_INET_POST_ROUTING,
192 .priority = NF_IP_PRI_CONNTRACK_CONFIRM, 192 .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
193 }, 193 },
194 { 194 {
195 .hook = ipv4_confirm, 195 .hook = ipv4_confirm,
196 .owner = THIS_MODULE, 196 .owner = THIS_MODULE,
197 .pf = NFPROTO_IPV4, 197 .pf = NFPROTO_IPV4,
198 .hooknum = NF_INET_LOCAL_IN, 198 .hooknum = NF_INET_LOCAL_IN,
199 .priority = NF_IP_PRI_CONNTRACK_CONFIRM, 199 .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
200 }, 200 },
201 }; 201 };
202 202
203 #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) 203 #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
204 static int log_invalid_proto_min = 0; 204 static int log_invalid_proto_min = 0;
205 static int log_invalid_proto_max = 255; 205 static int log_invalid_proto_max = 255;
206 206
207 static ctl_table ip_ct_sysctl_table[] = { 207 static ctl_table ip_ct_sysctl_table[] = {
208 { 208 {
209 .procname = "ip_conntrack_max", 209 .procname = "ip_conntrack_max",
210 .data = &nf_conntrack_max, 210 .data = &nf_conntrack_max,
211 .maxlen = sizeof(int), 211 .maxlen = sizeof(int),
212 .mode = 0644, 212 .mode = 0644,
213 .proc_handler = proc_dointvec, 213 .proc_handler = proc_dointvec,
214 }, 214 },
215 { 215 {
216 .procname = "ip_conntrack_count", 216 .procname = "ip_conntrack_count",
217 .data = &init_net.ct.count, 217 .data = &init_net.ct.count,
218 .maxlen = sizeof(int), 218 .maxlen = sizeof(int),
219 .mode = 0444, 219 .mode = 0444,
220 .proc_handler = proc_dointvec, 220 .proc_handler = proc_dointvec,
221 }, 221 },
222 { 222 {
223 .procname = "ip_conntrack_buckets", 223 .procname = "ip_conntrack_buckets",
224 .data = &init_net.ct.htable_size, 224 .data = &init_net.ct.htable_size,
225 .maxlen = sizeof(unsigned int), 225 .maxlen = sizeof(unsigned int),
226 .mode = 0444, 226 .mode = 0444,
227 .proc_handler = proc_dointvec, 227 .proc_handler = proc_dointvec,
228 }, 228 },
229 { 229 {
230 .procname = "ip_conntrack_checksum", 230 .procname = "ip_conntrack_checksum",
231 .data = &init_net.ct.sysctl_checksum, 231 .data = &init_net.ct.sysctl_checksum,
232 .maxlen = sizeof(int), 232 .maxlen = sizeof(int),
233 .mode = 0644, 233 .mode = 0644,
234 .proc_handler = proc_dointvec, 234 .proc_handler = proc_dointvec,
235 }, 235 },
236 { 236 {
237 .procname = "ip_conntrack_log_invalid", 237 .procname = "ip_conntrack_log_invalid",
238 .data = &init_net.ct.sysctl_log_invalid, 238 .data = &init_net.ct.sysctl_log_invalid,
239 .maxlen = sizeof(unsigned int), 239 .maxlen = sizeof(unsigned int),
240 .mode = 0644, 240 .mode = 0644,
241 .proc_handler = proc_dointvec_minmax, 241 .proc_handler = proc_dointvec_minmax,
242 .extra1 = &log_invalid_proto_min, 242 .extra1 = &log_invalid_proto_min,
243 .extra2 = &log_invalid_proto_max, 243 .extra2 = &log_invalid_proto_max,
244 }, 244 },
245 { } 245 { }
246 }; 246 };
247 #endif /* CONFIG_SYSCTL && CONFIG_NF_CONNTRACK_PROC_COMPAT */ 247 #endif /* CONFIG_SYSCTL && CONFIG_NF_CONNTRACK_PROC_COMPAT */
248 248
249 /* Fast function for those who don't want to parse /proc (and I don't 249 /* Fast function for those who don't want to parse /proc (and I don't
250 blame them). */ 250 blame them). */
251 /* Reversing the socket's dst/src point of view gives us the reply 251 /* Reversing the socket's dst/src point of view gives us the reply
252 mapping. */ 252 mapping. */
253 static int 253 static int
254 getorigdst(struct sock *sk, int optval, void __user *user, int *len) 254 getorigdst(struct sock *sk, int optval, void __user *user, int *len)
255 { 255 {
256 const struct inet_sock *inet = inet_sk(sk); 256 const struct inet_sock *inet = inet_sk(sk);
257 const struct nf_conntrack_tuple_hash *h; 257 const struct nf_conntrack_tuple_hash *h;
258 struct nf_conntrack_tuple tuple; 258 struct nf_conntrack_tuple tuple;
259 259
260 memset(&tuple, 0, sizeof(tuple)); 260 memset(&tuple, 0, sizeof(tuple));
261 tuple.src.u3.ip = inet->inet_rcv_saddr; 261 tuple.src.u3.ip = inet->inet_rcv_saddr;
262 tuple.src.u.tcp.port = inet->inet_sport; 262 tuple.src.u.tcp.port = inet->inet_sport;
263 tuple.dst.u3.ip = inet->inet_daddr; 263 tuple.dst.u3.ip = inet->inet_daddr;
264 tuple.dst.u.tcp.port = inet->inet_dport; 264 tuple.dst.u.tcp.port = inet->inet_dport;
265 tuple.src.l3num = PF_INET; 265 tuple.src.l3num = PF_INET;
266 tuple.dst.protonum = sk->sk_protocol; 266 tuple.dst.protonum = sk->sk_protocol;
267 267
268 /* We only do TCP and SCTP at the moment: is there a better way? */ 268 /* We only do TCP and SCTP at the moment: is there a better way? */
269 if (sk->sk_protocol != IPPROTO_TCP && sk->sk_protocol != IPPROTO_SCTP) { 269 if (sk->sk_protocol != IPPROTO_TCP && sk->sk_protocol != IPPROTO_SCTP) {
270 pr_debug("SO_ORIGINAL_DST: Not a TCP/SCTP socket\n"); 270 pr_debug("SO_ORIGINAL_DST: Not a TCP/SCTP socket\n");
271 return -ENOPROTOOPT; 271 return -ENOPROTOOPT;
272 } 272 }
273 273
274 if ((unsigned int) *len < sizeof(struct sockaddr_in)) { 274 if ((unsigned int) *len < sizeof(struct sockaddr_in)) {
275 pr_debug("SO_ORIGINAL_DST: len %d not %Zu\n", 275 pr_debug("SO_ORIGINAL_DST: len %d not %Zu\n",
276 *len, sizeof(struct sockaddr_in)); 276 *len, sizeof(struct sockaddr_in));
277 return -EINVAL; 277 return -EINVAL;
278 } 278 }
279 279
280 h = nf_conntrack_find_get(sock_net(sk), NF_CT_DEFAULT_ZONE, &tuple); 280 h = nf_conntrack_find_get(sock_net(sk), NF_CT_DEFAULT_ZONE, &tuple);
281 if (h) { 281 if (h) {
282 struct sockaddr_in sin; 282 struct sockaddr_in sin;
283 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h); 283 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
284 284
285 sin.sin_family = AF_INET; 285 sin.sin_family = AF_INET;
286 sin.sin_port = ct->tuplehash[IP_CT_DIR_ORIGINAL] 286 sin.sin_port = ct->tuplehash[IP_CT_DIR_ORIGINAL]
287 .tuple.dst.u.tcp.port; 287 .tuple.dst.u.tcp.port;
288 sin.sin_addr.s_addr = ct->tuplehash[IP_CT_DIR_ORIGINAL] 288 sin.sin_addr.s_addr = ct->tuplehash[IP_CT_DIR_ORIGINAL]
289 .tuple.dst.u3.ip; 289 .tuple.dst.u3.ip;
290 memset(sin.sin_zero, 0, sizeof(sin.sin_zero)); 290 memset(sin.sin_zero, 0, sizeof(sin.sin_zero));
291 291
292 pr_debug("SO_ORIGINAL_DST: %pI4 %u\n", 292 pr_debug("SO_ORIGINAL_DST: %pI4 %u\n",
293 &sin.sin_addr.s_addr, ntohs(sin.sin_port)); 293 &sin.sin_addr.s_addr, ntohs(sin.sin_port));
294 nf_ct_put(ct); 294 nf_ct_put(ct);
295 if (copy_to_user(user, &sin, sizeof(sin)) != 0) 295 if (copy_to_user(user, &sin, sizeof(sin)) != 0)
296 return -EFAULT; 296 return -EFAULT;
297 else 297 else
298 return 0; 298 return 0;
299 } 299 }
300 pr_debug("SO_ORIGINAL_DST: Can't find %pI4/%u-%pI4/%u.\n", 300 pr_debug("SO_ORIGINAL_DST: Can't find %pI4/%u-%pI4/%u.\n",
301 &tuple.src.u3.ip, ntohs(tuple.src.u.tcp.port), 301 &tuple.src.u3.ip, ntohs(tuple.src.u.tcp.port),
302 &tuple.dst.u3.ip, ntohs(tuple.dst.u.tcp.port)); 302 &tuple.dst.u3.ip, ntohs(tuple.dst.u.tcp.port));
303 return -ENOENT; 303 return -ENOENT;
304 } 304 }
305 305
306 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 306 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
307 307
308 #include <linux/netfilter/nfnetlink.h> 308 #include <linux/netfilter/nfnetlink.h>
309 #include <linux/netfilter/nfnetlink_conntrack.h> 309 #include <linux/netfilter/nfnetlink_conntrack.h>
310 310
311 static int ipv4_tuple_to_nlattr(struct sk_buff *skb, 311 static int ipv4_tuple_to_nlattr(struct sk_buff *skb,
312 const struct nf_conntrack_tuple *tuple) 312 const struct nf_conntrack_tuple *tuple)
313 { 313 {
314 if (nla_put_be32(skb, CTA_IP_V4_SRC, tuple->src.u3.ip) || 314 if (nla_put_be32(skb, CTA_IP_V4_SRC, tuple->src.u3.ip) ||
315 nla_put_be32(skb, CTA_IP_V4_DST, tuple->dst.u3.ip)) 315 nla_put_be32(skb, CTA_IP_V4_DST, tuple->dst.u3.ip))
316 goto nla_put_failure; 316 goto nla_put_failure;
317 return 0; 317 return 0;
318 318
319 nla_put_failure: 319 nla_put_failure:
320 return -1; 320 return -1;
321 } 321 }
322 322
323 static const struct nla_policy ipv4_nla_policy[CTA_IP_MAX+1] = { 323 static const struct nla_policy ipv4_nla_policy[CTA_IP_MAX+1] = {
324 [CTA_IP_V4_SRC] = { .type = NLA_U32 }, 324 [CTA_IP_V4_SRC] = { .type = NLA_U32 },
325 [CTA_IP_V4_DST] = { .type = NLA_U32 }, 325 [CTA_IP_V4_DST] = { .type = NLA_U32 },
326 }; 326 };
327 327
328 static int ipv4_nlattr_to_tuple(struct nlattr *tb[], 328 static int ipv4_nlattr_to_tuple(struct nlattr *tb[],
329 struct nf_conntrack_tuple *t) 329 struct nf_conntrack_tuple *t)
330 { 330 {
331 if (!tb[CTA_IP_V4_SRC] || !tb[CTA_IP_V4_DST]) 331 if (!tb[CTA_IP_V4_SRC] || !tb[CTA_IP_V4_DST])
332 return -EINVAL; 332 return -EINVAL;
333 333
334 t->src.u3.ip = nla_get_be32(tb[CTA_IP_V4_SRC]); 334 t->src.u3.ip = nla_get_be32(tb[CTA_IP_V4_SRC]);
335 t->dst.u3.ip = nla_get_be32(tb[CTA_IP_V4_DST]); 335 t->dst.u3.ip = nla_get_be32(tb[CTA_IP_V4_DST]);
336 336
337 return 0; 337 return 0;
338 } 338 }
339 339
340 static int ipv4_nlattr_tuple_size(void) 340 static int ipv4_nlattr_tuple_size(void)
341 { 341 {
342 return nla_policy_len(ipv4_nla_policy, CTA_IP_MAX + 1); 342 return nla_policy_len(ipv4_nla_policy, CTA_IP_MAX + 1);
343 } 343 }
344 #endif 344 #endif
345 345
346 static struct nf_sockopt_ops so_getorigdst = { 346 static struct nf_sockopt_ops so_getorigdst = {
347 .pf = PF_INET, 347 .pf = PF_INET,
348 .get_optmin = SO_ORIGINAL_DST, 348 .get_optmin = SO_ORIGINAL_DST,
349 .get_optmax = SO_ORIGINAL_DST+1, 349 .get_optmax = SO_ORIGINAL_DST+1,
350 .get = &getorigdst, 350 .get = &getorigdst,
351 .owner = THIS_MODULE, 351 .owner = THIS_MODULE,
352 }; 352 };
353 353
354 struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = { 354 struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = {
355 .l3proto = PF_INET, 355 .l3proto = PF_INET,
356 .name = "ipv4", 356 .name = "ipv4",
357 .pkt_to_tuple = ipv4_pkt_to_tuple, 357 .pkt_to_tuple = ipv4_pkt_to_tuple,
358 .invert_tuple = ipv4_invert_tuple, 358 .invert_tuple = ipv4_invert_tuple,
359 .print_tuple = ipv4_print_tuple, 359 .print_tuple = ipv4_print_tuple,
360 .get_l4proto = ipv4_get_l4proto, 360 .get_l4proto = ipv4_get_l4proto,
361 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 361 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
362 .tuple_to_nlattr = ipv4_tuple_to_nlattr, 362 .tuple_to_nlattr = ipv4_tuple_to_nlattr,
363 .nlattr_tuple_size = ipv4_nlattr_tuple_size, 363 .nlattr_tuple_size = ipv4_nlattr_tuple_size,
364 .nlattr_to_tuple = ipv4_nlattr_to_tuple, 364 .nlattr_to_tuple = ipv4_nlattr_to_tuple,
365 .nla_policy = ipv4_nla_policy, 365 .nla_policy = ipv4_nla_policy,
366 #endif 366 #endif
367 #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) 367 #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
368 .ctl_table_path = "net/ipv4/netfilter", 368 .ctl_table_path = "net/ipv4/netfilter",
369 .ctl_table = ip_ct_sysctl_table, 369 .ctl_table = ip_ct_sysctl_table,
370 #endif 370 #endif
371 .me = THIS_MODULE, 371 .me = THIS_MODULE,
372 }; 372 };
373 373
374 module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, 374 module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint,
375 &nf_conntrack_htable_size, 0600); 375 &nf_conntrack_htable_size, 0600);
376 376
377 MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET)); 377 MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET));
378 MODULE_ALIAS("ip_conntrack"); 378 MODULE_ALIAS("ip_conntrack");
379 MODULE_LICENSE("GPL"); 379 MODULE_LICENSE("GPL");
380 380
381 static int __init nf_conntrack_l3proto_ipv4_init(void) 381 static int __init nf_conntrack_l3proto_ipv4_init(void)
382 { 382 {
383 int ret = 0; 383 int ret = 0;
384 384
385 need_conntrack(); 385 need_conntrack();
386 nf_defrag_ipv4_enable(); 386 nf_defrag_ipv4_enable();
387 387
388 ret = nf_register_sockopt(&so_getorigdst); 388 ret = nf_register_sockopt(&so_getorigdst);
389 if (ret < 0) { 389 if (ret < 0) {
390 printk(KERN_ERR "Unable to register netfilter socket option\n"); 390 printk(KERN_ERR "Unable to register netfilter socket option\n");
391 return ret; 391 return ret;
392 } 392 }
393 393
394 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp4); 394 ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_tcp4);
395 if (ret < 0) { 395 if (ret < 0) {
396 pr_err("nf_conntrack_ipv4: can't register tcp.\n"); 396 pr_err("nf_conntrack_ipv4: can't register tcp.\n");
397 goto cleanup_sockopt; 397 goto cleanup_sockopt;
398 } 398 }
399 399
400 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp4); 400 ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_udp4);
401 if (ret < 0) { 401 if (ret < 0) {
402 pr_err("nf_conntrack_ipv4: can't register udp.\n"); 402 pr_err("nf_conntrack_ipv4: can't register udp.\n");
403 goto cleanup_tcp; 403 goto cleanup_tcp;
404 } 404 }
405 405
406 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmp); 406 ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_icmp);
407 if (ret < 0) { 407 if (ret < 0) {
408 pr_err("nf_conntrack_ipv4: can't register icmp.\n"); 408 pr_err("nf_conntrack_ipv4: can't register icmp.\n");
409 goto cleanup_udp; 409 goto cleanup_udp;
410 } 410 }
411 411
412 ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv4); 412 ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv4);
413 if (ret < 0) { 413 if (ret < 0) {
414 pr_err("nf_conntrack_ipv4: can't register ipv4\n"); 414 pr_err("nf_conntrack_ipv4: can't register ipv4\n");
415 goto cleanup_icmp; 415 goto cleanup_icmp;
416 } 416 }
417 417
418 ret = nf_register_hooks(ipv4_conntrack_ops, 418 ret = nf_register_hooks(ipv4_conntrack_ops,
419 ARRAY_SIZE(ipv4_conntrack_ops)); 419 ARRAY_SIZE(ipv4_conntrack_ops));
420 if (ret < 0) { 420 if (ret < 0) {
421 pr_err("nf_conntrack_ipv4: can't register hooks.\n"); 421 pr_err("nf_conntrack_ipv4: can't register hooks.\n");
422 goto cleanup_ipv4; 422 goto cleanup_ipv4;
423 } 423 }
424 #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) 424 #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
425 ret = nf_conntrack_ipv4_compat_init(); 425 ret = nf_conntrack_ipv4_compat_init();
426 if (ret < 0) 426 if (ret < 0)
427 goto cleanup_hooks; 427 goto cleanup_hooks;
428 #endif 428 #endif
429 return ret; 429 return ret;
430 #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) 430 #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
431 cleanup_hooks: 431 cleanup_hooks:
432 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); 432 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
433 #endif 433 #endif
434 cleanup_ipv4: 434 cleanup_ipv4:
435 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); 435 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
436 cleanup_icmp: 436 cleanup_icmp:
437 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmp); 437 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmp);
438 cleanup_udp: 438 cleanup_udp:
439 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp4); 439 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udp4);
440 cleanup_tcp: 440 cleanup_tcp:
441 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp4); 441 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_tcp4);
442 cleanup_sockopt: 442 cleanup_sockopt:
443 nf_unregister_sockopt(&so_getorigdst); 443 nf_unregister_sockopt(&so_getorigdst);
444 return ret; 444 return ret;
445 } 445 }
446 446
447 static void __exit nf_conntrack_l3proto_ipv4_fini(void) 447 static void __exit nf_conntrack_l3proto_ipv4_fini(void)
448 { 448 {
449 synchronize_net(); 449 synchronize_net();
450 #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) 450 #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
451 nf_conntrack_ipv4_compat_fini(); 451 nf_conntrack_ipv4_compat_fini();
452 #endif 452 #endif
453 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); 453 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
454 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); 454 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
455 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmp); 455 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmp);
456 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp4); 456 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udp4);
457 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp4); 457 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_tcp4);
458 nf_unregister_sockopt(&so_getorigdst); 458 nf_unregister_sockopt(&so_getorigdst);
459 } 459 }
460 460
461 module_init(nf_conntrack_l3proto_ipv4_init); 461 module_init(nf_conntrack_l3proto_ipv4_init);
462 module_exit(nf_conntrack_l3proto_ipv4_fini); 462 module_exit(nf_conntrack_l3proto_ipv4_fini);
463 463
464 void need_ipv4_conntrack(void) 464 void need_ipv4_conntrack(void)
465 { 465 {
466 return; 466 return;
467 } 467 }
468 EXPORT_SYMBOL_GPL(need_ipv4_conntrack); 468 EXPORT_SYMBOL_GPL(need_ipv4_conntrack);
469 469
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
1 /* 1 /*
2 * Copyright (C)2004 USAGI/WIDE Project 2 * Copyright (C)2004 USAGI/WIDE Project
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 * 7 *
8 * Author: 8 * Author:
9 * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> 9 * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
10 */ 10 */
11 11
12 #include <linux/types.h> 12 #include <linux/types.h>
13 #include <linux/ipv6.h> 13 #include <linux/ipv6.h>
14 #include <linux/in6.h> 14 #include <linux/in6.h>
15 #include <linux/netfilter.h> 15 #include <linux/netfilter.h>
16 #include <linux/module.h> 16 #include <linux/module.h>
17 #include <linux/skbuff.h> 17 #include <linux/skbuff.h>
18 #include <linux/icmp.h> 18 #include <linux/icmp.h>
19 #include <net/ipv6.h> 19 #include <net/ipv6.h>
20 #include <net/inet_frag.h> 20 #include <net/inet_frag.h>
21 21
22 #include <linux/netfilter_bridge.h> 22 #include <linux/netfilter_bridge.h>
23 #include <linux/netfilter_ipv6.h> 23 #include <linux/netfilter_ipv6.h>
24 #include <net/netfilter/nf_conntrack.h> 24 #include <net/netfilter/nf_conntrack.h>
25 #include <net/netfilter/nf_conntrack_helper.h> 25 #include <net/netfilter/nf_conntrack_helper.h>
26 #include <net/netfilter/nf_conntrack_l4proto.h> 26 #include <net/netfilter/nf_conntrack_l4proto.h>
27 #include <net/netfilter/nf_conntrack_l3proto.h> 27 #include <net/netfilter/nf_conntrack_l3proto.h>
28 #include <net/netfilter/nf_conntrack_core.h> 28 #include <net/netfilter/nf_conntrack_core.h>
29 #include <net/netfilter/nf_conntrack_zones.h> 29 #include <net/netfilter/nf_conntrack_zones.h>
30 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h> 30 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
31 #include <net/netfilter/ipv6/nf_defrag_ipv6.h> 31 #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
32 #include <net/netfilter/nf_log.h> 32 #include <net/netfilter/nf_log.h>
33 33
34 static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, 34 static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
35 struct nf_conntrack_tuple *tuple) 35 struct nf_conntrack_tuple *tuple)
36 { 36 {
37 const u_int32_t *ap; 37 const u_int32_t *ap;
38 u_int32_t _addrs[8]; 38 u_int32_t _addrs[8];
39 39
40 ap = skb_header_pointer(skb, nhoff + offsetof(struct ipv6hdr, saddr), 40 ap = skb_header_pointer(skb, nhoff + offsetof(struct ipv6hdr, saddr),
41 sizeof(_addrs), _addrs); 41 sizeof(_addrs), _addrs);
42 if (ap == NULL) 42 if (ap == NULL)
43 return false; 43 return false;
44 44
45 memcpy(tuple->src.u3.ip6, ap, sizeof(tuple->src.u3.ip6)); 45 memcpy(tuple->src.u3.ip6, ap, sizeof(tuple->src.u3.ip6));
46 memcpy(tuple->dst.u3.ip6, ap + 4, sizeof(tuple->dst.u3.ip6)); 46 memcpy(tuple->dst.u3.ip6, ap + 4, sizeof(tuple->dst.u3.ip6));
47 47
48 return true; 48 return true;
49 } 49 }
50 50
51 static bool ipv6_invert_tuple(struct nf_conntrack_tuple *tuple, 51 static bool ipv6_invert_tuple(struct nf_conntrack_tuple *tuple,
52 const struct nf_conntrack_tuple *orig) 52 const struct nf_conntrack_tuple *orig)
53 { 53 {
54 memcpy(tuple->src.u3.ip6, orig->dst.u3.ip6, sizeof(tuple->src.u3.ip6)); 54 memcpy(tuple->src.u3.ip6, orig->dst.u3.ip6, sizeof(tuple->src.u3.ip6));
55 memcpy(tuple->dst.u3.ip6, orig->src.u3.ip6, sizeof(tuple->dst.u3.ip6)); 55 memcpy(tuple->dst.u3.ip6, orig->src.u3.ip6, sizeof(tuple->dst.u3.ip6));
56 56
57 return true; 57 return true;
58 } 58 }
59 59
60 static int ipv6_print_tuple(struct seq_file *s, 60 static int ipv6_print_tuple(struct seq_file *s,
61 const struct nf_conntrack_tuple *tuple) 61 const struct nf_conntrack_tuple *tuple)
62 { 62 {
63 return seq_printf(s, "src=%pI6 dst=%pI6 ", 63 return seq_printf(s, "src=%pI6 dst=%pI6 ",
64 tuple->src.u3.ip6, tuple->dst.u3.ip6); 64 tuple->src.u3.ip6, tuple->dst.u3.ip6);
65 } 65 }
66 66
67 /* 67 /*
68 * Based on ipv6_skip_exthdr() in net/ipv6/exthdr.c 68 * Based on ipv6_skip_exthdr() in net/ipv6/exthdr.c
69 * 69 *
70 * This function parses (probably truncated) exthdr set "hdr" 70 * This function parses (probably truncated) exthdr set "hdr"
71 * of length "len". "nexthdrp" initially points to some place, 71 * of length "len". "nexthdrp" initially points to some place,
72 * where type of the first header can be found. 72 * where type of the first header can be found.
73 * 73 *
74 * It skips all well-known exthdrs, and returns pointer to the start 74 * It skips all well-known exthdrs, and returns pointer to the start
75 * of unparsable area i.e. the first header with unknown type. 75 * of unparsable area i.e. the first header with unknown type.
76 * if success, *nexthdr is updated by type/protocol of this header. 76 * if success, *nexthdr is updated by type/protocol of this header.
77 * 77 *
78 * NOTES: - it may return pointer pointing beyond end of packet, 78 * NOTES: - it may return pointer pointing beyond end of packet,
79 * if the last recognized header is truncated in the middle. 79 * if the last recognized header is truncated in the middle.
80 * - if packet is truncated, so that all parsed headers are skipped, 80 * - if packet is truncated, so that all parsed headers are skipped,
81 * it returns -1. 81 * it returns -1.
82 * - if packet is fragmented, return pointer of the fragment header. 82 * - if packet is fragmented, return pointer of the fragment header.
83 * - ESP is unparsable for now and considered like 83 * - ESP is unparsable for now and considered like
84 * normal payload protocol. 84 * normal payload protocol.
85 * - Note also special handling of AUTH header. Thanks to IPsec wizards. 85 * - Note also special handling of AUTH header. Thanks to IPsec wizards.
86 */ 86 */
87 87
88 static int nf_ct_ipv6_skip_exthdr(const struct sk_buff *skb, int start, 88 static int nf_ct_ipv6_skip_exthdr(const struct sk_buff *skb, int start,
89 u8 *nexthdrp, int len) 89 u8 *nexthdrp, int len)
90 { 90 {
91 u8 nexthdr = *nexthdrp; 91 u8 nexthdr = *nexthdrp;
92 92
93 while (ipv6_ext_hdr(nexthdr)) { 93 while (ipv6_ext_hdr(nexthdr)) {
94 struct ipv6_opt_hdr hdr; 94 struct ipv6_opt_hdr hdr;
95 int hdrlen; 95 int hdrlen;
96 96
97 if (len < (int)sizeof(struct ipv6_opt_hdr)) 97 if (len < (int)sizeof(struct ipv6_opt_hdr))
98 return -1; 98 return -1;
99 if (nexthdr == NEXTHDR_NONE) 99 if (nexthdr == NEXTHDR_NONE)
100 break; 100 break;
101 if (nexthdr == NEXTHDR_FRAGMENT) 101 if (nexthdr == NEXTHDR_FRAGMENT)
102 break; 102 break;
103 if (skb_copy_bits(skb, start, &hdr, sizeof(hdr))) 103 if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
104 BUG(); 104 BUG();
105 if (nexthdr == NEXTHDR_AUTH) 105 if (nexthdr == NEXTHDR_AUTH)
106 hdrlen = (hdr.hdrlen+2)<<2; 106 hdrlen = (hdr.hdrlen+2)<<2;
107 else 107 else
108 hdrlen = ipv6_optlen(&hdr); 108 hdrlen = ipv6_optlen(&hdr);
109 109
110 nexthdr = hdr.nexthdr; 110 nexthdr = hdr.nexthdr;
111 len -= hdrlen; 111 len -= hdrlen;
112 start += hdrlen; 112 start += hdrlen;
113 } 113 }
114 114
115 *nexthdrp = nexthdr; 115 *nexthdrp = nexthdr;
116 return start; 116 return start;
117 } 117 }
118 118
119 static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, 119 static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
120 unsigned int *dataoff, u_int8_t *protonum) 120 unsigned int *dataoff, u_int8_t *protonum)
121 { 121 {
122 unsigned int extoff = nhoff + sizeof(struct ipv6hdr); 122 unsigned int extoff = nhoff + sizeof(struct ipv6hdr);
123 unsigned char pnum; 123 unsigned char pnum;
124 int protoff; 124 int protoff;
125 125
126 if (skb_copy_bits(skb, nhoff + offsetof(struct ipv6hdr, nexthdr), 126 if (skb_copy_bits(skb, nhoff + offsetof(struct ipv6hdr, nexthdr),
127 &pnum, sizeof(pnum)) != 0) { 127 &pnum, sizeof(pnum)) != 0) {
128 pr_debug("ip6_conntrack_core: can't get nexthdr\n"); 128 pr_debug("ip6_conntrack_core: can't get nexthdr\n");
129 return -NF_ACCEPT; 129 return -NF_ACCEPT;
130 } 130 }
131 protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum, skb->len - extoff); 131 protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum, skb->len - extoff);
132 /* 132 /*
133 * (protoff == skb->len) mean that the packet doesn't have no data 133 * (protoff == skb->len) mean that the packet doesn't have no data
134 * except of IPv6 & ext headers. but it's tracked anyway. - YK 134 * except of IPv6 & ext headers. but it's tracked anyway. - YK
135 */ 135 */
136 if ((protoff < 0) || (protoff > skb->len)) { 136 if ((protoff < 0) || (protoff > skb->len)) {
137 pr_debug("ip6_conntrack_core: can't find proto in pkt\n"); 137 pr_debug("ip6_conntrack_core: can't find proto in pkt\n");
138 return -NF_ACCEPT; 138 return -NF_ACCEPT;
139 } 139 }
140 140
141 *dataoff = protoff; 141 *dataoff = protoff;
142 *protonum = pnum; 142 *protonum = pnum;
143 return NF_ACCEPT; 143 return NF_ACCEPT;
144 } 144 }
145 145
146 static unsigned int ipv6_confirm(unsigned int hooknum, 146 static unsigned int ipv6_confirm(unsigned int hooknum,
147 struct sk_buff *skb, 147 struct sk_buff *skb,
148 const struct net_device *in, 148 const struct net_device *in,
149 const struct net_device *out, 149 const struct net_device *out,
150 int (*okfn)(struct sk_buff *)) 150 int (*okfn)(struct sk_buff *))
151 { 151 {
152 struct nf_conn *ct; 152 struct nf_conn *ct;
153 const struct nf_conn_help *help; 153 const struct nf_conn_help *help;
154 const struct nf_conntrack_helper *helper; 154 const struct nf_conntrack_helper *helper;
155 enum ip_conntrack_info ctinfo; 155 enum ip_conntrack_info ctinfo;
156 unsigned int ret, protoff; 156 unsigned int ret, protoff;
157 unsigned int extoff = (u8 *)(ipv6_hdr(skb) + 1) - skb->data; 157 unsigned int extoff = (u8 *)(ipv6_hdr(skb) + 1) - skb->data;
158 unsigned char pnum = ipv6_hdr(skb)->nexthdr; 158 unsigned char pnum = ipv6_hdr(skb)->nexthdr;
159 159
160 160
161 /* This is where we call the helper: as the packet goes out. */ 161 /* This is where we call the helper: as the packet goes out. */
162 ct = nf_ct_get(skb, &ctinfo); 162 ct = nf_ct_get(skb, &ctinfo);
163 if (!ct || ctinfo == IP_CT_RELATED_REPLY) 163 if (!ct || ctinfo == IP_CT_RELATED_REPLY)
164 goto out; 164 goto out;
165 165
166 help = nfct_help(ct); 166 help = nfct_help(ct);
167 if (!help) 167 if (!help)
168 goto out; 168 goto out;
169 /* rcu_read_lock()ed by nf_hook_slow */ 169 /* rcu_read_lock()ed by nf_hook_slow */
170 helper = rcu_dereference(help->helper); 170 helper = rcu_dereference(help->helper);
171 if (!helper) 171 if (!helper)
172 goto out; 172 goto out;
173 173
174 protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum, 174 protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum,
175 skb->len - extoff); 175 skb->len - extoff);
176 if (protoff > skb->len || pnum == NEXTHDR_FRAGMENT) { 176 if (protoff > skb->len || pnum == NEXTHDR_FRAGMENT) {
177 pr_debug("proto header not found\n"); 177 pr_debug("proto header not found\n");
178 return NF_ACCEPT; 178 return NF_ACCEPT;
179 } 179 }
180 180
181 ret = helper->help(skb, protoff, ct, ctinfo); 181 ret = helper->help(skb, protoff, ct, ctinfo);
182 if (ret != NF_ACCEPT) { 182 if (ret != NF_ACCEPT) {
183 nf_log_packet(NFPROTO_IPV6, hooknum, skb, in, out, NULL, 183 nf_log_packet(NFPROTO_IPV6, hooknum, skb, in, out, NULL,
184 "nf_ct_%s: dropping packet", helper->name); 184 "nf_ct_%s: dropping packet", helper->name);
185 return ret; 185 return ret;
186 } 186 }
187 out: 187 out:
188 /* We've seen it coming out the other side: confirm it */ 188 /* We've seen it coming out the other side: confirm it */
189 return nf_conntrack_confirm(skb); 189 return nf_conntrack_confirm(skb);
190 } 190 }
191 191
192 static unsigned int __ipv6_conntrack_in(struct net *net, 192 static unsigned int __ipv6_conntrack_in(struct net *net,
193 unsigned int hooknum, 193 unsigned int hooknum,
194 struct sk_buff *skb, 194 struct sk_buff *skb,
195 int (*okfn)(struct sk_buff *)) 195 int (*okfn)(struct sk_buff *))
196 { 196 {
197 struct sk_buff *reasm = skb->nfct_reasm; 197 struct sk_buff *reasm = skb->nfct_reasm;
198 198
199 /* This packet is fragmented and has reassembled packet. */ 199 /* This packet is fragmented and has reassembled packet. */
200 if (reasm) { 200 if (reasm) {
201 /* Reassembled packet isn't parsed yet ? */ 201 /* Reassembled packet isn't parsed yet ? */
202 if (!reasm->nfct) { 202 if (!reasm->nfct) {
203 unsigned int ret; 203 unsigned int ret;
204 204
205 ret = nf_conntrack_in(net, PF_INET6, hooknum, reasm); 205 ret = nf_conntrack_in(net, PF_INET6, hooknum, reasm);
206 if (ret != NF_ACCEPT) 206 if (ret != NF_ACCEPT)
207 return ret; 207 return ret;
208 } 208 }
209 nf_conntrack_get(reasm->nfct); 209 nf_conntrack_get(reasm->nfct);
210 skb->nfct = reasm->nfct; 210 skb->nfct = reasm->nfct;
211 skb->nfctinfo = reasm->nfctinfo; 211 skb->nfctinfo = reasm->nfctinfo;
212 return NF_ACCEPT; 212 return NF_ACCEPT;
213 } 213 }
214 214
215 return nf_conntrack_in(net, PF_INET6, hooknum, skb); 215 return nf_conntrack_in(net, PF_INET6, hooknum, skb);
216 } 216 }
217 217
218 static unsigned int ipv6_conntrack_in(unsigned int hooknum, 218 static unsigned int ipv6_conntrack_in(unsigned int hooknum,
219 struct sk_buff *skb, 219 struct sk_buff *skb,
220 const struct net_device *in, 220 const struct net_device *in,
221 const struct net_device *out, 221 const struct net_device *out,
222 int (*okfn)(struct sk_buff *)) 222 int (*okfn)(struct sk_buff *))
223 { 223 {
224 return __ipv6_conntrack_in(dev_net(in), hooknum, skb, okfn); 224 return __ipv6_conntrack_in(dev_net(in), hooknum, skb, okfn);
225 } 225 }
226 226
227 static unsigned int ipv6_conntrack_local(unsigned int hooknum, 227 static unsigned int ipv6_conntrack_local(unsigned int hooknum,
228 struct sk_buff *skb, 228 struct sk_buff *skb,
229 const struct net_device *in, 229 const struct net_device *in,
230 const struct net_device *out, 230 const struct net_device *out,
231 int (*okfn)(struct sk_buff *)) 231 int (*okfn)(struct sk_buff *))
232 { 232 {
233 /* root is playing with raw sockets. */ 233 /* root is playing with raw sockets. */
234 if (skb->len < sizeof(struct ipv6hdr)) { 234 if (skb->len < sizeof(struct ipv6hdr)) {
235 net_notice_ratelimited("ipv6_conntrack_local: packet too short\n"); 235 net_notice_ratelimited("ipv6_conntrack_local: packet too short\n");
236 return NF_ACCEPT; 236 return NF_ACCEPT;
237 } 237 }
238 return __ipv6_conntrack_in(dev_net(out), hooknum, skb, okfn); 238 return __ipv6_conntrack_in(dev_net(out), hooknum, skb, okfn);
239 } 239 }
240 240
241 static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { 241 static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
242 { 242 {
243 .hook = ipv6_conntrack_in, 243 .hook = ipv6_conntrack_in,
244 .owner = THIS_MODULE, 244 .owner = THIS_MODULE,
245 .pf = NFPROTO_IPV6, 245 .pf = NFPROTO_IPV6,
246 .hooknum = NF_INET_PRE_ROUTING, 246 .hooknum = NF_INET_PRE_ROUTING,
247 .priority = NF_IP6_PRI_CONNTRACK, 247 .priority = NF_IP6_PRI_CONNTRACK,
248 }, 248 },
249 { 249 {
250 .hook = ipv6_conntrack_local, 250 .hook = ipv6_conntrack_local,
251 .owner = THIS_MODULE, 251 .owner = THIS_MODULE,
252 .pf = NFPROTO_IPV6, 252 .pf = NFPROTO_IPV6,
253 .hooknum = NF_INET_LOCAL_OUT, 253 .hooknum = NF_INET_LOCAL_OUT,
254 .priority = NF_IP6_PRI_CONNTRACK, 254 .priority = NF_IP6_PRI_CONNTRACK,
255 }, 255 },
256 { 256 {
257 .hook = ipv6_confirm, 257 .hook = ipv6_confirm,
258 .owner = THIS_MODULE, 258 .owner = THIS_MODULE,
259 .pf = NFPROTO_IPV6, 259 .pf = NFPROTO_IPV6,
260 .hooknum = NF_INET_POST_ROUTING, 260 .hooknum = NF_INET_POST_ROUTING,
261 .priority = NF_IP6_PRI_LAST, 261 .priority = NF_IP6_PRI_LAST,
262 }, 262 },
263 { 263 {
264 .hook = ipv6_confirm, 264 .hook = ipv6_confirm,
265 .owner = THIS_MODULE, 265 .owner = THIS_MODULE,
266 .pf = NFPROTO_IPV6, 266 .pf = NFPROTO_IPV6,
267 .hooknum = NF_INET_LOCAL_IN, 267 .hooknum = NF_INET_LOCAL_IN,
268 .priority = NF_IP6_PRI_LAST-1, 268 .priority = NF_IP6_PRI_LAST-1,
269 }, 269 },
270 }; 270 };
271 271
272 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 272 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
273 273
274 #include <linux/netfilter/nfnetlink.h> 274 #include <linux/netfilter/nfnetlink.h>
275 #include <linux/netfilter/nfnetlink_conntrack.h> 275 #include <linux/netfilter/nfnetlink_conntrack.h>
276 276
277 static int ipv6_tuple_to_nlattr(struct sk_buff *skb, 277 static int ipv6_tuple_to_nlattr(struct sk_buff *skb,
278 const struct nf_conntrack_tuple *tuple) 278 const struct nf_conntrack_tuple *tuple)
279 { 279 {
280 if (nla_put(skb, CTA_IP_V6_SRC, sizeof(u_int32_t) * 4, 280 if (nla_put(skb, CTA_IP_V6_SRC, sizeof(u_int32_t) * 4,
281 &tuple->src.u3.ip6) || 281 &tuple->src.u3.ip6) ||
282 nla_put(skb, CTA_IP_V6_DST, sizeof(u_int32_t) * 4, 282 nla_put(skb, CTA_IP_V6_DST, sizeof(u_int32_t) * 4,
283 &tuple->dst.u3.ip6)) 283 &tuple->dst.u3.ip6))
284 goto nla_put_failure; 284 goto nla_put_failure;
285 return 0; 285 return 0;
286 286
287 nla_put_failure: 287 nla_put_failure:
288 return -1; 288 return -1;
289 } 289 }
290 290
291 static const struct nla_policy ipv6_nla_policy[CTA_IP_MAX+1] = { 291 static const struct nla_policy ipv6_nla_policy[CTA_IP_MAX+1] = {
292 [CTA_IP_V6_SRC] = { .len = sizeof(u_int32_t)*4 }, 292 [CTA_IP_V6_SRC] = { .len = sizeof(u_int32_t)*4 },
293 [CTA_IP_V6_DST] = { .len = sizeof(u_int32_t)*4 }, 293 [CTA_IP_V6_DST] = { .len = sizeof(u_int32_t)*4 },
294 }; 294 };
295 295
296 static int ipv6_nlattr_to_tuple(struct nlattr *tb[], 296 static int ipv6_nlattr_to_tuple(struct nlattr *tb[],
297 struct nf_conntrack_tuple *t) 297 struct nf_conntrack_tuple *t)
298 { 298 {
299 if (!tb[CTA_IP_V6_SRC] || !tb[CTA_IP_V6_DST]) 299 if (!tb[CTA_IP_V6_SRC] || !tb[CTA_IP_V6_DST])
300 return -EINVAL; 300 return -EINVAL;
301 301
302 memcpy(&t->src.u3.ip6, nla_data(tb[CTA_IP_V6_SRC]), 302 memcpy(&t->src.u3.ip6, nla_data(tb[CTA_IP_V6_SRC]),
303 sizeof(u_int32_t) * 4); 303 sizeof(u_int32_t) * 4);
304 memcpy(&t->dst.u3.ip6, nla_data(tb[CTA_IP_V6_DST]), 304 memcpy(&t->dst.u3.ip6, nla_data(tb[CTA_IP_V6_DST]),
305 sizeof(u_int32_t) * 4); 305 sizeof(u_int32_t) * 4);
306 306
307 return 0; 307 return 0;
308 } 308 }
309 309
310 static int ipv6_nlattr_tuple_size(void) 310 static int ipv6_nlattr_tuple_size(void)
311 { 311 {
312 return nla_policy_len(ipv6_nla_policy, CTA_IP_MAX + 1); 312 return nla_policy_len(ipv6_nla_policy, CTA_IP_MAX + 1);
313 } 313 }
314 #endif 314 #endif
315 315
316 struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = { 316 struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
317 .l3proto = PF_INET6, 317 .l3proto = PF_INET6,
318 .name = "ipv6", 318 .name = "ipv6",
319 .pkt_to_tuple = ipv6_pkt_to_tuple, 319 .pkt_to_tuple = ipv6_pkt_to_tuple,
320 .invert_tuple = ipv6_invert_tuple, 320 .invert_tuple = ipv6_invert_tuple,
321 .print_tuple = ipv6_print_tuple, 321 .print_tuple = ipv6_print_tuple,
322 .get_l4proto = ipv6_get_l4proto, 322 .get_l4proto = ipv6_get_l4proto,
323 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 323 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
324 .tuple_to_nlattr = ipv6_tuple_to_nlattr, 324 .tuple_to_nlattr = ipv6_tuple_to_nlattr,
325 .nlattr_tuple_size = ipv6_nlattr_tuple_size, 325 .nlattr_tuple_size = ipv6_nlattr_tuple_size,
326 .nlattr_to_tuple = ipv6_nlattr_to_tuple, 326 .nlattr_to_tuple = ipv6_nlattr_to_tuple,
327 .nla_policy = ipv6_nla_policy, 327 .nla_policy = ipv6_nla_policy,
328 #endif 328 #endif
329 .me = THIS_MODULE, 329 .me = THIS_MODULE,
330 }; 330 };
331 331
332 MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6)); 332 MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6));
333 MODULE_LICENSE("GPL"); 333 MODULE_LICENSE("GPL");
334 MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>"); 334 MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>");
335 335
336 static int __init nf_conntrack_l3proto_ipv6_init(void) 336 static int __init nf_conntrack_l3proto_ipv6_init(void)
337 { 337 {
338 int ret = 0; 338 int ret = 0;
339 339
340 need_conntrack(); 340 need_conntrack();
341 nf_defrag_ipv6_enable(); 341 nf_defrag_ipv6_enable();
342 342
343 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6); 343 ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_tcp6);
344 if (ret < 0) { 344 if (ret < 0) {
345 pr_err("nf_conntrack_ipv6: can't register tcp.\n"); 345 pr_err("nf_conntrack_ipv6: can't register tcp.\n");
346 return ret; 346 return ret;
347 } 347 }
348 348
349 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6); 349 ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_udp6);
350 if (ret < 0) { 350 if (ret < 0) {
351 pr_err("nf_conntrack_ipv6: can't register udp.\n"); 351 pr_err("nf_conntrack_ipv6: can't register udp.\n");
352 goto cleanup_tcp; 352 goto cleanup_tcp;
353 } 353 }
354 354
355 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmpv6); 355 ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_icmpv6);
356 if (ret < 0) { 356 if (ret < 0) {
357 pr_err("nf_conntrack_ipv6: can't register icmpv6.\n"); 357 pr_err("nf_conntrack_ipv6: can't register icmpv6.\n");
358 goto cleanup_udp; 358 goto cleanup_udp;
359 } 359 }
360 360
361 ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv6); 361 ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv6);
362 if (ret < 0) { 362 if (ret < 0) {
363 pr_err("nf_conntrack_ipv6: can't register ipv6\n"); 363 pr_err("nf_conntrack_ipv6: can't register ipv6\n");
364 goto cleanup_icmpv6; 364 goto cleanup_icmpv6;
365 } 365 }
366 366
367 ret = nf_register_hooks(ipv6_conntrack_ops, 367 ret = nf_register_hooks(ipv6_conntrack_ops,
368 ARRAY_SIZE(ipv6_conntrack_ops)); 368 ARRAY_SIZE(ipv6_conntrack_ops));
369 if (ret < 0) { 369 if (ret < 0) {
370 pr_err("nf_conntrack_ipv6: can't register pre-routing defrag " 370 pr_err("nf_conntrack_ipv6: can't register pre-routing defrag "
371 "hook.\n"); 371 "hook.\n");
372 goto cleanup_ipv6; 372 goto cleanup_ipv6;
373 } 373 }
374 return ret; 374 return ret;
375 375
376 cleanup_ipv6: 376 cleanup_ipv6:
377 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); 377 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
378 cleanup_icmpv6: 378 cleanup_icmpv6:
379 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6); 379 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmpv6);
380 cleanup_udp: 380 cleanup_udp:
381 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); 381 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udp6);
382 cleanup_tcp: 382 cleanup_tcp:
383 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); 383 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_tcp6);
384 return ret; 384 return ret;
385 } 385 }
386 386
387 static void __exit nf_conntrack_l3proto_ipv6_fini(void) 387 static void __exit nf_conntrack_l3proto_ipv6_fini(void)
388 { 388 {
389 synchronize_net(); 389 synchronize_net();
390 nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops)); 390 nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
391 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); 391 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
392 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6); 392 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_icmpv6);
393 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); 393 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udp6);
394 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); 394 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_tcp6);
395 } 395 }
396 396
397 module_init(nf_conntrack_l3proto_ipv6_init); 397 module_init(nf_conntrack_l3proto_ipv6_init);
398 module_exit(nf_conntrack_l3proto_ipv6_fini); 398 module_exit(nf_conntrack_l3proto_ipv6_fini);
399 399
net/netfilter/nf_conntrack_proto.c
1 /* L3/L4 protocol support for nf_conntrack. */ 1 /* L3/L4 protocol support for nf_conntrack. */
2 2
3 /* (C) 1999-2001 Paul `Rusty' Russell 3 /* (C) 1999-2001 Paul `Rusty' Russell
4 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org> 4 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
5 * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org> 5 * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12 #include <linux/types.h> 12 #include <linux/types.h>
13 #include <linux/netfilter.h> 13 #include <linux/netfilter.h>
14 #include <linux/module.h> 14 #include <linux/module.h>
15 #include <linux/slab.h> 15 #include <linux/slab.h>
16 #include <linux/mutex.h> 16 #include <linux/mutex.h>
17 #include <linux/vmalloc.h> 17 #include <linux/vmalloc.h>
18 #include <linux/stddef.h> 18 #include <linux/stddef.h>
19 #include <linux/err.h> 19 #include <linux/err.h>
20 #include <linux/percpu.h> 20 #include <linux/percpu.h>
21 #include <linux/notifier.h> 21 #include <linux/notifier.h>
22 #include <linux/kernel.h> 22 #include <linux/kernel.h>
23 #include <linux/netdevice.h> 23 #include <linux/netdevice.h>
24 #include <linux/rtnetlink.h> 24 #include <linux/rtnetlink.h>
25 25
26 #include <net/netfilter/nf_conntrack.h> 26 #include <net/netfilter/nf_conntrack.h>
27 #include <net/netfilter/nf_conntrack_l3proto.h> 27 #include <net/netfilter/nf_conntrack_l3proto.h>
28 #include <net/netfilter/nf_conntrack_l4proto.h> 28 #include <net/netfilter/nf_conntrack_l4proto.h>
29 #include <net/netfilter/nf_conntrack_core.h> 29 #include <net/netfilter/nf_conntrack_core.h>
30 30
31 static struct nf_conntrack_l4proto __rcu **nf_ct_protos[PF_MAX] __read_mostly; 31 static struct nf_conntrack_l4proto __rcu **nf_ct_protos[PF_MAX] __read_mostly;
32 struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[AF_MAX] __read_mostly; 32 struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[AF_MAX] __read_mostly;
33 EXPORT_SYMBOL_GPL(nf_ct_l3protos); 33 EXPORT_SYMBOL_GPL(nf_ct_l3protos);
34 34
35 static DEFINE_MUTEX(nf_ct_proto_mutex); 35 static DEFINE_MUTEX(nf_ct_proto_mutex);
36 36
37 #ifdef CONFIG_SYSCTL 37 #ifdef CONFIG_SYSCTL
38 static int 38 static int
39 nf_ct_register_sysctl(struct ctl_table_header **header, const char *path, 39 nf_ct_register_sysctl(struct net *net,
40 struct ctl_table *table, unsigned int *users) 40 struct ctl_table_header **header,
41 const char *path,
42 struct ctl_table *table,
43 unsigned int *users)
41 { 44 {
42 if (*header == NULL) { 45 if (*header == NULL) {
43 *header = register_net_sysctl(&init_net, path, table); 46 *header = register_net_sysctl(net, path, table);
44 if (*header == NULL) 47 if (*header == NULL)
45 return -ENOMEM; 48 return -ENOMEM;
46 } 49 }
47 if (users != NULL) 50 if (users != NULL)
48 (*users)++; 51 (*users)++;
52
49 return 0; 53 return 0;
50 } 54 }
51 55
52 static void 56 static void
53 nf_ct_unregister_sysctl(struct ctl_table_header **header, 57 nf_ct_unregister_sysctl(struct ctl_table_header **header,
54 struct ctl_table *table, unsigned int *users) 58 struct ctl_table **table,
59 unsigned int *users)
55 { 60 {
56 if (users != NULL && --*users > 0) 61 if (users != NULL && --*users > 0)
57 return; 62 return;
58 63
59 unregister_net_sysctl_table(*header); 64 unregister_net_sysctl_table(*header);
65 kfree(*table);
60 *header = NULL; 66 *header = NULL;
67 *table = NULL;
61 } 68 }
62 #endif 69 #endif
63 70
64 struct nf_conntrack_l4proto * 71 struct nf_conntrack_l4proto *
65 __nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto) 72 __nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto)
66 { 73 {
67 if (unlikely(l3proto >= AF_MAX || nf_ct_protos[l3proto] == NULL)) 74 if (unlikely(l3proto >= AF_MAX || nf_ct_protos[l3proto] == NULL))
68 return &nf_conntrack_l4proto_generic; 75 return &nf_conntrack_l4proto_generic;
69 76
70 return rcu_dereference(nf_ct_protos[l3proto][l4proto]); 77 return rcu_dereference(nf_ct_protos[l3proto][l4proto]);
71 } 78 }
72 EXPORT_SYMBOL_GPL(__nf_ct_l4proto_find); 79 EXPORT_SYMBOL_GPL(__nf_ct_l4proto_find);
73 80
74 /* this is guaranteed to always return a valid protocol helper, since 81 /* this is guaranteed to always return a valid protocol helper, since
75 * it falls back to generic_protocol */ 82 * it falls back to generic_protocol */
76 struct nf_conntrack_l3proto * 83 struct nf_conntrack_l3proto *
77 nf_ct_l3proto_find_get(u_int16_t l3proto) 84 nf_ct_l3proto_find_get(u_int16_t l3proto)
78 { 85 {
79 struct nf_conntrack_l3proto *p; 86 struct nf_conntrack_l3proto *p;
80 87
81 rcu_read_lock(); 88 rcu_read_lock();
82 p = __nf_ct_l3proto_find(l3proto); 89 p = __nf_ct_l3proto_find(l3proto);
83 if (!try_module_get(p->me)) 90 if (!try_module_get(p->me))
84 p = &nf_conntrack_l3proto_generic; 91 p = &nf_conntrack_l3proto_generic;
85 rcu_read_unlock(); 92 rcu_read_unlock();
86 93
87 return p; 94 return p;
88 } 95 }
89 EXPORT_SYMBOL_GPL(nf_ct_l3proto_find_get); 96 EXPORT_SYMBOL_GPL(nf_ct_l3proto_find_get);
90 97
91 void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p) 98 void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p)
92 { 99 {
93 module_put(p->me); 100 module_put(p->me);
94 } 101 }
95 EXPORT_SYMBOL_GPL(nf_ct_l3proto_put); 102 EXPORT_SYMBOL_GPL(nf_ct_l3proto_put);
96 103
97 int 104 int
98 nf_ct_l3proto_try_module_get(unsigned short l3proto) 105 nf_ct_l3proto_try_module_get(unsigned short l3proto)
99 { 106 {
100 int ret; 107 int ret;
101 struct nf_conntrack_l3proto *p; 108 struct nf_conntrack_l3proto *p;
102 109
103 retry: p = nf_ct_l3proto_find_get(l3proto); 110 retry: p = nf_ct_l3proto_find_get(l3proto);
104 if (p == &nf_conntrack_l3proto_generic) { 111 if (p == &nf_conntrack_l3proto_generic) {
105 ret = request_module("nf_conntrack-%d", l3proto); 112 ret = request_module("nf_conntrack-%d", l3proto);
106 if (!ret) 113 if (!ret)
107 goto retry; 114 goto retry;
108 115
109 return -EPROTOTYPE; 116 return -EPROTOTYPE;
110 } 117 }
111 118
112 return 0; 119 return 0;
113 } 120 }
114 EXPORT_SYMBOL_GPL(nf_ct_l3proto_try_module_get); 121 EXPORT_SYMBOL_GPL(nf_ct_l3proto_try_module_get);
115 122
116 void nf_ct_l3proto_module_put(unsigned short l3proto) 123 void nf_ct_l3proto_module_put(unsigned short l3proto)
117 { 124 {
118 struct nf_conntrack_l3proto *p; 125 struct nf_conntrack_l3proto *p;
119 126
120 /* rcu_read_lock not necessary since the caller holds a reference, but 127 /* rcu_read_lock not necessary since the caller holds a reference, but
121 * taken anyways to avoid lockdep warnings in __nf_ct_l3proto_find() 128 * taken anyways to avoid lockdep warnings in __nf_ct_l3proto_find()
122 */ 129 */
123 rcu_read_lock(); 130 rcu_read_lock();
124 p = __nf_ct_l3proto_find(l3proto); 131 p = __nf_ct_l3proto_find(l3proto);
125 module_put(p->me); 132 module_put(p->me);
126 rcu_read_unlock(); 133 rcu_read_unlock();
127 } 134 }
128 EXPORT_SYMBOL_GPL(nf_ct_l3proto_module_put); 135 EXPORT_SYMBOL_GPL(nf_ct_l3proto_module_put);
129 136
130 struct nf_conntrack_l4proto * 137 struct nf_conntrack_l4proto *
131 nf_ct_l4proto_find_get(u_int16_t l3num, u_int8_t l4num) 138 nf_ct_l4proto_find_get(u_int16_t l3num, u_int8_t l4num)
132 { 139 {
133 struct nf_conntrack_l4proto *p; 140 struct nf_conntrack_l4proto *p;
134 141
135 rcu_read_lock(); 142 rcu_read_lock();
136 p = __nf_ct_l4proto_find(l3num, l4num); 143 p = __nf_ct_l4proto_find(l3num, l4num);
137 if (!try_module_get(p->me)) 144 if (!try_module_get(p->me))
138 p = &nf_conntrack_l4proto_generic; 145 p = &nf_conntrack_l4proto_generic;
139 rcu_read_unlock(); 146 rcu_read_unlock();
140 147
141 return p; 148 return p;
142 } 149 }
143 EXPORT_SYMBOL_GPL(nf_ct_l4proto_find_get); 150 EXPORT_SYMBOL_GPL(nf_ct_l4proto_find_get);
144 151
145 void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p) 152 void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p)
146 { 153 {
147 module_put(p->me); 154 module_put(p->me);
148 } 155 }
149 EXPORT_SYMBOL_GPL(nf_ct_l4proto_put); 156 EXPORT_SYMBOL_GPL(nf_ct_l4proto_put);
150 157
151 static int kill_l3proto(struct nf_conn *i, void *data) 158 static int kill_l3proto(struct nf_conn *i, void *data)
152 { 159 {
153 return nf_ct_l3num(i) == ((struct nf_conntrack_l3proto *)data)->l3proto; 160 return nf_ct_l3num(i) == ((struct nf_conntrack_l3proto *)data)->l3proto;
154 } 161 }
155 162
156 static int kill_l4proto(struct nf_conn *i, void *data) 163 static int kill_l4proto(struct nf_conn *i, void *data)
157 { 164 {
158 struct nf_conntrack_l4proto *l4proto; 165 struct nf_conntrack_l4proto *l4proto;
159 l4proto = (struct nf_conntrack_l4proto *)data; 166 l4proto = (struct nf_conntrack_l4proto *)data;
160 return nf_ct_protonum(i) == l4proto->l4proto && 167 return nf_ct_protonum(i) == l4proto->l4proto &&
161 nf_ct_l3num(i) == l4proto->l3proto; 168 nf_ct_l3num(i) == l4proto->l3proto;
162 } 169 }
163 170
164 static int nf_ct_l3proto_register_sysctl(struct nf_conntrack_l3proto *l3proto) 171 static int nf_ct_l3proto_register_sysctl(struct nf_conntrack_l3proto *l3proto)
165 { 172 {
166 int err = 0; 173 int err = 0;
167 174
168 #ifdef CONFIG_SYSCTL 175 #ifdef CONFIG_SYSCTL
169 if (l3proto->ctl_table != NULL) { 176 if (l3proto->ctl_table != NULL) {
170 err = nf_ct_register_sysctl(&l3proto->ctl_table_header, 177 err = nf_ct_register_sysctl(&init_net,
178 &l3proto->ctl_table_header,
171 l3proto->ctl_table_path, 179 l3proto->ctl_table_path,
172 l3proto->ctl_table, NULL); 180 l3proto->ctl_table, NULL);
173 } 181 }
174 #endif 182 #endif
175 return err; 183 return err;
176 } 184 }
177 185
178 static void nf_ct_l3proto_unregister_sysctl(struct nf_conntrack_l3proto *l3proto) 186 static void nf_ct_l3proto_unregister_sysctl(struct nf_conntrack_l3proto *l3proto)
179 { 187 {
180 #ifdef CONFIG_SYSCTL 188 #ifdef CONFIG_SYSCTL
181 if (l3proto->ctl_table_header != NULL) 189 if (l3proto->ctl_table_header != NULL)
182 nf_ct_unregister_sysctl(&l3proto->ctl_table_header, 190 nf_ct_unregister_sysctl(&l3proto->ctl_table_header,
183 l3proto->ctl_table, NULL); 191 &l3proto->ctl_table, NULL);
184 #endif 192 #endif
185 } 193 }
186 194
187 int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto) 195 int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
188 { 196 {
189 int ret = 0; 197 int ret = 0;
190 struct nf_conntrack_l3proto *old; 198 struct nf_conntrack_l3proto *old;
191 199
192 if (proto->l3proto >= AF_MAX) 200 if (proto->l3proto >= AF_MAX)
193 return -EBUSY; 201 return -EBUSY;
194 202
195 if (proto->tuple_to_nlattr && !proto->nlattr_tuple_size) 203 if (proto->tuple_to_nlattr && !proto->nlattr_tuple_size)
196 return -EINVAL; 204 return -EINVAL;
197 205
198 mutex_lock(&nf_ct_proto_mutex); 206 mutex_lock(&nf_ct_proto_mutex);
199 old = rcu_dereference_protected(nf_ct_l3protos[proto->l3proto], 207 old = rcu_dereference_protected(nf_ct_l3protos[proto->l3proto],
200 lockdep_is_held(&nf_ct_proto_mutex)); 208 lockdep_is_held(&nf_ct_proto_mutex));
201 if (old != &nf_conntrack_l3proto_generic) { 209 if (old != &nf_conntrack_l3proto_generic) {
202 ret = -EBUSY; 210 ret = -EBUSY;
203 goto out_unlock; 211 goto out_unlock;
204 } 212 }
205 213
206 ret = nf_ct_l3proto_register_sysctl(proto); 214 ret = nf_ct_l3proto_register_sysctl(proto);
207 if (ret < 0) 215 if (ret < 0)
208 goto out_unlock; 216 goto out_unlock;
209 217
210 if (proto->nlattr_tuple_size) 218 if (proto->nlattr_tuple_size)
211 proto->nla_size = 3 * proto->nlattr_tuple_size(); 219 proto->nla_size = 3 * proto->nlattr_tuple_size();
212 220
213 rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], proto); 221 rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], proto);
214 222
215 out_unlock: 223 out_unlock:
216 mutex_unlock(&nf_ct_proto_mutex); 224 mutex_unlock(&nf_ct_proto_mutex);
217 return ret; 225 return ret;
218 } 226 }
219 EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register); 227 EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register);
220 228
221 void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto) 229 void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
222 { 230 {
223 struct net *net; 231 struct net *net;
224 232
225 BUG_ON(proto->l3proto >= AF_MAX); 233 BUG_ON(proto->l3proto >= AF_MAX);
226 234
227 mutex_lock(&nf_ct_proto_mutex); 235 mutex_lock(&nf_ct_proto_mutex);
228 BUG_ON(rcu_dereference_protected(nf_ct_l3protos[proto->l3proto], 236 BUG_ON(rcu_dereference_protected(nf_ct_l3protos[proto->l3proto],
229 lockdep_is_held(&nf_ct_proto_mutex) 237 lockdep_is_held(&nf_ct_proto_mutex)
230 ) != proto); 238 ) != proto);
231 rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], 239 rcu_assign_pointer(nf_ct_l3protos[proto->l3proto],
232 &nf_conntrack_l3proto_generic); 240 &nf_conntrack_l3proto_generic);
233 nf_ct_l3proto_unregister_sysctl(proto); 241 nf_ct_l3proto_unregister_sysctl(proto);
234 mutex_unlock(&nf_ct_proto_mutex); 242 mutex_unlock(&nf_ct_proto_mutex);
235 243
236 synchronize_rcu(); 244 synchronize_rcu();
237 245
238 /* Remove all contrack entries for this protocol */ 246 /* Remove all contrack entries for this protocol */
239 rtnl_lock(); 247 rtnl_lock();
240 for_each_net(net) 248 for_each_net(net)
241 nf_ct_iterate_cleanup(net, kill_l3proto, proto); 249 nf_ct_iterate_cleanup(net, kill_l3proto, proto);
242 rtnl_unlock(); 250 rtnl_unlock();
243 } 251 }
244 EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister); 252 EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister);
245 253
246 static int nf_ct_l4proto_register_sysctl(struct nf_conntrack_l4proto *l4proto) 254 static struct nf_proto_net *nf_ct_l4proto_net(struct net *net,
255 struct nf_conntrack_l4proto *l4proto)
247 { 256 {
257 if (l4proto->net_id)
258 return net_generic(net, *l4proto->net_id);
259 else
260 return NULL;
261 }
262
263 static
264 int nf_ct_l4proto_register_sysctl(struct net *net,
265 struct nf_conntrack_l4proto *l4proto)
266 {
248 int err = 0; 267 int err = 0;
268 struct nf_proto_net *pn = nf_ct_l4proto_net(net, l4proto);
269 if (pn == NULL)
270 return 0;
249 271
250 #ifdef CONFIG_SYSCTL 272 #ifdef CONFIG_SYSCTL
251 if (l4proto->ctl_table != NULL) { 273 if (pn->ctl_table != NULL) {
252 err = nf_ct_register_sysctl(l4proto->ctl_table_header, 274 err = nf_ct_register_sysctl(net,
275 &pn->ctl_table_header,
253 "net/netfilter", 276 "net/netfilter",
254 l4proto->ctl_table, 277 pn->ctl_table,
255 l4proto->ctl_table_users); 278 &pn->users);
256 if (err < 0) 279 if (err < 0) {
280 if (!pn->users) {
281 kfree(pn->ctl_table);
282 pn->ctl_table = NULL;
283 }
257 goto out; 284 goto out;
285 }
258 } 286 }
259 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 287 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
260 if (l4proto->ctl_compat_table != NULL) { 288 if (l4proto->l3proto != AF_INET6 && pn->ctl_compat_table != NULL) {
261 err = nf_ct_register_sysctl(&l4proto->ctl_compat_table_header, 289 err = nf_ct_register_sysctl(net,
290 &pn->ctl_compat_header,
262 "net/ipv4/netfilter", 291 "net/ipv4/netfilter",
263 l4proto->ctl_compat_table, NULL); 292 pn->ctl_compat_table,
293 NULL);
264 if (err == 0) 294 if (err == 0)
265 goto out; 295 goto out;
266 nf_ct_unregister_sysctl(l4proto->ctl_table_header, 296
267 l4proto->ctl_table, 297 kfree(pn->ctl_compat_table);
268 l4proto->ctl_table_users); 298 pn->ctl_compat_table = NULL;
299 nf_ct_unregister_sysctl(&pn->ctl_table_header,
300 &pn->ctl_table,
301 &pn->users);
269 } 302 }
270 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ 303 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
271 out: 304 out:
272 #endif /* CONFIG_SYSCTL */ 305 #endif /* CONFIG_SYSCTL */
273 return err; 306 return err;
274 } 307 }
275 308
276 static void nf_ct_l4proto_unregister_sysctl(struct nf_conntrack_l4proto *l4proto) 309 static
310 void nf_ct_l4proto_unregister_sysctl(struct net *net,
311 struct nf_conntrack_l4proto *l4proto)
277 { 312 {
313 struct nf_proto_net *pn = nf_ct_l4proto_net(net, l4proto);
314 if (pn == NULL)
315 return;
278 #ifdef CONFIG_SYSCTL 316 #ifdef CONFIG_SYSCTL
279 if (l4proto->ctl_table_header != NULL && 317 if (pn->ctl_table_header != NULL)
280 *l4proto->ctl_table_header != NULL) 318 nf_ct_unregister_sysctl(&pn->ctl_table_header,
281 nf_ct_unregister_sysctl(l4proto->ctl_table_header, 319 &pn->ctl_table,
282 l4proto->ctl_table, 320 &pn->users);
283 l4proto->ctl_table_users); 321
284 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 322 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
285 if (l4proto->ctl_compat_table_header != NULL) 323 if (l4proto->l3proto != AF_INET6 && pn->ctl_compat_header != NULL)
286 nf_ct_unregister_sysctl(&l4proto->ctl_compat_table_header, 324 nf_ct_unregister_sysctl(&pn->ctl_compat_header,
287 l4proto->ctl_compat_table, NULL); 325 &pn->ctl_compat_table,
326 NULL);
288 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ 327 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
328 #else
329 pn->users--;
289 #endif /* CONFIG_SYSCTL */ 330 #endif /* CONFIG_SYSCTL */
290 } 331 }
291 332
292 /* FIXME: Allow NULL functions and sub in pointers to generic for 333 /* FIXME: Allow NULL functions and sub in pointers to generic for
293 them. --RR */ 334 them. --RR */
294 int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto) 335 static int
336 nf_conntrack_l4proto_register_net(struct nf_conntrack_l4proto *l4proto)
295 { 337 {
296 int ret = 0; 338 int ret = 0;
297 339
298 if (l4proto->l3proto >= PF_MAX) 340 if (l4proto->l3proto >= PF_MAX)
299 return -EBUSY; 341 return -EBUSY;
300 342
301 if ((l4proto->to_nlattr && !l4proto->nlattr_size) 343 if ((l4proto->to_nlattr && !l4proto->nlattr_size)
302 || (l4proto->tuple_to_nlattr && !l4proto->nlattr_tuple_size)) 344 || (l4proto->tuple_to_nlattr && !l4proto->nlattr_tuple_size))
303 return -EINVAL; 345 return -EINVAL;
304 346
305 mutex_lock(&nf_ct_proto_mutex); 347 mutex_lock(&nf_ct_proto_mutex);
306 if (!nf_ct_protos[l4proto->l3proto]) { 348 if (!nf_ct_protos[l4proto->l3proto]) {
307 /* l3proto may be loaded latter. */ 349 /* l3proto may be loaded latter. */
308 struct nf_conntrack_l4proto __rcu **proto_array; 350 struct nf_conntrack_l4proto __rcu **proto_array;
309 int i; 351 int i;
310 352
311 proto_array = kmalloc(MAX_NF_CT_PROTO * 353 proto_array = kmalloc(MAX_NF_CT_PROTO *
312 sizeof(struct nf_conntrack_l4proto *), 354 sizeof(struct nf_conntrack_l4proto *),
313 GFP_KERNEL); 355 GFP_KERNEL);
314 if (proto_array == NULL) { 356 if (proto_array == NULL) {
315 ret = -ENOMEM; 357 ret = -ENOMEM;
316 goto out_unlock; 358 goto out_unlock;
317 } 359 }
318 360
319 for (i = 0; i < MAX_NF_CT_PROTO; i++) 361 for (i = 0; i < MAX_NF_CT_PROTO; i++)
320 RCU_INIT_POINTER(proto_array[i], &nf_conntrack_l4proto_generic); 362 RCU_INIT_POINTER(proto_array[i], &nf_conntrack_l4proto_generic);
321 363
322 /* Before making proto_array visible to lockless readers, 364 /* Before making proto_array visible to lockless readers,
323 * we must make sure its content is committed to memory. 365 * we must make sure its content is committed to memory.
324 */ 366 */
325 smp_wmb(); 367 smp_wmb();
326 368
327 nf_ct_protos[l4proto->l3proto] = proto_array; 369 nf_ct_protos[l4proto->l3proto] = proto_array;
328 } else if (rcu_dereference_protected( 370 } else if (rcu_dereference_protected(
329 nf_ct_protos[l4proto->l3proto][l4proto->l4proto], 371 nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
330 lockdep_is_held(&nf_ct_proto_mutex) 372 lockdep_is_held(&nf_ct_proto_mutex)
331 ) != &nf_conntrack_l4proto_generic) { 373 ) != &nf_conntrack_l4proto_generic) {
332 ret = -EBUSY; 374 ret = -EBUSY;
333 goto out_unlock; 375 goto out_unlock;
334 } 376 }
335 377
336 ret = nf_ct_l4proto_register_sysctl(l4proto);
337 if (ret < 0)
338 goto out_unlock;
339
340 l4proto->nla_size = 0; 378 l4proto->nla_size = 0;
341 if (l4proto->nlattr_size) 379 if (l4proto->nlattr_size)
342 l4proto->nla_size += l4proto->nlattr_size(); 380 l4proto->nla_size += l4proto->nlattr_size();
343 if (l4proto->nlattr_tuple_size) 381 if (l4proto->nlattr_tuple_size)
344 l4proto->nla_size += 3 * l4proto->nlattr_tuple_size(); 382 l4proto->nla_size += 3 * l4proto->nlattr_tuple_size();
345 383
346 rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], 384 rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
347 l4proto); 385 l4proto);
348
349 out_unlock: 386 out_unlock:
350 mutex_unlock(&nf_ct_proto_mutex); 387 mutex_unlock(&nf_ct_proto_mutex);
351 return ret; 388 return ret;
352 } 389 }
353 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);
354 390
355 void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto) 391 int nf_conntrack_l4proto_register(struct net *net,
392 struct nf_conntrack_l4proto *l4proto)
356 { 393 {
357 struct net *net; 394 int ret = 0;
395 if (net == &init_net)
396 ret = nf_conntrack_l4proto_register_net(l4proto);
358 397
398 if (ret < 0)
399 return ret;
400
401 if (l4proto->init_net)
402 ret = l4proto->init_net(net);
403
404 if (ret < 0)
405 return ret;
406
407 return nf_ct_l4proto_register_sysctl(net, l4proto);
408 }
409 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);
410
411 static void
412 nf_conntrack_l4proto_unregister_net(struct nf_conntrack_l4proto *l4proto)
413 {
359 BUG_ON(l4proto->l3proto >= PF_MAX); 414 BUG_ON(l4proto->l3proto >= PF_MAX);
360 415
361 mutex_lock(&nf_ct_proto_mutex); 416 mutex_lock(&nf_ct_proto_mutex);
362 BUG_ON(rcu_dereference_protected( 417 BUG_ON(rcu_dereference_protected(
363 nf_ct_protos[l4proto->l3proto][l4proto->l4proto], 418 nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
364 lockdep_is_held(&nf_ct_proto_mutex) 419 lockdep_is_held(&nf_ct_proto_mutex)
365 ) != l4proto); 420 ) != l4proto);
366 rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], 421 rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
367 &nf_conntrack_l4proto_generic); 422 &nf_conntrack_l4proto_generic);
368 nf_ct_l4proto_unregister_sysctl(l4proto);
369 mutex_unlock(&nf_ct_proto_mutex); 423 mutex_unlock(&nf_ct_proto_mutex);
370 424
371 synchronize_rcu(); 425 synchronize_rcu();
426 }
372 427
428 void nf_conntrack_l4proto_unregister(struct net *net,
429 struct nf_conntrack_l4proto *l4proto)
430 {
431 if (net == &init_net)
432 nf_conntrack_l4proto_unregister_net(l4proto);
433
434 nf_ct_l4proto_unregister_sysctl(net, l4proto);
373 /* Remove all contrack entries for this protocol */ 435 /* Remove all contrack entries for this protocol */
374 rtnl_lock(); 436 rtnl_lock();
375 for_each_net(net) 437 nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
376 nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
377 rtnl_unlock(); 438 rtnl_unlock();
378 } 439 }
379 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister); 440 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister);
380 441
381 int nf_conntrack_proto_init(void) 442 int nf_conntrack_proto_init(void)
382 { 443 {
383 unsigned int i; 444 unsigned int i;
384 int err; 445 int err;
385 446
386 err = nf_ct_l4proto_register_sysctl(&nf_conntrack_l4proto_generic); 447 err = nf_ct_l4proto_register_sysctl(&init_net, &nf_conntrack_l4proto_generic);
387 if (err < 0) 448 if (err < 0)
388 return err; 449 return err;
389 450
390 for (i = 0; i < AF_MAX; i++) 451 for (i = 0; i < AF_MAX; i++)
391 rcu_assign_pointer(nf_ct_l3protos[i], 452 rcu_assign_pointer(nf_ct_l3protos[i],
392 &nf_conntrack_l3proto_generic); 453 &nf_conntrack_l3proto_generic);
393 return 0; 454 return 0;
394 } 455 }
395 456
396 void nf_conntrack_proto_fini(void) 457 void nf_conntrack_proto_fini(void)
397 { 458 {
398 unsigned int i; 459 unsigned int i;
net/netfilter/nf_conntrack_proto_dccp.c
1 /* 1 /*
2 * DCCP connection tracking protocol helper 2 * DCCP connection tracking protocol helper
3 * 3 *
4 * Copyright (c) 2005, 2006, 2008 Patrick McHardy <kaber@trash.net> 4 * Copyright (c) 2005, 2006, 2008 Patrick McHardy <kaber@trash.net>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 * 9 *
10 */ 10 */
11 #include <linux/kernel.h> 11 #include <linux/kernel.h>
12 #include <linux/module.h> 12 #include <linux/module.h>
13 #include <linux/init.h> 13 #include <linux/init.h>
14 #include <linux/sysctl.h> 14 #include <linux/sysctl.h>
15 #include <linux/spinlock.h> 15 #include <linux/spinlock.h>
16 #include <linux/skbuff.h> 16 #include <linux/skbuff.h>
17 #include <linux/dccp.h> 17 #include <linux/dccp.h>
18 #include <linux/slab.h> 18 #include <linux/slab.h>
19 19
20 #include <net/net_namespace.h> 20 #include <net/net_namespace.h>
21 #include <net/netns/generic.h> 21 #include <net/netns/generic.h>
22 22
23 #include <linux/netfilter/nfnetlink_conntrack.h> 23 #include <linux/netfilter/nfnetlink_conntrack.h>
24 #include <net/netfilter/nf_conntrack.h> 24 #include <net/netfilter/nf_conntrack.h>
25 #include <net/netfilter/nf_conntrack_l4proto.h> 25 #include <net/netfilter/nf_conntrack_l4proto.h>
26 #include <net/netfilter/nf_conntrack_ecache.h> 26 #include <net/netfilter/nf_conntrack_ecache.h>
27 #include <net/netfilter/nf_log.h> 27 #include <net/netfilter/nf_log.h>
28 28
29 /* Timeouts are based on values from RFC4340: 29 /* Timeouts are based on values from RFC4340:
30 * 30 *
31 * - REQUEST: 31 * - REQUEST:
32 * 32 *
33 * 8.1.2. Client Request 33 * 8.1.2. Client Request
34 * 34 *
35 * A client MAY give up on its DCCP-Requests after some time 35 * A client MAY give up on its DCCP-Requests after some time
36 * (3 minutes, for example). 36 * (3 minutes, for example).
37 * 37 *
38 * - RESPOND: 38 * - RESPOND:
39 * 39 *
40 * 8.1.3. Server Response 40 * 8.1.3. Server Response
41 * 41 *
42 * It MAY also leave the RESPOND state for CLOSED after a timeout of 42 * It MAY also leave the RESPOND state for CLOSED after a timeout of
43 * not less than 4MSL (8 minutes); 43 * not less than 4MSL (8 minutes);
44 * 44 *
45 * - PARTOPEN: 45 * - PARTOPEN:
46 * 46 *
47 * 8.1.5. Handshake Completion 47 * 8.1.5. Handshake Completion
48 * 48 *
49 * If the client remains in PARTOPEN for more than 4MSL (8 minutes), 49 * If the client remains in PARTOPEN for more than 4MSL (8 minutes),
50 * it SHOULD reset the connection with Reset Code 2, "Aborted". 50 * it SHOULD reset the connection with Reset Code 2, "Aborted".
51 * 51 *
52 * - OPEN: 52 * - OPEN:
53 * 53 *
54 * The DCCP timestamp overflows after 11.9 hours. If the connection 54 * The DCCP timestamp overflows after 11.9 hours. If the connection
55 * stays idle this long the sequence number won't be recognized 55 * stays idle this long the sequence number won't be recognized
56 * as valid anymore. 56 * as valid anymore.
57 * 57 *
58 * - CLOSEREQ/CLOSING: 58 * - CLOSEREQ/CLOSING:
59 * 59 *
60 * 8.3. Termination 60 * 8.3. Termination
61 * 61 *
62 * The retransmission timer should initially be set to go off in two 62 * The retransmission timer should initially be set to go off in two
63 * round-trip times and should back off to not less than once every 63 * round-trip times and should back off to not less than once every
64 * 64 seconds ... 64 * 64 seconds ...
65 * 65 *
66 * - TIMEWAIT: 66 * - TIMEWAIT:
67 * 67 *
68 * 4.3. States 68 * 4.3. States
69 * 69 *
70 * A server or client socket remains in this state for 2MSL (4 minutes) 70 * A server or client socket remains in this state for 2MSL (4 minutes)
71 * after the connection has been town down, ... 71 * after the connection has been town down, ...
72 */ 72 */
73 73
74 #define DCCP_MSL (2 * 60 * HZ) 74 #define DCCP_MSL (2 * 60 * HZ)
75 75
76 static const char * const dccp_state_names[] = { 76 static const char * const dccp_state_names[] = {
77 [CT_DCCP_NONE] = "NONE", 77 [CT_DCCP_NONE] = "NONE",
78 [CT_DCCP_REQUEST] = "REQUEST", 78 [CT_DCCP_REQUEST] = "REQUEST",
79 [CT_DCCP_RESPOND] = "RESPOND", 79 [CT_DCCP_RESPOND] = "RESPOND",
80 [CT_DCCP_PARTOPEN] = "PARTOPEN", 80 [CT_DCCP_PARTOPEN] = "PARTOPEN",
81 [CT_DCCP_OPEN] = "OPEN", 81 [CT_DCCP_OPEN] = "OPEN",
82 [CT_DCCP_CLOSEREQ] = "CLOSEREQ", 82 [CT_DCCP_CLOSEREQ] = "CLOSEREQ",
83 [CT_DCCP_CLOSING] = "CLOSING", 83 [CT_DCCP_CLOSING] = "CLOSING",
84 [CT_DCCP_TIMEWAIT] = "TIMEWAIT", 84 [CT_DCCP_TIMEWAIT] = "TIMEWAIT",
85 [CT_DCCP_IGNORE] = "IGNORE", 85 [CT_DCCP_IGNORE] = "IGNORE",
86 [CT_DCCP_INVALID] = "INVALID", 86 [CT_DCCP_INVALID] = "INVALID",
87 }; 87 };
88 88
89 #define sNO CT_DCCP_NONE 89 #define sNO CT_DCCP_NONE
90 #define sRQ CT_DCCP_REQUEST 90 #define sRQ CT_DCCP_REQUEST
91 #define sRS CT_DCCP_RESPOND 91 #define sRS CT_DCCP_RESPOND
92 #define sPO CT_DCCP_PARTOPEN 92 #define sPO CT_DCCP_PARTOPEN
93 #define sOP CT_DCCP_OPEN 93 #define sOP CT_DCCP_OPEN
94 #define sCR CT_DCCP_CLOSEREQ 94 #define sCR CT_DCCP_CLOSEREQ
95 #define sCG CT_DCCP_CLOSING 95 #define sCG CT_DCCP_CLOSING
96 #define sTW CT_DCCP_TIMEWAIT 96 #define sTW CT_DCCP_TIMEWAIT
97 #define sIG CT_DCCP_IGNORE 97 #define sIG CT_DCCP_IGNORE
98 #define sIV CT_DCCP_INVALID 98 #define sIV CT_DCCP_INVALID
99 99
100 /* 100 /*
101 * DCCP state transition table 101 * DCCP state transition table
102 * 102 *
103 * The assumption is the same as for TCP tracking: 103 * The assumption is the same as for TCP tracking:
104 * 104 *
105 * We are the man in the middle. All the packets go through us but might 105 * We are the man in the middle. All the packets go through us but might
106 * get lost in transit to the destination. It is assumed that the destination 106 * get lost in transit to the destination. It is assumed that the destination
107 * can't receive segments we haven't seen. 107 * can't receive segments we haven't seen.
108 * 108 *
109 * The following states exist: 109 * The following states exist:
110 * 110 *
111 * NONE: Initial state, expecting Request 111 * NONE: Initial state, expecting Request
112 * REQUEST: Request seen, waiting for Response from server 112 * REQUEST: Request seen, waiting for Response from server
113 * RESPOND: Response from server seen, waiting for Ack from client 113 * RESPOND: Response from server seen, waiting for Ack from client
114 * PARTOPEN: Ack after Response seen, waiting for packet other than Response, 114 * PARTOPEN: Ack after Response seen, waiting for packet other than Response,
115 * Reset or Sync from server 115 * Reset or Sync from server
116 * OPEN: Packet other than Response, Reset or Sync seen 116 * OPEN: Packet other than Response, Reset or Sync seen
117 * CLOSEREQ: CloseReq from server seen, expecting Close from client 117 * CLOSEREQ: CloseReq from server seen, expecting Close from client
118 * CLOSING: Close seen, expecting Reset 118 * CLOSING: Close seen, expecting Reset
119 * TIMEWAIT: Reset seen 119 * TIMEWAIT: Reset seen
120 * IGNORE: Not determinable whether packet is valid 120 * IGNORE: Not determinable whether packet is valid
121 * 121 *
122 * Some states exist only on one side of the connection: REQUEST, RESPOND, 122 * Some states exist only on one side of the connection: REQUEST, RESPOND,
123 * PARTOPEN, CLOSEREQ. For the other side these states are equivalent to 123 * PARTOPEN, CLOSEREQ. For the other side these states are equivalent to
124 * the one it was in before. 124 * the one it was in before.
125 * 125 *
126 * Packets are marked as ignored (sIG) if we don't know if they're valid 126 * Packets are marked as ignored (sIG) if we don't know if they're valid
127 * (for example a reincarnation of a connection we didn't notice is dead 127 * (for example a reincarnation of a connection we didn't notice is dead
128 * already) and the server may send back a connection closing Reset or a 128 * already) and the server may send back a connection closing Reset or a
129 * Response. They're also used for Sync/SyncAck packets, which we don't 129 * Response. They're also used for Sync/SyncAck packets, which we don't
130 * care about. 130 * care about.
131 */ 131 */
132 static const u_int8_t 132 static const u_int8_t
133 dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] = { 133 dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] = {
134 [CT_DCCP_ROLE_CLIENT] = { 134 [CT_DCCP_ROLE_CLIENT] = {
135 [DCCP_PKT_REQUEST] = { 135 [DCCP_PKT_REQUEST] = {
136 /* 136 /*
137 * sNO -> sRQ Regular Request 137 * sNO -> sRQ Regular Request
138 * sRQ -> sRQ Retransmitted Request or reincarnation 138 * sRQ -> sRQ Retransmitted Request or reincarnation
139 * sRS -> sRS Retransmitted Request (apparently Response 139 * sRS -> sRS Retransmitted Request (apparently Response
140 * got lost after we saw it) or reincarnation 140 * got lost after we saw it) or reincarnation
141 * sPO -> sIG Ignore, conntrack might be out of sync 141 * sPO -> sIG Ignore, conntrack might be out of sync
142 * sOP -> sIG Ignore, conntrack might be out of sync 142 * sOP -> sIG Ignore, conntrack might be out of sync
143 * sCR -> sIG Ignore, conntrack might be out of sync 143 * sCR -> sIG Ignore, conntrack might be out of sync
144 * sCG -> sIG Ignore, conntrack might be out of sync 144 * sCG -> sIG Ignore, conntrack might be out of sync
145 * sTW -> sRQ Reincarnation 145 * sTW -> sRQ Reincarnation
146 * 146 *
147 * sNO, sRQ, sRS, sPO. sOP, sCR, sCG, sTW, */ 147 * sNO, sRQ, sRS, sPO. sOP, sCR, sCG, sTW, */
148 sRQ, sRQ, sRS, sIG, sIG, sIG, sIG, sRQ, 148 sRQ, sRQ, sRS, sIG, sIG, sIG, sIG, sRQ,
149 }, 149 },
150 [DCCP_PKT_RESPONSE] = { 150 [DCCP_PKT_RESPONSE] = {
151 /* 151 /*
152 * sNO -> sIV Invalid 152 * sNO -> sIV Invalid
153 * sRQ -> sIG Ignore, might be response to ignored Request 153 * sRQ -> sIG Ignore, might be response to ignored Request
154 * sRS -> sIG Ignore, might be response to ignored Request 154 * sRS -> sIG Ignore, might be response to ignored Request
155 * sPO -> sIG Ignore, might be response to ignored Request 155 * sPO -> sIG Ignore, might be response to ignored Request
156 * sOP -> sIG Ignore, might be response to ignored Request 156 * sOP -> sIG Ignore, might be response to ignored Request
157 * sCR -> sIG Ignore, might be response to ignored Request 157 * sCR -> sIG Ignore, might be response to ignored Request
158 * sCG -> sIG Ignore, might be response to ignored Request 158 * sCG -> sIG Ignore, might be response to ignored Request
159 * sTW -> sIV Invalid, reincarnation in reverse direction 159 * sTW -> sIV Invalid, reincarnation in reverse direction
160 * goes through sRQ 160 * goes through sRQ
161 * 161 *
162 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 162 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
163 sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIV, 163 sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIV,
164 }, 164 },
165 [DCCP_PKT_ACK] = { 165 [DCCP_PKT_ACK] = {
166 /* 166 /*
167 * sNO -> sIV No connection 167 * sNO -> sIV No connection
168 * sRQ -> sIV No connection 168 * sRQ -> sIV No connection
169 * sRS -> sPO Ack for Response, move to PARTOPEN (8.1.5.) 169 * sRS -> sPO Ack for Response, move to PARTOPEN (8.1.5.)
170 * sPO -> sPO Retransmitted Ack for Response, remain in PARTOPEN 170 * sPO -> sPO Retransmitted Ack for Response, remain in PARTOPEN
171 * sOP -> sOP Regular ACK, remain in OPEN 171 * sOP -> sOP Regular ACK, remain in OPEN
172 * sCR -> sCR Ack in CLOSEREQ MAY be processed (8.3.) 172 * sCR -> sCR Ack in CLOSEREQ MAY be processed (8.3.)
173 * sCG -> sCG Ack in CLOSING MAY be processed (8.3.) 173 * sCG -> sCG Ack in CLOSING MAY be processed (8.3.)
174 * sTW -> sIV 174 * sTW -> sIV
175 * 175 *
176 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 176 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
177 sIV, sIV, sPO, sPO, sOP, sCR, sCG, sIV 177 sIV, sIV, sPO, sPO, sOP, sCR, sCG, sIV
178 }, 178 },
179 [DCCP_PKT_DATA] = { 179 [DCCP_PKT_DATA] = {
180 /* 180 /*
181 * sNO -> sIV No connection 181 * sNO -> sIV No connection
182 * sRQ -> sIV No connection 182 * sRQ -> sIV No connection
183 * sRS -> sIV No connection 183 * sRS -> sIV No connection
184 * sPO -> sIV MUST use DataAck in PARTOPEN state (8.1.5.) 184 * sPO -> sIV MUST use DataAck in PARTOPEN state (8.1.5.)
185 * sOP -> sOP Regular Data packet 185 * sOP -> sOP Regular Data packet
186 * sCR -> sCR Data in CLOSEREQ MAY be processed (8.3.) 186 * sCR -> sCR Data in CLOSEREQ MAY be processed (8.3.)
187 * sCG -> sCG Data in CLOSING MAY be processed (8.3.) 187 * sCG -> sCG Data in CLOSING MAY be processed (8.3.)
188 * sTW -> sIV 188 * sTW -> sIV
189 * 189 *
190 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 190 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
191 sIV, sIV, sIV, sIV, sOP, sCR, sCG, sIV, 191 sIV, sIV, sIV, sIV, sOP, sCR, sCG, sIV,
192 }, 192 },
193 [DCCP_PKT_DATAACK] = { 193 [DCCP_PKT_DATAACK] = {
194 /* 194 /*
195 * sNO -> sIV No connection 195 * sNO -> sIV No connection
196 * sRQ -> sIV No connection 196 * sRQ -> sIV No connection
197 * sRS -> sPO Ack for Response, move to PARTOPEN (8.1.5.) 197 * sRS -> sPO Ack for Response, move to PARTOPEN (8.1.5.)
198 * sPO -> sPO Remain in PARTOPEN state 198 * sPO -> sPO Remain in PARTOPEN state
199 * sOP -> sOP Regular DataAck packet in OPEN state 199 * sOP -> sOP Regular DataAck packet in OPEN state
200 * sCR -> sCR DataAck in CLOSEREQ MAY be processed (8.3.) 200 * sCR -> sCR DataAck in CLOSEREQ MAY be processed (8.3.)
201 * sCG -> sCG DataAck in CLOSING MAY be processed (8.3.) 201 * sCG -> sCG DataAck in CLOSING MAY be processed (8.3.)
202 * sTW -> sIV 202 * sTW -> sIV
203 * 203 *
204 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 204 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
205 sIV, sIV, sPO, sPO, sOP, sCR, sCG, sIV 205 sIV, sIV, sPO, sPO, sOP, sCR, sCG, sIV
206 }, 206 },
207 [DCCP_PKT_CLOSEREQ] = { 207 [DCCP_PKT_CLOSEREQ] = {
208 /* 208 /*
209 * CLOSEREQ may only be sent by the server. 209 * CLOSEREQ may only be sent by the server.
210 * 210 *
211 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 211 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
212 sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV 212 sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV
213 }, 213 },
214 [DCCP_PKT_CLOSE] = { 214 [DCCP_PKT_CLOSE] = {
215 /* 215 /*
216 * sNO -> sIV No connection 216 * sNO -> sIV No connection
217 * sRQ -> sIV No connection 217 * sRQ -> sIV No connection
218 * sRS -> sIV No connection 218 * sRS -> sIV No connection
219 * sPO -> sCG Client-initiated close 219 * sPO -> sCG Client-initiated close
220 * sOP -> sCG Client-initiated close 220 * sOP -> sCG Client-initiated close
221 * sCR -> sCG Close in response to CloseReq (8.3.) 221 * sCR -> sCG Close in response to CloseReq (8.3.)
222 * sCG -> sCG Retransmit 222 * sCG -> sCG Retransmit
223 * sTW -> sIV Late retransmit, already in TIME_WAIT 223 * sTW -> sIV Late retransmit, already in TIME_WAIT
224 * 224 *
225 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 225 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
226 sIV, sIV, sIV, sCG, sCG, sCG, sIV, sIV 226 sIV, sIV, sIV, sCG, sCG, sCG, sIV, sIV
227 }, 227 },
228 [DCCP_PKT_RESET] = { 228 [DCCP_PKT_RESET] = {
229 /* 229 /*
230 * sNO -> sIV No connection 230 * sNO -> sIV No connection
231 * sRQ -> sTW Sync received or timeout, SHOULD send Reset (8.1.1.) 231 * sRQ -> sTW Sync received or timeout, SHOULD send Reset (8.1.1.)
232 * sRS -> sTW Response received without Request 232 * sRS -> sTW Response received without Request
233 * sPO -> sTW Timeout, SHOULD send Reset (8.1.5.) 233 * sPO -> sTW Timeout, SHOULD send Reset (8.1.5.)
234 * sOP -> sTW Connection reset 234 * sOP -> sTW Connection reset
235 * sCR -> sTW Connection reset 235 * sCR -> sTW Connection reset
236 * sCG -> sTW Connection reset 236 * sCG -> sTW Connection reset
237 * sTW -> sIG Ignore (don't refresh timer) 237 * sTW -> sIG Ignore (don't refresh timer)
238 * 238 *
239 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 239 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
240 sIV, sTW, sTW, sTW, sTW, sTW, sTW, sIG 240 sIV, sTW, sTW, sTW, sTW, sTW, sTW, sIG
241 }, 241 },
242 [DCCP_PKT_SYNC] = { 242 [DCCP_PKT_SYNC] = {
243 /* 243 /*
244 * We currently ignore Sync packets 244 * We currently ignore Sync packets
245 * 245 *
246 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 246 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
247 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG, 247 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
248 }, 248 },
249 [DCCP_PKT_SYNCACK] = { 249 [DCCP_PKT_SYNCACK] = {
250 /* 250 /*
251 * We currently ignore SyncAck packets 251 * We currently ignore SyncAck packets
252 * 252 *
253 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 253 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
254 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG, 254 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
255 }, 255 },
256 }, 256 },
257 [CT_DCCP_ROLE_SERVER] = { 257 [CT_DCCP_ROLE_SERVER] = {
258 [DCCP_PKT_REQUEST] = { 258 [DCCP_PKT_REQUEST] = {
259 /* 259 /*
260 * sNO -> sIV Invalid 260 * sNO -> sIV Invalid
261 * sRQ -> sIG Ignore, conntrack might be out of sync 261 * sRQ -> sIG Ignore, conntrack might be out of sync
262 * sRS -> sIG Ignore, conntrack might be out of sync 262 * sRS -> sIG Ignore, conntrack might be out of sync
263 * sPO -> sIG Ignore, conntrack might be out of sync 263 * sPO -> sIG Ignore, conntrack might be out of sync
264 * sOP -> sIG Ignore, conntrack might be out of sync 264 * sOP -> sIG Ignore, conntrack might be out of sync
265 * sCR -> sIG Ignore, conntrack might be out of sync 265 * sCR -> sIG Ignore, conntrack might be out of sync
266 * sCG -> sIG Ignore, conntrack might be out of sync 266 * sCG -> sIG Ignore, conntrack might be out of sync
267 * sTW -> sRQ Reincarnation, must reverse roles 267 * sTW -> sRQ Reincarnation, must reverse roles
268 * 268 *
269 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 269 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
270 sIV, sIG, sIG, sIG, sIG, sIG, sIG, sRQ 270 sIV, sIG, sIG, sIG, sIG, sIG, sIG, sRQ
271 }, 271 },
272 [DCCP_PKT_RESPONSE] = { 272 [DCCP_PKT_RESPONSE] = {
273 /* 273 /*
274 * sNO -> sIV Response without Request 274 * sNO -> sIV Response without Request
275 * sRQ -> sRS Response to clients Request 275 * sRQ -> sRS Response to clients Request
276 * sRS -> sRS Retransmitted Response (8.1.3. SHOULD NOT) 276 * sRS -> sRS Retransmitted Response (8.1.3. SHOULD NOT)
277 * sPO -> sIG Response to an ignored Request or late retransmit 277 * sPO -> sIG Response to an ignored Request or late retransmit
278 * sOP -> sIG Ignore, might be response to ignored Request 278 * sOP -> sIG Ignore, might be response to ignored Request
279 * sCR -> sIG Ignore, might be response to ignored Request 279 * sCR -> sIG Ignore, might be response to ignored Request
280 * sCG -> sIG Ignore, might be response to ignored Request 280 * sCG -> sIG Ignore, might be response to ignored Request
281 * sTW -> sIV Invalid, Request from client in sTW moves to sRQ 281 * sTW -> sIV Invalid, Request from client in sTW moves to sRQ
282 * 282 *
283 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 283 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
284 sIV, sRS, sRS, sIG, sIG, sIG, sIG, sIV 284 sIV, sRS, sRS, sIG, sIG, sIG, sIG, sIV
285 }, 285 },
286 [DCCP_PKT_ACK] = { 286 [DCCP_PKT_ACK] = {
287 /* 287 /*
288 * sNO -> sIV No connection 288 * sNO -> sIV No connection
289 * sRQ -> sIV No connection 289 * sRQ -> sIV No connection
290 * sRS -> sIV No connection 290 * sRS -> sIV No connection
291 * sPO -> sOP Enter OPEN state (8.1.5.) 291 * sPO -> sOP Enter OPEN state (8.1.5.)
292 * sOP -> sOP Regular Ack in OPEN state 292 * sOP -> sOP Regular Ack in OPEN state
293 * sCR -> sIV Waiting for Close from client 293 * sCR -> sIV Waiting for Close from client
294 * sCG -> sCG Ack in CLOSING MAY be processed (8.3.) 294 * sCG -> sCG Ack in CLOSING MAY be processed (8.3.)
295 * sTW -> sIV 295 * sTW -> sIV
296 * 296 *
297 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 297 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
298 sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV 298 sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV
299 }, 299 },
300 [DCCP_PKT_DATA] = { 300 [DCCP_PKT_DATA] = {
301 /* 301 /*
302 * sNO -> sIV No connection 302 * sNO -> sIV No connection
303 * sRQ -> sIV No connection 303 * sRQ -> sIV No connection
304 * sRS -> sIV No connection 304 * sRS -> sIV No connection
305 * sPO -> sOP Enter OPEN state (8.1.5.) 305 * sPO -> sOP Enter OPEN state (8.1.5.)
306 * sOP -> sOP Regular Data packet in OPEN state 306 * sOP -> sOP Regular Data packet in OPEN state
307 * sCR -> sIV Waiting for Close from client 307 * sCR -> sIV Waiting for Close from client
308 * sCG -> sCG Data in CLOSING MAY be processed (8.3.) 308 * sCG -> sCG Data in CLOSING MAY be processed (8.3.)
309 * sTW -> sIV 309 * sTW -> sIV
310 * 310 *
311 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 311 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
312 sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV 312 sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV
313 }, 313 },
314 [DCCP_PKT_DATAACK] = { 314 [DCCP_PKT_DATAACK] = {
315 /* 315 /*
316 * sNO -> sIV No connection 316 * sNO -> sIV No connection
317 * sRQ -> sIV No connection 317 * sRQ -> sIV No connection
318 * sRS -> sIV No connection 318 * sRS -> sIV No connection
319 * sPO -> sOP Enter OPEN state (8.1.5.) 319 * sPO -> sOP Enter OPEN state (8.1.5.)
320 * sOP -> sOP Regular DataAck in OPEN state 320 * sOP -> sOP Regular DataAck in OPEN state
321 * sCR -> sIV Waiting for Close from client 321 * sCR -> sIV Waiting for Close from client
322 * sCG -> sCG Data in CLOSING MAY be processed (8.3.) 322 * sCG -> sCG Data in CLOSING MAY be processed (8.3.)
323 * sTW -> sIV 323 * sTW -> sIV
324 * 324 *
325 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 325 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
326 sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV 326 sIV, sIV, sIV, sOP, sOP, sIV, sCG, sIV
327 }, 327 },
328 [DCCP_PKT_CLOSEREQ] = { 328 [DCCP_PKT_CLOSEREQ] = {
329 /* 329 /*
330 * sNO -> sIV No connection 330 * sNO -> sIV No connection
331 * sRQ -> sIV No connection 331 * sRQ -> sIV No connection
332 * sRS -> sIV No connection 332 * sRS -> sIV No connection
333 * sPO -> sOP -> sCR Move directly to CLOSEREQ (8.1.5.) 333 * sPO -> sOP -> sCR Move directly to CLOSEREQ (8.1.5.)
334 * sOP -> sCR CloseReq in OPEN state 334 * sOP -> sCR CloseReq in OPEN state
335 * sCR -> sCR Retransmit 335 * sCR -> sCR Retransmit
336 * sCG -> sCR Simultaneous close, client sends another Close 336 * sCG -> sCR Simultaneous close, client sends another Close
337 * sTW -> sIV Already closed 337 * sTW -> sIV Already closed
338 * 338 *
339 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 339 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
340 sIV, sIV, sIV, sCR, sCR, sCR, sCR, sIV 340 sIV, sIV, sIV, sCR, sCR, sCR, sCR, sIV
341 }, 341 },
342 [DCCP_PKT_CLOSE] = { 342 [DCCP_PKT_CLOSE] = {
343 /* 343 /*
344 * sNO -> sIV No connection 344 * sNO -> sIV No connection
345 * sRQ -> sIV No connection 345 * sRQ -> sIV No connection
346 * sRS -> sIV No connection 346 * sRS -> sIV No connection
347 * sPO -> sOP -> sCG Move direcly to CLOSING 347 * sPO -> sOP -> sCG Move direcly to CLOSING
348 * sOP -> sCG Move to CLOSING 348 * sOP -> sCG Move to CLOSING
349 * sCR -> sIV Close after CloseReq is invalid 349 * sCR -> sIV Close after CloseReq is invalid
350 * sCG -> sCG Retransmit 350 * sCG -> sCG Retransmit
351 * sTW -> sIV Already closed 351 * sTW -> sIV Already closed
352 * 352 *
353 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 353 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
354 sIV, sIV, sIV, sCG, sCG, sIV, sCG, sIV 354 sIV, sIV, sIV, sCG, sCG, sIV, sCG, sIV
355 }, 355 },
356 [DCCP_PKT_RESET] = { 356 [DCCP_PKT_RESET] = {
357 /* 357 /*
358 * sNO -> sIV No connection 358 * sNO -> sIV No connection
359 * sRQ -> sTW Reset in response to Request 359 * sRQ -> sTW Reset in response to Request
360 * sRS -> sTW Timeout, SHOULD send Reset (8.1.3.) 360 * sRS -> sTW Timeout, SHOULD send Reset (8.1.3.)
361 * sPO -> sTW Timeout, SHOULD send Reset (8.1.3.) 361 * sPO -> sTW Timeout, SHOULD send Reset (8.1.3.)
362 * sOP -> sTW 362 * sOP -> sTW
363 * sCR -> sTW 363 * sCR -> sTW
364 * sCG -> sTW 364 * sCG -> sTW
365 * sTW -> sIG Ignore (don't refresh timer) 365 * sTW -> sIG Ignore (don't refresh timer)
366 * 366 *
367 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW, sTW */ 367 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW, sTW */
368 sIV, sTW, sTW, sTW, sTW, sTW, sTW, sTW, sIG 368 sIV, sTW, sTW, sTW, sTW, sTW, sTW, sTW, sIG
369 }, 369 },
370 [DCCP_PKT_SYNC] = { 370 [DCCP_PKT_SYNC] = {
371 /* 371 /*
372 * We currently ignore Sync packets 372 * We currently ignore Sync packets
373 * 373 *
374 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 374 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
375 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG, 375 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
376 }, 376 },
377 [DCCP_PKT_SYNCACK] = { 377 [DCCP_PKT_SYNCACK] = {
378 /* 378 /*
379 * We currently ignore SyncAck packets 379 * We currently ignore SyncAck packets
380 * 380 *
381 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */ 381 * sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
382 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG, 382 sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
383 }, 383 },
384 }, 384 },
385 }; 385 };
386 386
387 /* this module per-net specifics */ 387 /* this module per-net specifics */
388 static int dccp_net_id __read_mostly; 388 static int dccp_net_id __read_mostly;
389 struct dccp_net { 389 struct dccp_net {
390 int dccp_loose; 390 int dccp_loose;
391 unsigned int dccp_timeout[CT_DCCP_MAX + 1]; 391 unsigned int dccp_timeout[CT_DCCP_MAX + 1];
392 #ifdef CONFIG_SYSCTL 392 #ifdef CONFIG_SYSCTL
393 struct ctl_table_header *sysctl_header; 393 struct ctl_table_header *sysctl_header;
394 struct ctl_table *sysctl_table; 394 struct ctl_table *sysctl_table;
395 #endif 395 #endif
396 }; 396 };
397 397
398 static inline struct dccp_net *dccp_pernet(struct net *net) 398 static inline struct dccp_net *dccp_pernet(struct net *net)
399 { 399 {
400 return net_generic(net, dccp_net_id); 400 return net_generic(net, dccp_net_id);
401 } 401 }
402 402
403 static bool dccp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, 403 static bool dccp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
404 struct nf_conntrack_tuple *tuple) 404 struct nf_conntrack_tuple *tuple)
405 { 405 {
406 struct dccp_hdr _hdr, *dh; 406 struct dccp_hdr _hdr, *dh;
407 407
408 dh = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr); 408 dh = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
409 if (dh == NULL) 409 if (dh == NULL)
410 return false; 410 return false;
411 411
412 tuple->src.u.dccp.port = dh->dccph_sport; 412 tuple->src.u.dccp.port = dh->dccph_sport;
413 tuple->dst.u.dccp.port = dh->dccph_dport; 413 tuple->dst.u.dccp.port = dh->dccph_dport;
414 return true; 414 return true;
415 } 415 }
416 416
417 static bool dccp_invert_tuple(struct nf_conntrack_tuple *inv, 417 static bool dccp_invert_tuple(struct nf_conntrack_tuple *inv,
418 const struct nf_conntrack_tuple *tuple) 418 const struct nf_conntrack_tuple *tuple)
419 { 419 {
420 inv->src.u.dccp.port = tuple->dst.u.dccp.port; 420 inv->src.u.dccp.port = tuple->dst.u.dccp.port;
421 inv->dst.u.dccp.port = tuple->src.u.dccp.port; 421 inv->dst.u.dccp.port = tuple->src.u.dccp.port;
422 return true; 422 return true;
423 } 423 }
424 424
425 static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb, 425 static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
426 unsigned int dataoff, unsigned int *timeouts) 426 unsigned int dataoff, unsigned int *timeouts)
427 { 427 {
428 struct net *net = nf_ct_net(ct); 428 struct net *net = nf_ct_net(ct);
429 struct dccp_net *dn; 429 struct dccp_net *dn;
430 struct dccp_hdr _dh, *dh; 430 struct dccp_hdr _dh, *dh;
431 const char *msg; 431 const char *msg;
432 u_int8_t state; 432 u_int8_t state;
433 433
434 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh); 434 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
435 BUG_ON(dh == NULL); 435 BUG_ON(dh == NULL);
436 436
437 state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE]; 437 state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE];
438 switch (state) { 438 switch (state) {
439 default: 439 default:
440 dn = dccp_pernet(net); 440 dn = dccp_pernet(net);
441 if (dn->dccp_loose == 0) { 441 if (dn->dccp_loose == 0) {
442 msg = "nf_ct_dccp: not picking up existing connection "; 442 msg = "nf_ct_dccp: not picking up existing connection ";
443 goto out_invalid; 443 goto out_invalid;
444 } 444 }
445 case CT_DCCP_REQUEST: 445 case CT_DCCP_REQUEST:
446 break; 446 break;
447 case CT_DCCP_INVALID: 447 case CT_DCCP_INVALID:
448 msg = "nf_ct_dccp: invalid state transition "; 448 msg = "nf_ct_dccp: invalid state transition ";
449 goto out_invalid; 449 goto out_invalid;
450 } 450 }
451 451
452 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_CLIENT; 452 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_CLIENT;
453 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_SERVER; 453 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_SERVER;
454 ct->proto.dccp.state = CT_DCCP_NONE; 454 ct->proto.dccp.state = CT_DCCP_NONE;
455 ct->proto.dccp.last_pkt = DCCP_PKT_REQUEST; 455 ct->proto.dccp.last_pkt = DCCP_PKT_REQUEST;
456 ct->proto.dccp.last_dir = IP_CT_DIR_ORIGINAL; 456 ct->proto.dccp.last_dir = IP_CT_DIR_ORIGINAL;
457 ct->proto.dccp.handshake_seq = 0; 457 ct->proto.dccp.handshake_seq = 0;
458 return true; 458 return true;
459 459
460 out_invalid: 460 out_invalid:
461 if (LOG_INVALID(net, IPPROTO_DCCP)) 461 if (LOG_INVALID(net, IPPROTO_DCCP))
462 nf_log_packet(nf_ct_l3num(ct), 0, skb, NULL, NULL, NULL, msg); 462 nf_log_packet(nf_ct_l3num(ct), 0, skb, NULL, NULL, NULL, msg);
463 return false; 463 return false;
464 } 464 }
465 465
466 static u64 dccp_ack_seq(const struct dccp_hdr *dh) 466 static u64 dccp_ack_seq(const struct dccp_hdr *dh)
467 { 467 {
468 const struct dccp_hdr_ack_bits *dhack; 468 const struct dccp_hdr_ack_bits *dhack;
469 469
470 dhack = (void *)dh + __dccp_basic_hdr_len(dh); 470 dhack = (void *)dh + __dccp_basic_hdr_len(dh);
471 return ((u64)ntohs(dhack->dccph_ack_nr_high) << 32) + 471 return ((u64)ntohs(dhack->dccph_ack_nr_high) << 32) +
472 ntohl(dhack->dccph_ack_nr_low); 472 ntohl(dhack->dccph_ack_nr_low);
473 } 473 }
474 474
475 static unsigned int *dccp_get_timeouts(struct net *net) 475 static unsigned int *dccp_get_timeouts(struct net *net)
476 { 476 {
477 return dccp_pernet(net)->dccp_timeout; 477 return dccp_pernet(net)->dccp_timeout;
478 } 478 }
479 479
480 static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb, 480 static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
481 unsigned int dataoff, enum ip_conntrack_info ctinfo, 481 unsigned int dataoff, enum ip_conntrack_info ctinfo,
482 u_int8_t pf, unsigned int hooknum, 482 u_int8_t pf, unsigned int hooknum,
483 unsigned int *timeouts) 483 unsigned int *timeouts)
484 { 484 {
485 struct net *net = nf_ct_net(ct); 485 struct net *net = nf_ct_net(ct);
486 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 486 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
487 struct dccp_hdr _dh, *dh; 487 struct dccp_hdr _dh, *dh;
488 u_int8_t type, old_state, new_state; 488 u_int8_t type, old_state, new_state;
489 enum ct_dccp_roles role; 489 enum ct_dccp_roles role;
490 490
491 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh); 491 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
492 BUG_ON(dh == NULL); 492 BUG_ON(dh == NULL);
493 type = dh->dccph_type; 493 type = dh->dccph_type;
494 494
495 if (type == DCCP_PKT_RESET && 495 if (type == DCCP_PKT_RESET &&
496 !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { 496 !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
497 /* Tear down connection immediately if only reply is a RESET */ 497 /* Tear down connection immediately if only reply is a RESET */
498 nf_ct_kill_acct(ct, ctinfo, skb); 498 nf_ct_kill_acct(ct, ctinfo, skb);
499 return NF_ACCEPT; 499 return NF_ACCEPT;
500 } 500 }
501 501
502 spin_lock_bh(&ct->lock); 502 spin_lock_bh(&ct->lock);
503 503
504 role = ct->proto.dccp.role[dir]; 504 role = ct->proto.dccp.role[dir];
505 old_state = ct->proto.dccp.state; 505 old_state = ct->proto.dccp.state;
506 new_state = dccp_state_table[role][type][old_state]; 506 new_state = dccp_state_table[role][type][old_state];
507 507
508 switch (new_state) { 508 switch (new_state) {
509 case CT_DCCP_REQUEST: 509 case CT_DCCP_REQUEST:
510 if (old_state == CT_DCCP_TIMEWAIT && 510 if (old_state == CT_DCCP_TIMEWAIT &&
511 role == CT_DCCP_ROLE_SERVER) { 511 role == CT_DCCP_ROLE_SERVER) {
512 /* Reincarnation in the reverse direction: reopen and 512 /* Reincarnation in the reverse direction: reopen and
513 * reverse client/server roles. */ 513 * reverse client/server roles. */
514 ct->proto.dccp.role[dir] = CT_DCCP_ROLE_CLIENT; 514 ct->proto.dccp.role[dir] = CT_DCCP_ROLE_CLIENT;
515 ct->proto.dccp.role[!dir] = CT_DCCP_ROLE_SERVER; 515 ct->proto.dccp.role[!dir] = CT_DCCP_ROLE_SERVER;
516 } 516 }
517 break; 517 break;
518 case CT_DCCP_RESPOND: 518 case CT_DCCP_RESPOND:
519 if (old_state == CT_DCCP_REQUEST) 519 if (old_state == CT_DCCP_REQUEST)
520 ct->proto.dccp.handshake_seq = dccp_hdr_seq(dh); 520 ct->proto.dccp.handshake_seq = dccp_hdr_seq(dh);
521 break; 521 break;
522 case CT_DCCP_PARTOPEN: 522 case CT_DCCP_PARTOPEN:
523 if (old_state == CT_DCCP_RESPOND && 523 if (old_state == CT_DCCP_RESPOND &&
524 type == DCCP_PKT_ACK && 524 type == DCCP_PKT_ACK &&
525 dccp_ack_seq(dh) == ct->proto.dccp.handshake_seq) 525 dccp_ack_seq(dh) == ct->proto.dccp.handshake_seq)
526 set_bit(IPS_ASSURED_BIT, &ct->status); 526 set_bit(IPS_ASSURED_BIT, &ct->status);
527 break; 527 break;
528 case CT_DCCP_IGNORE: 528 case CT_DCCP_IGNORE:
529 /* 529 /*
530 * Connection tracking might be out of sync, so we ignore 530 * Connection tracking might be out of sync, so we ignore
531 * packets that might establish a new connection and resync 531 * packets that might establish a new connection and resync
532 * if the server responds with a valid Response. 532 * if the server responds with a valid Response.
533 */ 533 */
534 if (ct->proto.dccp.last_dir == !dir && 534 if (ct->proto.dccp.last_dir == !dir &&
535 ct->proto.dccp.last_pkt == DCCP_PKT_REQUEST && 535 ct->proto.dccp.last_pkt == DCCP_PKT_REQUEST &&
536 type == DCCP_PKT_RESPONSE) { 536 type == DCCP_PKT_RESPONSE) {
537 ct->proto.dccp.role[!dir] = CT_DCCP_ROLE_CLIENT; 537 ct->proto.dccp.role[!dir] = CT_DCCP_ROLE_CLIENT;
538 ct->proto.dccp.role[dir] = CT_DCCP_ROLE_SERVER; 538 ct->proto.dccp.role[dir] = CT_DCCP_ROLE_SERVER;
539 ct->proto.dccp.handshake_seq = dccp_hdr_seq(dh); 539 ct->proto.dccp.handshake_seq = dccp_hdr_seq(dh);
540 new_state = CT_DCCP_RESPOND; 540 new_state = CT_DCCP_RESPOND;
541 break; 541 break;
542 } 542 }
543 ct->proto.dccp.last_dir = dir; 543 ct->proto.dccp.last_dir = dir;
544 ct->proto.dccp.last_pkt = type; 544 ct->proto.dccp.last_pkt = type;
545 545
546 spin_unlock_bh(&ct->lock); 546 spin_unlock_bh(&ct->lock);
547 if (LOG_INVALID(net, IPPROTO_DCCP)) 547 if (LOG_INVALID(net, IPPROTO_DCCP))
548 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 548 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
549 "nf_ct_dccp: invalid packet ignored "); 549 "nf_ct_dccp: invalid packet ignored ");
550 return NF_ACCEPT; 550 return NF_ACCEPT;
551 case CT_DCCP_INVALID: 551 case CT_DCCP_INVALID:
552 spin_unlock_bh(&ct->lock); 552 spin_unlock_bh(&ct->lock);
553 if (LOG_INVALID(net, IPPROTO_DCCP)) 553 if (LOG_INVALID(net, IPPROTO_DCCP))
554 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 554 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
555 "nf_ct_dccp: invalid state transition "); 555 "nf_ct_dccp: invalid state transition ");
556 return -NF_ACCEPT; 556 return -NF_ACCEPT;
557 } 557 }
558 558
559 ct->proto.dccp.last_dir = dir; 559 ct->proto.dccp.last_dir = dir;
560 ct->proto.dccp.last_pkt = type; 560 ct->proto.dccp.last_pkt = type;
561 ct->proto.dccp.state = new_state; 561 ct->proto.dccp.state = new_state;
562 spin_unlock_bh(&ct->lock); 562 spin_unlock_bh(&ct->lock);
563 563
564 if (new_state != old_state) 564 if (new_state != old_state)
565 nf_conntrack_event_cache(IPCT_PROTOINFO, ct); 565 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
566 566
567 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]); 567 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
568 568
569 return NF_ACCEPT; 569 return NF_ACCEPT;
570 } 570 }
571 571
572 static int dccp_error(struct net *net, struct nf_conn *tmpl, 572 static int dccp_error(struct net *net, struct nf_conn *tmpl,
573 struct sk_buff *skb, unsigned int dataoff, 573 struct sk_buff *skb, unsigned int dataoff,
574 enum ip_conntrack_info *ctinfo, 574 enum ip_conntrack_info *ctinfo,
575 u_int8_t pf, unsigned int hooknum) 575 u_int8_t pf, unsigned int hooknum)
576 { 576 {
577 struct dccp_hdr _dh, *dh; 577 struct dccp_hdr _dh, *dh;
578 unsigned int dccp_len = skb->len - dataoff; 578 unsigned int dccp_len = skb->len - dataoff;
579 unsigned int cscov; 579 unsigned int cscov;
580 const char *msg; 580 const char *msg;
581 581
582 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh); 582 dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
583 if (dh == NULL) { 583 if (dh == NULL) {
584 msg = "nf_ct_dccp: short packet "; 584 msg = "nf_ct_dccp: short packet ";
585 goto out_invalid; 585 goto out_invalid;
586 } 586 }
587 587
588 if (dh->dccph_doff * 4 < sizeof(struct dccp_hdr) || 588 if (dh->dccph_doff * 4 < sizeof(struct dccp_hdr) ||
589 dh->dccph_doff * 4 > dccp_len) { 589 dh->dccph_doff * 4 > dccp_len) {
590 msg = "nf_ct_dccp: truncated/malformed packet "; 590 msg = "nf_ct_dccp: truncated/malformed packet ";
591 goto out_invalid; 591 goto out_invalid;
592 } 592 }
593 593
594 cscov = dccp_len; 594 cscov = dccp_len;
595 if (dh->dccph_cscov) { 595 if (dh->dccph_cscov) {
596 cscov = (dh->dccph_cscov - 1) * 4; 596 cscov = (dh->dccph_cscov - 1) * 4;
597 if (cscov > dccp_len) { 597 if (cscov > dccp_len) {
598 msg = "nf_ct_dccp: bad checksum coverage "; 598 msg = "nf_ct_dccp: bad checksum coverage ";
599 goto out_invalid; 599 goto out_invalid;
600 } 600 }
601 } 601 }
602 602
603 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && 603 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
604 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_DCCP, 604 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_DCCP,
605 pf)) { 605 pf)) {
606 msg = "nf_ct_dccp: bad checksum "; 606 msg = "nf_ct_dccp: bad checksum ";
607 goto out_invalid; 607 goto out_invalid;
608 } 608 }
609 609
610 if (dh->dccph_type >= DCCP_PKT_INVALID) { 610 if (dh->dccph_type >= DCCP_PKT_INVALID) {
611 msg = "nf_ct_dccp: reserved packet type "; 611 msg = "nf_ct_dccp: reserved packet type ";
612 goto out_invalid; 612 goto out_invalid;
613 } 613 }
614 614
615 return NF_ACCEPT; 615 return NF_ACCEPT;
616 616
617 out_invalid: 617 out_invalid:
618 if (LOG_INVALID(net, IPPROTO_DCCP)) 618 if (LOG_INVALID(net, IPPROTO_DCCP))
619 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, msg); 619 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, msg);
620 return -NF_ACCEPT; 620 return -NF_ACCEPT;
621 } 621 }
622 622
623 static int dccp_print_tuple(struct seq_file *s, 623 static int dccp_print_tuple(struct seq_file *s,
624 const struct nf_conntrack_tuple *tuple) 624 const struct nf_conntrack_tuple *tuple)
625 { 625 {
626 return seq_printf(s, "sport=%hu dport=%hu ", 626 return seq_printf(s, "sport=%hu dport=%hu ",
627 ntohs(tuple->src.u.dccp.port), 627 ntohs(tuple->src.u.dccp.port),
628 ntohs(tuple->dst.u.dccp.port)); 628 ntohs(tuple->dst.u.dccp.port));
629 } 629 }
630 630
631 static int dccp_print_conntrack(struct seq_file *s, struct nf_conn *ct) 631 static int dccp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
632 { 632 {
633 return seq_printf(s, "%s ", dccp_state_names[ct->proto.dccp.state]); 633 return seq_printf(s, "%s ", dccp_state_names[ct->proto.dccp.state]);
634 } 634 }
635 635
636 #if IS_ENABLED(CONFIG_NF_CT_NETLINK) 636 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
637 static int dccp_to_nlattr(struct sk_buff *skb, struct nlattr *nla, 637 static int dccp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
638 struct nf_conn *ct) 638 struct nf_conn *ct)
639 { 639 {
640 struct nlattr *nest_parms; 640 struct nlattr *nest_parms;
641 641
642 spin_lock_bh(&ct->lock); 642 spin_lock_bh(&ct->lock);
643 nest_parms = nla_nest_start(skb, CTA_PROTOINFO_DCCP | NLA_F_NESTED); 643 nest_parms = nla_nest_start(skb, CTA_PROTOINFO_DCCP | NLA_F_NESTED);
644 if (!nest_parms) 644 if (!nest_parms)
645 goto nla_put_failure; 645 goto nla_put_failure;
646 if (nla_put_u8(skb, CTA_PROTOINFO_DCCP_STATE, ct->proto.dccp.state) || 646 if (nla_put_u8(skb, CTA_PROTOINFO_DCCP_STATE, ct->proto.dccp.state) ||
647 nla_put_u8(skb, CTA_PROTOINFO_DCCP_ROLE, 647 nla_put_u8(skb, CTA_PROTOINFO_DCCP_ROLE,
648 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL]) || 648 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL]) ||
649 nla_put_be64(skb, CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ, 649 nla_put_be64(skb, CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
650 cpu_to_be64(ct->proto.dccp.handshake_seq))) 650 cpu_to_be64(ct->proto.dccp.handshake_seq)))
651 goto nla_put_failure; 651 goto nla_put_failure;
652 nla_nest_end(skb, nest_parms); 652 nla_nest_end(skb, nest_parms);
653 spin_unlock_bh(&ct->lock); 653 spin_unlock_bh(&ct->lock);
654 return 0; 654 return 0;
655 655
656 nla_put_failure: 656 nla_put_failure:
657 spin_unlock_bh(&ct->lock); 657 spin_unlock_bh(&ct->lock);
658 return -1; 658 return -1;
659 } 659 }
660 660
661 static const struct nla_policy dccp_nla_policy[CTA_PROTOINFO_DCCP_MAX + 1] = { 661 static const struct nla_policy dccp_nla_policy[CTA_PROTOINFO_DCCP_MAX + 1] = {
662 [CTA_PROTOINFO_DCCP_STATE] = { .type = NLA_U8 }, 662 [CTA_PROTOINFO_DCCP_STATE] = { .type = NLA_U8 },
663 [CTA_PROTOINFO_DCCP_ROLE] = { .type = NLA_U8 }, 663 [CTA_PROTOINFO_DCCP_ROLE] = { .type = NLA_U8 },
664 [CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ] = { .type = NLA_U64 }, 664 [CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ] = { .type = NLA_U64 },
665 }; 665 };
666 666
667 static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct) 667 static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
668 { 668 {
669 struct nlattr *attr = cda[CTA_PROTOINFO_DCCP]; 669 struct nlattr *attr = cda[CTA_PROTOINFO_DCCP];
670 struct nlattr *tb[CTA_PROTOINFO_DCCP_MAX + 1]; 670 struct nlattr *tb[CTA_PROTOINFO_DCCP_MAX + 1];
671 int err; 671 int err;
672 672
673 if (!attr) 673 if (!attr)
674 return 0; 674 return 0;
675 675
676 err = nla_parse_nested(tb, CTA_PROTOINFO_DCCP_MAX, attr, 676 err = nla_parse_nested(tb, CTA_PROTOINFO_DCCP_MAX, attr,
677 dccp_nla_policy); 677 dccp_nla_policy);
678 if (err < 0) 678 if (err < 0)
679 return err; 679 return err;
680 680
681 if (!tb[CTA_PROTOINFO_DCCP_STATE] || 681 if (!tb[CTA_PROTOINFO_DCCP_STATE] ||
682 !tb[CTA_PROTOINFO_DCCP_ROLE] || 682 !tb[CTA_PROTOINFO_DCCP_ROLE] ||
683 nla_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]) > CT_DCCP_ROLE_MAX || 683 nla_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]) > CT_DCCP_ROLE_MAX ||
684 nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]) >= CT_DCCP_IGNORE) { 684 nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]) >= CT_DCCP_IGNORE) {
685 return -EINVAL; 685 return -EINVAL;
686 } 686 }
687 687
688 spin_lock_bh(&ct->lock); 688 spin_lock_bh(&ct->lock);
689 ct->proto.dccp.state = nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]); 689 ct->proto.dccp.state = nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]);
690 if (nla_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]) == CT_DCCP_ROLE_CLIENT) { 690 if (nla_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]) == CT_DCCP_ROLE_CLIENT) {
691 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_CLIENT; 691 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_CLIENT;
692 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_SERVER; 692 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_SERVER;
693 } else { 693 } else {
694 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_SERVER; 694 ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_SERVER;
695 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_CLIENT; 695 ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_CLIENT;
696 } 696 }
697 if (tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]) { 697 if (tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]) {
698 ct->proto.dccp.handshake_seq = 698 ct->proto.dccp.handshake_seq =
699 be64_to_cpu(nla_get_be64(tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ])); 699 be64_to_cpu(nla_get_be64(tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]));
700 } 700 }
701 spin_unlock_bh(&ct->lock); 701 spin_unlock_bh(&ct->lock);
702 return 0; 702 return 0;
703 } 703 }
704 704
705 static int dccp_nlattr_size(void) 705 static int dccp_nlattr_size(void)
706 { 706 {
707 return nla_total_size(0) /* CTA_PROTOINFO_DCCP */ 707 return nla_total_size(0) /* CTA_PROTOINFO_DCCP */
708 + nla_policy_len(dccp_nla_policy, CTA_PROTOINFO_DCCP_MAX + 1); 708 + nla_policy_len(dccp_nla_policy, CTA_PROTOINFO_DCCP_MAX + 1);
709 } 709 }
710 710
711 #endif 711 #endif
712 712
713 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 713 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
714 714
715 #include <linux/netfilter/nfnetlink.h> 715 #include <linux/netfilter/nfnetlink.h>
716 #include <linux/netfilter/nfnetlink_cttimeout.h> 716 #include <linux/netfilter/nfnetlink_cttimeout.h>
717 717
718 static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) 718 static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
719 { 719 {
720 struct dccp_net *dn = dccp_pernet(&init_net); 720 struct dccp_net *dn = dccp_pernet(&init_net);
721 unsigned int *timeouts = data; 721 unsigned int *timeouts = data;
722 int i; 722 int i;
723 723
724 /* set default DCCP timeouts. */ 724 /* set default DCCP timeouts. */
725 for (i=0; i<CT_DCCP_MAX; i++) 725 for (i=0; i<CT_DCCP_MAX; i++)
726 timeouts[i] = dn->dccp_timeout[i]; 726 timeouts[i] = dn->dccp_timeout[i];
727 727
728 /* there's a 1:1 mapping between attributes and protocol states. */ 728 /* there's a 1:1 mapping between attributes and protocol states. */
729 for (i=CTA_TIMEOUT_DCCP_UNSPEC+1; i<CTA_TIMEOUT_DCCP_MAX+1; i++) { 729 for (i=CTA_TIMEOUT_DCCP_UNSPEC+1; i<CTA_TIMEOUT_DCCP_MAX+1; i++) {
730 if (tb[i]) { 730 if (tb[i]) {
731 timeouts[i] = ntohl(nla_get_be32(tb[i])) * HZ; 731 timeouts[i] = ntohl(nla_get_be32(tb[i])) * HZ;
732 } 732 }
733 } 733 }
734 return 0; 734 return 0;
735 } 735 }
736 736
737 static int 737 static int
738 dccp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data) 738 dccp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
739 { 739 {
740 const unsigned int *timeouts = data; 740 const unsigned int *timeouts = data;
741 int i; 741 int i;
742 742
743 for (i=CTA_TIMEOUT_DCCP_UNSPEC+1; i<CTA_TIMEOUT_DCCP_MAX+1; i++) { 743 for (i=CTA_TIMEOUT_DCCP_UNSPEC+1; i<CTA_TIMEOUT_DCCP_MAX+1; i++) {
744 if (nla_put_be32(skb, i, htonl(timeouts[i] / HZ))) 744 if (nla_put_be32(skb, i, htonl(timeouts[i] / HZ)))
745 goto nla_put_failure; 745 goto nla_put_failure;
746 } 746 }
747 return 0; 747 return 0;
748 748
749 nla_put_failure: 749 nla_put_failure:
750 return -ENOSPC; 750 return -ENOSPC;
751 } 751 }
752 752
753 static const struct nla_policy 753 static const struct nla_policy
754 dccp_timeout_nla_policy[CTA_TIMEOUT_DCCP_MAX+1] = { 754 dccp_timeout_nla_policy[CTA_TIMEOUT_DCCP_MAX+1] = {
755 [CTA_TIMEOUT_DCCP_REQUEST] = { .type = NLA_U32 }, 755 [CTA_TIMEOUT_DCCP_REQUEST] = { .type = NLA_U32 },
756 [CTA_TIMEOUT_DCCP_RESPOND] = { .type = NLA_U32 }, 756 [CTA_TIMEOUT_DCCP_RESPOND] = { .type = NLA_U32 },
757 [CTA_TIMEOUT_DCCP_PARTOPEN] = { .type = NLA_U32 }, 757 [CTA_TIMEOUT_DCCP_PARTOPEN] = { .type = NLA_U32 },
758 [CTA_TIMEOUT_DCCP_OPEN] = { .type = NLA_U32 }, 758 [CTA_TIMEOUT_DCCP_OPEN] = { .type = NLA_U32 },
759 [CTA_TIMEOUT_DCCP_CLOSEREQ] = { .type = NLA_U32 }, 759 [CTA_TIMEOUT_DCCP_CLOSEREQ] = { .type = NLA_U32 },
760 [CTA_TIMEOUT_DCCP_CLOSING] = { .type = NLA_U32 }, 760 [CTA_TIMEOUT_DCCP_CLOSING] = { .type = NLA_U32 },
761 [CTA_TIMEOUT_DCCP_TIMEWAIT] = { .type = NLA_U32 }, 761 [CTA_TIMEOUT_DCCP_TIMEWAIT] = { .type = NLA_U32 },
762 }; 762 };
763 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 763 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
764 764
765 #ifdef CONFIG_SYSCTL 765 #ifdef CONFIG_SYSCTL
766 /* template, data assigned later */ 766 /* template, data assigned later */
767 static struct ctl_table dccp_sysctl_table[] = { 767 static struct ctl_table dccp_sysctl_table[] = {
768 { 768 {
769 .procname = "nf_conntrack_dccp_timeout_request", 769 .procname = "nf_conntrack_dccp_timeout_request",
770 .maxlen = sizeof(unsigned int), 770 .maxlen = sizeof(unsigned int),
771 .mode = 0644, 771 .mode = 0644,
772 .proc_handler = proc_dointvec_jiffies, 772 .proc_handler = proc_dointvec_jiffies,
773 }, 773 },
774 { 774 {
775 .procname = "nf_conntrack_dccp_timeout_respond", 775 .procname = "nf_conntrack_dccp_timeout_respond",
776 .maxlen = sizeof(unsigned int), 776 .maxlen = sizeof(unsigned int),
777 .mode = 0644, 777 .mode = 0644,
778 .proc_handler = proc_dointvec_jiffies, 778 .proc_handler = proc_dointvec_jiffies,
779 }, 779 },
780 { 780 {
781 .procname = "nf_conntrack_dccp_timeout_partopen", 781 .procname = "nf_conntrack_dccp_timeout_partopen",
782 .maxlen = sizeof(unsigned int), 782 .maxlen = sizeof(unsigned int),
783 .mode = 0644, 783 .mode = 0644,
784 .proc_handler = proc_dointvec_jiffies, 784 .proc_handler = proc_dointvec_jiffies,
785 }, 785 },
786 { 786 {
787 .procname = "nf_conntrack_dccp_timeout_open", 787 .procname = "nf_conntrack_dccp_timeout_open",
788 .maxlen = sizeof(unsigned int), 788 .maxlen = sizeof(unsigned int),
789 .mode = 0644, 789 .mode = 0644,
790 .proc_handler = proc_dointvec_jiffies, 790 .proc_handler = proc_dointvec_jiffies,
791 }, 791 },
792 { 792 {
793 .procname = "nf_conntrack_dccp_timeout_closereq", 793 .procname = "nf_conntrack_dccp_timeout_closereq",
794 .maxlen = sizeof(unsigned int), 794 .maxlen = sizeof(unsigned int),
795 .mode = 0644, 795 .mode = 0644,
796 .proc_handler = proc_dointvec_jiffies, 796 .proc_handler = proc_dointvec_jiffies,
797 }, 797 },
798 { 798 {
799 .procname = "nf_conntrack_dccp_timeout_closing", 799 .procname = "nf_conntrack_dccp_timeout_closing",
800 .maxlen = sizeof(unsigned int), 800 .maxlen = sizeof(unsigned int),
801 .mode = 0644, 801 .mode = 0644,
802 .proc_handler = proc_dointvec_jiffies, 802 .proc_handler = proc_dointvec_jiffies,
803 }, 803 },
804 { 804 {
805 .procname = "nf_conntrack_dccp_timeout_timewait", 805 .procname = "nf_conntrack_dccp_timeout_timewait",
806 .maxlen = sizeof(unsigned int), 806 .maxlen = sizeof(unsigned int),
807 .mode = 0644, 807 .mode = 0644,
808 .proc_handler = proc_dointvec_jiffies, 808 .proc_handler = proc_dointvec_jiffies,
809 }, 809 },
810 { 810 {
811 .procname = "nf_conntrack_dccp_loose", 811 .procname = "nf_conntrack_dccp_loose",
812 .maxlen = sizeof(int), 812 .maxlen = sizeof(int),
813 .mode = 0644, 813 .mode = 0644,
814 .proc_handler = proc_dointvec, 814 .proc_handler = proc_dointvec,
815 }, 815 },
816 { } 816 { }
817 }; 817 };
818 #endif /* CONFIG_SYSCTL */ 818 #endif /* CONFIG_SYSCTL */
819 819
820 static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = { 820 static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = {
821 .l3proto = AF_INET, 821 .l3proto = AF_INET,
822 .l4proto = IPPROTO_DCCP, 822 .l4proto = IPPROTO_DCCP,
823 .name = "dccp", 823 .name = "dccp",
824 .pkt_to_tuple = dccp_pkt_to_tuple, 824 .pkt_to_tuple = dccp_pkt_to_tuple,
825 .invert_tuple = dccp_invert_tuple, 825 .invert_tuple = dccp_invert_tuple,
826 .new = dccp_new, 826 .new = dccp_new,
827 .packet = dccp_packet, 827 .packet = dccp_packet,
828 .get_timeouts = dccp_get_timeouts, 828 .get_timeouts = dccp_get_timeouts,
829 .error = dccp_error, 829 .error = dccp_error,
830 .print_tuple = dccp_print_tuple, 830 .print_tuple = dccp_print_tuple,
831 .print_conntrack = dccp_print_conntrack, 831 .print_conntrack = dccp_print_conntrack,
832 #if IS_ENABLED(CONFIG_NF_CT_NETLINK) 832 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
833 .to_nlattr = dccp_to_nlattr, 833 .to_nlattr = dccp_to_nlattr,
834 .nlattr_size = dccp_nlattr_size, 834 .nlattr_size = dccp_nlattr_size,
835 .from_nlattr = nlattr_to_dccp, 835 .from_nlattr = nlattr_to_dccp,
836 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 836 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
837 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size, 837 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
838 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 838 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
839 .nla_policy = nf_ct_port_nla_policy, 839 .nla_policy = nf_ct_port_nla_policy,
840 #endif 840 #endif
841 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 841 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
842 .ctnl_timeout = { 842 .ctnl_timeout = {
843 .nlattr_to_obj = dccp_timeout_nlattr_to_obj, 843 .nlattr_to_obj = dccp_timeout_nlattr_to_obj,
844 .obj_to_nlattr = dccp_timeout_obj_to_nlattr, 844 .obj_to_nlattr = dccp_timeout_obj_to_nlattr,
845 .nlattr_max = CTA_TIMEOUT_DCCP_MAX, 845 .nlattr_max = CTA_TIMEOUT_DCCP_MAX,
846 .obj_size = sizeof(unsigned int) * CT_DCCP_MAX, 846 .obj_size = sizeof(unsigned int) * CT_DCCP_MAX,
847 .nla_policy = dccp_timeout_nla_policy, 847 .nla_policy = dccp_timeout_nla_policy,
848 }, 848 },
849 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 849 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
850 }; 850 };
851 851
852 static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = { 852 static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = {
853 .l3proto = AF_INET6, 853 .l3proto = AF_INET6,
854 .l4proto = IPPROTO_DCCP, 854 .l4proto = IPPROTO_DCCP,
855 .name = "dccp", 855 .name = "dccp",
856 .pkt_to_tuple = dccp_pkt_to_tuple, 856 .pkt_to_tuple = dccp_pkt_to_tuple,
857 .invert_tuple = dccp_invert_tuple, 857 .invert_tuple = dccp_invert_tuple,
858 .new = dccp_new, 858 .new = dccp_new,
859 .packet = dccp_packet, 859 .packet = dccp_packet,
860 .get_timeouts = dccp_get_timeouts, 860 .get_timeouts = dccp_get_timeouts,
861 .error = dccp_error, 861 .error = dccp_error,
862 .print_tuple = dccp_print_tuple, 862 .print_tuple = dccp_print_tuple,
863 .print_conntrack = dccp_print_conntrack, 863 .print_conntrack = dccp_print_conntrack,
864 #if IS_ENABLED(CONFIG_NF_CT_NETLINK) 864 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
865 .to_nlattr = dccp_to_nlattr, 865 .to_nlattr = dccp_to_nlattr,
866 .nlattr_size = dccp_nlattr_size, 866 .nlattr_size = dccp_nlattr_size,
867 .from_nlattr = nlattr_to_dccp, 867 .from_nlattr = nlattr_to_dccp,
868 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 868 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
869 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size, 869 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
870 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 870 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
871 .nla_policy = nf_ct_port_nla_policy, 871 .nla_policy = nf_ct_port_nla_policy,
872 #endif 872 #endif
873 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 873 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
874 .ctnl_timeout = { 874 .ctnl_timeout = {
875 .nlattr_to_obj = dccp_timeout_nlattr_to_obj, 875 .nlattr_to_obj = dccp_timeout_nlattr_to_obj,
876 .obj_to_nlattr = dccp_timeout_obj_to_nlattr, 876 .obj_to_nlattr = dccp_timeout_obj_to_nlattr,
877 .nlattr_max = CTA_TIMEOUT_DCCP_MAX, 877 .nlattr_max = CTA_TIMEOUT_DCCP_MAX,
878 .obj_size = sizeof(unsigned int) * CT_DCCP_MAX, 878 .obj_size = sizeof(unsigned int) * CT_DCCP_MAX,
879 .nla_policy = dccp_timeout_nla_policy, 879 .nla_policy = dccp_timeout_nla_policy,
880 }, 880 },
881 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 881 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
882 }; 882 };
883 883
884 static __net_init int dccp_net_init(struct net *net) 884 static __net_init int dccp_net_init(struct net *net)
885 { 885 {
886 struct dccp_net *dn = dccp_pernet(net); 886 struct dccp_net *dn = dccp_pernet(net);
887 887
888 /* default values */ 888 /* default values */
889 dn->dccp_loose = 1; 889 dn->dccp_loose = 1;
890 dn->dccp_timeout[CT_DCCP_REQUEST] = 2 * DCCP_MSL; 890 dn->dccp_timeout[CT_DCCP_REQUEST] = 2 * DCCP_MSL;
891 dn->dccp_timeout[CT_DCCP_RESPOND] = 4 * DCCP_MSL; 891 dn->dccp_timeout[CT_DCCP_RESPOND] = 4 * DCCP_MSL;
892 dn->dccp_timeout[CT_DCCP_PARTOPEN] = 4 * DCCP_MSL; 892 dn->dccp_timeout[CT_DCCP_PARTOPEN] = 4 * DCCP_MSL;
893 dn->dccp_timeout[CT_DCCP_OPEN] = 12 * 3600 * HZ; 893 dn->dccp_timeout[CT_DCCP_OPEN] = 12 * 3600 * HZ;
894 dn->dccp_timeout[CT_DCCP_CLOSEREQ] = 64 * HZ; 894 dn->dccp_timeout[CT_DCCP_CLOSEREQ] = 64 * HZ;
895 dn->dccp_timeout[CT_DCCP_CLOSING] = 64 * HZ; 895 dn->dccp_timeout[CT_DCCP_CLOSING] = 64 * HZ;
896 dn->dccp_timeout[CT_DCCP_TIMEWAIT] = 2 * DCCP_MSL; 896 dn->dccp_timeout[CT_DCCP_TIMEWAIT] = 2 * DCCP_MSL;
897 897
898 #ifdef CONFIG_SYSCTL 898 #ifdef CONFIG_SYSCTL
899 dn->sysctl_table = kmemdup(dccp_sysctl_table, 899 dn->sysctl_table = kmemdup(dccp_sysctl_table,
900 sizeof(dccp_sysctl_table), GFP_KERNEL); 900 sizeof(dccp_sysctl_table), GFP_KERNEL);
901 if (!dn->sysctl_table) 901 if (!dn->sysctl_table)
902 return -ENOMEM; 902 return -ENOMEM;
903 903
904 dn->sysctl_table[0].data = &dn->dccp_timeout[CT_DCCP_REQUEST]; 904 dn->sysctl_table[0].data = &dn->dccp_timeout[CT_DCCP_REQUEST];
905 dn->sysctl_table[1].data = &dn->dccp_timeout[CT_DCCP_RESPOND]; 905 dn->sysctl_table[1].data = &dn->dccp_timeout[CT_DCCP_RESPOND];
906 dn->sysctl_table[2].data = &dn->dccp_timeout[CT_DCCP_PARTOPEN]; 906 dn->sysctl_table[2].data = &dn->dccp_timeout[CT_DCCP_PARTOPEN];
907 dn->sysctl_table[3].data = &dn->dccp_timeout[CT_DCCP_OPEN]; 907 dn->sysctl_table[3].data = &dn->dccp_timeout[CT_DCCP_OPEN];
908 dn->sysctl_table[4].data = &dn->dccp_timeout[CT_DCCP_CLOSEREQ]; 908 dn->sysctl_table[4].data = &dn->dccp_timeout[CT_DCCP_CLOSEREQ];
909 dn->sysctl_table[5].data = &dn->dccp_timeout[CT_DCCP_CLOSING]; 909 dn->sysctl_table[5].data = &dn->dccp_timeout[CT_DCCP_CLOSING];
910 dn->sysctl_table[6].data = &dn->dccp_timeout[CT_DCCP_TIMEWAIT]; 910 dn->sysctl_table[6].data = &dn->dccp_timeout[CT_DCCP_TIMEWAIT];
911 dn->sysctl_table[7].data = &dn->dccp_loose; 911 dn->sysctl_table[7].data = &dn->dccp_loose;
912 912
913 dn->sysctl_header = register_net_sysctl(net, "net/netfilter", 913 dn->sysctl_header = register_net_sysctl(net, "net/netfilter",
914 dn->sysctl_table); 914 dn->sysctl_table);
915 if (!dn->sysctl_header) { 915 if (!dn->sysctl_header) {
916 kfree(dn->sysctl_table); 916 kfree(dn->sysctl_table);
917 return -ENOMEM; 917 return -ENOMEM;
918 } 918 }
919 #endif 919 #endif
920 920
921 return 0; 921 return 0;
922 } 922 }
923 923
924 static __net_exit void dccp_net_exit(struct net *net) 924 static __net_exit void dccp_net_exit(struct net *net)
925 { 925 {
926 struct dccp_net *dn = dccp_pernet(net); 926 struct dccp_net *dn = dccp_pernet(net);
927 #ifdef CONFIG_SYSCTL 927 #ifdef CONFIG_SYSCTL
928 unregister_net_sysctl_table(dn->sysctl_header); 928 unregister_net_sysctl_table(dn->sysctl_header);
929 kfree(dn->sysctl_table); 929 kfree(dn->sysctl_table);
930 #endif 930 #endif
931 } 931 }
932 932
933 static struct pernet_operations dccp_net_ops = { 933 static struct pernet_operations dccp_net_ops = {
934 .init = dccp_net_init, 934 .init = dccp_net_init,
935 .exit = dccp_net_exit, 935 .exit = dccp_net_exit,
936 .id = &dccp_net_id, 936 .id = &dccp_net_id,
937 .size = sizeof(struct dccp_net), 937 .size = sizeof(struct dccp_net),
938 }; 938 };
939 939
940 static int __init nf_conntrack_proto_dccp_init(void) 940 static int __init nf_conntrack_proto_dccp_init(void)
941 { 941 {
942 int err; 942 int err;
943 943
944 err = register_pernet_subsys(&dccp_net_ops); 944 err = register_pernet_subsys(&dccp_net_ops);
945 if (err < 0) 945 if (err < 0)
946 goto err1; 946 goto err1;
947 947
948 err = nf_conntrack_l4proto_register(&dccp_proto4); 948 err = nf_conntrack_l4proto_register(&init_net, &dccp_proto4);
949 if (err < 0) 949 if (err < 0)
950 goto err2; 950 goto err2;
951 951
952 err = nf_conntrack_l4proto_register(&dccp_proto6); 952 err = nf_conntrack_l4proto_register(&init_net, &dccp_proto6);
953 if (err < 0) 953 if (err < 0)
954 goto err3; 954 goto err3;
955 return 0; 955 return 0;
956 956
957 err3: 957 err3:
958 nf_conntrack_l4proto_unregister(&dccp_proto4); 958 nf_conntrack_l4proto_unregister(&init_net, &dccp_proto4);
959 err2: 959 err2:
960 unregister_pernet_subsys(&dccp_net_ops); 960 unregister_pernet_subsys(&dccp_net_ops);
961 err1: 961 err1:
962 return err; 962 return err;
963 } 963 }
964 964
965 static void __exit nf_conntrack_proto_dccp_fini(void) 965 static void __exit nf_conntrack_proto_dccp_fini(void)
966 { 966 {
967 unregister_pernet_subsys(&dccp_net_ops); 967 unregister_pernet_subsys(&dccp_net_ops);
968 nf_conntrack_l4proto_unregister(&dccp_proto6); 968 nf_conntrack_l4proto_unregister(&init_net, &dccp_proto6);
969 nf_conntrack_l4proto_unregister(&dccp_proto4); 969 nf_conntrack_l4proto_unregister(&init_net, &dccp_proto4);
970 } 970 }
971 971
972 module_init(nf_conntrack_proto_dccp_init); 972 module_init(nf_conntrack_proto_dccp_init);
973 module_exit(nf_conntrack_proto_dccp_fini); 973 module_exit(nf_conntrack_proto_dccp_fini);
974 974
975 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 975 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
976 MODULE_DESCRIPTION("DCCP connection tracking protocol helper"); 976 MODULE_DESCRIPTION("DCCP connection tracking protocol helper");
977 MODULE_LICENSE("GPL"); 977 MODULE_LICENSE("GPL");
978 978
net/netfilter/nf_conntrack_proto_gre.c
1 /* 1 /*
2 * ip_conntrack_proto_gre.c - Version 3.0 2 * ip_conntrack_proto_gre.c - Version 3.0
3 * 3 *
4 * Connection tracking protocol helper module for GRE. 4 * Connection tracking protocol helper module for GRE.
5 * 5 *
6 * GRE is a generic encapsulation protocol, which is generally not very 6 * GRE is a generic encapsulation protocol, which is generally not very
7 * suited for NAT, as it has no protocol-specific part as port numbers. 7 * suited for NAT, as it has no protocol-specific part as port numbers.
8 * 8 *
9 * It has an optional key field, which may help us distinguishing two 9 * It has an optional key field, which may help us distinguishing two
10 * connections between the same two hosts. 10 * connections between the same two hosts.
11 * 11 *
12 * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784 12 * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784
13 * 13 *
14 * PPTP is built on top of a modified version of GRE, and has a mandatory 14 * PPTP is built on top of a modified version of GRE, and has a mandatory
15 * field called "CallID", which serves us for the same purpose as the key 15 * field called "CallID", which serves us for the same purpose as the key
16 * field in plain GRE. 16 * field in plain GRE.
17 * 17 *
18 * Documentation about PPTP can be found in RFC 2637 18 * Documentation about PPTP can be found in RFC 2637
19 * 19 *
20 * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org> 20 * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>
21 * 21 *
22 * Development of this code funded by Astaro AG (http://www.astaro.com/) 22 * Development of this code funded by Astaro AG (http://www.astaro.com/)
23 * 23 *
24 */ 24 */
25 25
26 #include <linux/module.h> 26 #include <linux/module.h>
27 #include <linux/types.h> 27 #include <linux/types.h>
28 #include <linux/timer.h> 28 #include <linux/timer.h>
29 #include <linux/list.h> 29 #include <linux/list.h>
30 #include <linux/seq_file.h> 30 #include <linux/seq_file.h>
31 #include <linux/in.h> 31 #include <linux/in.h>
32 #include <linux/netdevice.h> 32 #include <linux/netdevice.h>
33 #include <linux/skbuff.h> 33 #include <linux/skbuff.h>
34 #include <linux/slab.h> 34 #include <linux/slab.h>
35 #include <net/dst.h> 35 #include <net/dst.h>
36 #include <net/net_namespace.h> 36 #include <net/net_namespace.h>
37 #include <net/netns/generic.h> 37 #include <net/netns/generic.h>
38 #include <net/netfilter/nf_conntrack_l4proto.h> 38 #include <net/netfilter/nf_conntrack_l4proto.h>
39 #include <net/netfilter/nf_conntrack_helper.h> 39 #include <net/netfilter/nf_conntrack_helper.h>
40 #include <net/netfilter/nf_conntrack_core.h> 40 #include <net/netfilter/nf_conntrack_core.h>
41 #include <linux/netfilter/nf_conntrack_proto_gre.h> 41 #include <linux/netfilter/nf_conntrack_proto_gre.h>
42 #include <linux/netfilter/nf_conntrack_pptp.h> 42 #include <linux/netfilter/nf_conntrack_pptp.h>
43 43
44 enum grep_conntrack { 44 enum grep_conntrack {
45 GRE_CT_UNREPLIED, 45 GRE_CT_UNREPLIED,
46 GRE_CT_REPLIED, 46 GRE_CT_REPLIED,
47 GRE_CT_MAX 47 GRE_CT_MAX
48 }; 48 };
49 49
50 static unsigned int gre_timeouts[GRE_CT_MAX] = { 50 static unsigned int gre_timeouts[GRE_CT_MAX] = {
51 [GRE_CT_UNREPLIED] = 30*HZ, 51 [GRE_CT_UNREPLIED] = 30*HZ,
52 [GRE_CT_REPLIED] = 180*HZ, 52 [GRE_CT_REPLIED] = 180*HZ,
53 }; 53 };
54 54
55 static int proto_gre_net_id __read_mostly; 55 static int proto_gre_net_id __read_mostly;
56 struct netns_proto_gre { 56 struct netns_proto_gre {
57 rwlock_t keymap_lock; 57 rwlock_t keymap_lock;
58 struct list_head keymap_list; 58 struct list_head keymap_list;
59 }; 59 };
60 60
61 void nf_ct_gre_keymap_flush(struct net *net) 61 void nf_ct_gre_keymap_flush(struct net *net)
62 { 62 {
63 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id); 63 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
64 struct nf_ct_gre_keymap *km, *tmp; 64 struct nf_ct_gre_keymap *km, *tmp;
65 65
66 write_lock_bh(&net_gre->keymap_lock); 66 write_lock_bh(&net_gre->keymap_lock);
67 list_for_each_entry_safe(km, tmp, &net_gre->keymap_list, list) { 67 list_for_each_entry_safe(km, tmp, &net_gre->keymap_list, list) {
68 list_del(&km->list); 68 list_del(&km->list);
69 kfree(km); 69 kfree(km);
70 } 70 }
71 write_unlock_bh(&net_gre->keymap_lock); 71 write_unlock_bh(&net_gre->keymap_lock);
72 } 72 }
73 EXPORT_SYMBOL(nf_ct_gre_keymap_flush); 73 EXPORT_SYMBOL(nf_ct_gre_keymap_flush);
74 74
75 static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km, 75 static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km,
76 const struct nf_conntrack_tuple *t) 76 const struct nf_conntrack_tuple *t)
77 { 77 {
78 return km->tuple.src.l3num == t->src.l3num && 78 return km->tuple.src.l3num == t->src.l3num &&
79 !memcmp(&km->tuple.src.u3, &t->src.u3, sizeof(t->src.u3)) && 79 !memcmp(&km->tuple.src.u3, &t->src.u3, sizeof(t->src.u3)) &&
80 !memcmp(&km->tuple.dst.u3, &t->dst.u3, sizeof(t->dst.u3)) && 80 !memcmp(&km->tuple.dst.u3, &t->dst.u3, sizeof(t->dst.u3)) &&
81 km->tuple.dst.protonum == t->dst.protonum && 81 km->tuple.dst.protonum == t->dst.protonum &&
82 km->tuple.dst.u.all == t->dst.u.all; 82 km->tuple.dst.u.all == t->dst.u.all;
83 } 83 }
84 84
85 /* look up the source key for a given tuple */ 85 /* look up the source key for a given tuple */
86 static __be16 gre_keymap_lookup(struct net *net, struct nf_conntrack_tuple *t) 86 static __be16 gre_keymap_lookup(struct net *net, struct nf_conntrack_tuple *t)
87 { 87 {
88 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id); 88 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
89 struct nf_ct_gre_keymap *km; 89 struct nf_ct_gre_keymap *km;
90 __be16 key = 0; 90 __be16 key = 0;
91 91
92 read_lock_bh(&net_gre->keymap_lock); 92 read_lock_bh(&net_gre->keymap_lock);
93 list_for_each_entry(km, &net_gre->keymap_list, list) { 93 list_for_each_entry(km, &net_gre->keymap_list, list) {
94 if (gre_key_cmpfn(km, t)) { 94 if (gre_key_cmpfn(km, t)) {
95 key = km->tuple.src.u.gre.key; 95 key = km->tuple.src.u.gre.key;
96 break; 96 break;
97 } 97 }
98 } 98 }
99 read_unlock_bh(&net_gre->keymap_lock); 99 read_unlock_bh(&net_gre->keymap_lock);
100 100
101 pr_debug("lookup src key 0x%x for ", key); 101 pr_debug("lookup src key 0x%x for ", key);
102 nf_ct_dump_tuple(t); 102 nf_ct_dump_tuple(t);
103 103
104 return key; 104 return key;
105 } 105 }
106 106
107 /* add a single keymap entry, associate with specified master ct */ 107 /* add a single keymap entry, associate with specified master ct */
108 int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, 108 int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
109 struct nf_conntrack_tuple *t) 109 struct nf_conntrack_tuple *t)
110 { 110 {
111 struct net *net = nf_ct_net(ct); 111 struct net *net = nf_ct_net(ct);
112 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id); 112 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
113 struct nf_conn_help *help = nfct_help(ct); 113 struct nf_conn_help *help = nfct_help(ct);
114 struct nf_ct_gre_keymap **kmp, *km; 114 struct nf_ct_gre_keymap **kmp, *km;
115 115
116 kmp = &help->help.ct_pptp_info.keymap[dir]; 116 kmp = &help->help.ct_pptp_info.keymap[dir];
117 if (*kmp) { 117 if (*kmp) {
118 /* check whether it's a retransmission */ 118 /* check whether it's a retransmission */
119 read_lock_bh(&net_gre->keymap_lock); 119 read_lock_bh(&net_gre->keymap_lock);
120 list_for_each_entry(km, &net_gre->keymap_list, list) { 120 list_for_each_entry(km, &net_gre->keymap_list, list) {
121 if (gre_key_cmpfn(km, t) && km == *kmp) { 121 if (gre_key_cmpfn(km, t) && km == *kmp) {
122 read_unlock_bh(&net_gre->keymap_lock); 122 read_unlock_bh(&net_gre->keymap_lock);
123 return 0; 123 return 0;
124 } 124 }
125 } 125 }
126 read_unlock_bh(&net_gre->keymap_lock); 126 read_unlock_bh(&net_gre->keymap_lock);
127 pr_debug("trying to override keymap_%s for ct %p\n", 127 pr_debug("trying to override keymap_%s for ct %p\n",
128 dir == IP_CT_DIR_REPLY ? "reply" : "orig", ct); 128 dir == IP_CT_DIR_REPLY ? "reply" : "orig", ct);
129 return -EEXIST; 129 return -EEXIST;
130 } 130 }
131 131
132 km = kmalloc(sizeof(*km), GFP_ATOMIC); 132 km = kmalloc(sizeof(*km), GFP_ATOMIC);
133 if (!km) 133 if (!km)
134 return -ENOMEM; 134 return -ENOMEM;
135 memcpy(&km->tuple, t, sizeof(*t)); 135 memcpy(&km->tuple, t, sizeof(*t));
136 *kmp = km; 136 *kmp = km;
137 137
138 pr_debug("adding new entry %p: ", km); 138 pr_debug("adding new entry %p: ", km);
139 nf_ct_dump_tuple(&km->tuple); 139 nf_ct_dump_tuple(&km->tuple);
140 140
141 write_lock_bh(&net_gre->keymap_lock); 141 write_lock_bh(&net_gre->keymap_lock);
142 list_add_tail(&km->list, &net_gre->keymap_list); 142 list_add_tail(&km->list, &net_gre->keymap_list);
143 write_unlock_bh(&net_gre->keymap_lock); 143 write_unlock_bh(&net_gre->keymap_lock);
144 144
145 return 0; 145 return 0;
146 } 146 }
147 EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_add); 147 EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_add);
148 148
149 /* destroy the keymap entries associated with specified master ct */ 149 /* destroy the keymap entries associated with specified master ct */
150 void nf_ct_gre_keymap_destroy(struct nf_conn *ct) 150 void nf_ct_gre_keymap_destroy(struct nf_conn *ct)
151 { 151 {
152 struct net *net = nf_ct_net(ct); 152 struct net *net = nf_ct_net(ct);
153 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id); 153 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
154 struct nf_conn_help *help = nfct_help(ct); 154 struct nf_conn_help *help = nfct_help(ct);
155 enum ip_conntrack_dir dir; 155 enum ip_conntrack_dir dir;
156 156
157 pr_debug("entering for ct %p\n", ct); 157 pr_debug("entering for ct %p\n", ct);
158 158
159 write_lock_bh(&net_gre->keymap_lock); 159 write_lock_bh(&net_gre->keymap_lock);
160 for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) { 160 for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) {
161 if (help->help.ct_pptp_info.keymap[dir]) { 161 if (help->help.ct_pptp_info.keymap[dir]) {
162 pr_debug("removing %p from list\n", 162 pr_debug("removing %p from list\n",
163 help->help.ct_pptp_info.keymap[dir]); 163 help->help.ct_pptp_info.keymap[dir]);
164 list_del(&help->help.ct_pptp_info.keymap[dir]->list); 164 list_del(&help->help.ct_pptp_info.keymap[dir]->list);
165 kfree(help->help.ct_pptp_info.keymap[dir]); 165 kfree(help->help.ct_pptp_info.keymap[dir]);
166 help->help.ct_pptp_info.keymap[dir] = NULL; 166 help->help.ct_pptp_info.keymap[dir] = NULL;
167 } 167 }
168 } 168 }
169 write_unlock_bh(&net_gre->keymap_lock); 169 write_unlock_bh(&net_gre->keymap_lock);
170 } 170 }
171 EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_destroy); 171 EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_destroy);
172 172
173 /* PUBLIC CONNTRACK PROTO HELPER FUNCTIONS */ 173 /* PUBLIC CONNTRACK PROTO HELPER FUNCTIONS */
174 174
175 /* invert gre part of tuple */ 175 /* invert gre part of tuple */
176 static bool gre_invert_tuple(struct nf_conntrack_tuple *tuple, 176 static bool gre_invert_tuple(struct nf_conntrack_tuple *tuple,
177 const struct nf_conntrack_tuple *orig) 177 const struct nf_conntrack_tuple *orig)
178 { 178 {
179 tuple->dst.u.gre.key = orig->src.u.gre.key; 179 tuple->dst.u.gre.key = orig->src.u.gre.key;
180 tuple->src.u.gre.key = orig->dst.u.gre.key; 180 tuple->src.u.gre.key = orig->dst.u.gre.key;
181 return true; 181 return true;
182 } 182 }
183 183
184 /* gre hdr info to tuple */ 184 /* gre hdr info to tuple */
185 static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, 185 static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
186 struct nf_conntrack_tuple *tuple) 186 struct nf_conntrack_tuple *tuple)
187 { 187 {
188 struct net *net = dev_net(skb->dev ? skb->dev : skb_dst(skb)->dev); 188 struct net *net = dev_net(skb->dev ? skb->dev : skb_dst(skb)->dev);
189 const struct gre_hdr_pptp *pgrehdr; 189 const struct gre_hdr_pptp *pgrehdr;
190 struct gre_hdr_pptp _pgrehdr; 190 struct gre_hdr_pptp _pgrehdr;
191 __be16 srckey; 191 __be16 srckey;
192 const struct gre_hdr *grehdr; 192 const struct gre_hdr *grehdr;
193 struct gre_hdr _grehdr; 193 struct gre_hdr _grehdr;
194 194
195 /* first only delinearize old RFC1701 GRE header */ 195 /* first only delinearize old RFC1701 GRE header */
196 grehdr = skb_header_pointer(skb, dataoff, sizeof(_grehdr), &_grehdr); 196 grehdr = skb_header_pointer(skb, dataoff, sizeof(_grehdr), &_grehdr);
197 if (!grehdr || grehdr->version != GRE_VERSION_PPTP) { 197 if (!grehdr || grehdr->version != GRE_VERSION_PPTP) {
198 /* try to behave like "nf_conntrack_proto_generic" */ 198 /* try to behave like "nf_conntrack_proto_generic" */
199 tuple->src.u.all = 0; 199 tuple->src.u.all = 0;
200 tuple->dst.u.all = 0; 200 tuple->dst.u.all = 0;
201 return true; 201 return true;
202 } 202 }
203 203
204 /* PPTP header is variable length, only need up to the call_id field */ 204 /* PPTP header is variable length, only need up to the call_id field */
205 pgrehdr = skb_header_pointer(skb, dataoff, 8, &_pgrehdr); 205 pgrehdr = skb_header_pointer(skb, dataoff, 8, &_pgrehdr);
206 if (!pgrehdr) 206 if (!pgrehdr)
207 return true; 207 return true;
208 208
209 if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) { 209 if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) {
210 pr_debug("GRE_VERSION_PPTP but unknown proto\n"); 210 pr_debug("GRE_VERSION_PPTP but unknown proto\n");
211 return false; 211 return false;
212 } 212 }
213 213
214 tuple->dst.u.gre.key = pgrehdr->call_id; 214 tuple->dst.u.gre.key = pgrehdr->call_id;
215 srckey = gre_keymap_lookup(net, tuple); 215 srckey = gre_keymap_lookup(net, tuple);
216 tuple->src.u.gre.key = srckey; 216 tuple->src.u.gre.key = srckey;
217 217
218 return true; 218 return true;
219 } 219 }
220 220
221 /* print gre part of tuple */ 221 /* print gre part of tuple */
222 static int gre_print_tuple(struct seq_file *s, 222 static int gre_print_tuple(struct seq_file *s,
223 const struct nf_conntrack_tuple *tuple) 223 const struct nf_conntrack_tuple *tuple)
224 { 224 {
225 return seq_printf(s, "srckey=0x%x dstkey=0x%x ", 225 return seq_printf(s, "srckey=0x%x dstkey=0x%x ",
226 ntohs(tuple->src.u.gre.key), 226 ntohs(tuple->src.u.gre.key),
227 ntohs(tuple->dst.u.gre.key)); 227 ntohs(tuple->dst.u.gre.key));
228 } 228 }
229 229
230 /* print private data for conntrack */ 230 /* print private data for conntrack */
231 static int gre_print_conntrack(struct seq_file *s, struct nf_conn *ct) 231 static int gre_print_conntrack(struct seq_file *s, struct nf_conn *ct)
232 { 232 {
233 return seq_printf(s, "timeout=%u, stream_timeout=%u ", 233 return seq_printf(s, "timeout=%u, stream_timeout=%u ",
234 (ct->proto.gre.timeout / HZ), 234 (ct->proto.gre.timeout / HZ),
235 (ct->proto.gre.stream_timeout / HZ)); 235 (ct->proto.gre.stream_timeout / HZ));
236 } 236 }
237 237
238 static unsigned int *gre_get_timeouts(struct net *net) 238 static unsigned int *gre_get_timeouts(struct net *net)
239 { 239 {
240 return gre_timeouts; 240 return gre_timeouts;
241 } 241 }
242 242
243 /* Returns verdict for packet, and may modify conntrack */ 243 /* Returns verdict for packet, and may modify conntrack */
244 static int gre_packet(struct nf_conn *ct, 244 static int gre_packet(struct nf_conn *ct,
245 const struct sk_buff *skb, 245 const struct sk_buff *skb,
246 unsigned int dataoff, 246 unsigned int dataoff,
247 enum ip_conntrack_info ctinfo, 247 enum ip_conntrack_info ctinfo,
248 u_int8_t pf, 248 u_int8_t pf,
249 unsigned int hooknum, 249 unsigned int hooknum,
250 unsigned int *timeouts) 250 unsigned int *timeouts)
251 { 251 {
252 /* If we've seen traffic both ways, this is a GRE connection. 252 /* If we've seen traffic both ways, this is a GRE connection.
253 * Extend timeout. */ 253 * Extend timeout. */
254 if (ct->status & IPS_SEEN_REPLY) { 254 if (ct->status & IPS_SEEN_REPLY) {
255 nf_ct_refresh_acct(ct, ctinfo, skb, 255 nf_ct_refresh_acct(ct, ctinfo, skb,
256 ct->proto.gre.stream_timeout); 256 ct->proto.gre.stream_timeout);
257 /* Also, more likely to be important, and not a probe. */ 257 /* Also, more likely to be important, and not a probe. */
258 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status)) 258 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
259 nf_conntrack_event_cache(IPCT_ASSURED, ct); 259 nf_conntrack_event_cache(IPCT_ASSURED, ct);
260 } else 260 } else
261 nf_ct_refresh_acct(ct, ctinfo, skb, 261 nf_ct_refresh_acct(ct, ctinfo, skb,
262 ct->proto.gre.timeout); 262 ct->proto.gre.timeout);
263 263
264 return NF_ACCEPT; 264 return NF_ACCEPT;
265 } 265 }
266 266
267 /* Called when a new connection for this protocol found. */ 267 /* Called when a new connection for this protocol found. */
268 static bool gre_new(struct nf_conn *ct, const struct sk_buff *skb, 268 static bool gre_new(struct nf_conn *ct, const struct sk_buff *skb,
269 unsigned int dataoff, unsigned int *timeouts) 269 unsigned int dataoff, unsigned int *timeouts)
270 { 270 {
271 pr_debug(": "); 271 pr_debug(": ");
272 nf_ct_dump_tuple(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); 272 nf_ct_dump_tuple(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
273 273
274 /* initialize to sane value. Ideally a conntrack helper 274 /* initialize to sane value. Ideally a conntrack helper
275 * (e.g. in case of pptp) is increasing them */ 275 * (e.g. in case of pptp) is increasing them */
276 ct->proto.gre.stream_timeout = timeouts[GRE_CT_REPLIED]; 276 ct->proto.gre.stream_timeout = timeouts[GRE_CT_REPLIED];
277 ct->proto.gre.timeout = timeouts[GRE_CT_UNREPLIED]; 277 ct->proto.gre.timeout = timeouts[GRE_CT_UNREPLIED];
278 278
279 return true; 279 return true;
280 } 280 }
281 281
282 /* Called when a conntrack entry has already been removed from the hashes 282 /* Called when a conntrack entry has already been removed from the hashes
283 * and is about to be deleted from memory */ 283 * and is about to be deleted from memory */
284 static void gre_destroy(struct nf_conn *ct) 284 static void gre_destroy(struct nf_conn *ct)
285 { 285 {
286 struct nf_conn *master = ct->master; 286 struct nf_conn *master = ct->master;
287 pr_debug(" entering\n"); 287 pr_debug(" entering\n");
288 288
289 if (!master) 289 if (!master)
290 pr_debug("no master !?!\n"); 290 pr_debug("no master !?!\n");
291 else 291 else
292 nf_ct_gre_keymap_destroy(master); 292 nf_ct_gre_keymap_destroy(master);
293 } 293 }
294 294
295 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 295 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
296 296
297 #include <linux/netfilter/nfnetlink.h> 297 #include <linux/netfilter/nfnetlink.h>
298 #include <linux/netfilter/nfnetlink_cttimeout.h> 298 #include <linux/netfilter/nfnetlink_cttimeout.h>
299 299
300 static int gre_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) 300 static int gre_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
301 { 301 {
302 unsigned int *timeouts = data; 302 unsigned int *timeouts = data;
303 303
304 /* set default timeouts for GRE. */ 304 /* set default timeouts for GRE. */
305 timeouts[GRE_CT_UNREPLIED] = gre_timeouts[GRE_CT_UNREPLIED]; 305 timeouts[GRE_CT_UNREPLIED] = gre_timeouts[GRE_CT_UNREPLIED];
306 timeouts[GRE_CT_REPLIED] = gre_timeouts[GRE_CT_REPLIED]; 306 timeouts[GRE_CT_REPLIED] = gre_timeouts[GRE_CT_REPLIED];
307 307
308 if (tb[CTA_TIMEOUT_GRE_UNREPLIED]) { 308 if (tb[CTA_TIMEOUT_GRE_UNREPLIED]) {
309 timeouts[GRE_CT_UNREPLIED] = 309 timeouts[GRE_CT_UNREPLIED] =
310 ntohl(nla_get_be32(tb[CTA_TIMEOUT_GRE_UNREPLIED])) * HZ; 310 ntohl(nla_get_be32(tb[CTA_TIMEOUT_GRE_UNREPLIED])) * HZ;
311 } 311 }
312 if (tb[CTA_TIMEOUT_GRE_REPLIED]) { 312 if (tb[CTA_TIMEOUT_GRE_REPLIED]) {
313 timeouts[GRE_CT_REPLIED] = 313 timeouts[GRE_CT_REPLIED] =
314 ntohl(nla_get_be32(tb[CTA_TIMEOUT_GRE_REPLIED])) * HZ; 314 ntohl(nla_get_be32(tb[CTA_TIMEOUT_GRE_REPLIED])) * HZ;
315 } 315 }
316 return 0; 316 return 0;
317 } 317 }
318 318
319 static int 319 static int
320 gre_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data) 320 gre_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
321 { 321 {
322 const unsigned int *timeouts = data; 322 const unsigned int *timeouts = data;
323 323
324 if (nla_put_be32(skb, CTA_TIMEOUT_GRE_UNREPLIED, 324 if (nla_put_be32(skb, CTA_TIMEOUT_GRE_UNREPLIED,
325 htonl(timeouts[GRE_CT_UNREPLIED] / HZ)) || 325 htonl(timeouts[GRE_CT_UNREPLIED] / HZ)) ||
326 nla_put_be32(skb, CTA_TIMEOUT_GRE_REPLIED, 326 nla_put_be32(skb, CTA_TIMEOUT_GRE_REPLIED,
327 htonl(timeouts[GRE_CT_REPLIED] / HZ))) 327 htonl(timeouts[GRE_CT_REPLIED] / HZ)))
328 goto nla_put_failure; 328 goto nla_put_failure;
329 return 0; 329 return 0;
330 330
331 nla_put_failure: 331 nla_put_failure:
332 return -ENOSPC; 332 return -ENOSPC;
333 } 333 }
334 334
335 static const struct nla_policy 335 static const struct nla_policy
336 gre_timeout_nla_policy[CTA_TIMEOUT_GRE_MAX+1] = { 336 gre_timeout_nla_policy[CTA_TIMEOUT_GRE_MAX+1] = {
337 [CTA_TIMEOUT_GRE_UNREPLIED] = { .type = NLA_U32 }, 337 [CTA_TIMEOUT_GRE_UNREPLIED] = { .type = NLA_U32 },
338 [CTA_TIMEOUT_GRE_REPLIED] = { .type = NLA_U32 }, 338 [CTA_TIMEOUT_GRE_REPLIED] = { .type = NLA_U32 },
339 }; 339 };
340 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 340 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
341 341
342 /* protocol helper struct */ 342 /* protocol helper struct */
343 static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = { 343 static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = {
344 .l3proto = AF_INET, 344 .l3proto = AF_INET,
345 .l4proto = IPPROTO_GRE, 345 .l4proto = IPPROTO_GRE,
346 .name = "gre", 346 .name = "gre",
347 .pkt_to_tuple = gre_pkt_to_tuple, 347 .pkt_to_tuple = gre_pkt_to_tuple,
348 .invert_tuple = gre_invert_tuple, 348 .invert_tuple = gre_invert_tuple,
349 .print_tuple = gre_print_tuple, 349 .print_tuple = gre_print_tuple,
350 .print_conntrack = gre_print_conntrack, 350 .print_conntrack = gre_print_conntrack,
351 .get_timeouts = gre_get_timeouts, 351 .get_timeouts = gre_get_timeouts,
352 .packet = gre_packet, 352 .packet = gre_packet,
353 .new = gre_new, 353 .new = gre_new,
354 .destroy = gre_destroy, 354 .destroy = gre_destroy,
355 .me = THIS_MODULE, 355 .me = THIS_MODULE,
356 #if IS_ENABLED(CONFIG_NF_CT_NETLINK) 356 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
357 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 357 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
358 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size, 358 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
359 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 359 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
360 .nla_policy = nf_ct_port_nla_policy, 360 .nla_policy = nf_ct_port_nla_policy,
361 #endif 361 #endif
362 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 362 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
363 .ctnl_timeout = { 363 .ctnl_timeout = {
364 .nlattr_to_obj = gre_timeout_nlattr_to_obj, 364 .nlattr_to_obj = gre_timeout_nlattr_to_obj,
365 .obj_to_nlattr = gre_timeout_obj_to_nlattr, 365 .obj_to_nlattr = gre_timeout_obj_to_nlattr,
366 .nlattr_max = CTA_TIMEOUT_GRE_MAX, 366 .nlattr_max = CTA_TIMEOUT_GRE_MAX,
367 .obj_size = sizeof(unsigned int) * GRE_CT_MAX, 367 .obj_size = sizeof(unsigned int) * GRE_CT_MAX,
368 .nla_policy = gre_timeout_nla_policy, 368 .nla_policy = gre_timeout_nla_policy,
369 }, 369 },
370 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 370 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
371 }; 371 };
372 372
373 static int proto_gre_net_init(struct net *net) 373 static int proto_gre_net_init(struct net *net)
374 { 374 {
375 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id); 375 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
376 376
377 rwlock_init(&net_gre->keymap_lock); 377 rwlock_init(&net_gre->keymap_lock);
378 INIT_LIST_HEAD(&net_gre->keymap_list); 378 INIT_LIST_HEAD(&net_gre->keymap_list);
379 379
380 return 0; 380 return 0;
381 } 381 }
382 382
383 static void proto_gre_net_exit(struct net *net) 383 static void proto_gre_net_exit(struct net *net)
384 { 384 {
385 nf_ct_gre_keymap_flush(net); 385 nf_ct_gre_keymap_flush(net);
386 } 386 }
387 387
388 static struct pernet_operations proto_gre_net_ops = { 388 static struct pernet_operations proto_gre_net_ops = {
389 .init = proto_gre_net_init, 389 .init = proto_gre_net_init,
390 .exit = proto_gre_net_exit, 390 .exit = proto_gre_net_exit,
391 .id = &proto_gre_net_id, 391 .id = &proto_gre_net_id,
392 .size = sizeof(struct netns_proto_gre), 392 .size = sizeof(struct netns_proto_gre),
393 }; 393 };
394 394
395 static int __init nf_ct_proto_gre_init(void) 395 static int __init nf_ct_proto_gre_init(void)
396 { 396 {
397 int rv; 397 int rv;
398 398
399 rv = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_gre4); 399 rv = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_gre4);
400 if (rv < 0) 400 if (rv < 0)
401 return rv; 401 return rv;
402 rv = register_pernet_subsys(&proto_gre_net_ops); 402 rv = register_pernet_subsys(&proto_gre_net_ops);
403 if (rv < 0) 403 if (rv < 0)
404 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4); 404 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_gre4);
405 return rv; 405 return rv;
406 } 406 }
407 407
408 static void __exit nf_ct_proto_gre_fini(void) 408 static void __exit nf_ct_proto_gre_fini(void)
409 { 409 {
410 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4); 410 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_gre4);
411 unregister_pernet_subsys(&proto_gre_net_ops); 411 unregister_pernet_subsys(&proto_gre_net_ops);
412 } 412 }
413 413
414 module_init(nf_ct_proto_gre_init); 414 module_init(nf_ct_proto_gre_init);
415 module_exit(nf_ct_proto_gre_fini); 415 module_exit(nf_ct_proto_gre_fini);
416 416
417 MODULE_LICENSE("GPL"); 417 MODULE_LICENSE("GPL");
418 418
net/netfilter/nf_conntrack_proto_sctp.c
1 /* 1 /*
2 * Connection tracking protocol helper module for SCTP. 2 * Connection tracking protocol helper module for SCTP.
3 * 3 *
4 * SCTP is defined in RFC 2960. References to various sections in this code 4 * SCTP is defined in RFC 2960. References to various sections in this code
5 * are to this RFC. 5 * are to this RFC.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12 #include <linux/types.h> 12 #include <linux/types.h>
13 #include <linux/timer.h> 13 #include <linux/timer.h>
14 #include <linux/netfilter.h> 14 #include <linux/netfilter.h>
15 #include <linux/module.h> 15 #include <linux/module.h>
16 #include <linux/in.h> 16 #include <linux/in.h>
17 #include <linux/ip.h> 17 #include <linux/ip.h>
18 #include <linux/sctp.h> 18 #include <linux/sctp.h>
19 #include <linux/string.h> 19 #include <linux/string.h>
20 #include <linux/seq_file.h> 20 #include <linux/seq_file.h>
21 #include <linux/spinlock.h> 21 #include <linux/spinlock.h>
22 #include <linux/interrupt.h> 22 #include <linux/interrupt.h>
23 23
24 #include <net/netfilter/nf_conntrack.h> 24 #include <net/netfilter/nf_conntrack.h>
25 #include <net/netfilter/nf_conntrack_l4proto.h> 25 #include <net/netfilter/nf_conntrack_l4proto.h>
26 #include <net/netfilter/nf_conntrack_ecache.h> 26 #include <net/netfilter/nf_conntrack_ecache.h>
27 27
28 /* FIXME: Examine ipfilter's timeouts and conntrack transitions more 28 /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
29 closely. They're more complex. --RR 29 closely. They're more complex. --RR
30 30
31 And so for me for SCTP :D -Kiran */ 31 And so for me for SCTP :D -Kiran */
32 32
33 static const char *const sctp_conntrack_names[] = { 33 static const char *const sctp_conntrack_names[] = {
34 "NONE", 34 "NONE",
35 "CLOSED", 35 "CLOSED",
36 "COOKIE_WAIT", 36 "COOKIE_WAIT",
37 "COOKIE_ECHOED", 37 "COOKIE_ECHOED",
38 "ESTABLISHED", 38 "ESTABLISHED",
39 "SHUTDOWN_SENT", 39 "SHUTDOWN_SENT",
40 "SHUTDOWN_RECD", 40 "SHUTDOWN_RECD",
41 "SHUTDOWN_ACK_SENT", 41 "SHUTDOWN_ACK_SENT",
42 }; 42 };
43 43
44 #define SECS * HZ 44 #define SECS * HZ
45 #define MINS * 60 SECS 45 #define MINS * 60 SECS
46 #define HOURS * 60 MINS 46 #define HOURS * 60 MINS
47 #define DAYS * 24 HOURS 47 #define DAYS * 24 HOURS
48 48
49 static unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] __read_mostly = { 49 static unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] __read_mostly = {
50 [SCTP_CONNTRACK_CLOSED] = 10 SECS, 50 [SCTP_CONNTRACK_CLOSED] = 10 SECS,
51 [SCTP_CONNTRACK_COOKIE_WAIT] = 3 SECS, 51 [SCTP_CONNTRACK_COOKIE_WAIT] = 3 SECS,
52 [SCTP_CONNTRACK_COOKIE_ECHOED] = 3 SECS, 52 [SCTP_CONNTRACK_COOKIE_ECHOED] = 3 SECS,
53 [SCTP_CONNTRACK_ESTABLISHED] = 5 DAYS, 53 [SCTP_CONNTRACK_ESTABLISHED] = 5 DAYS,
54 [SCTP_CONNTRACK_SHUTDOWN_SENT] = 300 SECS / 1000, 54 [SCTP_CONNTRACK_SHUTDOWN_SENT] = 300 SECS / 1000,
55 [SCTP_CONNTRACK_SHUTDOWN_RECD] = 300 SECS / 1000, 55 [SCTP_CONNTRACK_SHUTDOWN_RECD] = 300 SECS / 1000,
56 [SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = 3 SECS, 56 [SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = 3 SECS,
57 }; 57 };
58 58
59 #define sNO SCTP_CONNTRACK_NONE 59 #define sNO SCTP_CONNTRACK_NONE
60 #define sCL SCTP_CONNTRACK_CLOSED 60 #define sCL SCTP_CONNTRACK_CLOSED
61 #define sCW SCTP_CONNTRACK_COOKIE_WAIT 61 #define sCW SCTP_CONNTRACK_COOKIE_WAIT
62 #define sCE SCTP_CONNTRACK_COOKIE_ECHOED 62 #define sCE SCTP_CONNTRACK_COOKIE_ECHOED
63 #define sES SCTP_CONNTRACK_ESTABLISHED 63 #define sES SCTP_CONNTRACK_ESTABLISHED
64 #define sSS SCTP_CONNTRACK_SHUTDOWN_SENT 64 #define sSS SCTP_CONNTRACK_SHUTDOWN_SENT
65 #define sSR SCTP_CONNTRACK_SHUTDOWN_RECD 65 #define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
66 #define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT 66 #define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
67 #define sIV SCTP_CONNTRACK_MAX 67 #define sIV SCTP_CONNTRACK_MAX
68 68
69 /* 69 /*
70 These are the descriptions of the states: 70 These are the descriptions of the states:
71 71
72 NOTE: These state names are tantalizingly similar to the states of an 72 NOTE: These state names are tantalizingly similar to the states of an
73 SCTP endpoint. But the interpretation of the states is a little different, 73 SCTP endpoint. But the interpretation of the states is a little different,
74 considering that these are the states of the connection and not of an end 74 considering that these are the states of the connection and not of an end
75 point. Please note the subtleties. -Kiran 75 point. Please note the subtleties. -Kiran
76 76
77 NONE - Nothing so far. 77 NONE - Nothing so far.
78 COOKIE WAIT - We have seen an INIT chunk in the original direction, or also 78 COOKIE WAIT - We have seen an INIT chunk in the original direction, or also
79 an INIT_ACK chunk in the reply direction. 79 an INIT_ACK chunk in the reply direction.
80 COOKIE ECHOED - We have seen a COOKIE_ECHO chunk in the original direction. 80 COOKIE ECHOED - We have seen a COOKIE_ECHO chunk in the original direction.
81 ESTABLISHED - We have seen a COOKIE_ACK in the reply direction. 81 ESTABLISHED - We have seen a COOKIE_ACK in the reply direction.
82 SHUTDOWN_SENT - We have seen a SHUTDOWN chunk in the original direction. 82 SHUTDOWN_SENT - We have seen a SHUTDOWN chunk in the original direction.
83 SHUTDOWN_RECD - We have seen a SHUTDOWN chunk in the reply directoin. 83 SHUTDOWN_RECD - We have seen a SHUTDOWN chunk in the reply directoin.
84 SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opposite 84 SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opposite
85 to that of the SHUTDOWN chunk. 85 to that of the SHUTDOWN chunk.
86 CLOSED - We have seen a SHUTDOWN_COMPLETE chunk in the direction of 86 CLOSED - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
87 the SHUTDOWN chunk. Connection is closed. 87 the SHUTDOWN chunk. Connection is closed.
88 */ 88 */
89 89
90 /* TODO 90 /* TODO
91 - I have assumed that the first INIT is in the original direction. 91 - I have assumed that the first INIT is in the original direction.
92 This messes things when an INIT comes in the reply direction in CLOSED 92 This messes things when an INIT comes in the reply direction in CLOSED
93 state. 93 state.
94 - Check the error type in the reply dir before transitioning from 94 - Check the error type in the reply dir before transitioning from
95 cookie echoed to closed. 95 cookie echoed to closed.
96 - Sec 5.2.4 of RFC 2960 96 - Sec 5.2.4 of RFC 2960
97 - Multi Homing support. 97 - Multi Homing support.
98 */ 98 */
99 99
100 /* SCTP conntrack state transitions */ 100 /* SCTP conntrack state transitions */
101 static const u8 sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = { 101 static const u8 sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
102 { 102 {
103 /* ORIGINAL */ 103 /* ORIGINAL */
104 /* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */ 104 /* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
105 /* init */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA}, 105 /* init */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA},
106 /* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA}, 106 /* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
107 /* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL}, 107 /* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
108 /* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA}, 108 /* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA},
109 /* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA}, 109 /* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA},
110 /* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't have Stale cookie*/ 110 /* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't have Stale cookie*/
111 /* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},/* 5.2.4 - Big TODO */ 111 /* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},/* 5.2.4 - Big TODO */
112 /* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't come in orig dir */ 112 /* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't come in orig dir */
113 /* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL} 113 /* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL}
114 }, 114 },
115 { 115 {
116 /* REPLY */ 116 /* REPLY */
117 /* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */ 117 /* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
118 /* init */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* INIT in sCL Big TODO */ 118 /* init */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* INIT in sCL Big TODO */
119 /* init_ack */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA}, 119 /* init_ack */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
120 /* abort */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL}, 120 /* abort */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
121 /* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA}, 121 /* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA},
122 /* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA}, 122 /* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA},
123 /* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA}, 123 /* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA},
124 /* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't come in reply dir */ 124 /* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't come in reply dir */
125 /* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA}, 125 /* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA},
126 /* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL} 126 /* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL}
127 } 127 }
128 }; 128 };
129 129
130 static bool sctp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, 130 static bool sctp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
131 struct nf_conntrack_tuple *tuple) 131 struct nf_conntrack_tuple *tuple)
132 { 132 {
133 const struct sctphdr *hp; 133 const struct sctphdr *hp;
134 struct sctphdr _hdr; 134 struct sctphdr _hdr;
135 135
136 /* Actually only need first 8 bytes. */ 136 /* Actually only need first 8 bytes. */
137 hp = skb_header_pointer(skb, dataoff, 8, &_hdr); 137 hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
138 if (hp == NULL) 138 if (hp == NULL)
139 return false; 139 return false;
140 140
141 tuple->src.u.sctp.port = hp->source; 141 tuple->src.u.sctp.port = hp->source;
142 tuple->dst.u.sctp.port = hp->dest; 142 tuple->dst.u.sctp.port = hp->dest;
143 return true; 143 return true;
144 } 144 }
145 145
146 static bool sctp_invert_tuple(struct nf_conntrack_tuple *tuple, 146 static bool sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
147 const struct nf_conntrack_tuple *orig) 147 const struct nf_conntrack_tuple *orig)
148 { 148 {
149 tuple->src.u.sctp.port = orig->dst.u.sctp.port; 149 tuple->src.u.sctp.port = orig->dst.u.sctp.port;
150 tuple->dst.u.sctp.port = orig->src.u.sctp.port; 150 tuple->dst.u.sctp.port = orig->src.u.sctp.port;
151 return true; 151 return true;
152 } 152 }
153 153
154 /* Print out the per-protocol part of the tuple. */ 154 /* Print out the per-protocol part of the tuple. */
155 static int sctp_print_tuple(struct seq_file *s, 155 static int sctp_print_tuple(struct seq_file *s,
156 const struct nf_conntrack_tuple *tuple) 156 const struct nf_conntrack_tuple *tuple)
157 { 157 {
158 return seq_printf(s, "sport=%hu dport=%hu ", 158 return seq_printf(s, "sport=%hu dport=%hu ",
159 ntohs(tuple->src.u.sctp.port), 159 ntohs(tuple->src.u.sctp.port),
160 ntohs(tuple->dst.u.sctp.port)); 160 ntohs(tuple->dst.u.sctp.port));
161 } 161 }
162 162
163 /* Print out the private part of the conntrack. */ 163 /* Print out the private part of the conntrack. */
164 static int sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct) 164 static int sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
165 { 165 {
166 enum sctp_conntrack state; 166 enum sctp_conntrack state;
167 167
168 spin_lock_bh(&ct->lock); 168 spin_lock_bh(&ct->lock);
169 state = ct->proto.sctp.state; 169 state = ct->proto.sctp.state;
170 spin_unlock_bh(&ct->lock); 170 spin_unlock_bh(&ct->lock);
171 171
172 return seq_printf(s, "%s ", sctp_conntrack_names[state]); 172 return seq_printf(s, "%s ", sctp_conntrack_names[state]);
173 } 173 }
174 174
175 #define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \ 175 #define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \
176 for ((offset) = (dataoff) + sizeof(sctp_sctphdr_t), (count) = 0; \ 176 for ((offset) = (dataoff) + sizeof(sctp_sctphdr_t), (count) = 0; \
177 (offset) < (skb)->len && \ 177 (offset) < (skb)->len && \
178 ((sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch))); \ 178 ((sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch))); \
179 (offset) += (ntohs((sch)->length) + 3) & ~3, (count)++) 179 (offset) += (ntohs((sch)->length) + 3) & ~3, (count)++)
180 180
181 /* Some validity checks to make sure the chunks are fine */ 181 /* Some validity checks to make sure the chunks are fine */
182 static int do_basic_checks(struct nf_conn *ct, 182 static int do_basic_checks(struct nf_conn *ct,
183 const struct sk_buff *skb, 183 const struct sk_buff *skb,
184 unsigned int dataoff, 184 unsigned int dataoff,
185 unsigned long *map) 185 unsigned long *map)
186 { 186 {
187 u_int32_t offset, count; 187 u_int32_t offset, count;
188 sctp_chunkhdr_t _sch, *sch; 188 sctp_chunkhdr_t _sch, *sch;
189 int flag; 189 int flag;
190 190
191 flag = 0; 191 flag = 0;
192 192
193 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) { 193 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
194 pr_debug("Chunk Num: %d Type: %d\n", count, sch->type); 194 pr_debug("Chunk Num: %d Type: %d\n", count, sch->type);
195 195
196 if (sch->type == SCTP_CID_INIT || 196 if (sch->type == SCTP_CID_INIT ||
197 sch->type == SCTP_CID_INIT_ACK || 197 sch->type == SCTP_CID_INIT_ACK ||
198 sch->type == SCTP_CID_SHUTDOWN_COMPLETE) 198 sch->type == SCTP_CID_SHUTDOWN_COMPLETE)
199 flag = 1; 199 flag = 1;
200 200
201 /* 201 /*
202 * Cookie Ack/Echo chunks not the first OR 202 * Cookie Ack/Echo chunks not the first OR
203 * Init / Init Ack / Shutdown compl chunks not the only chunks 203 * Init / Init Ack / Shutdown compl chunks not the only chunks
204 * OR zero-length. 204 * OR zero-length.
205 */ 205 */
206 if (((sch->type == SCTP_CID_COOKIE_ACK || 206 if (((sch->type == SCTP_CID_COOKIE_ACK ||
207 sch->type == SCTP_CID_COOKIE_ECHO || 207 sch->type == SCTP_CID_COOKIE_ECHO ||
208 flag) && 208 flag) &&
209 count != 0) || !sch->length) { 209 count != 0) || !sch->length) {
210 pr_debug("Basic checks failed\n"); 210 pr_debug("Basic checks failed\n");
211 return 1; 211 return 1;
212 } 212 }
213 213
214 if (map) 214 if (map)
215 set_bit(sch->type, map); 215 set_bit(sch->type, map);
216 } 216 }
217 217
218 pr_debug("Basic checks passed\n"); 218 pr_debug("Basic checks passed\n");
219 return count == 0; 219 return count == 0;
220 } 220 }
221 221
222 static int sctp_new_state(enum ip_conntrack_dir dir, 222 static int sctp_new_state(enum ip_conntrack_dir dir,
223 enum sctp_conntrack cur_state, 223 enum sctp_conntrack cur_state,
224 int chunk_type) 224 int chunk_type)
225 { 225 {
226 int i; 226 int i;
227 227
228 pr_debug("Chunk type: %d\n", chunk_type); 228 pr_debug("Chunk type: %d\n", chunk_type);
229 229
230 switch (chunk_type) { 230 switch (chunk_type) {
231 case SCTP_CID_INIT: 231 case SCTP_CID_INIT:
232 pr_debug("SCTP_CID_INIT\n"); 232 pr_debug("SCTP_CID_INIT\n");
233 i = 0; 233 i = 0;
234 break; 234 break;
235 case SCTP_CID_INIT_ACK: 235 case SCTP_CID_INIT_ACK:
236 pr_debug("SCTP_CID_INIT_ACK\n"); 236 pr_debug("SCTP_CID_INIT_ACK\n");
237 i = 1; 237 i = 1;
238 break; 238 break;
239 case SCTP_CID_ABORT: 239 case SCTP_CID_ABORT:
240 pr_debug("SCTP_CID_ABORT\n"); 240 pr_debug("SCTP_CID_ABORT\n");
241 i = 2; 241 i = 2;
242 break; 242 break;
243 case SCTP_CID_SHUTDOWN: 243 case SCTP_CID_SHUTDOWN:
244 pr_debug("SCTP_CID_SHUTDOWN\n"); 244 pr_debug("SCTP_CID_SHUTDOWN\n");
245 i = 3; 245 i = 3;
246 break; 246 break;
247 case SCTP_CID_SHUTDOWN_ACK: 247 case SCTP_CID_SHUTDOWN_ACK:
248 pr_debug("SCTP_CID_SHUTDOWN_ACK\n"); 248 pr_debug("SCTP_CID_SHUTDOWN_ACK\n");
249 i = 4; 249 i = 4;
250 break; 250 break;
251 case SCTP_CID_ERROR: 251 case SCTP_CID_ERROR:
252 pr_debug("SCTP_CID_ERROR\n"); 252 pr_debug("SCTP_CID_ERROR\n");
253 i = 5; 253 i = 5;
254 break; 254 break;
255 case SCTP_CID_COOKIE_ECHO: 255 case SCTP_CID_COOKIE_ECHO:
256 pr_debug("SCTP_CID_COOKIE_ECHO\n"); 256 pr_debug("SCTP_CID_COOKIE_ECHO\n");
257 i = 6; 257 i = 6;
258 break; 258 break;
259 case SCTP_CID_COOKIE_ACK: 259 case SCTP_CID_COOKIE_ACK:
260 pr_debug("SCTP_CID_COOKIE_ACK\n"); 260 pr_debug("SCTP_CID_COOKIE_ACK\n");
261 i = 7; 261 i = 7;
262 break; 262 break;
263 case SCTP_CID_SHUTDOWN_COMPLETE: 263 case SCTP_CID_SHUTDOWN_COMPLETE:
264 pr_debug("SCTP_CID_SHUTDOWN_COMPLETE\n"); 264 pr_debug("SCTP_CID_SHUTDOWN_COMPLETE\n");
265 i = 8; 265 i = 8;
266 break; 266 break;
267 default: 267 default:
268 /* Other chunks like DATA, SACK, HEARTBEAT and 268 /* Other chunks like DATA, SACK, HEARTBEAT and
269 its ACK do not cause a change in state */ 269 its ACK do not cause a change in state */
270 pr_debug("Unknown chunk type, Will stay in %s\n", 270 pr_debug("Unknown chunk type, Will stay in %s\n",
271 sctp_conntrack_names[cur_state]); 271 sctp_conntrack_names[cur_state]);
272 return cur_state; 272 return cur_state;
273 } 273 }
274 274
275 pr_debug("dir: %d cur_state: %s chunk_type: %d new_state: %s\n", 275 pr_debug("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",
276 dir, sctp_conntrack_names[cur_state], chunk_type, 276 dir, sctp_conntrack_names[cur_state], chunk_type,
277 sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]); 277 sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
278 278
279 return sctp_conntracks[dir][i][cur_state]; 279 return sctp_conntracks[dir][i][cur_state];
280 } 280 }
281 281
282 static unsigned int *sctp_get_timeouts(struct net *net) 282 static unsigned int *sctp_get_timeouts(struct net *net)
283 { 283 {
284 return sctp_timeouts; 284 return sctp_timeouts;
285 } 285 }
286 286
287 /* Returns verdict for packet, or -NF_ACCEPT for invalid. */ 287 /* Returns verdict for packet, or -NF_ACCEPT for invalid. */
288 static int sctp_packet(struct nf_conn *ct, 288 static int sctp_packet(struct nf_conn *ct,
289 const struct sk_buff *skb, 289 const struct sk_buff *skb,
290 unsigned int dataoff, 290 unsigned int dataoff,
291 enum ip_conntrack_info ctinfo, 291 enum ip_conntrack_info ctinfo,
292 u_int8_t pf, 292 u_int8_t pf,
293 unsigned int hooknum, 293 unsigned int hooknum,
294 unsigned int *timeouts) 294 unsigned int *timeouts)
295 { 295 {
296 enum sctp_conntrack new_state, old_state; 296 enum sctp_conntrack new_state, old_state;
297 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 297 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
298 const struct sctphdr *sh; 298 const struct sctphdr *sh;
299 struct sctphdr _sctph; 299 struct sctphdr _sctph;
300 const struct sctp_chunkhdr *sch; 300 const struct sctp_chunkhdr *sch;
301 struct sctp_chunkhdr _sch; 301 struct sctp_chunkhdr _sch;
302 u_int32_t offset, count; 302 u_int32_t offset, count;
303 unsigned long map[256 / sizeof(unsigned long)] = { 0 }; 303 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
304 304
305 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph); 305 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
306 if (sh == NULL) 306 if (sh == NULL)
307 goto out; 307 goto out;
308 308
309 if (do_basic_checks(ct, skb, dataoff, map) != 0) 309 if (do_basic_checks(ct, skb, dataoff, map) != 0)
310 goto out; 310 goto out;
311 311
312 /* Check the verification tag (Sec 8.5) */ 312 /* Check the verification tag (Sec 8.5) */
313 if (!test_bit(SCTP_CID_INIT, map) && 313 if (!test_bit(SCTP_CID_INIT, map) &&
314 !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) && 314 !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) &&
315 !test_bit(SCTP_CID_COOKIE_ECHO, map) && 315 !test_bit(SCTP_CID_COOKIE_ECHO, map) &&
316 !test_bit(SCTP_CID_ABORT, map) && 316 !test_bit(SCTP_CID_ABORT, map) &&
317 !test_bit(SCTP_CID_SHUTDOWN_ACK, map) && 317 !test_bit(SCTP_CID_SHUTDOWN_ACK, map) &&
318 sh->vtag != ct->proto.sctp.vtag[dir]) { 318 sh->vtag != ct->proto.sctp.vtag[dir]) {
319 pr_debug("Verification tag check failed\n"); 319 pr_debug("Verification tag check failed\n");
320 goto out; 320 goto out;
321 } 321 }
322 322
323 old_state = new_state = SCTP_CONNTRACK_NONE; 323 old_state = new_state = SCTP_CONNTRACK_NONE;
324 spin_lock_bh(&ct->lock); 324 spin_lock_bh(&ct->lock);
325 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) { 325 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
326 /* Special cases of Verification tag check (Sec 8.5.1) */ 326 /* Special cases of Verification tag check (Sec 8.5.1) */
327 if (sch->type == SCTP_CID_INIT) { 327 if (sch->type == SCTP_CID_INIT) {
328 /* Sec 8.5.1 (A) */ 328 /* Sec 8.5.1 (A) */
329 if (sh->vtag != 0) 329 if (sh->vtag != 0)
330 goto out_unlock; 330 goto out_unlock;
331 } else if (sch->type == SCTP_CID_ABORT) { 331 } else if (sch->type == SCTP_CID_ABORT) {
332 /* Sec 8.5.1 (B) */ 332 /* Sec 8.5.1 (B) */
333 if (sh->vtag != ct->proto.sctp.vtag[dir] && 333 if (sh->vtag != ct->proto.sctp.vtag[dir] &&
334 sh->vtag != ct->proto.sctp.vtag[!dir]) 334 sh->vtag != ct->proto.sctp.vtag[!dir])
335 goto out_unlock; 335 goto out_unlock;
336 } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) { 336 } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
337 /* Sec 8.5.1 (C) */ 337 /* Sec 8.5.1 (C) */
338 if (sh->vtag != ct->proto.sctp.vtag[dir] && 338 if (sh->vtag != ct->proto.sctp.vtag[dir] &&
339 sh->vtag != ct->proto.sctp.vtag[!dir] && 339 sh->vtag != ct->proto.sctp.vtag[!dir] &&
340 sch->flags & SCTP_CHUNK_FLAG_T) 340 sch->flags & SCTP_CHUNK_FLAG_T)
341 goto out_unlock; 341 goto out_unlock;
342 } else if (sch->type == SCTP_CID_COOKIE_ECHO) { 342 } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
343 /* Sec 8.5.1 (D) */ 343 /* Sec 8.5.1 (D) */
344 if (sh->vtag != ct->proto.sctp.vtag[dir]) 344 if (sh->vtag != ct->proto.sctp.vtag[dir])
345 goto out_unlock; 345 goto out_unlock;
346 } 346 }
347 347
348 old_state = ct->proto.sctp.state; 348 old_state = ct->proto.sctp.state;
349 new_state = sctp_new_state(dir, old_state, sch->type); 349 new_state = sctp_new_state(dir, old_state, sch->type);
350 350
351 /* Invalid */ 351 /* Invalid */
352 if (new_state == SCTP_CONNTRACK_MAX) { 352 if (new_state == SCTP_CONNTRACK_MAX) {
353 pr_debug("nf_conntrack_sctp: Invalid dir=%i ctype=%u " 353 pr_debug("nf_conntrack_sctp: Invalid dir=%i ctype=%u "
354 "conntrack=%u\n", 354 "conntrack=%u\n",
355 dir, sch->type, old_state); 355 dir, sch->type, old_state);
356 goto out_unlock; 356 goto out_unlock;
357 } 357 }
358 358
359 /* If it is an INIT or an INIT ACK note down the vtag */ 359 /* If it is an INIT or an INIT ACK note down the vtag */
360 if (sch->type == SCTP_CID_INIT || 360 if (sch->type == SCTP_CID_INIT ||
361 sch->type == SCTP_CID_INIT_ACK) { 361 sch->type == SCTP_CID_INIT_ACK) {
362 sctp_inithdr_t _inithdr, *ih; 362 sctp_inithdr_t _inithdr, *ih;
363 363
364 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t), 364 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
365 sizeof(_inithdr), &_inithdr); 365 sizeof(_inithdr), &_inithdr);
366 if (ih == NULL) 366 if (ih == NULL)
367 goto out_unlock; 367 goto out_unlock;
368 pr_debug("Setting vtag %x for dir %d\n", 368 pr_debug("Setting vtag %x for dir %d\n",
369 ih->init_tag, !dir); 369 ih->init_tag, !dir);
370 ct->proto.sctp.vtag[!dir] = ih->init_tag; 370 ct->proto.sctp.vtag[!dir] = ih->init_tag;
371 } 371 }
372 372
373 ct->proto.sctp.state = new_state; 373 ct->proto.sctp.state = new_state;
374 if (old_state != new_state) 374 if (old_state != new_state)
375 nf_conntrack_event_cache(IPCT_PROTOINFO, ct); 375 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
376 } 376 }
377 spin_unlock_bh(&ct->lock); 377 spin_unlock_bh(&ct->lock);
378 378
379 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]); 379 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
380 380
381 if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED && 381 if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
382 dir == IP_CT_DIR_REPLY && 382 dir == IP_CT_DIR_REPLY &&
383 new_state == SCTP_CONNTRACK_ESTABLISHED) { 383 new_state == SCTP_CONNTRACK_ESTABLISHED) {
384 pr_debug("Setting assured bit\n"); 384 pr_debug("Setting assured bit\n");
385 set_bit(IPS_ASSURED_BIT, &ct->status); 385 set_bit(IPS_ASSURED_BIT, &ct->status);
386 nf_conntrack_event_cache(IPCT_ASSURED, ct); 386 nf_conntrack_event_cache(IPCT_ASSURED, ct);
387 } 387 }
388 388
389 return NF_ACCEPT; 389 return NF_ACCEPT;
390 390
391 out_unlock: 391 out_unlock:
392 spin_unlock_bh(&ct->lock); 392 spin_unlock_bh(&ct->lock);
393 out: 393 out:
394 return -NF_ACCEPT; 394 return -NF_ACCEPT;
395 } 395 }
396 396
397 /* Called when a new connection for this protocol found. */ 397 /* Called when a new connection for this protocol found. */
398 static bool sctp_new(struct nf_conn *ct, const struct sk_buff *skb, 398 static bool sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
399 unsigned int dataoff, unsigned int *timeouts) 399 unsigned int dataoff, unsigned int *timeouts)
400 { 400 {
401 enum sctp_conntrack new_state; 401 enum sctp_conntrack new_state;
402 const struct sctphdr *sh; 402 const struct sctphdr *sh;
403 struct sctphdr _sctph; 403 struct sctphdr _sctph;
404 const struct sctp_chunkhdr *sch; 404 const struct sctp_chunkhdr *sch;
405 struct sctp_chunkhdr _sch; 405 struct sctp_chunkhdr _sch;
406 u_int32_t offset, count; 406 u_int32_t offset, count;
407 unsigned long map[256 / sizeof(unsigned long)] = { 0 }; 407 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
408 408
409 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph); 409 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
410 if (sh == NULL) 410 if (sh == NULL)
411 return false; 411 return false;
412 412
413 if (do_basic_checks(ct, skb, dataoff, map) != 0) 413 if (do_basic_checks(ct, skb, dataoff, map) != 0)
414 return false; 414 return false;
415 415
416 /* If an OOTB packet has any of these chunks discard (Sec 8.4) */ 416 /* If an OOTB packet has any of these chunks discard (Sec 8.4) */
417 if (test_bit(SCTP_CID_ABORT, map) || 417 if (test_bit(SCTP_CID_ABORT, map) ||
418 test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) || 418 test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) ||
419 test_bit(SCTP_CID_COOKIE_ACK, map)) 419 test_bit(SCTP_CID_COOKIE_ACK, map))
420 return false; 420 return false;
421 421
422 memset(&ct->proto.sctp, 0, sizeof(ct->proto.sctp)); 422 memset(&ct->proto.sctp, 0, sizeof(ct->proto.sctp));
423 new_state = SCTP_CONNTRACK_MAX; 423 new_state = SCTP_CONNTRACK_MAX;
424 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) { 424 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
425 /* Don't need lock here: this conntrack not in circulation yet */ 425 /* Don't need lock here: this conntrack not in circulation yet */
426 new_state = sctp_new_state(IP_CT_DIR_ORIGINAL, 426 new_state = sctp_new_state(IP_CT_DIR_ORIGINAL,
427 SCTP_CONNTRACK_NONE, sch->type); 427 SCTP_CONNTRACK_NONE, sch->type);
428 428
429 /* Invalid: delete conntrack */ 429 /* Invalid: delete conntrack */
430 if (new_state == SCTP_CONNTRACK_NONE || 430 if (new_state == SCTP_CONNTRACK_NONE ||
431 new_state == SCTP_CONNTRACK_MAX) { 431 new_state == SCTP_CONNTRACK_MAX) {
432 pr_debug("nf_conntrack_sctp: invalid new deleting.\n"); 432 pr_debug("nf_conntrack_sctp: invalid new deleting.\n");
433 return false; 433 return false;
434 } 434 }
435 435
436 /* Copy the vtag into the state info */ 436 /* Copy the vtag into the state info */
437 if (sch->type == SCTP_CID_INIT) { 437 if (sch->type == SCTP_CID_INIT) {
438 if (sh->vtag == 0) { 438 if (sh->vtag == 0) {
439 sctp_inithdr_t _inithdr, *ih; 439 sctp_inithdr_t _inithdr, *ih;
440 440
441 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t), 441 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
442 sizeof(_inithdr), &_inithdr); 442 sizeof(_inithdr), &_inithdr);
443 if (ih == NULL) 443 if (ih == NULL)
444 return false; 444 return false;
445 445
446 pr_debug("Setting vtag %x for new conn\n", 446 pr_debug("Setting vtag %x for new conn\n",
447 ih->init_tag); 447 ih->init_tag);
448 448
449 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = 449 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
450 ih->init_tag; 450 ih->init_tag;
451 } else { 451 } else {
452 /* Sec 8.5.1 (A) */ 452 /* Sec 8.5.1 (A) */
453 return false; 453 return false;
454 } 454 }
455 } 455 }
456 /* If it is a shutdown ack OOTB packet, we expect a return 456 /* If it is a shutdown ack OOTB packet, we expect a return
457 shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */ 457 shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
458 else { 458 else {
459 pr_debug("Setting vtag %x for new conn OOTB\n", 459 pr_debug("Setting vtag %x for new conn OOTB\n",
460 sh->vtag); 460 sh->vtag);
461 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag; 461 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
462 } 462 }
463 463
464 ct->proto.sctp.state = new_state; 464 ct->proto.sctp.state = new_state;
465 } 465 }
466 466
467 return true; 467 return true;
468 } 468 }
469 469
470 #if IS_ENABLED(CONFIG_NF_CT_NETLINK) 470 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
471 471
472 #include <linux/netfilter/nfnetlink.h> 472 #include <linux/netfilter/nfnetlink.h>
473 #include <linux/netfilter/nfnetlink_conntrack.h> 473 #include <linux/netfilter/nfnetlink_conntrack.h>
474 474
475 static int sctp_to_nlattr(struct sk_buff *skb, struct nlattr *nla, 475 static int sctp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
476 struct nf_conn *ct) 476 struct nf_conn *ct)
477 { 477 {
478 struct nlattr *nest_parms; 478 struct nlattr *nest_parms;
479 479
480 spin_lock_bh(&ct->lock); 480 spin_lock_bh(&ct->lock);
481 nest_parms = nla_nest_start(skb, CTA_PROTOINFO_SCTP | NLA_F_NESTED); 481 nest_parms = nla_nest_start(skb, CTA_PROTOINFO_SCTP | NLA_F_NESTED);
482 if (!nest_parms) 482 if (!nest_parms)
483 goto nla_put_failure; 483 goto nla_put_failure;
484 484
485 if (nla_put_u8(skb, CTA_PROTOINFO_SCTP_STATE, ct->proto.sctp.state) || 485 if (nla_put_u8(skb, CTA_PROTOINFO_SCTP_STATE, ct->proto.sctp.state) ||
486 nla_put_be32(skb, CTA_PROTOINFO_SCTP_VTAG_ORIGINAL, 486 nla_put_be32(skb, CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
487 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]) || 487 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]) ||
488 nla_put_be32(skb, CTA_PROTOINFO_SCTP_VTAG_REPLY, 488 nla_put_be32(skb, CTA_PROTOINFO_SCTP_VTAG_REPLY,
489 ct->proto.sctp.vtag[IP_CT_DIR_REPLY])) 489 ct->proto.sctp.vtag[IP_CT_DIR_REPLY]))
490 goto nla_put_failure; 490 goto nla_put_failure;
491 491
492 spin_unlock_bh(&ct->lock); 492 spin_unlock_bh(&ct->lock);
493 493
494 nla_nest_end(skb, nest_parms); 494 nla_nest_end(skb, nest_parms);
495 495
496 return 0; 496 return 0;
497 497
498 nla_put_failure: 498 nla_put_failure:
499 spin_unlock_bh(&ct->lock); 499 spin_unlock_bh(&ct->lock);
500 return -1; 500 return -1;
501 } 501 }
502 502
503 static const struct nla_policy sctp_nla_policy[CTA_PROTOINFO_SCTP_MAX+1] = { 503 static const struct nla_policy sctp_nla_policy[CTA_PROTOINFO_SCTP_MAX+1] = {
504 [CTA_PROTOINFO_SCTP_STATE] = { .type = NLA_U8 }, 504 [CTA_PROTOINFO_SCTP_STATE] = { .type = NLA_U8 },
505 [CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] = { .type = NLA_U32 }, 505 [CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] = { .type = NLA_U32 },
506 [CTA_PROTOINFO_SCTP_VTAG_REPLY] = { .type = NLA_U32 }, 506 [CTA_PROTOINFO_SCTP_VTAG_REPLY] = { .type = NLA_U32 },
507 }; 507 };
508 508
509 static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct) 509 static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct)
510 { 510 {
511 struct nlattr *attr = cda[CTA_PROTOINFO_SCTP]; 511 struct nlattr *attr = cda[CTA_PROTOINFO_SCTP];
512 struct nlattr *tb[CTA_PROTOINFO_SCTP_MAX+1]; 512 struct nlattr *tb[CTA_PROTOINFO_SCTP_MAX+1];
513 int err; 513 int err;
514 514
515 /* updates may not contain the internal protocol info, skip parsing */ 515 /* updates may not contain the internal protocol info, skip parsing */
516 if (!attr) 516 if (!attr)
517 return 0; 517 return 0;
518 518
519 err = nla_parse_nested(tb, 519 err = nla_parse_nested(tb,
520 CTA_PROTOINFO_SCTP_MAX, 520 CTA_PROTOINFO_SCTP_MAX,
521 attr, 521 attr,
522 sctp_nla_policy); 522 sctp_nla_policy);
523 if (err < 0) 523 if (err < 0)
524 return err; 524 return err;
525 525
526 if (!tb[CTA_PROTOINFO_SCTP_STATE] || 526 if (!tb[CTA_PROTOINFO_SCTP_STATE] ||
527 !tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] || 527 !tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] ||
528 !tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]) 528 !tb[CTA_PROTOINFO_SCTP_VTAG_REPLY])
529 return -EINVAL; 529 return -EINVAL;
530 530
531 spin_lock_bh(&ct->lock); 531 spin_lock_bh(&ct->lock);
532 ct->proto.sctp.state = nla_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]); 532 ct->proto.sctp.state = nla_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]);
533 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] = 533 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] =
534 nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]); 534 nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]);
535 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = 535 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
536 nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]); 536 nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]);
537 spin_unlock_bh(&ct->lock); 537 spin_unlock_bh(&ct->lock);
538 538
539 return 0; 539 return 0;
540 } 540 }
541 541
542 static int sctp_nlattr_size(void) 542 static int sctp_nlattr_size(void)
543 { 543 {
544 return nla_total_size(0) /* CTA_PROTOINFO_SCTP */ 544 return nla_total_size(0) /* CTA_PROTOINFO_SCTP */
545 + nla_policy_len(sctp_nla_policy, CTA_PROTOINFO_SCTP_MAX + 1); 545 + nla_policy_len(sctp_nla_policy, CTA_PROTOINFO_SCTP_MAX + 1);
546 } 546 }
547 #endif 547 #endif
548 548
549 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 549 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
550 550
551 #include <linux/netfilter/nfnetlink.h> 551 #include <linux/netfilter/nfnetlink.h>
552 #include <linux/netfilter/nfnetlink_cttimeout.h> 552 #include <linux/netfilter/nfnetlink_cttimeout.h>
553 553
554 static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) 554 static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
555 { 555 {
556 unsigned int *timeouts = data; 556 unsigned int *timeouts = data;
557 int i; 557 int i;
558 558
559 /* set default SCTP timeouts. */ 559 /* set default SCTP timeouts. */
560 for (i=0; i<SCTP_CONNTRACK_MAX; i++) 560 for (i=0; i<SCTP_CONNTRACK_MAX; i++)
561 timeouts[i] = sctp_timeouts[i]; 561 timeouts[i] = sctp_timeouts[i];
562 562
563 /* there's a 1:1 mapping between attributes and protocol states. */ 563 /* there's a 1:1 mapping between attributes and protocol states. */
564 for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) { 564 for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) {
565 if (tb[i]) { 565 if (tb[i]) {
566 timeouts[i] = ntohl(nla_get_be32(tb[i])) * HZ; 566 timeouts[i] = ntohl(nla_get_be32(tb[i])) * HZ;
567 } 567 }
568 } 568 }
569 return 0; 569 return 0;
570 } 570 }
571 571
572 static int 572 static int
573 sctp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data) 573 sctp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
574 { 574 {
575 const unsigned int *timeouts = data; 575 const unsigned int *timeouts = data;
576 int i; 576 int i;
577 577
578 for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) { 578 for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) {
579 if (nla_put_be32(skb, i, htonl(timeouts[i] / HZ))) 579 if (nla_put_be32(skb, i, htonl(timeouts[i] / HZ)))
580 goto nla_put_failure; 580 goto nla_put_failure;
581 } 581 }
582 return 0; 582 return 0;
583 583
584 nla_put_failure: 584 nla_put_failure:
585 return -ENOSPC; 585 return -ENOSPC;
586 } 586 }
587 587
588 static const struct nla_policy 588 static const struct nla_policy
589 sctp_timeout_nla_policy[CTA_TIMEOUT_SCTP_MAX+1] = { 589 sctp_timeout_nla_policy[CTA_TIMEOUT_SCTP_MAX+1] = {
590 [CTA_TIMEOUT_SCTP_CLOSED] = { .type = NLA_U32 }, 590 [CTA_TIMEOUT_SCTP_CLOSED] = { .type = NLA_U32 },
591 [CTA_TIMEOUT_SCTP_COOKIE_WAIT] = { .type = NLA_U32 }, 591 [CTA_TIMEOUT_SCTP_COOKIE_WAIT] = { .type = NLA_U32 },
592 [CTA_TIMEOUT_SCTP_COOKIE_ECHOED] = { .type = NLA_U32 }, 592 [CTA_TIMEOUT_SCTP_COOKIE_ECHOED] = { .type = NLA_U32 },
593 [CTA_TIMEOUT_SCTP_ESTABLISHED] = { .type = NLA_U32 }, 593 [CTA_TIMEOUT_SCTP_ESTABLISHED] = { .type = NLA_U32 },
594 [CTA_TIMEOUT_SCTP_SHUTDOWN_SENT] = { .type = NLA_U32 }, 594 [CTA_TIMEOUT_SCTP_SHUTDOWN_SENT] = { .type = NLA_U32 },
595 [CTA_TIMEOUT_SCTP_SHUTDOWN_RECD] = { .type = NLA_U32 }, 595 [CTA_TIMEOUT_SCTP_SHUTDOWN_RECD] = { .type = NLA_U32 },
596 [CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT] = { .type = NLA_U32 }, 596 [CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT] = { .type = NLA_U32 },
597 }; 597 };
598 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 598 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
599 599
600 600
601 #ifdef CONFIG_SYSCTL 601 #ifdef CONFIG_SYSCTL
602 static unsigned int sctp_sysctl_table_users; 602 static unsigned int sctp_sysctl_table_users;
603 static struct ctl_table_header *sctp_sysctl_header; 603 static struct ctl_table_header *sctp_sysctl_header;
604 static struct ctl_table sctp_sysctl_table[] = { 604 static struct ctl_table sctp_sysctl_table[] = {
605 { 605 {
606 .procname = "nf_conntrack_sctp_timeout_closed", 606 .procname = "nf_conntrack_sctp_timeout_closed",
607 .data = &sctp_timeouts[SCTP_CONNTRACK_CLOSED], 607 .data = &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
608 .maxlen = sizeof(unsigned int), 608 .maxlen = sizeof(unsigned int),
609 .mode = 0644, 609 .mode = 0644,
610 .proc_handler = proc_dointvec_jiffies, 610 .proc_handler = proc_dointvec_jiffies,
611 }, 611 },
612 { 612 {
613 .procname = "nf_conntrack_sctp_timeout_cookie_wait", 613 .procname = "nf_conntrack_sctp_timeout_cookie_wait",
614 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT], 614 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
615 .maxlen = sizeof(unsigned int), 615 .maxlen = sizeof(unsigned int),
616 .mode = 0644, 616 .mode = 0644,
617 .proc_handler = proc_dointvec_jiffies, 617 .proc_handler = proc_dointvec_jiffies,
618 }, 618 },
619 { 619 {
620 .procname = "nf_conntrack_sctp_timeout_cookie_echoed", 620 .procname = "nf_conntrack_sctp_timeout_cookie_echoed",
621 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED], 621 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
622 .maxlen = sizeof(unsigned int), 622 .maxlen = sizeof(unsigned int),
623 .mode = 0644, 623 .mode = 0644,
624 .proc_handler = proc_dointvec_jiffies, 624 .proc_handler = proc_dointvec_jiffies,
625 }, 625 },
626 { 626 {
627 .procname = "nf_conntrack_sctp_timeout_established", 627 .procname = "nf_conntrack_sctp_timeout_established",
628 .data = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED], 628 .data = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
629 .maxlen = sizeof(unsigned int), 629 .maxlen = sizeof(unsigned int),
630 .mode = 0644, 630 .mode = 0644,
631 .proc_handler = proc_dointvec_jiffies, 631 .proc_handler = proc_dointvec_jiffies,
632 }, 632 },
633 { 633 {
634 .procname = "nf_conntrack_sctp_timeout_shutdown_sent", 634 .procname = "nf_conntrack_sctp_timeout_shutdown_sent",
635 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT], 635 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
636 .maxlen = sizeof(unsigned int), 636 .maxlen = sizeof(unsigned int),
637 .mode = 0644, 637 .mode = 0644,
638 .proc_handler = proc_dointvec_jiffies, 638 .proc_handler = proc_dointvec_jiffies,
639 }, 639 },
640 { 640 {
641 .procname = "nf_conntrack_sctp_timeout_shutdown_recd", 641 .procname = "nf_conntrack_sctp_timeout_shutdown_recd",
642 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD], 642 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
643 .maxlen = sizeof(unsigned int), 643 .maxlen = sizeof(unsigned int),
644 .mode = 0644, 644 .mode = 0644,
645 .proc_handler = proc_dointvec_jiffies, 645 .proc_handler = proc_dointvec_jiffies,
646 }, 646 },
647 { 647 {
648 .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent", 648 .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
649 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT], 649 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
650 .maxlen = sizeof(unsigned int), 650 .maxlen = sizeof(unsigned int),
651 .mode = 0644, 651 .mode = 0644,
652 .proc_handler = proc_dointvec_jiffies, 652 .proc_handler = proc_dointvec_jiffies,
653 }, 653 },
654 { } 654 { }
655 }; 655 };
656 656
657 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 657 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
658 static struct ctl_table sctp_compat_sysctl_table[] = { 658 static struct ctl_table sctp_compat_sysctl_table[] = {
659 { 659 {
660 .procname = "ip_conntrack_sctp_timeout_closed", 660 .procname = "ip_conntrack_sctp_timeout_closed",
661 .data = &sctp_timeouts[SCTP_CONNTRACK_CLOSED], 661 .data = &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
662 .maxlen = sizeof(unsigned int), 662 .maxlen = sizeof(unsigned int),
663 .mode = 0644, 663 .mode = 0644,
664 .proc_handler = proc_dointvec_jiffies, 664 .proc_handler = proc_dointvec_jiffies,
665 }, 665 },
666 { 666 {
667 .procname = "ip_conntrack_sctp_timeout_cookie_wait", 667 .procname = "ip_conntrack_sctp_timeout_cookie_wait",
668 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT], 668 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
669 .maxlen = sizeof(unsigned int), 669 .maxlen = sizeof(unsigned int),
670 .mode = 0644, 670 .mode = 0644,
671 .proc_handler = proc_dointvec_jiffies, 671 .proc_handler = proc_dointvec_jiffies,
672 }, 672 },
673 { 673 {
674 .procname = "ip_conntrack_sctp_timeout_cookie_echoed", 674 .procname = "ip_conntrack_sctp_timeout_cookie_echoed",
675 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED], 675 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
676 .maxlen = sizeof(unsigned int), 676 .maxlen = sizeof(unsigned int),
677 .mode = 0644, 677 .mode = 0644,
678 .proc_handler = proc_dointvec_jiffies, 678 .proc_handler = proc_dointvec_jiffies,
679 }, 679 },
680 { 680 {
681 .procname = "ip_conntrack_sctp_timeout_established", 681 .procname = "ip_conntrack_sctp_timeout_established",
682 .data = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED], 682 .data = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
683 .maxlen = sizeof(unsigned int), 683 .maxlen = sizeof(unsigned int),
684 .mode = 0644, 684 .mode = 0644,
685 .proc_handler = proc_dointvec_jiffies, 685 .proc_handler = proc_dointvec_jiffies,
686 }, 686 },
687 { 687 {
688 .procname = "ip_conntrack_sctp_timeout_shutdown_sent", 688 .procname = "ip_conntrack_sctp_timeout_shutdown_sent",
689 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT], 689 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
690 .maxlen = sizeof(unsigned int), 690 .maxlen = sizeof(unsigned int),
691 .mode = 0644, 691 .mode = 0644,
692 .proc_handler = proc_dointvec_jiffies, 692 .proc_handler = proc_dointvec_jiffies,
693 }, 693 },
694 { 694 {
695 .procname = "ip_conntrack_sctp_timeout_shutdown_recd", 695 .procname = "ip_conntrack_sctp_timeout_shutdown_recd",
696 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD], 696 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
697 .maxlen = sizeof(unsigned int), 697 .maxlen = sizeof(unsigned int),
698 .mode = 0644, 698 .mode = 0644,
699 .proc_handler = proc_dointvec_jiffies, 699 .proc_handler = proc_dointvec_jiffies,
700 }, 700 },
701 { 701 {
702 .procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent", 702 .procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent",
703 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT], 703 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
704 .maxlen = sizeof(unsigned int), 704 .maxlen = sizeof(unsigned int),
705 .mode = 0644, 705 .mode = 0644,
706 .proc_handler = proc_dointvec_jiffies, 706 .proc_handler = proc_dointvec_jiffies,
707 }, 707 },
708 { } 708 { }
709 }; 709 };
710 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ 710 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
711 #endif 711 #endif
712 712
713 static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = { 713 static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
714 .l3proto = PF_INET, 714 .l3proto = PF_INET,
715 .l4proto = IPPROTO_SCTP, 715 .l4proto = IPPROTO_SCTP,
716 .name = "sctp", 716 .name = "sctp",
717 .pkt_to_tuple = sctp_pkt_to_tuple, 717 .pkt_to_tuple = sctp_pkt_to_tuple,
718 .invert_tuple = sctp_invert_tuple, 718 .invert_tuple = sctp_invert_tuple,
719 .print_tuple = sctp_print_tuple, 719 .print_tuple = sctp_print_tuple,
720 .print_conntrack = sctp_print_conntrack, 720 .print_conntrack = sctp_print_conntrack,
721 .packet = sctp_packet, 721 .packet = sctp_packet,
722 .get_timeouts = sctp_get_timeouts, 722 .get_timeouts = sctp_get_timeouts,
723 .new = sctp_new, 723 .new = sctp_new,
724 .me = THIS_MODULE, 724 .me = THIS_MODULE,
725 #if IS_ENABLED(CONFIG_NF_CT_NETLINK) 725 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
726 .to_nlattr = sctp_to_nlattr, 726 .to_nlattr = sctp_to_nlattr,
727 .nlattr_size = sctp_nlattr_size, 727 .nlattr_size = sctp_nlattr_size,
728 .from_nlattr = nlattr_to_sctp, 728 .from_nlattr = nlattr_to_sctp,
729 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 729 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
730 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size, 730 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
731 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 731 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
732 .nla_policy = nf_ct_port_nla_policy, 732 .nla_policy = nf_ct_port_nla_policy,
733 #endif 733 #endif
734 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 734 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
735 .ctnl_timeout = { 735 .ctnl_timeout = {
736 .nlattr_to_obj = sctp_timeout_nlattr_to_obj, 736 .nlattr_to_obj = sctp_timeout_nlattr_to_obj,
737 .obj_to_nlattr = sctp_timeout_obj_to_nlattr, 737 .obj_to_nlattr = sctp_timeout_obj_to_nlattr,
738 .nlattr_max = CTA_TIMEOUT_SCTP_MAX, 738 .nlattr_max = CTA_TIMEOUT_SCTP_MAX,
739 .obj_size = sizeof(unsigned int) * SCTP_CONNTRACK_MAX, 739 .obj_size = sizeof(unsigned int) * SCTP_CONNTRACK_MAX,
740 .nla_policy = sctp_timeout_nla_policy, 740 .nla_policy = sctp_timeout_nla_policy,
741 }, 741 },
742 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 742 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
743 #ifdef CONFIG_SYSCTL 743 #ifdef CONFIG_SYSCTL
744 .ctl_table_users = &sctp_sysctl_table_users, 744 .ctl_table_users = &sctp_sysctl_table_users,
745 .ctl_table_header = &sctp_sysctl_header, 745 .ctl_table_header = &sctp_sysctl_header,
746 .ctl_table = sctp_sysctl_table, 746 .ctl_table = sctp_sysctl_table,
747 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 747 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
748 .ctl_compat_table = sctp_compat_sysctl_table, 748 .ctl_compat_table = sctp_compat_sysctl_table,
749 #endif 749 #endif
750 #endif 750 #endif
751 }; 751 };
752 752
753 static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = { 753 static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
754 .l3proto = PF_INET6, 754 .l3proto = PF_INET6,
755 .l4proto = IPPROTO_SCTP, 755 .l4proto = IPPROTO_SCTP,
756 .name = "sctp", 756 .name = "sctp",
757 .pkt_to_tuple = sctp_pkt_to_tuple, 757 .pkt_to_tuple = sctp_pkt_to_tuple,
758 .invert_tuple = sctp_invert_tuple, 758 .invert_tuple = sctp_invert_tuple,
759 .print_tuple = sctp_print_tuple, 759 .print_tuple = sctp_print_tuple,
760 .print_conntrack = sctp_print_conntrack, 760 .print_conntrack = sctp_print_conntrack,
761 .packet = sctp_packet, 761 .packet = sctp_packet,
762 .get_timeouts = sctp_get_timeouts, 762 .get_timeouts = sctp_get_timeouts,
763 .new = sctp_new, 763 .new = sctp_new,
764 .me = THIS_MODULE, 764 .me = THIS_MODULE,
765 #if IS_ENABLED(CONFIG_NF_CT_NETLINK) 765 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
766 .to_nlattr = sctp_to_nlattr, 766 .to_nlattr = sctp_to_nlattr,
767 .nlattr_size = sctp_nlattr_size, 767 .nlattr_size = sctp_nlattr_size,
768 .from_nlattr = nlattr_to_sctp, 768 .from_nlattr = nlattr_to_sctp,
769 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 769 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
770 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size, 770 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
771 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 771 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
772 .nla_policy = nf_ct_port_nla_policy, 772 .nla_policy = nf_ct_port_nla_policy,
773 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 773 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
774 .ctnl_timeout = { 774 .ctnl_timeout = {
775 .nlattr_to_obj = sctp_timeout_nlattr_to_obj, 775 .nlattr_to_obj = sctp_timeout_nlattr_to_obj,
776 .obj_to_nlattr = sctp_timeout_obj_to_nlattr, 776 .obj_to_nlattr = sctp_timeout_obj_to_nlattr,
777 .nlattr_max = CTA_TIMEOUT_SCTP_MAX, 777 .nlattr_max = CTA_TIMEOUT_SCTP_MAX,
778 .obj_size = sizeof(unsigned int) * SCTP_CONNTRACK_MAX, 778 .obj_size = sizeof(unsigned int) * SCTP_CONNTRACK_MAX,
779 .nla_policy = sctp_timeout_nla_policy, 779 .nla_policy = sctp_timeout_nla_policy,
780 }, 780 },
781 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 781 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
782 #endif 782 #endif
783 #ifdef CONFIG_SYSCTL 783 #ifdef CONFIG_SYSCTL
784 .ctl_table_users = &sctp_sysctl_table_users, 784 .ctl_table_users = &sctp_sysctl_table_users,
785 .ctl_table_header = &sctp_sysctl_header, 785 .ctl_table_header = &sctp_sysctl_header,
786 .ctl_table = sctp_sysctl_table, 786 .ctl_table = sctp_sysctl_table,
787 #endif 787 #endif
788 }; 788 };
789 789
790 static int __init nf_conntrack_proto_sctp_init(void) 790 static int __init nf_conntrack_proto_sctp_init(void)
791 { 791 {
792 int ret; 792 int ret;
793 793
794 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp4); 794 ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_sctp4);
795 if (ret) { 795 if (ret) {
796 pr_err("nf_conntrack_l4proto_sctp4: protocol register failed\n"); 796 pr_err("nf_conntrack_l4proto_sctp4: protocol register failed\n");
797 goto out; 797 goto out;
798 } 798 }
799 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp6); 799 ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_sctp6);
800 if (ret) { 800 if (ret) {
801 pr_err("nf_conntrack_l4proto_sctp6: protocol register failed\n"); 801 pr_err("nf_conntrack_l4proto_sctp6: protocol register failed\n");
802 goto cleanup_sctp4; 802 goto cleanup_sctp4;
803 } 803 }
804 804
805 return ret; 805 return ret;
806 806
807 cleanup_sctp4: 807 cleanup_sctp4:
808 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4); 808 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_sctp4);
809 out: 809 out:
810 return ret; 810 return ret;
811 } 811 }
812 812
813 static void __exit nf_conntrack_proto_sctp_fini(void) 813 static void __exit nf_conntrack_proto_sctp_fini(void)
814 { 814 {
815 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6); 815 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_sctp6);
816 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4); 816 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_sctp4);
817 } 817 }
818 818
819 module_init(nf_conntrack_proto_sctp_init); 819 module_init(nf_conntrack_proto_sctp_init);
820 module_exit(nf_conntrack_proto_sctp_fini); 820 module_exit(nf_conntrack_proto_sctp_fini);
821 821
822 MODULE_LICENSE("GPL"); 822 MODULE_LICENSE("GPL");
823 MODULE_AUTHOR("Kiran Kumar Immidi"); 823 MODULE_AUTHOR("Kiran Kumar Immidi");
824 MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP"); 824 MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");
825 MODULE_ALIAS("ip_conntrack_proto_sctp"); 825 MODULE_ALIAS("ip_conntrack_proto_sctp");
826 826
net/netfilter/nf_conntrack_proto_udplite.c
1 /* (C) 1999-2001 Paul `Rusty' Russell 1 /* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 * (C) 2007 Patrick McHardy <kaber@trash.net> 3 * (C) 2007 Patrick McHardy <kaber@trash.net>
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 */ 8 */
9 9
10 #include <linux/types.h> 10 #include <linux/types.h>
11 #include <linux/timer.h> 11 #include <linux/timer.h>
12 #include <linux/module.h> 12 #include <linux/module.h>
13 #include <linux/udp.h> 13 #include <linux/udp.h>
14 #include <linux/seq_file.h> 14 #include <linux/seq_file.h>
15 #include <linux/skbuff.h> 15 #include <linux/skbuff.h>
16 #include <linux/ipv6.h> 16 #include <linux/ipv6.h>
17 #include <net/ip6_checksum.h> 17 #include <net/ip6_checksum.h>
18 #include <net/checksum.h> 18 #include <net/checksum.h>
19 19
20 #include <linux/netfilter.h> 20 #include <linux/netfilter.h>
21 #include <linux/netfilter_ipv4.h> 21 #include <linux/netfilter_ipv4.h>
22 #include <linux/netfilter_ipv6.h> 22 #include <linux/netfilter_ipv6.h>
23 #include <net/netfilter/nf_conntrack_l4proto.h> 23 #include <net/netfilter/nf_conntrack_l4proto.h>
24 #include <net/netfilter/nf_conntrack_ecache.h> 24 #include <net/netfilter/nf_conntrack_ecache.h>
25 #include <net/netfilter/nf_log.h> 25 #include <net/netfilter/nf_log.h>
26 26
27 enum udplite_conntrack { 27 enum udplite_conntrack {
28 UDPLITE_CT_UNREPLIED, 28 UDPLITE_CT_UNREPLIED,
29 UDPLITE_CT_REPLIED, 29 UDPLITE_CT_REPLIED,
30 UDPLITE_CT_MAX 30 UDPLITE_CT_MAX
31 }; 31 };
32 32
33 static unsigned int udplite_timeouts[UDPLITE_CT_MAX] = { 33 static unsigned int udplite_timeouts[UDPLITE_CT_MAX] = {
34 [UDPLITE_CT_UNREPLIED] = 30*HZ, 34 [UDPLITE_CT_UNREPLIED] = 30*HZ,
35 [UDPLITE_CT_REPLIED] = 180*HZ, 35 [UDPLITE_CT_REPLIED] = 180*HZ,
36 }; 36 };
37 37
38 static bool udplite_pkt_to_tuple(const struct sk_buff *skb, 38 static bool udplite_pkt_to_tuple(const struct sk_buff *skb,
39 unsigned int dataoff, 39 unsigned int dataoff,
40 struct nf_conntrack_tuple *tuple) 40 struct nf_conntrack_tuple *tuple)
41 { 41 {
42 const struct udphdr *hp; 42 const struct udphdr *hp;
43 struct udphdr _hdr; 43 struct udphdr _hdr;
44 44
45 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr); 45 hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
46 if (hp == NULL) 46 if (hp == NULL)
47 return false; 47 return false;
48 48
49 tuple->src.u.udp.port = hp->source; 49 tuple->src.u.udp.port = hp->source;
50 tuple->dst.u.udp.port = hp->dest; 50 tuple->dst.u.udp.port = hp->dest;
51 return true; 51 return true;
52 } 52 }
53 53
54 static bool udplite_invert_tuple(struct nf_conntrack_tuple *tuple, 54 static bool udplite_invert_tuple(struct nf_conntrack_tuple *tuple,
55 const struct nf_conntrack_tuple *orig) 55 const struct nf_conntrack_tuple *orig)
56 { 56 {
57 tuple->src.u.udp.port = orig->dst.u.udp.port; 57 tuple->src.u.udp.port = orig->dst.u.udp.port;
58 tuple->dst.u.udp.port = orig->src.u.udp.port; 58 tuple->dst.u.udp.port = orig->src.u.udp.port;
59 return true; 59 return true;
60 } 60 }
61 61
62 /* Print out the per-protocol part of the tuple. */ 62 /* Print out the per-protocol part of the tuple. */
63 static int udplite_print_tuple(struct seq_file *s, 63 static int udplite_print_tuple(struct seq_file *s,
64 const struct nf_conntrack_tuple *tuple) 64 const struct nf_conntrack_tuple *tuple)
65 { 65 {
66 return seq_printf(s, "sport=%hu dport=%hu ", 66 return seq_printf(s, "sport=%hu dport=%hu ",
67 ntohs(tuple->src.u.udp.port), 67 ntohs(tuple->src.u.udp.port),
68 ntohs(tuple->dst.u.udp.port)); 68 ntohs(tuple->dst.u.udp.port));
69 } 69 }
70 70
71 static unsigned int *udplite_get_timeouts(struct net *net) 71 static unsigned int *udplite_get_timeouts(struct net *net)
72 { 72 {
73 return udplite_timeouts; 73 return udplite_timeouts;
74 } 74 }
75 75
76 /* Returns verdict for packet, and may modify conntracktype */ 76 /* Returns verdict for packet, and may modify conntracktype */
77 static int udplite_packet(struct nf_conn *ct, 77 static int udplite_packet(struct nf_conn *ct,
78 const struct sk_buff *skb, 78 const struct sk_buff *skb,
79 unsigned int dataoff, 79 unsigned int dataoff,
80 enum ip_conntrack_info ctinfo, 80 enum ip_conntrack_info ctinfo,
81 u_int8_t pf, 81 u_int8_t pf,
82 unsigned int hooknum, 82 unsigned int hooknum,
83 unsigned int *timeouts) 83 unsigned int *timeouts)
84 { 84 {
85 /* If we've seen traffic both ways, this is some kind of UDP 85 /* If we've seen traffic both ways, this is some kind of UDP
86 stream. Extend timeout. */ 86 stream. Extend timeout. */
87 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { 87 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
88 nf_ct_refresh_acct(ct, ctinfo, skb, 88 nf_ct_refresh_acct(ct, ctinfo, skb,
89 timeouts[UDPLITE_CT_REPLIED]); 89 timeouts[UDPLITE_CT_REPLIED]);
90 /* Also, more likely to be important, and not a probe */ 90 /* Also, more likely to be important, and not a probe */
91 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status)) 91 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
92 nf_conntrack_event_cache(IPCT_ASSURED, ct); 92 nf_conntrack_event_cache(IPCT_ASSURED, ct);
93 } else { 93 } else {
94 nf_ct_refresh_acct(ct, ctinfo, skb, 94 nf_ct_refresh_acct(ct, ctinfo, skb,
95 timeouts[UDPLITE_CT_UNREPLIED]); 95 timeouts[UDPLITE_CT_UNREPLIED]);
96 } 96 }
97 return NF_ACCEPT; 97 return NF_ACCEPT;
98 } 98 }
99 99
100 /* Called when a new connection for this protocol found. */ 100 /* Called when a new connection for this protocol found. */
101 static bool udplite_new(struct nf_conn *ct, const struct sk_buff *skb, 101 static bool udplite_new(struct nf_conn *ct, const struct sk_buff *skb,
102 unsigned int dataoff, unsigned int *timeouts) 102 unsigned int dataoff, unsigned int *timeouts)
103 { 103 {
104 return true; 104 return true;
105 } 105 }
106 106
107 static int udplite_error(struct net *net, struct nf_conn *tmpl, 107 static int udplite_error(struct net *net, struct nf_conn *tmpl,
108 struct sk_buff *skb, 108 struct sk_buff *skb,
109 unsigned int dataoff, 109 unsigned int dataoff,
110 enum ip_conntrack_info *ctinfo, 110 enum ip_conntrack_info *ctinfo,
111 u_int8_t pf, 111 u_int8_t pf,
112 unsigned int hooknum) 112 unsigned int hooknum)
113 { 113 {
114 unsigned int udplen = skb->len - dataoff; 114 unsigned int udplen = skb->len - dataoff;
115 const struct udphdr *hdr; 115 const struct udphdr *hdr;
116 struct udphdr _hdr; 116 struct udphdr _hdr;
117 unsigned int cscov; 117 unsigned int cscov;
118 118
119 /* Header is too small? */ 119 /* Header is too small? */
120 hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr); 120 hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
121 if (hdr == NULL) { 121 if (hdr == NULL) {
122 if (LOG_INVALID(net, IPPROTO_UDPLITE)) 122 if (LOG_INVALID(net, IPPROTO_UDPLITE))
123 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 123 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
124 "nf_ct_udplite: short packet "); 124 "nf_ct_udplite: short packet ");
125 return -NF_ACCEPT; 125 return -NF_ACCEPT;
126 } 126 }
127 127
128 cscov = ntohs(hdr->len); 128 cscov = ntohs(hdr->len);
129 if (cscov == 0) 129 if (cscov == 0)
130 cscov = udplen; 130 cscov = udplen;
131 else if (cscov < sizeof(*hdr) || cscov > udplen) { 131 else if (cscov < sizeof(*hdr) || cscov > udplen) {
132 if (LOG_INVALID(net, IPPROTO_UDPLITE)) 132 if (LOG_INVALID(net, IPPROTO_UDPLITE))
133 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 133 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
134 "nf_ct_udplite: invalid checksum coverage "); 134 "nf_ct_udplite: invalid checksum coverage ");
135 return -NF_ACCEPT; 135 return -NF_ACCEPT;
136 } 136 }
137 137
138 /* UDPLITE mandates checksums */ 138 /* UDPLITE mandates checksums */
139 if (!hdr->check) { 139 if (!hdr->check) {
140 if (LOG_INVALID(net, IPPROTO_UDPLITE)) 140 if (LOG_INVALID(net, IPPROTO_UDPLITE))
141 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 141 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
142 "nf_ct_udplite: checksum missing "); 142 "nf_ct_udplite: checksum missing ");
143 return -NF_ACCEPT; 143 return -NF_ACCEPT;
144 } 144 }
145 145
146 /* Checksum invalid? Ignore. */ 146 /* Checksum invalid? Ignore. */
147 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && 147 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
148 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_UDP, 148 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_UDP,
149 pf)) { 149 pf)) {
150 if (LOG_INVALID(net, IPPROTO_UDPLITE)) 150 if (LOG_INVALID(net, IPPROTO_UDPLITE))
151 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 151 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
152 "nf_ct_udplite: bad UDPLite checksum "); 152 "nf_ct_udplite: bad UDPLite checksum ");
153 return -NF_ACCEPT; 153 return -NF_ACCEPT;
154 } 154 }
155 155
156 return NF_ACCEPT; 156 return NF_ACCEPT;
157 } 157 }
158 158
159 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 159 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
160 160
161 #include <linux/netfilter/nfnetlink.h> 161 #include <linux/netfilter/nfnetlink.h>
162 #include <linux/netfilter/nfnetlink_cttimeout.h> 162 #include <linux/netfilter/nfnetlink_cttimeout.h>
163 163
164 static int udplite_timeout_nlattr_to_obj(struct nlattr *tb[], void *data) 164 static int udplite_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
165 { 165 {
166 unsigned int *timeouts = data; 166 unsigned int *timeouts = data;
167 167
168 /* set default timeouts for UDPlite. */ 168 /* set default timeouts for UDPlite. */
169 timeouts[UDPLITE_CT_UNREPLIED] = udplite_timeouts[UDPLITE_CT_UNREPLIED]; 169 timeouts[UDPLITE_CT_UNREPLIED] = udplite_timeouts[UDPLITE_CT_UNREPLIED];
170 timeouts[UDPLITE_CT_REPLIED] = udplite_timeouts[UDPLITE_CT_REPLIED]; 170 timeouts[UDPLITE_CT_REPLIED] = udplite_timeouts[UDPLITE_CT_REPLIED];
171 171
172 if (tb[CTA_TIMEOUT_UDPLITE_UNREPLIED]) { 172 if (tb[CTA_TIMEOUT_UDPLITE_UNREPLIED]) {
173 timeouts[UDPLITE_CT_UNREPLIED] = 173 timeouts[UDPLITE_CT_UNREPLIED] =
174 ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDPLITE_UNREPLIED])) * HZ; 174 ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDPLITE_UNREPLIED])) * HZ;
175 } 175 }
176 if (tb[CTA_TIMEOUT_UDPLITE_REPLIED]) { 176 if (tb[CTA_TIMEOUT_UDPLITE_REPLIED]) {
177 timeouts[UDPLITE_CT_REPLIED] = 177 timeouts[UDPLITE_CT_REPLIED] =
178 ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDPLITE_REPLIED])) * HZ; 178 ntohl(nla_get_be32(tb[CTA_TIMEOUT_UDPLITE_REPLIED])) * HZ;
179 } 179 }
180 return 0; 180 return 0;
181 } 181 }
182 182
183 static int 183 static int
184 udplite_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data) 184 udplite_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
185 { 185 {
186 const unsigned int *timeouts = data; 186 const unsigned int *timeouts = data;
187 187
188 if (nla_put_be32(skb, CTA_TIMEOUT_UDPLITE_UNREPLIED, 188 if (nla_put_be32(skb, CTA_TIMEOUT_UDPLITE_UNREPLIED,
189 htonl(timeouts[UDPLITE_CT_UNREPLIED] / HZ)) || 189 htonl(timeouts[UDPLITE_CT_UNREPLIED] / HZ)) ||
190 nla_put_be32(skb, CTA_TIMEOUT_UDPLITE_REPLIED, 190 nla_put_be32(skb, CTA_TIMEOUT_UDPLITE_REPLIED,
191 htonl(timeouts[UDPLITE_CT_REPLIED] / HZ))) 191 htonl(timeouts[UDPLITE_CT_REPLIED] / HZ)))
192 goto nla_put_failure; 192 goto nla_put_failure;
193 return 0; 193 return 0;
194 194
195 nla_put_failure: 195 nla_put_failure:
196 return -ENOSPC; 196 return -ENOSPC;
197 } 197 }
198 198
199 static const struct nla_policy 199 static const struct nla_policy
200 udplite_timeout_nla_policy[CTA_TIMEOUT_UDPLITE_MAX+1] = { 200 udplite_timeout_nla_policy[CTA_TIMEOUT_UDPLITE_MAX+1] = {
201 [CTA_TIMEOUT_UDPLITE_UNREPLIED] = { .type = NLA_U32 }, 201 [CTA_TIMEOUT_UDPLITE_UNREPLIED] = { .type = NLA_U32 },
202 [CTA_TIMEOUT_UDPLITE_REPLIED] = { .type = NLA_U32 }, 202 [CTA_TIMEOUT_UDPLITE_REPLIED] = { .type = NLA_U32 },
203 }; 203 };
204 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 204 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
205 205
206 #ifdef CONFIG_SYSCTL 206 #ifdef CONFIG_SYSCTL
207 static unsigned int udplite_sysctl_table_users; 207 static unsigned int udplite_sysctl_table_users;
208 static struct ctl_table_header *udplite_sysctl_header; 208 static struct ctl_table_header *udplite_sysctl_header;
209 static struct ctl_table udplite_sysctl_table[] = { 209 static struct ctl_table udplite_sysctl_table[] = {
210 { 210 {
211 .procname = "nf_conntrack_udplite_timeout", 211 .procname = "nf_conntrack_udplite_timeout",
212 .data = &udplite_timeouts[UDPLITE_CT_UNREPLIED], 212 .data = &udplite_timeouts[UDPLITE_CT_UNREPLIED],
213 .maxlen = sizeof(unsigned int), 213 .maxlen = sizeof(unsigned int),
214 .mode = 0644, 214 .mode = 0644,
215 .proc_handler = proc_dointvec_jiffies, 215 .proc_handler = proc_dointvec_jiffies,
216 }, 216 },
217 { 217 {
218 .procname = "nf_conntrack_udplite_timeout_stream", 218 .procname = "nf_conntrack_udplite_timeout_stream",
219 .data = &udplite_timeouts[UDPLITE_CT_REPLIED], 219 .data = &udplite_timeouts[UDPLITE_CT_REPLIED],
220 .maxlen = sizeof(unsigned int), 220 .maxlen = sizeof(unsigned int),
221 .mode = 0644, 221 .mode = 0644,
222 .proc_handler = proc_dointvec_jiffies, 222 .proc_handler = proc_dointvec_jiffies,
223 }, 223 },
224 { } 224 { }
225 }; 225 };
226 #endif /* CONFIG_SYSCTL */ 226 #endif /* CONFIG_SYSCTL */
227 227
228 static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly = 228 static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
229 { 229 {
230 .l3proto = PF_INET, 230 .l3proto = PF_INET,
231 .l4proto = IPPROTO_UDPLITE, 231 .l4proto = IPPROTO_UDPLITE,
232 .name = "udplite", 232 .name = "udplite",
233 .pkt_to_tuple = udplite_pkt_to_tuple, 233 .pkt_to_tuple = udplite_pkt_to_tuple,
234 .invert_tuple = udplite_invert_tuple, 234 .invert_tuple = udplite_invert_tuple,
235 .print_tuple = udplite_print_tuple, 235 .print_tuple = udplite_print_tuple,
236 .packet = udplite_packet, 236 .packet = udplite_packet,
237 .get_timeouts = udplite_get_timeouts, 237 .get_timeouts = udplite_get_timeouts,
238 .new = udplite_new, 238 .new = udplite_new,
239 .error = udplite_error, 239 .error = udplite_error,
240 #if IS_ENABLED(CONFIG_NF_CT_NETLINK) 240 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
241 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 241 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
242 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size, 242 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
243 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 243 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
244 .nla_policy = nf_ct_port_nla_policy, 244 .nla_policy = nf_ct_port_nla_policy,
245 #endif 245 #endif
246 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 246 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
247 .ctnl_timeout = { 247 .ctnl_timeout = {
248 .nlattr_to_obj = udplite_timeout_nlattr_to_obj, 248 .nlattr_to_obj = udplite_timeout_nlattr_to_obj,
249 .obj_to_nlattr = udplite_timeout_obj_to_nlattr, 249 .obj_to_nlattr = udplite_timeout_obj_to_nlattr,
250 .nlattr_max = CTA_TIMEOUT_UDPLITE_MAX, 250 .nlattr_max = CTA_TIMEOUT_UDPLITE_MAX,
251 .obj_size = sizeof(unsigned int) * 251 .obj_size = sizeof(unsigned int) *
252 CTA_TIMEOUT_UDPLITE_MAX, 252 CTA_TIMEOUT_UDPLITE_MAX,
253 .nla_policy = udplite_timeout_nla_policy, 253 .nla_policy = udplite_timeout_nla_policy,
254 }, 254 },
255 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 255 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
256 #ifdef CONFIG_SYSCTL 256 #ifdef CONFIG_SYSCTL
257 .ctl_table_users = &udplite_sysctl_table_users, 257 .ctl_table_users = &udplite_sysctl_table_users,
258 .ctl_table_header = &udplite_sysctl_header, 258 .ctl_table_header = &udplite_sysctl_header,
259 .ctl_table = udplite_sysctl_table, 259 .ctl_table = udplite_sysctl_table,
260 #endif 260 #endif
261 }; 261 };
262 262
263 static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly = 263 static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly =
264 { 264 {
265 .l3proto = PF_INET6, 265 .l3proto = PF_INET6,
266 .l4proto = IPPROTO_UDPLITE, 266 .l4proto = IPPROTO_UDPLITE,
267 .name = "udplite", 267 .name = "udplite",
268 .pkt_to_tuple = udplite_pkt_to_tuple, 268 .pkt_to_tuple = udplite_pkt_to_tuple,
269 .invert_tuple = udplite_invert_tuple, 269 .invert_tuple = udplite_invert_tuple,
270 .print_tuple = udplite_print_tuple, 270 .print_tuple = udplite_print_tuple,
271 .packet = udplite_packet, 271 .packet = udplite_packet,
272 .get_timeouts = udplite_get_timeouts, 272 .get_timeouts = udplite_get_timeouts,
273 .new = udplite_new, 273 .new = udplite_new,
274 .error = udplite_error, 274 .error = udplite_error,
275 #if IS_ENABLED(CONFIG_NF_CT_NETLINK) 275 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
276 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 276 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
277 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size, 277 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
278 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 278 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
279 .nla_policy = nf_ct_port_nla_policy, 279 .nla_policy = nf_ct_port_nla_policy,
280 #endif 280 #endif
281 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 281 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
282 .ctnl_timeout = { 282 .ctnl_timeout = {
283 .nlattr_to_obj = udplite_timeout_nlattr_to_obj, 283 .nlattr_to_obj = udplite_timeout_nlattr_to_obj,
284 .obj_to_nlattr = udplite_timeout_obj_to_nlattr, 284 .obj_to_nlattr = udplite_timeout_obj_to_nlattr,
285 .nlattr_max = CTA_TIMEOUT_UDPLITE_MAX, 285 .nlattr_max = CTA_TIMEOUT_UDPLITE_MAX,
286 .obj_size = sizeof(unsigned int) * 286 .obj_size = sizeof(unsigned int) *
287 CTA_TIMEOUT_UDPLITE_MAX, 287 CTA_TIMEOUT_UDPLITE_MAX,
288 .nla_policy = udplite_timeout_nla_policy, 288 .nla_policy = udplite_timeout_nla_policy,
289 }, 289 },
290 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 290 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
291 #ifdef CONFIG_SYSCTL 291 #ifdef CONFIG_SYSCTL
292 .ctl_table_users = &udplite_sysctl_table_users, 292 .ctl_table_users = &udplite_sysctl_table_users,
293 .ctl_table_header = &udplite_sysctl_header, 293 .ctl_table_header = &udplite_sysctl_header,
294 .ctl_table = udplite_sysctl_table, 294 .ctl_table = udplite_sysctl_table,
295 #endif 295 #endif
296 }; 296 };
297 297
298 static int __init nf_conntrack_proto_udplite_init(void) 298 static int __init nf_conntrack_proto_udplite_init(void)
299 { 299 {
300 int err; 300 int err;
301 301
302 err = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite4); 302 err = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_udplite4);
303 if (err < 0) 303 if (err < 0)
304 goto err1; 304 goto err1;
305 err = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite6); 305 err = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_udplite6);
306 if (err < 0) 306 if (err < 0)
307 goto err2; 307 goto err2;
308 return 0; 308 return 0;
309 err2: 309 err2:
310 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite4); 310 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udplite4);
311 err1: 311 err1:
312 return err; 312 return err;
313 } 313 }
314 314
315 static void __exit nf_conntrack_proto_udplite_exit(void) 315 static void __exit nf_conntrack_proto_udplite_exit(void)
316 { 316 {
317 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite6); 317 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udplite6);
318 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite4); 318 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_udplite4);
319 } 319 }
320 320
321 module_init(nf_conntrack_proto_udplite_init); 321 module_init(nf_conntrack_proto_udplite_init);
322 module_exit(nf_conntrack_proto_udplite_exit); 322 module_exit(nf_conntrack_proto_udplite_exit);
323 323
324 MODULE_LICENSE("GPL"); 324 MODULE_LICENSE("GPL");
325 325