1 /* (C) 1999-2001 Paul `Rusty' Russell 2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 3 * 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 6 * published by the Free Software Foundation. 7 */ 8 9 #include <linux/types.h> 10 #include <linux/jiffies.h> 11 #include <linux/timer.h> 12 #include <linux/netfilter.h> 13 #include <net/netfilter/nf_conntrack_l4proto.h> 14 15 static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ; 16 17 static bool nf_generic_should_process(u8 proto) 18 { 19 switch (proto) { 20 #ifdef CONFIG_NF_CT_PROTO_SCTP_MODULE 21 case IPPROTO_SCTP: 22 return false; 23 #endif 24 #ifdef CONFIG_NF_CT_PROTO_DCCP_MODULE 25 case IPPROTO_DCCP: 26 return false; 27 #endif 28 #ifdef CONFIG_NF_CT_PROTO_GRE_MODULE 29 case IPPROTO_GRE: 30 return false; 31 #endif 32 #ifdef CONFIG_NF_CT_PROTO_UDPLITE_MODULE 33 case IPPROTO_UDPLITE: 34 return false; 35 #endif 36 default: 37 return true; 38 } 39 } 40 41 static inline struct nf_generic_net *generic_pernet(struct net *net) 42 { 43 return &net->ct.nf_ct_proto.generic; 44 } 45 46 static bool generic_pkt_to_tuple(const struct sk_buff *skb, 47 unsigned int dataoff, 48 struct net *net, struct nf_conntrack_tuple *tuple) 49 { 50 tuple->src.u.all = 0; 51 tuple->dst.u.all = 0; 52 53 return true; 54 } 55 56 static bool generic_invert_tuple(struct nf_conntrack_tuple *tuple, 57 const struct nf_conntrack_tuple *orig) 58 { 59 tuple->src.u.all = 0; 60 tuple->dst.u.all = 0; 61 62 return true; 63 } 64 65 /* Print out the per-protocol part of the tuple. */ 66 static void generic_print_tuple(struct seq_file *s, 67 const struct nf_conntrack_tuple *tuple) 68 { 69 } 70 71 static unsigned int *generic_get_timeouts(struct net *net) 72 { 73 return &(generic_pernet(net)->timeout); 74 } 75 76 /* Returns verdict for packet, or -1 for invalid. */ 77 static int generic_packet(struct nf_conn *ct, 78 const struct sk_buff *skb, 79 unsigned int dataoff, 80 enum ip_conntrack_info ctinfo, 81 u_int8_t pf, 82 unsigned int hooknum, 83 unsigned int *timeout) 84 { 85 nf_ct_refresh_acct(ct, ctinfo, skb, *timeout); 86 return NF_ACCEPT; 87 } 88 89 /* Called when a new connection for this protocol found. */ 90 static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb, 91 unsigned int dataoff, unsigned int *timeouts) 92 { 93 bool ret; 94 95 ret = nf_generic_should_process(nf_ct_protonum(ct)); 96 if (!ret) 97 pr_warn_once("conntrack: generic helper won't handle protocol %d. Please consider loading the specific helper module.\n", 98 nf_ct_protonum(ct)); 99 return ret; 100 } 101 102 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 103 104 #include <linux/netfilter/nfnetlink.h> 105 #include <linux/netfilter/nfnetlink_cttimeout.h> 106 107 static int generic_timeout_nlattr_to_obj(struct nlattr *tb[], 108 struct net *net, void *data) 109 { 110 unsigned int *timeout = data; 111 struct nf_generic_net *gn = generic_pernet(net); 112 113 if (tb[CTA_TIMEOUT_GENERIC_TIMEOUT]) 114 *timeout = 115 ntohl(nla_get_be32(tb[CTA_TIMEOUT_GENERIC_TIMEOUT])) * HZ; 116 else { 117 /* Set default generic timeout. */ 118 *timeout = gn->timeout; 119 } 120 121 return 0; 122 } 123 124 static int 125 generic_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data) 126 { 127 const unsigned int *timeout = data; 128 129 if (nla_put_be32(skb, CTA_TIMEOUT_GENERIC_TIMEOUT, htonl(*timeout / HZ))) 130 goto nla_put_failure; 131 132 return 0; 133 134 nla_put_failure: 135 return -ENOSPC; 136 } 137 138 static const struct nla_policy 139 generic_timeout_nla_policy[CTA_TIMEOUT_GENERIC_MAX+1] = { 140 [CTA_TIMEOUT_GENERIC_TIMEOUT] = { .type = NLA_U32 }, 141 }; 142 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 143 144 #ifdef CONFIG_SYSCTL 145 static struct ctl_table generic_sysctl_table[] = { 146 { 147 .procname = "nf_conntrack_generic_timeout", 148 .maxlen = sizeof(unsigned int), 149 .mode = 0644, 150 .proc_handler = proc_dointvec_jiffies, 151 }, 152 { } 153 }; 154 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 155 static struct ctl_table generic_compat_sysctl_table[] = { 156 { 157 .procname = "ip_conntrack_generic_timeout", 158 .maxlen = sizeof(unsigned int), 159 .mode = 0644, 160 .proc_handler = proc_dointvec_jiffies, 161 }, 162 { } 163 }; 164 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ 165 #endif /* CONFIG_SYSCTL */ 166 167 static int generic_kmemdup_sysctl_table(struct nf_proto_net *pn, 168 struct nf_generic_net *gn) 169 { 170 #ifdef CONFIG_SYSCTL 171 pn->ctl_table = kmemdup(generic_sysctl_table, 172 sizeof(generic_sysctl_table), 173 GFP_KERNEL); 174 if (!pn->ctl_table) 175 return -ENOMEM; 176 177 pn->ctl_table[0].data = &gn->timeout; 178 #endif 179 return 0; 180 } 181 182 static int generic_kmemdup_compat_sysctl_table(struct nf_proto_net *pn, 183 struct nf_generic_net *gn) 184 { 185 #ifdef CONFIG_SYSCTL 186 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 187 pn->ctl_compat_table = kmemdup(generic_compat_sysctl_table, 188 sizeof(generic_compat_sysctl_table), 189 GFP_KERNEL); 190 if (!pn->ctl_compat_table) 191 return -ENOMEM; 192 193 pn->ctl_compat_table[0].data = &gn->timeout; 194 #endif 195 #endif 196 return 0; 197 } 198 199 static int generic_init_net(struct net *net, u_int16_t proto) 200 { 201 int ret; 202 struct nf_generic_net *gn = generic_pernet(net); 203 struct nf_proto_net *pn = &gn->pn; 204 205 gn->timeout = nf_ct_generic_timeout; 206 207 ret = generic_kmemdup_compat_sysctl_table(pn, gn); 208 if (ret < 0) 209 return ret; 210 211 ret = generic_kmemdup_sysctl_table(pn, gn); 212 if (ret < 0) 213 nf_ct_kfree_compat_sysctl_table(pn); 214 215 return ret; 216 } 217 218 static struct nf_proto_net *generic_get_net_proto(struct net *net) 219 { 220 return &net->ct.nf_ct_proto.generic.pn; 221 } 222 223 struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly = 224 { 225 .l3proto = PF_UNSPEC, 226 .l4proto = 255, 227 .name = "unknown", 228 .pkt_to_tuple = generic_pkt_to_tuple, 229 .invert_tuple = generic_invert_tuple, 230 .print_tuple = generic_print_tuple, 231 .packet = generic_packet, 232 .get_timeouts = generic_get_timeouts, 233 .new = generic_new, 234 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 235 .ctnl_timeout = { 236 .nlattr_to_obj = generic_timeout_nlattr_to_obj, 237 .obj_to_nlattr = generic_timeout_obj_to_nlattr, 238 .nlattr_max = CTA_TIMEOUT_GENERIC_MAX, 239 .obj_size = sizeof(unsigned int), 240 .nla_policy = generic_timeout_nla_policy, 241 }, 242 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 243 .init_net = generic_init_net, 244 .get_net_proto = generic_get_net_proto, 245 }; 246