Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nf_ct_helper: implement variable length helper private data

This patch uses the new variable length conntrack extensions.

Instead of using union nf_conntrack_help that contain all the
helper private data information, we allocate variable length
area to store the private helper data.

This patch includes the modification of all existing helpers.
It also includes a couple of include header to avoid compilation
warnings.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

+111 -106
+2
include/linux/netfilter/nf_conntrack_sip.h
··· 2 2 #define __NF_CONNTRACK_SIP_H__ 3 3 #ifdef __KERNEL__ 4 4 5 + #include <net/netfilter/nf_conntrack_expect.h> 6 + 5 7 #define SIP_PORT 5060 6 8 #define SIP_TIMEOUT 3600 7 9
+3 -32
include/net/netfilter/nf_conntrack.h
··· 39 39 /* insert expect proto private data here */ 40 40 }; 41 41 42 - /* Add protocol helper include file here */ 43 - #include <linux/netfilter/nf_conntrack_ftp.h> 44 - #include <linux/netfilter/nf_conntrack_pptp.h> 45 - #include <linux/netfilter/nf_conntrack_h323.h> 46 - #include <linux/netfilter/nf_conntrack_sane.h> 47 - #include <linux/netfilter/nf_conntrack_sip.h> 48 - 49 - /* per conntrack: application helper private data */ 50 - union nf_conntrack_help { 51 - /* insert conntrack helper private data (master) here */ 52 - #if defined(CONFIG_NF_CONNTRACK_FTP) || defined(CONFIG_NF_CONNTRACK_FTP_MODULE) 53 - struct nf_ct_ftp_master ct_ftp_info; 54 - #endif 55 - #if defined(CONFIG_NF_CONNTRACK_PPTP) || \ 56 - defined(CONFIG_NF_CONNTRACK_PPTP_MODULE) 57 - struct nf_ct_pptp_master ct_pptp_info; 58 - #endif 59 - #if defined(CONFIG_NF_CONNTRACK_H323) || \ 60 - defined(CONFIG_NF_CONNTRACK_H323_MODULE) 61 - struct nf_ct_h323_master ct_h323_info; 62 - #endif 63 - #if defined(CONFIG_NF_CONNTRACK_SANE) || \ 64 - defined(CONFIG_NF_CONNTRACK_SANE_MODULE) 65 - struct nf_ct_sane_master ct_sane_info; 66 - #endif 67 - #if defined(CONFIG_NF_CONNTRACK_SIP) || defined(CONFIG_NF_CONNTRACK_SIP_MODULE) 68 - struct nf_ct_sip_master ct_sip_info; 69 - #endif 70 - }; 71 - 72 42 #include <linux/types.h> 73 43 #include <linux/skbuff.h> 74 44 #include <linux/timer.h> ··· 59 89 /* Helper. if any */ 60 90 struct nf_conntrack_helper __rcu *helper; 61 91 62 - union nf_conntrack_help help; 63 - 64 92 struct hlist_head expectations; 65 93 66 94 /* Current number of expected connections */ 67 95 u8 expecting[NF_CT_MAX_EXPECT_CLASSES]; 96 + 97 + /* private helper information. */ 98 + char data[]; 68 99 }; 69 100 70 101 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
+14 -1
include/net/netfilter/nf_conntrack_helper.h
··· 11 11 #define _NF_CONNTRACK_HELPER_H 12 12 #include <net/netfilter/nf_conntrack.h> 13 13 #include <net/netfilter/nf_conntrack_extend.h> 14 + #include <net/netfilter/nf_conntrack_expect.h> 14 15 15 16 struct module; 16 17 ··· 23 22 char name[NF_CT_HELPER_NAME_LEN]; /* name of the module */ 24 23 struct module *me; /* pointer to self */ 25 24 const struct nf_conntrack_expect_policy *expect_policy; 25 + 26 + /* length of internal data, ie. sizeof(struct nf_ct_*_master) */ 27 + size_t data_len; 26 28 27 29 /* Tuple of things we will help (compared against server response) */ 28 30 struct nf_conntrack_tuple tuple; ··· 52 48 extern int nf_conntrack_helper_register(struct nf_conntrack_helper *); 53 49 extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *); 54 50 55 - extern struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp); 51 + extern struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, struct nf_conntrack_helper *helper, gfp_t gfp); 56 52 57 53 extern int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, 58 54 gfp_t flags); ··· 62 58 static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct) 63 59 { 64 60 return nf_ct_ext_find(ct, NF_CT_EXT_HELPER); 61 + } 62 + 63 + static inline void *nfct_help_data(const struct nf_conn *ct) 64 + { 65 + struct nf_conn_help *help; 66 + 67 + help = nf_ct_ext_find(ct, NF_CT_EXT_HELPER); 68 + 69 + return (void *)help->data; 65 70 } 66 71 67 72 extern int nf_conntrack_helper_init(struct net *net);
+2 -2
net/ipv4/netfilter/nf_nat_amanda.c
··· 13 13 #include <linux/skbuff.h> 14 14 #include <linux/udp.h> 15 15 16 - #include <net/netfilter/nf_nat_helper.h> 17 - #include <net/netfilter/nf_nat_rule.h> 18 16 #include <net/netfilter/nf_conntrack_helper.h> 19 17 #include <net/netfilter/nf_conntrack_expect.h> 18 + #include <net/netfilter/nf_nat_helper.h> 19 + #include <net/netfilter/nf_nat_rule.h> 20 20 #include <linux/netfilter/nf_conntrack_amanda.h> 21 21 22 22 MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
+4 -4
net/ipv4/netfilter/nf_nat_h323.c
··· 95 95 unsigned char **data, 96 96 TransportAddress *taddr, int count) 97 97 { 98 - const struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; 98 + const struct nf_ct_h323_master *info = nfct_help_data(ct); 99 99 int dir = CTINFO2DIR(ctinfo); 100 100 int i; 101 101 __be16 port; ··· 178 178 struct nf_conntrack_expect *rtp_exp, 179 179 struct nf_conntrack_expect *rtcp_exp) 180 180 { 181 - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; 181 + struct nf_ct_h323_master *info = nfct_help_data(ct); 182 182 int dir = CTINFO2DIR(ctinfo); 183 183 int i; 184 184 u_int16_t nated_port; ··· 330 330 TransportAddress *taddr, __be16 port, 331 331 struct nf_conntrack_expect *exp) 332 332 { 333 - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; 333 + struct nf_ct_h323_master *info = nfct_help_data(ct); 334 334 int dir = CTINFO2DIR(ctinfo); 335 335 u_int16_t nated_port = ntohs(port); 336 336 ··· 419 419 unsigned char **data, TransportAddress *taddr, int idx, 420 420 __be16 port, struct nf_conntrack_expect *exp) 421 421 { 422 - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; 422 + struct nf_ct_h323_master *info = nfct_help_data(ct); 423 423 int dir = CTINFO2DIR(ctinfo); 424 424 u_int16_t nated_port = ntohs(port); 425 425 union nf_inet_addr addr;
+3 -3
net/ipv4/netfilter/nf_nat_pptp.c
··· 49 49 const struct nf_nat_pptp *nat_pptp_info; 50 50 struct nf_nat_ipv4_range range; 51 51 52 - ct_pptp_info = &nfct_help(master)->help.ct_pptp_info; 52 + ct_pptp_info = nfct_help_data(master); 53 53 nat_pptp_info = &nfct_nat(master)->help.nat_pptp_info; 54 54 55 55 /* And here goes the grand finale of corrosion... */ ··· 123 123 __be16 new_callid; 124 124 unsigned int cid_off; 125 125 126 - ct_pptp_info = &nfct_help(ct)->help.ct_pptp_info; 126 + ct_pptp_info = nfct_help_data(ct); 127 127 nat_pptp_info = &nfct_nat(ct)->help.nat_pptp_info; 128 128 129 129 new_callid = ct_pptp_info->pns_call_id; ··· 192 192 struct nf_ct_pptp_master *ct_pptp_info; 193 193 struct nf_nat_pptp *nat_pptp_info; 194 194 195 - ct_pptp_info = &nfct_help(ct)->help.ct_pptp_info; 195 + ct_pptp_info = nfct_help_data(ct); 196 196 nat_pptp_info = &nfct_nat(ct)->help.nat_pptp_info; 197 197 198 198 /* save original PAC call ID in nat_info */
+2 -2
net/ipv4/netfilter/nf_nat_tftp.c
··· 8 8 #include <linux/module.h> 9 9 #include <linux/udp.h> 10 10 11 - #include <net/netfilter/nf_nat_helper.h> 12 - #include <net/netfilter/nf_nat_rule.h> 13 11 #include <net/netfilter/nf_conntrack_helper.h> 14 12 #include <net/netfilter/nf_conntrack_expect.h> 13 + #include <net/netfilter/nf_nat_helper.h> 14 + #include <net/netfilter/nf_nat_rule.h> 15 15 #include <linux/netfilter/nf_conntrack_tftp.h> 16 16 17 17 MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>");
+2 -1
net/netfilter/nf_conntrack_core.c
··· 819 819 __set_bit(IPS_EXPECTED_BIT, &ct->status); 820 820 ct->master = exp->master; 821 821 if (exp->helper) { 822 - help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); 822 + help = nf_ct_helper_ext_add(ct, exp->helper, 823 + GFP_ATOMIC); 823 824 if (help) 824 825 rcu_assign_pointer(help->helper, exp->helper); 825 826 }
+2 -1
net/netfilter/nf_conntrack_ftp.c
··· 358 358 u32 seq; 359 359 int dir = CTINFO2DIR(ctinfo); 360 360 unsigned int uninitialized_var(matchlen), uninitialized_var(matchoff); 361 - struct nf_ct_ftp_master *ct_ftp_info = &nfct_help(ct)->help.ct_ftp_info; 361 + struct nf_ct_ftp_master *ct_ftp_info = nfct_help_data(ct); 362 362 struct nf_conntrack_expect *exp; 363 363 union nf_inet_addr *daddr; 364 364 struct nf_conntrack_man cmd = {}; ··· 554 554 ftp[i][0].tuple.src.l3num = PF_INET; 555 555 ftp[i][1].tuple.src.l3num = PF_INET6; 556 556 for (j = 0; j < 2; j++) { 557 + ftp[i][j].data_len = sizeof(struct nf_ct_ftp_master); 557 558 ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]); 558 559 ftp[i][j].tuple.dst.protonum = IPPROTO_TCP; 559 560 ftp[i][j].expect_policy = &ftp_exp_policy;
+10 -6
net/netfilter/nf_conntrack_h323_main.c
··· 114 114 struct nf_conn *ct, enum ip_conntrack_info ctinfo, 115 115 unsigned char **data, int *datalen, int *dataoff) 116 116 { 117 - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; 117 + struct nf_ct_h323_master *info = nfct_help_data(ct); 118 118 int dir = CTINFO2DIR(ctinfo); 119 119 const struct tcphdr *th; 120 120 struct tcphdr _tcph; ··· 618 618 static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = { 619 619 .name = "H.245", 620 620 .me = THIS_MODULE, 621 + .data_len = sizeof(struct nf_ct_h323_master), 621 622 .tuple.src.l3num = AF_UNSPEC, 622 623 .tuple.dst.protonum = IPPROTO_UDP, 623 624 .help = h245_help, ··· 1171 1170 { 1172 1171 .name = "Q.931", 1173 1172 .me = THIS_MODULE, 1173 + .data_len = sizeof(struct nf_ct_h323_master), 1174 1174 .tuple.src.l3num = AF_INET, 1175 1175 .tuple.src.u.tcp.port = cpu_to_be16(Q931_PORT), 1176 1176 .tuple.dst.protonum = IPPROTO_TCP, ··· 1247 1245 unsigned char **data, 1248 1246 TransportAddress *taddr, int count) 1249 1247 { 1250 - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; 1248 + struct nf_ct_h323_master *info = nfct_help_data(ct); 1251 1249 int dir = CTINFO2DIR(ctinfo); 1252 1250 int ret = 0; 1253 1251 int i; ··· 1362 1360 enum ip_conntrack_info ctinfo, 1363 1361 unsigned char **data, RegistrationRequest *rrq) 1364 1362 { 1365 - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; 1363 + struct nf_ct_h323_master *info = nfct_help_data(ct); 1366 1364 int ret; 1367 1365 typeof(set_ras_addr_hook) set_ras_addr; 1368 1366 ··· 1397 1395 enum ip_conntrack_info ctinfo, 1398 1396 unsigned char **data, RegistrationConfirm *rcf) 1399 1397 { 1400 - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; 1398 + struct nf_ct_h323_master *info = nfct_help_data(ct); 1401 1399 int dir = CTINFO2DIR(ctinfo); 1402 1400 int ret; 1403 1401 struct nf_conntrack_expect *exp; ··· 1446 1444 enum ip_conntrack_info ctinfo, 1447 1445 unsigned char **data, UnregistrationRequest *urq) 1448 1446 { 1449 - struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; 1447 + struct nf_ct_h323_master *info = nfct_help_data(ct); 1450 1448 int dir = CTINFO2DIR(ctinfo); 1451 1449 int ret; 1452 1450 typeof(set_sig_addr_hook) set_sig_addr; ··· 1478 1476 enum ip_conntrack_info ctinfo, 1479 1477 unsigned char **data, AdmissionRequest *arq) 1480 1478 { 1481 - const struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info; 1479 + const struct nf_ct_h323_master *info = nfct_help_data(ct); 1482 1480 int dir = CTINFO2DIR(ctinfo); 1483 1481 __be16 port; 1484 1482 union nf_inet_addr addr; ··· 1745 1743 { 1746 1744 .name = "RAS", 1747 1745 .me = THIS_MODULE, 1746 + .data_len = sizeof(struct nf_ct_h323_master), 1748 1747 .tuple.src.l3num = AF_INET, 1749 1748 .tuple.src.u.udp.port = cpu_to_be16(RAS_PORT), 1750 1749 .tuple.dst.protonum = IPPROTO_UDP, ··· 1755 1752 { 1756 1753 .name = "RAS", 1757 1754 .me = THIS_MODULE, 1755 + .data_len = sizeof(struct nf_ct_h323_master), 1758 1756 .tuple.src.l3num = AF_INET6, 1759 1757 .tuple.src.u.udp.port = cpu_to_be16(RAS_PORT), 1760 1758 .tuple.dst.protonum = IPPROTO_UDP,
+7 -4
net/netfilter/nf_conntrack_helper.c
··· 161 161 } 162 162 EXPORT_SYMBOL_GPL(nf_conntrack_helper_try_module_get); 163 163 164 - struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp) 164 + struct nf_conn_help * 165 + nf_ct_helper_ext_add(struct nf_conn *ct, 166 + struct nf_conntrack_helper *helper, gfp_t gfp) 165 167 { 166 168 struct nf_conn_help *help; 167 169 168 - help = nf_ct_ext_add(ct, NF_CT_EXT_HELPER, gfp); 170 + help = nf_ct_ext_add_length(ct, NF_CT_EXT_HELPER, 171 + helper->data_len, gfp); 169 172 if (help) 170 173 INIT_HLIST_HEAD(&help->expectations); 171 174 else ··· 221 218 } 222 219 223 220 if (help == NULL) { 224 - help = nf_ct_helper_ext_add(ct, flags); 221 + help = nf_ct_helper_ext_add(ct, helper, flags); 225 222 if (help == NULL) { 226 223 ret = -ENOMEM; 227 224 goto out; 228 225 } 229 226 } else { 230 - memset(&help->help, 0, sizeof(help->help)); 227 + memset(help->data, 0, helper->data_len); 231 228 } 232 229 233 230 rcu_assign_pointer(help->helper, helper);
+2 -2
net/netfilter/nf_conntrack_netlink.c
··· 1218 1218 if (help->helper) 1219 1219 return -EBUSY; 1220 1220 /* need to zero data of old helper */ 1221 - memset(&help->help, 0, sizeof(help->help)); 1221 + memset(help->data, 0, help->helper->data_len); 1222 1222 } else { 1223 1223 /* we cannot set a helper for an existing conntrack */ 1224 1224 return -EOPNOTSUPP; ··· 1440 1440 } else { 1441 1441 struct nf_conn_help *help; 1442 1442 1443 - help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); 1443 + help = nf_ct_helper_ext_add(ct, helper, GFP_ATOMIC); 1444 1444 if (help == NULL) { 1445 1445 err = -ENOMEM; 1446 1446 goto err2;
+9 -8
net/netfilter/nf_conntrack_pptp.c
··· 174 174 static void pptp_destroy_siblings(struct nf_conn *ct) 175 175 { 176 176 struct net *net = nf_ct_net(ct); 177 - const struct nf_conn_help *help = nfct_help(ct); 177 + const struct nf_ct_pptp_master *ct_pptp_info = nfct_help_data(ct); 178 178 struct nf_conntrack_tuple t; 179 179 180 180 nf_ct_gre_keymap_destroy(ct); ··· 182 182 /* try original (pns->pac) tuple */ 183 183 memcpy(&t, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, sizeof(t)); 184 184 t.dst.protonum = IPPROTO_GRE; 185 - t.src.u.gre.key = help->help.ct_pptp_info.pns_call_id; 186 - t.dst.u.gre.key = help->help.ct_pptp_info.pac_call_id; 185 + t.src.u.gre.key = ct_pptp_info->pns_call_id; 186 + t.dst.u.gre.key = ct_pptp_info->pac_call_id; 187 187 if (!destroy_sibling_or_exp(net, ct, &t)) 188 188 pr_debug("failed to timeout original pns->pac ct/exp\n"); 189 189 190 190 /* try reply (pac->pns) tuple */ 191 191 memcpy(&t, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, sizeof(t)); 192 192 t.dst.protonum = IPPROTO_GRE; 193 - t.src.u.gre.key = help->help.ct_pptp_info.pac_call_id; 194 - t.dst.u.gre.key = help->help.ct_pptp_info.pns_call_id; 193 + t.src.u.gre.key = ct_pptp_info->pac_call_id; 194 + t.dst.u.gre.key = ct_pptp_info->pns_call_id; 195 195 if (!destroy_sibling_or_exp(net, ct, &t)) 196 196 pr_debug("failed to timeout reply pac->pns ct/exp\n"); 197 197 } ··· 269 269 struct nf_conn *ct, 270 270 enum ip_conntrack_info ctinfo) 271 271 { 272 - struct nf_ct_pptp_master *info = &nfct_help(ct)->help.ct_pptp_info; 272 + struct nf_ct_pptp_master *info = nfct_help_data(ct); 273 273 u_int16_t msg; 274 274 __be16 cid = 0, pcid = 0; 275 275 typeof(nf_nat_pptp_hook_inbound) nf_nat_pptp_inbound; ··· 396 396 struct nf_conn *ct, 397 397 enum ip_conntrack_info ctinfo) 398 398 { 399 - struct nf_ct_pptp_master *info = &nfct_help(ct)->help.ct_pptp_info; 399 + struct nf_ct_pptp_master *info = nfct_help_data(ct); 400 400 u_int16_t msg; 401 401 __be16 cid = 0, pcid = 0; 402 402 typeof(nf_nat_pptp_hook_outbound) nf_nat_pptp_outbound; ··· 506 506 507 507 { 508 508 int dir = CTINFO2DIR(ctinfo); 509 - const struct nf_ct_pptp_master *info = &nfct_help(ct)->help.ct_pptp_info; 509 + const struct nf_ct_pptp_master *info = nfct_help_data(ct); 510 510 const struct tcphdr *tcph; 511 511 struct tcphdr _tcph; 512 512 const struct pptp_pkt_hdr *pptph; ··· 592 592 static struct nf_conntrack_helper pptp __read_mostly = { 593 593 .name = "pptp", 594 594 .me = THIS_MODULE, 595 + .data_len = sizeof(struct nf_ct_pptp_master), 595 596 .tuple.src.l3num = AF_INET, 596 597 .tuple.src.u.tcp.port = cpu_to_be16(PPTP_CONTROL_PORT), 597 598 .tuple.dst.protonum = IPPROTO_TCP,
+8 -8
net/netfilter/nf_conntrack_proto_gre.c
··· 117 117 { 118 118 struct net *net = nf_ct_net(ct); 119 119 struct netns_proto_gre *net_gre = gre_pernet(net); 120 - struct nf_conn_help *help = nfct_help(ct); 120 + struct nf_ct_pptp_master *ct_pptp_info = nfct_help_data(ct); 121 121 struct nf_ct_gre_keymap **kmp, *km; 122 122 123 - kmp = &help->help.ct_pptp_info.keymap[dir]; 123 + kmp = &ct_pptp_info->keymap[dir]; 124 124 if (*kmp) { 125 125 /* check whether it's a retransmission */ 126 126 read_lock_bh(&net_gre->keymap_lock); ··· 158 158 { 159 159 struct net *net = nf_ct_net(ct); 160 160 struct netns_proto_gre *net_gre = gre_pernet(net); 161 - struct nf_conn_help *help = nfct_help(ct); 161 + struct nf_ct_pptp_master *ct_pptp_info = nfct_help_data(ct); 162 162 enum ip_conntrack_dir dir; 163 163 164 164 pr_debug("entering for ct %p\n", ct); 165 165 166 166 write_lock_bh(&net_gre->keymap_lock); 167 167 for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) { 168 - if (help->help.ct_pptp_info.keymap[dir]) { 168 + if (ct_pptp_info->keymap[dir]) { 169 169 pr_debug("removing %p from list\n", 170 - help->help.ct_pptp_info.keymap[dir]); 171 - list_del(&help->help.ct_pptp_info.keymap[dir]->list); 172 - kfree(help->help.ct_pptp_info.keymap[dir]); 173 - help->help.ct_pptp_info.keymap[dir] = NULL; 170 + ct_pptp_info->keymap[dir]); 171 + list_del(&ct_pptp_info->keymap[dir]->list); 172 + kfree(ct_pptp_info->keymap[dir]); 173 + ct_pptp_info->keymap[dir] = NULL; 174 174 } 175 175 } 176 176 write_unlock_bh(&net_gre->keymap_lock);
+2 -2
net/netfilter/nf_conntrack_sane.c
··· 69 69 void *sb_ptr; 70 70 int ret = NF_ACCEPT; 71 71 int dir = CTINFO2DIR(ctinfo); 72 - struct nf_ct_sane_master *ct_sane_info; 72 + struct nf_ct_sane_master *ct_sane_info = nfct_help_data(ct); 73 73 struct nf_conntrack_expect *exp; 74 74 struct nf_conntrack_tuple *tuple; 75 75 struct sane_request *req; 76 76 struct sane_reply_net_start *reply; 77 77 78 - ct_sane_info = &nfct_help(ct)->help.ct_sane_info; 79 78 /* Until there's been traffic both ways, don't look in packets. */ 80 79 if (ctinfo != IP_CT_ESTABLISHED && 81 80 ctinfo != IP_CT_ESTABLISHED_REPLY) ··· 202 203 sane[i][0].tuple.src.l3num = PF_INET; 203 204 sane[i][1].tuple.src.l3num = PF_INET6; 204 205 for (j = 0; j < 2; j++) { 206 + sane[i][j].data_len = sizeof(struct nf_ct_sane_master); 205 207 sane[i][j].tuple.src.u.tcp.port = htons(ports[i]); 206 208 sane[i][j].tuple.dst.protonum = IPPROTO_TCP; 207 209 sane[i][j].expect_policy = &sane_exp_policy;
+13 -12
net/netfilter/nf_conntrack_sip.c
··· 1075 1075 { 1076 1076 enum ip_conntrack_info ctinfo; 1077 1077 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1078 - struct nf_conn_help *help = nfct_help(ct); 1078 + struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct); 1079 1079 1080 1080 if ((code >= 100 && code <= 199) || 1081 1081 (code >= 200 && code <= 299)) 1082 1082 return process_sdp(skb, dataoff, dptr, datalen, cseq); 1083 - else if (help->help.ct_sip_info.invite_cseq == cseq) 1083 + else if (ct_sip_info->invite_cseq == cseq) 1084 1084 flush_expectations(ct, true); 1085 1085 return NF_ACCEPT; 1086 1086 } ··· 1091 1091 { 1092 1092 enum ip_conntrack_info ctinfo; 1093 1093 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1094 - struct nf_conn_help *help = nfct_help(ct); 1094 + struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct); 1095 1095 1096 1096 if ((code >= 100 && code <= 199) || 1097 1097 (code >= 200 && code <= 299)) 1098 1098 return process_sdp(skb, dataoff, dptr, datalen, cseq); 1099 - else if (help->help.ct_sip_info.invite_cseq == cseq) 1099 + else if (ct_sip_info->invite_cseq == cseq) 1100 1100 flush_expectations(ct, true); 1101 1101 return NF_ACCEPT; 1102 1102 } ··· 1107 1107 { 1108 1108 enum ip_conntrack_info ctinfo; 1109 1109 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1110 - struct nf_conn_help *help = nfct_help(ct); 1110 + struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct); 1111 1111 1112 1112 if ((code >= 100 && code <= 199) || 1113 1113 (code >= 200 && code <= 299)) 1114 1114 return process_sdp(skb, dataoff, dptr, datalen, cseq); 1115 - else if (help->help.ct_sip_info.invite_cseq == cseq) 1115 + else if (ct_sip_info->invite_cseq == cseq) 1116 1116 flush_expectations(ct, true); 1117 1117 return NF_ACCEPT; 1118 1118 } ··· 1123 1123 { 1124 1124 enum ip_conntrack_info ctinfo; 1125 1125 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1126 - struct nf_conn_help *help = nfct_help(ct); 1126 + struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct); 1127 1127 unsigned int ret; 1128 1128 1129 1129 flush_expectations(ct, true); 1130 1130 ret = process_sdp(skb, dataoff, dptr, datalen, cseq); 1131 1131 if (ret == NF_ACCEPT) 1132 - help->help.ct_sip_info.invite_cseq = cseq; 1132 + ct_sip_info->invite_cseq = cseq; 1133 1133 return ret; 1134 1134 } 1135 1135 ··· 1154 1154 { 1155 1155 enum ip_conntrack_info ctinfo; 1156 1156 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1157 - struct nf_conn_help *help = nfct_help(ct); 1157 + struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct); 1158 1158 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 1159 1159 unsigned int matchoff, matchlen; 1160 1160 struct nf_conntrack_expect *exp; ··· 1235 1235 1236 1236 store_cseq: 1237 1237 if (ret == NF_ACCEPT) 1238 - help->help.ct_sip_info.register_cseq = cseq; 1238 + ct_sip_info->register_cseq = cseq; 1239 1239 return ret; 1240 1240 } 1241 1241 ··· 1245 1245 { 1246 1246 enum ip_conntrack_info ctinfo; 1247 1247 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1248 - struct nf_conn_help *help = nfct_help(ct); 1248 + struct nf_ct_sip_master *ct_sip_info = nfct_help_data(ct); 1249 1249 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 1250 1250 union nf_inet_addr addr; 1251 1251 __be16 port; ··· 1262 1262 * responses, so we store the sequence number of the last valid 1263 1263 * request and compare it here. 1264 1264 */ 1265 - if (help->help.ct_sip_info.register_cseq != cseq) 1265 + if (ct_sip_info->register_cseq != cseq) 1266 1266 return NF_ACCEPT; 1267 1267 1268 1268 if (code >= 100 && code <= 199) ··· 1578 1578 sip[i][3].help = sip_help_tcp; 1579 1579 1580 1580 for (j = 0; j < ARRAY_SIZE(sip[i]); j++) { 1581 + sip[i][j].data_len = sizeof(struct nf_ct_sip_master); 1581 1582 sip[i][j].tuple.src.u.udp.port = htons(ports[i]); 1582 1583 sip[i][j].expect_policy = sip_exp_policy; 1583 1584 sip[i][j].expect_class_max = SIP_EXPECT_MAX;
+26 -18
net/netfilter/xt_CT.c
··· 112 112 goto err3; 113 113 114 114 if (info->helper[0]) { 115 + struct nf_conntrack_helper *helper; 116 + 115 117 ret = -ENOENT; 116 118 proto = xt_ct_find_proto(par); 117 119 if (!proto) { ··· 122 120 goto err3; 123 121 } 124 122 125 - ret = -ENOMEM; 126 - help = nf_ct_helper_ext_add(ct, GFP_KERNEL); 127 - if (help == NULL) 128 - goto err3; 129 - 130 123 ret = -ENOENT; 131 - help->helper = nf_conntrack_helper_try_module_get(info->helper, 132 - par->family, 133 - proto); 134 - if (help->helper == NULL) { 124 + helper = nf_conntrack_helper_try_module_get(info->helper, 125 + par->family, 126 + proto); 127 + if (helper == NULL) { 135 128 pr_info("No such helper \"%s\"\n", info->helper); 136 129 goto err3; 137 130 } 131 + 132 + ret = -ENOMEM; 133 + help = nf_ct_helper_ext_add(ct, helper, GFP_KERNEL); 134 + if (help == NULL) 135 + goto err3; 136 + 137 + help->helper = helper; 138 138 } 139 139 140 140 __set_bit(IPS_TEMPLATE_BIT, &ct->status); ··· 206 202 goto err3; 207 203 208 204 if (info->helper[0]) { 205 + struct nf_conntrack_helper *helper; 206 + 209 207 ret = -ENOENT; 210 208 proto = xt_ct_find_proto(par); 211 209 if (!proto) { ··· 216 210 goto err3; 217 211 } 218 212 219 - ret = -ENOMEM; 220 - help = nf_ct_helper_ext_add(ct, GFP_KERNEL); 221 - if (help == NULL) 222 - goto err3; 223 - 224 213 ret = -ENOENT; 225 - help->helper = nf_conntrack_helper_try_module_get(info->helper, 226 - par->family, 227 - proto); 228 - if (help->helper == NULL) { 214 + helper = nf_conntrack_helper_try_module_get(info->helper, 215 + par->family, 216 + proto); 217 + if (helper == NULL) { 229 218 pr_info("No such helper \"%s\"\n", info->helper); 230 219 goto err3; 231 220 } 221 + 222 + ret = -ENOMEM; 223 + help = nf_ct_helper_ext_add(ct, helper, GFP_KERNEL); 224 + if (help == NULL) 225 + goto err3; 226 + 227 + help->helper = helper; 232 228 } 233 229 234 230 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT