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 15static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ; 16 17static 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 41static inline struct nf_generic_net *generic_pernet(struct net *net) 42{ 43 return &net->ct.nf_ct_proto.generic; 44} 45 46static bool generic_pkt_to_tuple(const struct sk_buff *skb, 47 unsigned int dataoff, 48 struct nf_conntrack_tuple *tuple) 49{ 50 tuple->src.u.all = 0; 51 tuple->dst.u.all = 0; 52 53 return true; 54} 55 56static 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. */ 66static int generic_print_tuple(struct seq_file *s, 67 const struct nf_conntrack_tuple *tuple) 68{ 69 return 0; 70} 71 72static unsigned int *generic_get_timeouts(struct net *net) 73{ 74 return &(generic_pernet(net)->timeout); 75} 76 77/* Returns verdict for packet, or -1 for invalid. */ 78static int generic_packet(struct nf_conn *ct, 79 const struct sk_buff *skb, 80 unsigned int dataoff, 81 enum ip_conntrack_info ctinfo, 82 u_int8_t pf, 83 unsigned int hooknum, 84 unsigned int *timeout) 85{ 86 nf_ct_refresh_acct(ct, ctinfo, skb, *timeout); 87 return NF_ACCEPT; 88} 89 90/* Called when a new connection for this protocol found. */ 91static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb, 92 unsigned int dataoff, unsigned int *timeouts) 93{ 94 return nf_generic_should_process(nf_ct_protonum(ct)); 95} 96 97#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 98 99#include <linux/netfilter/nfnetlink.h> 100#include <linux/netfilter/nfnetlink_cttimeout.h> 101 102static int generic_timeout_nlattr_to_obj(struct nlattr *tb[], 103 struct net *net, void *data) 104{ 105 unsigned int *timeout = data; 106 struct nf_generic_net *gn = generic_pernet(net); 107 108 if (tb[CTA_TIMEOUT_GENERIC_TIMEOUT]) 109 *timeout = 110 ntohl(nla_get_be32(tb[CTA_TIMEOUT_GENERIC_TIMEOUT])) * HZ; 111 else { 112 /* Set default generic timeout. */ 113 *timeout = gn->timeout; 114 } 115 116 return 0; 117} 118 119static int 120generic_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data) 121{ 122 const unsigned int *timeout = data; 123 124 if (nla_put_be32(skb, CTA_TIMEOUT_GENERIC_TIMEOUT, htonl(*timeout / HZ))) 125 goto nla_put_failure; 126 127 return 0; 128 129nla_put_failure: 130 return -ENOSPC; 131} 132 133static const struct nla_policy 134generic_timeout_nla_policy[CTA_TIMEOUT_GENERIC_MAX+1] = { 135 [CTA_TIMEOUT_GENERIC_TIMEOUT] = { .type = NLA_U32 }, 136}; 137#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 138 139#ifdef CONFIG_SYSCTL 140static struct ctl_table generic_sysctl_table[] = { 141 { 142 .procname = "nf_conntrack_generic_timeout", 143 .maxlen = sizeof(unsigned int), 144 .mode = 0644, 145 .proc_handler = proc_dointvec_jiffies, 146 }, 147 { } 148}; 149#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 150static struct ctl_table generic_compat_sysctl_table[] = { 151 { 152 .procname = "ip_conntrack_generic_timeout", 153 .maxlen = sizeof(unsigned int), 154 .mode = 0644, 155 .proc_handler = proc_dointvec_jiffies, 156 }, 157 { } 158}; 159#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ 160#endif /* CONFIG_SYSCTL */ 161 162static int generic_kmemdup_sysctl_table(struct nf_proto_net *pn, 163 struct nf_generic_net *gn) 164{ 165#ifdef CONFIG_SYSCTL 166 pn->ctl_table = kmemdup(generic_sysctl_table, 167 sizeof(generic_sysctl_table), 168 GFP_KERNEL); 169 if (!pn->ctl_table) 170 return -ENOMEM; 171 172 pn->ctl_table[0].data = &gn->timeout; 173#endif 174 return 0; 175} 176 177static int generic_kmemdup_compat_sysctl_table(struct nf_proto_net *pn, 178 struct nf_generic_net *gn) 179{ 180#ifdef CONFIG_SYSCTL 181#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT 182 pn->ctl_compat_table = kmemdup(generic_compat_sysctl_table, 183 sizeof(generic_compat_sysctl_table), 184 GFP_KERNEL); 185 if (!pn->ctl_compat_table) 186 return -ENOMEM; 187 188 pn->ctl_compat_table[0].data = &gn->timeout; 189#endif 190#endif 191 return 0; 192} 193 194static int generic_init_net(struct net *net, u_int16_t proto) 195{ 196 int ret; 197 struct nf_generic_net *gn = generic_pernet(net); 198 struct nf_proto_net *pn = &gn->pn; 199 200 gn->timeout = nf_ct_generic_timeout; 201 202 ret = generic_kmemdup_compat_sysctl_table(pn, gn); 203 if (ret < 0) 204 return ret; 205 206 ret = generic_kmemdup_sysctl_table(pn, gn); 207 if (ret < 0) 208 nf_ct_kfree_compat_sysctl_table(pn); 209 210 return ret; 211} 212 213static struct nf_proto_net *generic_get_net_proto(struct net *net) 214{ 215 return &net->ct.nf_ct_proto.generic.pn; 216} 217 218struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly = 219{ 220 .l3proto = PF_UNSPEC, 221 .l4proto = 255, 222 .name = "unknown", 223 .pkt_to_tuple = generic_pkt_to_tuple, 224 .invert_tuple = generic_invert_tuple, 225 .print_tuple = generic_print_tuple, 226 .packet = generic_packet, 227 .get_timeouts = generic_get_timeouts, 228 .new = generic_new, 229#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT) 230 .ctnl_timeout = { 231 .nlattr_to_obj = generic_timeout_nlattr_to_obj, 232 .obj_to_nlattr = generic_timeout_obj_to_nlattr, 233 .nlattr_max = CTA_TIMEOUT_GENERIC_MAX, 234 .obj_size = sizeof(unsigned int), 235 .nla_policy = generic_timeout_nla_policy, 236 }, 237#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ 238 .init_net = generic_init_net, 239 .get_net_proto = generic_get_net_proto, 240}; 241