From 00b071447e8515511138000faad0ff4465d7dbde Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Wed, 7 Sep 2005 16:00:26 -0700 Subject: [PATCH] --- yaml --- r: 16247 b: refs/heads/master c: 37f779554404ddca981ac4b4cc6692fc09b71e96 h: refs/heads/master i: 16245: 2241e99d69e85ed64e9916925cac31381899ea6f 16243: fd378b75d642553a627a7c562c2e33cd93d92fbe 16239: e27416cb83968fed4783110b31b6eacb53b26d99 v: v3 --- [refs] | 2 +- trunk/arch/ia64/kernel/setup.c | 2 +- trunk/arch/ia64/pci/pci.c | 2 +- trunk/drivers/pcmcia/cistpl.c | 6 +- trunk/drivers/video/aty/atyfb_base.c | 2 +- .../linux/netfilter/nfnetlink_conntrack.h | 5 +- .../include/linux/netfilter_ipv6/ip6_tables.h | 6 +- trunk/include/net/ip.h | 1 + trunk/include/net/netfilter/nf_conntrack.h | 31 - .../net/netfilter/nf_conntrack_helper.h | 2 - .../net/netfilter/nf_conntrack_l3proto.h | 15 +- .../net/netfilter/nf_conntrack_protocol.h | 26 +- trunk/net/ipv4/ip_output.c | 30 +- trunk/net/ipv4/ipvs/ip_vs_core.c | 5 +- trunk/net/ipv4/ipvs/ip_vs_est.c | 1 - trunk/net/ipv4/ipvs/ip_vs_sched.c | 1 - .../net/ipv4/netfilter/ip_conntrack_amanda.c | 2 +- trunk/net/ipv4/netfilter/ip_conntrack_ftp.c | 2 +- trunk/net/ipv4/netfilter/ip_conntrack_irc.c | 10 +- .../ipv4/netfilter/ip_conntrack_netbios_ns.c | 2 +- .../net/ipv4/netfilter/ip_conntrack_netlink.c | 36 +- .../ipv4/netfilter/ip_conntrack_proto_icmp.c | 47 +- .../ipv4/netfilter/ip_conntrack_standalone.c | 26 +- trunk/net/ipv4/netfilter/ip_nat_standalone.c | 17 + trunk/net/ipv4/netfilter/ipt_REJECT.c | 2 +- trunk/net/ipv4/netfilter/ipt_ULOG.c | 10 +- trunk/net/ipv4/netfilter/ipt_recent.c | 20 +- .../netfilter/nf_conntrack_l3proto_ipv4.c | 74 +- .../ipv4/netfilter/nf_conntrack_proto_icmp.c | 97 +- trunk/net/ipv6/netfilter/ip6_tables.c | 124 +- trunk/net/ipv6/netfilter/ip6t_ah.c | 2 +- trunk/net/ipv6/netfilter/ip6t_dst.c | 4 +- trunk/net/ipv6/netfilter/ip6t_esp.c | 2 +- trunk/net/ipv6/netfilter/ip6t_frag.c | 2 +- trunk/net/ipv6/netfilter/ip6t_hbh.c | 4 +- trunk/net/ipv6/netfilter/ip6t_rt.c | 2 +- .../netfilter/nf_conntrack_l3proto_ipv6.c | 47 - .../netfilter/nf_conntrack_proto_icmpv6.c | 77 +- trunk/net/netfilter/Kconfig | 7 - trunk/net/netfilter/Makefile | 3 - trunk/net/netfilter/nf_conntrack_core.c | 239 +-- trunk/net/netfilter/nf_conntrack_ftp.c | 2 +- trunk/net/netfilter/nf_conntrack_netlink.c | 1653 ----------------- trunk/net/netfilter/nf_conntrack_proto_tcp.c | 71 - trunk/net/netfilter/nf_conntrack_proto_udp.c | 10 - trunk/net/netfilter/nf_conntrack_standalone.c | 42 +- trunk/net/netfilter/nfnetlink_queue.c | 79 +- 47 files changed, 353 insertions(+), 2499 deletions(-) delete mode 100644 trunk/net/netfilter/nf_conntrack_netlink.c diff --git a/[refs] b/[refs] index ac72613ebe1c..f8f7a1518496 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: fbd91ac22229fdb89f0dd2eaa11dd663f2ba1a92 +refs/heads/master: 37f779554404ddca981ac4b4cc6692fc09b71e96 diff --git a/trunk/arch/ia64/kernel/setup.c b/trunk/arch/ia64/kernel/setup.c index c33305d8e5eb..088e5dded8dc 100644 --- a/trunk/arch/ia64/kernel/setup.c +++ b/trunk/arch/ia64/kernel/setup.c @@ -518,7 +518,7 @@ show_cpuinfo (struct seq_file *m, void *v) char family[32], features[128], *cp, sep; struct cpuinfo_ia64 *c = v; unsigned long mask; - unsigned long proc_freq; + unsigned int proc_freq; int i; mask = c->features; diff --git a/trunk/arch/ia64/pci/pci.c b/trunk/arch/ia64/pci/pci.c index 30dbc98bf0b3..20d76fae24e8 100644 --- a/trunk/arch/ia64/pci/pci.c +++ b/trunk/arch/ia64/pci/pci.c @@ -700,7 +700,7 @@ int ia64_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size) */ int ia64_pci_legacy_write(struct pci_dev *bus, u16 port, u32 val, u8 size) { - int ret = size; + int ret = 0; switch (size) { case 1: diff --git a/trunk/drivers/pcmcia/cistpl.c b/trunk/drivers/pcmcia/cistpl.c index 2dc3e611a9a3..55d7247b58e7 100644 --- a/trunk/drivers/pcmcia/cistpl.c +++ b/trunk/drivers/pcmcia/cistpl.c @@ -60,9 +60,9 @@ static const u_int exponent[] = { /* Parameters that can be set with 'insmod' */ -#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) - -INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */ +/* 16-bit CIS? */ +static int cis_width; +module_param(cis_width, int, 0444); void release_cis_mem(struct pcmcia_socket *s) { diff --git a/trunk/drivers/video/aty/atyfb_base.c b/trunk/drivers/video/aty/atyfb_base.c index 3fefdb0cbf07..08edbfcfca58 100644 --- a/trunk/drivers/video/aty/atyfb_base.c +++ b/trunk/drivers/video/aty/atyfb_base.c @@ -403,7 +403,7 @@ static struct { { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP)", 230, 83, 63, ATI_CHIP_264XL }, { PCI_CHIP_MACH64GN, "3D RAGE XL (Mach64 GN, AGP)", 230, 83, 63, ATI_CHIP_264XL }, { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66/BGA)", 230, 83, 63, ATI_CHIP_264XL }, - { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 235, 83, 63, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL }, + { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 230, 83, 63, ATI_CHIP_264XL }, { PCI_CHIP_MACH64GL, "3D RAGE XL (Mach64 GL, PCI)", 230, 83, 63, ATI_CHIP_264XL }, { PCI_CHIP_MACH64GS, "3D RAGE XL (Mach64 GS, PCI)", 230, 83, 63, ATI_CHIP_264XL }, diff --git a/trunk/include/linux/netfilter/nfnetlink_conntrack.h b/trunk/include/linux/netfilter/nfnetlink_conntrack.h index 668ec946c8e2..116fcaced909 100644 --- a/trunk/include/linux/netfilter/nfnetlink_conntrack.h +++ b/trunk/include/linux/netfilter/nfnetlink_conntrack.h @@ -64,9 +64,6 @@ enum ctattr_l4proto { CTA_PROTO_ICMP_ID, CTA_PROTO_ICMP_TYPE, CTA_PROTO_ICMP_CODE, - CTA_PROTO_ICMPV6_ID, - CTA_PROTO_ICMPV6_TYPE, - CTA_PROTO_ICMPV6_CODE, __CTA_PROTO_MAX }; #define CTA_PROTO_MAX (__CTA_PROTO_MAX - 1) @@ -131,4 +128,6 @@ enum ctattr_help { }; #define CTA_HELP_MAX (__CTA_HELP_MAX - 1) +#define CTA_HELP_MAXNAMESIZE 32 + #endif /* _IPCONNTRACK_NETLINK_H */ diff --git a/trunk/include/linux/netfilter_ipv6/ip6_tables.h b/trunk/include/linux/netfilter_ipv6/ip6_tables.h index c163ba31aab7..2efc046d9e94 100644 --- a/trunk/include/linux/netfilter_ipv6/ip6_tables.h +++ b/trunk/include/linux/netfilter_ipv6/ip6_tables.h @@ -474,11 +474,7 @@ extern unsigned int ip6t_do_table(struct sk_buff **pskb, extern int ip6t_ext_hdr(u8 nexthdr); /* find specified header and get offset to it */ extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, - int target, unsigned short *fragoff); - -extern int ip6_masked_addrcmp(const struct in6_addr *addr1, - const struct in6_addr *mask, - const struct in6_addr *addr2); + u8 target); #define IP6T_ALIGN(s) (((s) + (__alignof__(struct ip6t_entry)-1)) & ~(__alignof__(struct ip6t_entry)-1)) diff --git a/trunk/include/net/ip.h b/trunk/include/net/ip.h index 7bb5804847f2..f7e7fd728b67 100644 --- a/trunk/include/net/ip.h +++ b/trunk/include/net/ip.h @@ -317,6 +317,7 @@ enum ip_defrag_users IP_DEFRAG_CALL_RA_CHAIN, IP_DEFRAG_CONNTRACK_IN, IP_DEFRAG_CONNTRACK_OUT, + IP_DEFRAG_NAT_OUT, IP_DEFRAG_VS_IN, IP_DEFRAG_VS_OUT, IP_DEFRAG_VS_FWD diff --git a/trunk/include/net/netfilter/nf_conntrack.h b/trunk/include/net/netfilter/nf_conntrack.h index 64b82b74a650..cc4825610795 100644 --- a/trunk/include/net/netfilter/nf_conntrack.h +++ b/trunk/include/net/netfilter/nf_conntrack.h @@ -94,9 +94,6 @@ struct nf_conn /* Current number of expected connections */ unsigned int expecting; - /* Unique ID that identifies this conntrack*/ - unsigned int id; - /* Helper. if any */ struct nf_conntrack_helper *helper; @@ -143,9 +140,6 @@ struct nf_conntrack_expect /* Usage count. */ atomic_t use; - /* Unique ID */ - unsigned int id; - /* Flags */ unsigned int flags; @@ -196,31 +190,6 @@ static inline void nf_ct_put(struct nf_conn *ct) nf_conntrack_put(&ct->ct_general); } -extern struct nf_conntrack_tuple_hash * -__nf_conntrack_find(const struct nf_conntrack_tuple *tuple, - const struct nf_conn *ignored_conntrack); - -extern void nf_conntrack_hash_insert(struct nf_conn *ct); - -extern struct nf_conntrack_expect * -__nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple); - -extern struct nf_conntrack_expect * -nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple); - -extern void nf_ct_unlink_expect(struct nf_conntrack_expect *exp); - -extern void nf_ct_remove_expectations(struct nf_conn *ct); - -extern void nf_conntrack_flush(void); - -extern struct nf_conntrack_helper * -nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple); -extern void nf_ct_helper_put(struct nf_conntrack_helper *helper); - -extern struct nf_conntrack_helper * -__nf_conntrack_helper_find_byname(const char *name); - /* call to create an explicit dependency on nf_conntrack. */ extern void need_nf_conntrack(void); diff --git a/trunk/include/net/netfilter/nf_conntrack_helper.h b/trunk/include/net/netfilter/nf_conntrack_helper.h index 86ec8174ad02..5a66b2a3a623 100644 --- a/trunk/include/net/netfilter/nf_conntrack_helper.h +++ b/trunk/include/net/netfilter/nf_conntrack_helper.h @@ -33,8 +33,6 @@ struct nf_conntrack_helper unsigned int protoff, struct nf_conn *ct, enum ip_conntrack_info conntrackinfo); - - int (*to_nfattr)(struct sk_buff *skb, const struct nf_conn *ct); }; extern int nf_conntrack_helper_register(struct nf_conntrack_helper *); diff --git a/trunk/include/net/netfilter/nf_conntrack_l3proto.h b/trunk/include/net/netfilter/nf_conntrack_l3proto.h index 67856eb93b43..01663e5b33df 100644 --- a/trunk/include/net/netfilter/nf_conntrack_l3proto.h +++ b/trunk/include/net/netfilter/nf_conntrack_l3proto.h @@ -14,8 +14,6 @@ #include #include -struct nfattr; - struct nf_conntrack_l3proto { /* Next pointer. */ @@ -72,12 +70,6 @@ struct nf_conntrack_l3proto u_int32_t (*get_features)(const struct nf_conntrack_tuple *tuple); - int (*tuple_to_nfattr)(struct sk_buff *skb, - const struct nf_conntrack_tuple *t); - - int (*nfattr_to_tuple)(struct nfattr *tb[], - struct nf_conntrack_tuple *t); - /* Module (if any) which this is connected to. */ struct module *me; }; @@ -89,16 +81,11 @@ extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto); extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto); static inline struct nf_conntrack_l3proto * -__nf_ct_l3proto_find(u_int16_t l3proto) +nf_ct_find_l3proto(u_int16_t l3proto) { return nf_ct_l3protos[l3proto]; } -extern struct nf_conntrack_l3proto * -nf_ct_l3proto_find_get(u_int16_t l3proto); - -extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p); - /* Existing built-in protocols */ extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4; extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6; diff --git a/trunk/include/net/netfilter/nf_conntrack_protocol.h b/trunk/include/net/netfilter/nf_conntrack_protocol.h index 1f33737fcea5..b3afda35397a 100644 --- a/trunk/include/net/netfilter/nf_conntrack_protocol.h +++ b/trunk/include/net/netfilter/nf_conntrack_protocol.h @@ -12,7 +12,6 @@ #include struct seq_file; -struct nfattr; struct nf_conntrack_protocol { @@ -67,18 +66,6 @@ struct nf_conntrack_protocol enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum); - /* convert protoinfo to nfnetink attributes */ - int (*to_nfattr)(struct sk_buff *skb, struct nfattr *nfa, - const struct nf_conn *ct); - - /* convert nfnetlink attributes to protoinfo */ - int (*from_nfattr)(struct nfattr *tb[], struct nf_conn *ct); - - int (*tuple_to_nfattr)(struct sk_buff *skb, - const struct nf_conntrack_tuple *t); - int (*nfattr_to_tuple)(struct nfattr *tb[], - struct nf_conntrack_tuple *t); - /* Module (if any) which this is connected to. */ struct module *me; }; @@ -93,23 +80,12 @@ extern struct nf_conntrack_protocol nf_conntrack_generic_protocol; extern struct nf_conntrack_protocol **nf_ct_protos[PF_MAX]; extern struct nf_conntrack_protocol * -__nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol); - -extern struct nf_conntrack_protocol * -nf_ct_proto_find_get(u_int16_t l3proto, u_int8_t protocol); - -extern void nf_ct_proto_put(struct nf_conntrack_protocol *p); +nf_ct_find_proto(u_int16_t l3proto, u_int8_t protocol); /* Protocol registration. */ extern int nf_conntrack_protocol_register(struct nf_conntrack_protocol *proto); extern void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto); -/* Generic netlink helpers */ -extern int nf_ct_port_tuple_to_nfattr(struct sk_buff *skb, - const struct nf_conntrack_tuple *tuple); -extern int nf_ct_port_nfattr_to_tuple(struct nfattr *tb[], - struct nf_conntrack_tuple *t); - /* Log invalid packets */ extern unsigned int nf_ct_log_invalid; diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index 71da31818cfc..2a830de3a699 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -202,11 +202,13 @@ static inline int ip_finish_output2(struct sk_buff *skb) static inline int ip_finish_output(struct sk_buff *skb) { - if (skb->len > dst_mtu(skb->dst) && - !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) - return ip_fragment(skb, ip_finish_output2); - else - return ip_finish_output2(skb); + struct net_device *dev = skb->dst->dev; + + skb->dev = dev; + skb->protocol = htons(ETH_P_IP); + + return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, + ip_finish_output2); } int ip_mc_output(struct sk_buff *skb) @@ -263,21 +265,21 @@ int ip_mc_output(struct sk_buff *skb) newskb->dev, ip_dev_loopback_xmit); } - return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev, - ip_finish_output); + if (skb->len > dst_mtu(&rt->u.dst)) + return ip_fragment(skb, ip_finish_output); + else + return ip_finish_output(skb); } int ip_output(struct sk_buff *skb) { - struct net_device *dev = skb->dst->dev; - IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS); - skb->dev = dev; - skb->protocol = htons(ETH_P_IP); - - return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, - ip_finish_output); + if (skb->len > dst_mtu(skb->dst) && + !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) + return ip_fragment(skb, ip_finish_output); + else + return ip_finish_output(skb); } int ip_queue_xmit(struct sk_buff *skb, int ipfragok) diff --git a/trunk/net/ipv4/ipvs/ip_vs_core.c b/trunk/net/ipv4/ipvs/ip_vs_core.c index 3f47ad8e1cad..1aca94a9fd8b 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_core.c +++ b/trunk/net/ipv4/ipvs/ip_vs_core.c @@ -532,8 +532,11 @@ static unsigned int ip_vs_post_routing(unsigned int hooknum, { if (!((*pskb)->ipvs_property)) return NF_ACCEPT; + /* The packet was sent from IPVS, exit this chain */ - return NF_STOP; + (*okfn)(*pskb); + + return NF_STOLEN; } u16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) diff --git a/trunk/net/ipv4/ipvs/ip_vs_est.c b/trunk/net/ipv4/ipvs/ip_vs_est.c index c453e1e57f4b..e7004741ac73 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_est.c +++ b/trunk/net/ipv4/ipvs/ip_vs_est.c @@ -18,7 +18,6 @@ #include #include #include -#include #include diff --git a/trunk/net/ipv4/ipvs/ip_vs_sched.c b/trunk/net/ipv4/ipvs/ip_vs_sched.c index 8bc42b76223d..0f7c56a225bd 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_sched.c +++ b/trunk/net/ipv4/ipvs/ip_vs_sched.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_amanda.c b/trunk/net/ipv4/netfilter/ip_conntrack_amanda.c index 84e4f79b7ffa..0366eedb4d70 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_amanda.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_amanda.c @@ -36,7 +36,7 @@ static unsigned int master_timeout = 300; MODULE_AUTHOR("Brian J. Murrell "); MODULE_DESCRIPTION("Amanda connection tracking module"); MODULE_LICENSE("GPL"); -module_param(master_timeout, uint, 0600); +module_param(master_timeout, int, 0600); MODULE_PARM_DESC(master_timeout, "timeout for the master connection"); static const char *conns[] = { "DATA ", "MESG ", "INDEX " }; diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_ftp.c b/trunk/net/ipv4/netfilter/ip_conntrack_ftp.c index e627e5856172..68b173bcda60 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_ftp.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_ftp.c @@ -34,7 +34,7 @@ static int ports_c; module_param_array(ports, ushort, &ports_c, 0400); static int loose; -module_param(loose, bool, 0600); +module_param(loose, int, 0600); unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb, enum ip_conntrack_info ctinfo, diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_irc.c b/trunk/net/ipv4/netfilter/ip_conntrack_irc.c index c51a2cf71b4b..d7c40421d0d1 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_irc.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_irc.c @@ -36,7 +36,7 @@ #define MAX_PORTS 8 static unsigned short ports[MAX_PORTS]; static int ports_c; -static unsigned int max_dcc_channels = 8; +static int max_dcc_channels = 8; static unsigned int dcc_timeout = 300; /* This is slow, but it's simple. --RR */ static char *irc_buffer; @@ -54,9 +54,9 @@ MODULE_DESCRIPTION("IRC (DCC) connection tracking helper"); MODULE_LICENSE("GPL"); module_param_array(ports, ushort, &ports_c, 0400); MODULE_PARM_DESC(ports, "port numbers of IRC servers"); -module_param(max_dcc_channels, uint, 0400); +module_param(max_dcc_channels, int, 0400); MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session"); -module_param(dcc_timeout, uint, 0400); +module_param(dcc_timeout, int, 0400); MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels"); static const char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " }; @@ -254,6 +254,10 @@ static int __init init(void) printk("ip_conntrack_irc: max_dcc_channels must be a positive integer\n"); return -EBUSY; } + if (dcc_timeout < 0) { + printk("ip_conntrack_irc: dcc_timeout must be a positive integer\n"); + return -EBUSY; + } irc_buffer = kmalloc(65536, GFP_KERNEL); if (!irc_buffer) diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/trunk/net/ipv4/netfilter/ip_conntrack_netbios_ns.c index 4e68e16a2612..186646eb249f 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_netbios_ns.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_netbios_ns.c @@ -37,7 +37,7 @@ MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper"); MODULE_LICENSE("GPL"); static unsigned int timeout = 3; -module_param(timeout, uint, 0400); +module_param(timeout, int, 0600); MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds"); static int help(struct sk_buff **pskb, diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_netlink.c b/trunk/net/ipv4/netfilter/ip_conntrack_netlink.c index c9ebbe0d2d9c..91fe8f2e38ff 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_netlink.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_netlink.c @@ -79,7 +79,6 @@ ctnetlink_dump_tuples(struct sk_buff *skb, const struct ip_conntrack_tuple *tuple) { struct nfattr *nest_parms; - int ret; nest_parms = NFA_NEST(skb, CTA_TUPLE_IP); NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip); @@ -87,10 +86,10 @@ ctnetlink_dump_tuples(struct sk_buff *skb, NFA_NEST_END(skb, nest_parms); nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); - ret = ctnetlink_dump_tuples_proto(skb, tuple); + ctnetlink_dump_tuples_proto(skb, tuple); NFA_NEST_END(skb, nest_parms); - return ret; + return 0; nfattr_failure: return -1; @@ -161,7 +160,7 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct ip_conntrack *ct) return 0; nest_helper = NFA_NEST(skb, CTA_HELP); - NFA_PUT(skb, CTA_HELP_NAME, strlen(ct->helper->name), ct->helper->name); + NFA_PUT(skb, CTA_HELP_NAME, CTA_HELP_MAXNAMESIZE, &ct->helper->name); if (ct->helper->to_nfattr) ct->helper->to_nfattr(skb, ct); @@ -230,7 +229,7 @@ ctnetlink_dump_id(struct sk_buff *skb, const struct ip_conntrack *ct) static inline int ctnetlink_dump_use(struct sk_buff *skb, const struct ip_conntrack *ct) { - u_int32_t use = htonl(atomic_read(&ct->ct_general.use)); + unsigned int use = htonl(atomic_read(&ct->ct_general.use)); NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use); return 0; @@ -312,22 +311,29 @@ static int ctnetlink_conntrack_event(struct notifier_block *this, if (events & IPCT_DESTROY) { type = IPCTNL_MSG_CT_DELETE; group = NFNLGRP_CONNTRACK_DESTROY; - } else if (events & (IPCT_NEW | IPCT_RELATED)) { + goto alloc_skb; + } + if (events & (IPCT_NEW | IPCT_RELATED)) { type = IPCTNL_MSG_CT_NEW; flags = NLM_F_CREATE|NLM_F_EXCL; /* dump everything */ events = ~0UL; group = NFNLGRP_CONNTRACK_NEW; - } else if (events & (IPCT_STATUS | + goto alloc_skb; + } + if (events & (IPCT_STATUS | IPCT_PROTOINFO | IPCT_HELPER | IPCT_HELPINFO | IPCT_NATINFO)) { type = IPCTNL_MSG_CT_NEW; group = NFNLGRP_CONNTRACK_UPDATE; - } else - return NOTIFY_DONE; + goto alloc_skb; + } + return NOTIFY_DONE; + +alloc_skb: /* FIXME: Check if there are any listeners before, don't hurt performance */ skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); @@ -1031,11 +1037,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[], return err; } -#if defined(CONFIG_IP_NF_CONNTRACK_MARK) - if (cda[CTA_MARK-1]) - ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); -#endif - ct->helper = ip_conntrack_helper_find_get(rtuple); add_timer(&ct->timeout); @@ -1044,6 +1045,11 @@ ctnetlink_create_conntrack(struct nfattr *cda[], if (ct->helper) ip_conntrack_helper_put(ct->helper); +#if defined(CONFIG_IP_NF_CONNTRACK_MARK) + if (cda[CTA_MARK-1]) + ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); +#endif + DEBUGP("conntrack with id %u inserted\n", ct->id); return 0; @@ -1203,6 +1209,7 @@ static int ctnetlink_expect_event(struct notifier_block *this, unsigned int type; unsigned char *b; int flags = 0; + u16 proto; if (events & IPEXP_NEW) { type = IPCTNL_MSG_EXP_NEW; @@ -1229,6 +1236,7 @@ static int ctnetlink_expect_event(struct notifier_block *this, goto nfattr_failure; nlh->nlmsg_len = skb->tail - b; + proto = exp->tuple.dst.protonum; nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0); return NOTIFY_DONE; diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/trunk/net/ipv4/netfilter/ip_conntrack_proto_icmp.c index 30fc21d6165a..5f9925db608e 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_proto_icmp.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_proto_icmp.c @@ -47,21 +47,20 @@ static int icmp_pkt_to_tuple(const struct sk_buff *skb, return 1; } -/* Add 1; spaces filled with 0. */ -static const u_int8_t invmap[] = { - [ICMP_ECHO] = ICMP_ECHOREPLY + 1, - [ICMP_ECHOREPLY] = ICMP_ECHO + 1, - [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, - [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1, - [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1, - [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1, - [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1, - [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1 -}; - static int icmp_invert_tuple(struct ip_conntrack_tuple *tuple, const struct ip_conntrack_tuple *orig) { + /* Add 1; spaces filled with 0. */ + static const u_int8_t invmap[] + = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1, + [ICMP_ECHOREPLY] = ICMP_ECHO + 1, + [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, + [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1, + [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1, + [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1, + [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1, + [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1}; + if (orig->dst.u.icmp.type >= sizeof(invmap) || !invmap[orig->dst.u.icmp.type]) return 0; @@ -111,17 +110,17 @@ static int icmp_packet(struct ip_conntrack *ct, return NF_ACCEPT; } +static const u_int8_t valid_new[] = { + [ICMP_ECHO] = 1, + [ICMP_TIMESTAMP] = 1, + [ICMP_INFO_REQUEST] = 1, + [ICMP_ADDRESS] = 1 +}; + /* Called when a new connection for this protocol found. */ static int icmp_new(struct ip_conntrack *conntrack, const struct sk_buff *skb) { - static const u_int8_t valid_new[] = { - [ICMP_ECHO] = 1, - [ICMP_TIMESTAMP] = 1, - [ICMP_INFO_REQUEST] = 1, - [ICMP_ADDRESS] = 1 - }; - if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new) || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) { /* Can't create a new ICMP `conn' with this. */ @@ -280,6 +279,10 @@ static int icmp_tuple_to_nfattr(struct sk_buff *skb, NFA_PUT(skb, CTA_PROTO_ICMP_CODE, sizeof(u_int8_t), &t->dst.u.icmp.code); + if (t->dst.u.icmp.type >= sizeof(valid_new) + || !valid_new[t->dst.u.icmp.type]) + return -EINVAL; + return 0; nfattr_failure: @@ -292,7 +295,7 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[], if (!tb[CTA_PROTO_ICMP_TYPE-1] || !tb[CTA_PROTO_ICMP_CODE-1] || !tb[CTA_PROTO_ICMP_ID-1]) - return -EINVAL; + return -1; tuple->dst.u.icmp.type = *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_TYPE-1]); @@ -301,10 +304,6 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[], tuple->src.u.icmp.id = *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]); - if (tuple->dst.u.icmp.type >= sizeof(invmap) - || !invmap[tuple->dst.u.icmp.type]) - return -EINVAL; - return 0; } #endif diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_standalone.c b/trunk/net/ipv4/netfilter/ip_conntrack_standalone.c index 7ba97783e741..a88bcc551244 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_standalone.c @@ -451,6 +451,30 @@ static unsigned int ip_conntrack_defrag(unsigned int hooknum, return NF_ACCEPT; } +static unsigned int ip_refrag(unsigned int hooknum, + struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + struct rtable *rt = (struct rtable *)(*pskb)->dst; + + /* We've seen it coming out the other side: confirm */ + if (ip_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT) + return NF_DROP; + + /* Local packets are never produced too large for their + interface. We degfragment them at LOCAL_OUT, however, + so we have to refragment them here. */ + if ((*pskb)->len > dst_mtu(&rt->u.dst) && + !skb_shinfo(*pskb)->tso_size) { + /* No hook can be after us, so this should be OK. */ + ip_fragment(*pskb, okfn); + return NF_STOLEN; + } + return NF_ACCEPT; +} + static unsigned int ip_conntrack_local(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, @@ -520,7 +544,7 @@ static struct nf_hook_ops ip_conntrack_helper_in_ops = { /* Refragmenter; last chance. */ static struct nf_hook_ops ip_conntrack_out_ops = { - .hook = ip_confirm, + .hook = ip_refrag, .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_IP_POST_ROUTING, diff --git a/trunk/net/ipv4/netfilter/ip_nat_standalone.c b/trunk/net/ipv4/netfilter/ip_nat_standalone.c index f04111f74e09..30cd4e18c129 100644 --- a/trunk/net/ipv4/netfilter/ip_nat_standalone.c +++ b/trunk/net/ipv4/netfilter/ip_nat_standalone.c @@ -190,6 +190,23 @@ ip_nat_out(unsigned int hooknum, || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) return NF_ACCEPT; + /* We can hit fragment here; forwarded packets get + defragmented by connection tracking coming in, then + fragmented (grr) by the forward code. + + In future: If we have nfct != NULL, AND we have NAT + initialized, AND there is no helper, then we can do full + NAPT on the head, and IP-address-only NAT on the rest. + + I'm starting to have nightmares about fragments. */ + + if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { + *pskb = ip_ct_gather_frags(*pskb, IP_DEFRAG_NAT_OUT); + + if (!*pskb) + return NF_STOLEN; + } + return ip_nat_fn(hooknum, pskb, in, out, okfn); } diff --git a/trunk/net/ipv4/netfilter/ipt_REJECT.c b/trunk/net/ipv4/netfilter/ipt_REJECT.c index 6693526ae128..f057025a719e 100644 --- a/trunk/net/ipv4/netfilter/ipt_REJECT.c +++ b/trunk/net/ipv4/netfilter/ipt_REJECT.c @@ -203,7 +203,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) sizeof(struct tcphdr), 0)); /* Adjust IP TTL, DF */ - nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); + nskb->nh.iph->ttl = MAXTTL; /* Set DF, id = 0 */ nskb->nh.iph->frag_off = htons(IP_DF); nskb->nh.iph->id = 0; diff --git a/trunk/net/ipv4/netfilter/ipt_ULOG.c b/trunk/net/ipv4/netfilter/ipt_ULOG.c index 38641cd06123..2883ccd8a91d 100644 --- a/trunk/net/ipv4/netfilter/ipt_ULOG.c +++ b/trunk/net/ipv4/netfilter/ipt_ULOG.c @@ -77,15 +77,15 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG); #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0) static unsigned int nlbufsiz = 4096; -module_param(nlbufsiz, uint, 0400); +module_param(nlbufsiz, uint, 0600); /* FIXME: Check size < 128k --RR */ MODULE_PARM_DESC(nlbufsiz, "netlink buffer size"); static unsigned int flushtimeout = 10; -module_param(flushtimeout, uint, 0600); +module_param(flushtimeout, int, 0600); MODULE_PARM_DESC(flushtimeout, "buffer flush timeout (hundredths of a second)"); -static int nflog = 1; -module_param(nflog, bool, 0400); +static unsigned int nflog = 1; +module_param(nflog, int, 0400); MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); /* global data structures */ @@ -376,7 +376,7 @@ static int __init init(void) DEBUGP("ipt_ULOG: init module\n"); - if (nlbufsiz > 128*1024) { + if (nlbufsiz >= 128*1024) { printk("Netlink buffer has to be <= 128kB\n"); return -EINVAL; } diff --git a/trunk/net/ipv4/netfilter/ipt_recent.c b/trunk/net/ipv4/netfilter/ipt_recent.c index 5ddccb18c65e..261cbb4d4c49 100644 --- a/trunk/net/ipv4/netfilter/ipt_recent.c +++ b/trunk/net/ipv4/netfilter/ipt_recent.c @@ -24,10 +24,10 @@ #define HASH_LOG 9 /* Defaults, these can be overridden on the module command-line. */ -static unsigned int ip_list_tot = 100; -static unsigned int ip_pkt_list_tot = 20; -static unsigned int ip_list_hash_size = 0; -static unsigned int ip_list_perms = 0644; +static int ip_list_tot = 100; +static int ip_pkt_list_tot = 20; +static int ip_list_hash_size = 0; +static int ip_list_perms = 0644; #ifdef DEBUG static int debug = 1; #endif @@ -38,13 +38,13 @@ KERN_INFO RECENT_NAME " " RECENT_VER ": Stephen Frost . htt MODULE_AUTHOR("Stephen Frost "); MODULE_DESCRIPTION("IP tables recently seen matching module " RECENT_VER); MODULE_LICENSE("GPL"); -module_param(ip_list_tot, uint, 0400); -module_param(ip_pkt_list_tot, uint, 0400); -module_param(ip_list_hash_size, uint, 0400); -module_param(ip_list_perms, uint, 0400); +module_param(ip_list_tot, int, 0400); +module_param(ip_pkt_list_tot, int, 0400); +module_param(ip_list_hash_size, int, 0400); +module_param(ip_list_perms, int, 0400); #ifdef DEBUG -module_param(debug, bool, 0600); -MODULE_PARM_DESC(debug,"enable debugging output"); +module_param(debug, int, 0600); +MODULE_PARM_DESC(debug,"debugging level, defaults to 1"); #endif MODULE_PARM_DESC(ip_list_tot,"number of IPs to remember per list"); MODULE_PARM_DESC(ip_pkt_list_tot,"number of packets per IP to remember"); diff --git a/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 9bdbb7793971..8202c1c0afad 100644 --- a/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -181,6 +180,30 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, return NF_ACCEPT; } +static unsigned int ipv4_refrag(unsigned int hooknum, + struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + struct rtable *rt = (struct rtable *)(*pskb)->dst; + + /* We've seen it coming out the other side: confirm */ + if (ipv4_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT) + return NF_DROP; + + /* Local packets are never produced too large for their + interface. We degfragment them at LOCAL_OUT, however, + so we have to refragment them here. */ + if ((*pskb)->len > dst_mtu(&rt->u.dst) && + !skb_shinfo(*pskb)->tso_size) { + /* No hook can be after us, so this should be OK. */ + ip_fragment(*pskb, okfn); + return NF_STOLEN; + } + return NF_ACCEPT; +} + static unsigned int ipv4_conntrack_in(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, @@ -260,7 +283,7 @@ static struct nf_hook_ops ipv4_conntrack_helper_in_ops = { /* Refragmenter; last chance. */ static struct nf_hook_ops ipv4_conntrack_out_ops = { - .hook = ipv4_confirm, + .hook = ipv4_refrag, .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_IP_POST_ROUTING, @@ -369,48 +392,6 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len) return -ENOENT; } -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) - -#include -#include - -static int ipv4_tuple_to_nfattr(struct sk_buff *skb, - const struct nf_conntrack_tuple *tuple) -{ - NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), - &tuple->src.u3.ip); - NFA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t), - &tuple->dst.u3.ip); - return 0; - -nfattr_failure: - return -1; -} - -static const size_t cta_min_ip[CTA_IP_MAX] = { - [CTA_IP_V4_SRC-1] = sizeof(u_int32_t), - [CTA_IP_V4_DST-1] = sizeof(u_int32_t), -}; - -static int ipv4_nfattr_to_tuple(struct nfattr *tb[], - struct nf_conntrack_tuple *t) -{ - if (!tb[CTA_IP_V4_SRC-1] || !tb[CTA_IP_V4_DST-1]) - return -EINVAL; - - if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) - return -EINVAL; - - t->src.u3.ip = - *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_SRC-1]); - t->dst.u3.ip = - *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_DST-1]); - - return 0; -} -#endif - static struct nf_sockopt_ops so_getorigdst = { .pf = PF_INET, .get_optmin = SO_ORIGINAL_DST, @@ -427,11 +408,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = { .print_conntrack = ipv4_print_conntrack, .prepare = ipv4_prepare, .get_features = ipv4_get_features, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) - .tuple_to_nfattr = ipv4_tuple_to_nfattr, - .nfattr_to_tuple = ipv4_nfattr_to_tuple, -#endif .me = THIS_MODULE, }; diff --git a/trunk/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/trunk/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 52dc175be39a..7ddb5c08f7b8 100644 --- a/trunk/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/trunk/net/ipv4/netfilter/nf_conntrack_proto_icmp.c @@ -50,21 +50,20 @@ static int icmp_pkt_to_tuple(const struct sk_buff *skb, return 1; } -/* Add 1; spaces filled with 0. */ -static const u_int8_t invmap[] = { - [ICMP_ECHO] = ICMP_ECHOREPLY + 1, - [ICMP_ECHOREPLY] = ICMP_ECHO + 1, - [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, - [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1, - [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1, - [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1, - [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1, - [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1 -}; - static int icmp_invert_tuple(struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *orig) { + /* Add 1; spaces filled with 0. */ + static u_int8_t invmap[] + = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1, + [ICMP_ECHOREPLY] = ICMP_ECHO + 1, + [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, + [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1, + [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1, + [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1, + [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1, + [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1}; + if (orig->dst.u.icmp.type >= sizeof(invmap) || !invmap[orig->dst.u.icmp.type]) return 0; @@ -121,12 +120,11 @@ static int icmp_packet(struct nf_conn *ct, static int icmp_new(struct nf_conn *conntrack, const struct sk_buff *skb, unsigned int dataoff) { - static const u_int8_t valid_new[] = { - [ICMP_ECHO] = 1, - [ICMP_TIMESTAMP] = 1, - [ICMP_INFO_REQUEST] = 1, - [ICMP_ADDRESS] = 1 - }; + static u_int8_t valid_new[] + = { [ICMP_ECHO] = 1, + [ICMP_TIMESTAMP] = 1, + [ICMP_INFO_REQUEST] = 1, + [ICMP_ADDRESS] = 1 }; if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new) || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) { @@ -170,7 +168,7 @@ icmp_error_message(struct sk_buff *skb, return -NF_ACCEPT; } - innerproto = __nf_ct_proto_find(PF_INET, inside->ip.protocol); + innerproto = nf_ct_find_proto(PF_INET, inside->ip.protocol); dataoff = skb->nh.iph->ihl*4 + sizeof(inside->icmp); /* Are they talking about one of our connections? */ if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET, @@ -283,60 +281,6 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff, return icmp_error_message(skb, ctinfo, hooknum); } -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) - -#include -#include - -static int icmp_tuple_to_nfattr(struct sk_buff *skb, - const struct nf_conntrack_tuple *t) -{ - NFA_PUT(skb, CTA_PROTO_ICMP_ID, sizeof(u_int16_t), - &t->src.u.icmp.id); - NFA_PUT(skb, CTA_PROTO_ICMP_TYPE, sizeof(u_int8_t), - &t->dst.u.icmp.type); - NFA_PUT(skb, CTA_PROTO_ICMP_CODE, sizeof(u_int8_t), - &t->dst.u.icmp.code); - - return 0; - -nfattr_failure: - return -1; -} - -static const size_t cta_min_proto[CTA_PROTO_MAX] = { - [CTA_PROTO_ICMP_TYPE-1] = sizeof(u_int8_t), - [CTA_PROTO_ICMP_CODE-1] = sizeof(u_int8_t), - [CTA_PROTO_ICMP_ID-1] = sizeof(u_int16_t) -}; - -static int icmp_nfattr_to_tuple(struct nfattr *tb[], - struct nf_conntrack_tuple *tuple) -{ - if (!tb[CTA_PROTO_ICMP_TYPE-1] - || !tb[CTA_PROTO_ICMP_CODE-1] - || !tb[CTA_PROTO_ICMP_ID-1]) - return -EINVAL; - - if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) - return -EINVAL; - - tuple->dst.u.icmp.type = - *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_TYPE-1]); - tuple->dst.u.icmp.code = - *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]); - tuple->src.u.icmp.id = - *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]); - - if (tuple->dst.u.icmp.type >= sizeof(invmap) - || !invmap[tuple->dst.u.icmp.type]) - return -EINVAL; - - return 0; -} -#endif - struct nf_conntrack_protocol nf_conntrack_protocol_icmp = { .list = { NULL, NULL }, @@ -351,12 +295,7 @@ struct nf_conntrack_protocol nf_conntrack_protocol_icmp = .new = icmp_new, .error = icmp_error, .destroy = NULL, - .me = NULL, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) - .tuple_to_nfattr = icmp_tuple_to_nfattr, - .nfattr_to_tuple = icmp_nfattr_to_tuple, -#endif + .me = NULL }; EXPORT_SYMBOL(nf_conntrack_protocol_icmp); diff --git a/trunk/net/ipv6/netfilter/ip6_tables.c b/trunk/net/ipv6/netfilter/ip6_tables.c index 925b42d48347..ea43ef1d94a7 100644 --- a/trunk/net/ipv6/netfilter/ip6_tables.c +++ b/trunk/net/ipv6/netfilter/ip6_tables.c @@ -119,14 +119,13 @@ static LIST_HEAD(ip6t_tables); #define up(x) do { printk("UP:%u:" #x "\n", __LINE__); up(x); } while(0) #endif -int -ip6_masked_addrcmp(const struct in6_addr *addr1, const struct in6_addr *mask, - const struct in6_addr *addr2) +static int ip6_masked_addrcmp(struct in6_addr addr1, struct in6_addr mask, + struct in6_addr addr2) { int i; for( i = 0; i < 16; i++){ - if((addr1->s6_addr[i] & mask->s6_addr[i]) != - (addr2->s6_addr[i] & mask->s6_addr[i])) + if((addr1.s6_addr[i] & mask.s6_addr[i]) != + (addr2.s6_addr[i] & mask.s6_addr[i])) return 1; } return 0; @@ -160,10 +159,10 @@ ip6_packet_match(const struct sk_buff *skb, #define FWINV(bool,invflg) ((bool) ^ !!(ip6info->invflags & invflg)) - if (FWINV(ip6_masked_addrcmp(&ipv6->saddr, &ip6info->smsk, - &ip6info->src), IP6T_INV_SRCIP) - || FWINV(ip6_masked_addrcmp(&ipv6->daddr, &ip6info->dmsk, - &ip6info->dst), IP6T_INV_DSTIP)) { + if (FWINV(ip6_masked_addrcmp(ipv6->saddr,ip6info->smsk,ip6info->src), + IP6T_INV_SRCIP) + || FWINV(ip6_masked_addrcmp(ipv6->daddr,ip6info->dmsk,ip6info->dst), + IP6T_INV_DSTIP)) { dprintf("Source or dest mismatch.\n"); /* dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr, @@ -206,21 +205,69 @@ ip6_packet_match(const struct sk_buff *skb, /* look for the desired protocol header */ if((ip6info->flags & IP6T_F_PROTO)) { - int protohdr; - unsigned short _frag_off; + u_int8_t currenthdr = ipv6->nexthdr; + struct ipv6_opt_hdr _hdr, *hp; + u_int16_t ptr; /* Header offset in skb */ + u_int16_t hdrlen; /* Header */ + u_int16_t _fragoff = 0, *fp = NULL; + + ptr = IPV6_HDR_LEN; + + while (ip6t_ext_hdr(currenthdr)) { + /* Is there enough space for the next ext header? */ + if (skb->len - ptr < IPV6_OPTHDR_LEN) + return 0; + + /* NONE or ESP: there isn't protocol part */ + /* If we want to count these packets in '-p all', + * we will change the return 0 to 1*/ + if ((currenthdr == IPPROTO_NONE) || + (currenthdr == IPPROTO_ESP)) + break; - protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off); - if (protohdr < 0) - return 0; + hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr); + BUG_ON(hp == NULL); + + /* Size calculation */ + if (currenthdr == IPPROTO_FRAGMENT) { + fp = skb_header_pointer(skb, + ptr+offsetof(struct frag_hdr, + frag_off), + sizeof(_fragoff), + &_fragoff); + if (fp == NULL) + return 0; + + _fragoff = ntohs(*fp) & ~0x7; + hdrlen = 8; + } else if (currenthdr == IPPROTO_AH) + hdrlen = (hp->hdrlen+2)<<2; + else + hdrlen = ipv6_optlen(hp); + + currenthdr = hp->nexthdr; + ptr += hdrlen; + /* ptr is too large */ + if ( ptr > skb->len ) + return 0; + if (_fragoff) { + if (ip6t_ext_hdr(currenthdr)) + return 0; + break; + } + } + + *protoff = ptr; + *fragoff = _fragoff; - *fragoff = _frag_off; + /* currenthdr contains the protocol header */ dprintf("Packet protocol %hi ?= %s%hi.\n", - protohdr, + currenthdr, ip6info->invflags & IP6T_INV_PROTO ? "!":"", ip6info->proto); - if (ip6info->proto == protohdr) { + if (ip6info->proto == currenthdr) { if(ip6info->invflags & IP6T_INV_PROTO) { return 0; } @@ -2051,39 +2098,26 @@ static void __exit fini(void) } /* - * find the offset to specified header or the protocol number of last header - * if target < 0. "last header" is transport protocol header, ESP, or - * "No next header". - * - * If target header is found, its offset is set in *offset and return protocol - * number. Otherwise, return -1. - * - * Note that non-1st fragment is special case that "the protocol number - * of last header" is "next header" field in Fragment header. In this case, - * *offset is meaningless and fragment offset is stored in *fragoff if fragoff - * isn't NULL. + * find specified header up to transport protocol header. + * If found target header, the offset to the header is set to *offset + * and return 0. otherwise, return -1. * + * Notes: - non-1st Fragment Header isn't skipped. + * - ESP header isn't skipped. + * - The target header may be trancated. */ -int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, - int target, unsigned short *fragoff) +int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, u8 target) { unsigned int start = (u8*)(skb->nh.ipv6h + 1) - skb->data; u8 nexthdr = skb->nh.ipv6h->nexthdr; unsigned int len = skb->len - start; - if (fragoff) - *fragoff = 0; - while (nexthdr != target) { struct ipv6_opt_hdr _hdr, *hp; unsigned int hdrlen; - if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { - if (target < 0) - break; + if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) return -1; - } - hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); if (hp == NULL) return -1; @@ -2097,17 +2131,8 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, if (fp == NULL) return -1; - _frag_off = ntohs(*fp) & ~0x7; - if (_frag_off) { - if (target < 0 && - ((!ipv6_ext_hdr(hp->nexthdr)) || - nexthdr == NEXTHDR_NONE)) { - if (fragoff) - *fragoff = _frag_off; - return hp->nexthdr; - } + if (ntohs(*fp) & ~0x7) return -1; - } hdrlen = 8; } else if (nexthdr == NEXTHDR_AUTH) hdrlen = (hp->hdrlen + 2) << 2; @@ -2120,7 +2145,7 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, } *offset = start; - return nexthdr; + return 0; } EXPORT_SYMBOL(ip6t_register_table); @@ -2132,7 +2157,6 @@ EXPORT_SYMBOL(ip6t_register_target); EXPORT_SYMBOL(ip6t_unregister_target); EXPORT_SYMBOL(ip6t_ext_hdr); EXPORT_SYMBOL(ipv6_find_hdr); -EXPORT_SYMBOL(ip6_masked_addrcmp); module_init(init); module_exit(fini); diff --git a/trunk/net/ipv6/netfilter/ip6t_ah.c b/trunk/net/ipv6/netfilter/ip6t_ah.c index f5c1a7ff4a1f..268918d5deea 100644 --- a/trunk/net/ipv6/netfilter/ip6t_ah.c +++ b/trunk/net/ipv6/netfilter/ip6t_ah.c @@ -54,7 +54,7 @@ match(const struct sk_buff *skb, unsigned int ptr; unsigned int hdrlen = 0; - if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL) < 0) + if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH) < 0) return 0; ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); diff --git a/trunk/net/ipv6/netfilter/ip6t_dst.c b/trunk/net/ipv6/netfilter/ip6t_dst.c index 48cf5f9efc95..c450a635e54b 100644 --- a/trunk/net/ipv6/netfilter/ip6t_dst.c +++ b/trunk/net/ipv6/netfilter/ip6t_dst.c @@ -71,9 +71,9 @@ match(const struct sk_buff *skb, unsigned int optlen; #if HOPBYHOP - if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL) < 0) + if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP) < 0) #else - if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST, NULL) < 0) + if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST) < 0) #endif return 0; diff --git a/trunk/net/ipv6/netfilter/ip6t_esp.c b/trunk/net/ipv6/netfilter/ip6t_esp.c index e1828f6d0a40..65937de1b58c 100644 --- a/trunk/net/ipv6/netfilter/ip6t_esp.c +++ b/trunk/net/ipv6/netfilter/ip6t_esp.c @@ -56,7 +56,7 @@ match(const struct sk_buff *skb, /* Make sure this isn't an evil packet */ /*DEBUGP("ipv6_esp entered \n");*/ - if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ESP, NULL) < 0) + if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ESP) < 0) return 0; eh = skb_header_pointer(skb, ptr, sizeof(_esp), &_esp); diff --git a/trunk/net/ipv6/netfilter/ip6t_frag.c b/trunk/net/ipv6/netfilter/ip6t_frag.c index d1549b268669..085d5f8eea29 100644 --- a/trunk/net/ipv6/netfilter/ip6t_frag.c +++ b/trunk/net/ipv6/netfilter/ip6t_frag.c @@ -52,7 +52,7 @@ match(const struct sk_buff *skb, const struct ip6t_frag *fraginfo = matchinfo; unsigned int ptr; - if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0) + if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT) < 0) return 0; fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); diff --git a/trunk/net/ipv6/netfilter/ip6t_hbh.c b/trunk/net/ipv6/netfilter/ip6t_hbh.c index e3bc8e2700e7..1d09485111d0 100644 --- a/trunk/net/ipv6/netfilter/ip6t_hbh.c +++ b/trunk/net/ipv6/netfilter/ip6t_hbh.c @@ -71,9 +71,9 @@ match(const struct sk_buff *skb, unsigned int optlen; #if HOPBYHOP - if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL) < 0) + if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP) < 0) #else - if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST, NULL) < 0) + if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST) < 0) #endif return 0; diff --git a/trunk/net/ipv6/netfilter/ip6t_rt.c b/trunk/net/ipv6/netfilter/ip6t_rt.c index c1e770e45543..beb2fd5cebbb 100644 --- a/trunk/net/ipv6/netfilter/ip6t_rt.c +++ b/trunk/net/ipv6/netfilter/ip6t_rt.c @@ -58,7 +58,7 @@ match(const struct sk_buff *skb, unsigned int ret = 0; struct in6_addr *ap, _addr; - if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0) + if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING) < 0) return 0; rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 704fbbe74874..753a3ae8502b 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -401,48 +401,6 @@ static ctl_table nf_ct_net_table[] = { }; #endif -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) - -#include -#include - -static int ipv6_tuple_to_nfattr(struct sk_buff *skb, - const struct nf_conntrack_tuple *tuple) -{ - NFA_PUT(skb, CTA_IP_V6_SRC, sizeof(u_int32_t) * 4, - &tuple->src.u3.ip6); - NFA_PUT(skb, CTA_IP_V6_DST, sizeof(u_int32_t) * 4, - &tuple->dst.u3.ip6); - return 0; - -nfattr_failure: - return -1; -} - -static const size_t cta_min_ip[CTA_IP_MAX] = { - [CTA_IP_V6_SRC-1] = sizeof(u_int32_t)*4, - [CTA_IP_V6_DST-1] = sizeof(u_int32_t)*4, -}; - -static int ipv6_nfattr_to_tuple(struct nfattr *tb[], - struct nf_conntrack_tuple *t) -{ - if (!tb[CTA_IP_V6_SRC-1] || !tb[CTA_IP_V6_DST-1]) - return -EINVAL; - - if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) - return -EINVAL; - - memcpy(&t->src.u3.ip6, NFA_DATA(tb[CTA_IP_V6_SRC-1]), - sizeof(u_int32_t) * 4); - memcpy(&t->dst.u3.ip6, NFA_DATA(tb[CTA_IP_V6_DST-1]), - sizeof(u_int32_t) * 4); - - return 0; -} -#endif - struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = { .l3proto = PF_INET6, .name = "ipv6", @@ -451,11 +409,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = { .print_tuple = ipv6_print_tuple, .print_conntrack = ipv6_print_conntrack, .prepare = ipv6_prepare, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) - .tuple_to_nfattr = ipv6_tuple_to_nfattr, - .nfattr_to_tuple = ipv6_nfattr_to_tuple, -#endif .get_features = ipv6_get_features, .me = THIS_MODULE, }; diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/trunk/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index 09945c333055..a7e03cfacd06 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -57,17 +57,17 @@ static int icmpv6_pkt_to_tuple(const struct sk_buff *skb, return 1; } -/* Add 1; spaces filled with 0. */ -static u_int8_t invmap[] = { - [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1, - [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1, - [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1, - [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY +1 -}; - static int icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *orig) { + /* Add 1; spaces filled with 0. */ + static u_int8_t invmap[] = { + [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1, + [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1, + [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1, + [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY +1 + }; + int type = orig->dst.u.icmp.type - 128; if (type < 0 || type >= sizeof(invmap) || !invmap[type]) return 0; @@ -185,7 +185,7 @@ icmpv6_error_message(struct sk_buff *skb, return -NF_ACCEPT; } - inproto = __nf_ct_proto_find(PF_INET6, inprotonum); + inproto = nf_ct_find_proto(PF_INET6, inprotonum); /* Are they talking about one of our connections? */ if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum, @@ -255,60 +255,6 @@ icmpv6_error(struct sk_buff *skb, unsigned int dataoff, return icmpv6_error_message(skb, dataoff, ctinfo, hooknum); } -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) - -#include -#include -static int icmpv6_tuple_to_nfattr(struct sk_buff *skb, - const struct nf_conntrack_tuple *t) -{ - NFA_PUT(skb, CTA_PROTO_ICMPV6_ID, sizeof(u_int16_t), - &t->src.u.icmp.id); - NFA_PUT(skb, CTA_PROTO_ICMPV6_TYPE, sizeof(u_int8_t), - &t->dst.u.icmp.type); - NFA_PUT(skb, CTA_PROTO_ICMPV6_CODE, sizeof(u_int8_t), - &t->dst.u.icmp.code); - - return 0; - -nfattr_failure: - return -1; -} - -static const size_t cta_min_proto[CTA_PROTO_MAX] = { - [CTA_PROTO_ICMPV6_TYPE-1] = sizeof(u_int8_t), - [CTA_PROTO_ICMPV6_CODE-1] = sizeof(u_int8_t), - [CTA_PROTO_ICMPV6_ID-1] = sizeof(u_int16_t) -}; - -static int icmpv6_nfattr_to_tuple(struct nfattr *tb[], - struct nf_conntrack_tuple *tuple) -{ - if (!tb[CTA_PROTO_ICMPV6_TYPE-1] - || !tb[CTA_PROTO_ICMPV6_CODE-1] - || !tb[CTA_PROTO_ICMPV6_ID-1]) - return -EINVAL; - - if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) - return -EINVAL; - - tuple->dst.u.icmp.type = - *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_TYPE-1]); - tuple->dst.u.icmp.code = - *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_CODE-1]); - tuple->src.u.icmp.id = - *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_ID-1]); - - if (tuple->dst.u.icmp.type < 128 - || tuple->dst.u.icmp.type - 128 >= sizeof(invmap) - || !invmap[tuple->dst.u.icmp.type - 128]) - return -EINVAL; - - return 0; -} -#endif - struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 = { .l3proto = PF_INET6, @@ -321,11 +267,6 @@ struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 = .packet = icmpv6_packet, .new = icmpv6_new, .error = icmpv6_error, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) - .tuple_to_nfattr = icmpv6_tuple_to_nfattr, - .nfattr_to_tuple = icmpv6_nfattr_to_tuple, -#endif }; EXPORT_SYMBOL(nf_conntrack_protocol_icmpv6); diff --git a/trunk/net/netfilter/Kconfig b/trunk/net/netfilter/Kconfig index 7d55f9cbd853..794c41d19b28 100644 --- a/trunk/net/netfilter/Kconfig +++ b/trunk/net/netfilter/Kconfig @@ -95,11 +95,4 @@ config NF_CONNTRACK_FTP To compile it as a module, choose M here. If unsure, say N. -config NF_CT_NETLINK - tristate 'Connection tracking netlink interface (EXPERIMENTAL)' - depends on EXPERIMENTAL && NF_CONNTRACK && NETFILTER_NETLINK - depends on NF_CONNTRACK!=y || NETFILTER_NETLINK!=m - help - This option enables support for a netlink-based userspace interface - endmenu diff --git a/trunk/net/netfilter/Makefile b/trunk/net/netfilter/Makefile index cb2183145c37..55f019ad2c08 100644 --- a/trunk/net/netfilter/Makefile +++ b/trunk/net/netfilter/Makefile @@ -13,6 +13,3 @@ obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o # SCTP protocol connection tracking obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o - -# netlink interface for nf_conntrack -obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o diff --git a/trunk/net/netfilter/nf_conntrack_core.c b/trunk/net/netfilter/nf_conntrack_core.c index 62bb509f05d4..a7c7b490cf22 100644 --- a/trunk/net/netfilter/nf_conntrack_core.c +++ b/trunk/net/netfilter/nf_conntrack_core.c @@ -82,8 +82,6 @@ unsigned int nf_ct_log_invalid; static LIST_HEAD(unconfirmed); static int nf_conntrack_vmalloc; -static unsigned int nf_conntrack_next_id = 1; -static unsigned int nf_conntrack_expect_next_id = 1; #ifdef CONFIG_NF_CONNTRACK_EVENTS struct notifier_block *nf_conntrack_chain; struct notifier_block *nf_conntrack_expect_chain; @@ -186,7 +184,7 @@ DECLARE_MUTEX(nf_ct_cache_mutex); extern struct nf_conntrack_protocol nf_conntrack_generic_protocol; struct nf_conntrack_protocol * -__nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol) +nf_ct_find_proto(u_int16_t l3proto, u_int8_t protocol) { if (unlikely(nf_ct_protos[l3proto] == NULL)) return &nf_conntrack_generic_protocol; @@ -194,50 +192,6 @@ __nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol) return nf_ct_protos[l3proto][protocol]; } -/* this is guaranteed to always return a valid protocol helper, since - * it falls back to generic_protocol */ -struct nf_conntrack_protocol * -nf_ct_proto_find_get(u_int16_t l3proto, u_int8_t protocol) -{ - struct nf_conntrack_protocol *p; - - preempt_disable(); - p = __nf_ct_proto_find(l3proto, protocol); - if (p) { - if (!try_module_get(p->me)) - p = &nf_conntrack_generic_protocol; - } - preempt_enable(); - - return p; -} - -void nf_ct_proto_put(struct nf_conntrack_protocol *p) -{ - module_put(p->me); -} - -struct nf_conntrack_l3proto * -nf_ct_l3proto_find_get(u_int16_t l3proto) -{ - struct nf_conntrack_l3proto *p; - - preempt_disable(); - p = __nf_ct_l3proto_find(l3proto); - if (p) { - if (!try_module_get(p->me)) - p = &nf_conntrack_generic_l3proto; - } - preempt_enable(); - - return p; -} - -void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p) -{ - module_put(p->me); -} - static int nf_conntrack_hash_rnd_initted; static unsigned int nf_conntrack_hash_rnd; @@ -430,7 +384,7 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse, } /* nf_conntrack_expect helper functions */ -void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) +static void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) { ASSERT_WRITE_LOCK(&nf_conntrack_lock); NF_CT_ASSERT(!timer_pending(&exp->timeout)); @@ -450,33 +404,6 @@ static void expectation_timed_out(unsigned long ul_expect) nf_conntrack_expect_put(exp); } -struct nf_conntrack_expect * -__nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple) -{ - struct nf_conntrack_expect *i; - - list_for_each_entry(i, &nf_conntrack_expect_list, list) { - if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) { - atomic_inc(&i->use); - return i; - } - } - return NULL; -} - -/* Just find a expectation corresponding to a tuple. */ -struct nf_conntrack_expect * -nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple) -{ - struct nf_conntrack_expect *i; - - read_lock_bh(&nf_conntrack_lock); - i = __nf_conntrack_expect_find(tuple); - read_unlock_bh(&nf_conntrack_lock); - - return i; -} - /* If an expectation for this connection is found, it gets delete from * global list then returned. */ static struct nf_conntrack_expect * @@ -505,7 +432,7 @@ find_expectation(const struct nf_conntrack_tuple *tuple) } /* delete all expectations for this conntrack */ -void nf_ct_remove_expectations(struct nf_conn *ct) +static void remove_expectations(struct nf_conn *ct) { struct nf_conntrack_expect *i, *tmp; @@ -535,7 +462,7 @@ clean_from_lists(struct nf_conn *ct) LIST_DELETE(&nf_conntrack_hash[hr], &ct->tuplehash[IP_CT_DIR_REPLY]); /* Destroy all pending expectations */ - nf_ct_remove_expectations(ct); + remove_expectations(ct); } static void @@ -555,11 +482,12 @@ destroy_conntrack(struct nf_conntrack *nfct) /* To make sure we don't get any weird locking issues here: * destroy_conntrack() MUST NOT be called with a write lock * to nf_conntrack_lock!!! -HW */ - l3proto = __nf_ct_l3proto_find(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num); + l3proto = nf_ct_find_l3proto(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num); if (l3proto && l3proto->destroy) l3proto->destroy(ct); - proto = __nf_ct_proto_find(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num, ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum); + proto = nf_ct_find_proto(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num, + ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum); if (proto && proto->destroy) proto->destroy(ct); @@ -571,7 +499,7 @@ destroy_conntrack(struct nf_conntrack *nfct) * except TFTP can create an expectation on the first packet, * before connection is in the list, so we need to clean here, * too. */ - nf_ct_remove_expectations(ct); + remove_expectations(ct); /* We overload first tuple to link into unconfirmed list. */ if (!nf_ct_is_confirmed(ct)) { @@ -612,7 +540,7 @@ conntrack_tuple_cmp(const struct nf_conntrack_tuple_hash *i, && nf_ct_tuple_equal(tuple, &i->tuple); } -struct nf_conntrack_tuple_hash * +static struct nf_conntrack_tuple_hash * __nf_conntrack_find(const struct nf_conntrack_tuple *tuple, const struct nf_conn *ignored_conntrack) { @@ -647,29 +575,6 @@ nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple, return h; } -static void __nf_conntrack_hash_insert(struct nf_conn *ct, - unsigned int hash, - unsigned int repl_hash) -{ - ct->id = ++nf_conntrack_next_id; - list_prepend(&nf_conntrack_hash[hash], - &ct->tuplehash[IP_CT_DIR_ORIGINAL].list); - list_prepend(&nf_conntrack_hash[repl_hash], - &ct->tuplehash[IP_CT_DIR_REPLY].list); -} - -void nf_conntrack_hash_insert(struct nf_conn *ct) -{ - unsigned int hash, repl_hash; - - hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); - repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); - - write_lock_bh(&nf_conntrack_lock); - __nf_conntrack_hash_insert(ct, hash, repl_hash); - write_unlock_bh(&nf_conntrack_lock); -} - /* Confirm a connection given skb; places it in hash table */ int __nf_conntrack_confirm(struct sk_buff **pskb) @@ -716,7 +621,10 @@ __nf_conntrack_confirm(struct sk_buff **pskb) /* Remove from unconfirmed list */ list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list); - __nf_conntrack_hash_insert(ct, hash, repl_hash); + list_prepend(&nf_conntrack_hash[hash], + &ct->tuplehash[IP_CT_DIR_ORIGINAL]); + list_prepend(&nf_conntrack_hash[repl_hash], + &ct->tuplehash[IP_CT_DIR_REPLY]); /* Timer relative to confirmation time, not original setting time, otherwise we'd get timer wrap in weird delay cases. */ @@ -800,41 +708,13 @@ static inline int helper_cmp(const struct nf_conntrack_helper *i, } static struct nf_conntrack_helper * -__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple) +nf_ct_find_helper(const struct nf_conntrack_tuple *tuple) { return LIST_FIND(&helpers, helper_cmp, struct nf_conntrack_helper *, tuple); } -struct nf_conntrack_helper * -nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple) -{ - struct nf_conntrack_helper *helper; - - /* need nf_conntrack_lock to assure that helper exists until - * try_module_get() is called */ - read_lock_bh(&nf_conntrack_lock); - - helper = __nf_ct_helper_find(tuple); - if (helper) { - /* need to increase module usage count to assure helper will - * not go away while the caller is e.g. busy putting a - * conntrack in the hash that uses the helper */ - if (!try_module_get(helper->me)) - helper = NULL; - } - - read_unlock_bh(&nf_conntrack_lock); - - return helper; -} - -void nf_ct_helper_put(struct nf_conntrack_helper *helper) -{ - module_put(helper->me); -} - static struct nf_conn * __nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, const struct nf_conntrack_tuple *repl, @@ -864,7 +744,7 @@ __nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, /* find features needed by this conntrack. */ features = l3proto->get_features(orig); read_lock_bh(&nf_conntrack_lock); - if (__nf_ct_helper_find(repl) != NULL) + if (nf_ct_find_helper(repl) != NULL) features |= NF_CT_F_HELP; read_unlock_bh(&nf_conntrack_lock); @@ -914,7 +794,7 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, { struct nf_conntrack_l3proto *l3proto; - l3proto = __nf_ct_l3proto_find(orig->src.l3num); + l3proto = nf_ct_find_l3proto(orig->src.l3num); return __nf_conntrack_alloc(orig, repl, l3proto); } @@ -973,7 +853,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, nf_conntrack_get(&conntrack->master->ct_general); NF_CT_STAT_INC(expect_new); } else { - conntrack->helper = __nf_ct_helper_find(&repl_tuple); + conntrack->helper = nf_ct_find_helper(&repl_tuple); NF_CT_STAT_INC(new); } @@ -1067,13 +947,13 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb) return NF_ACCEPT; } - l3proto = __nf_ct_l3proto_find((u_int16_t)pf); + l3proto = nf_ct_find_l3proto((u_int16_t)pf); if ((ret = l3proto->prepare(pskb, hooknum, &dataoff, &protonum)) <= 0) { DEBUGP("not prepared to track yet or error occured\n"); return -ret; } - proto = __nf_ct_proto_find((u_int16_t)pf, protonum); + proto = nf_ct_find_proto((u_int16_t)pf, protonum); /* It may be an special packet, error, unclean... * inverse of the return code tells to the netfilter @@ -1122,9 +1002,9 @@ int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse, const struct nf_conntrack_tuple *orig) { return nf_ct_invert_tuple(inverse, orig, - __nf_ct_l3proto_find(orig->src.l3num), - __nf_ct_proto_find(orig->src.l3num, - orig->dst.protonum)); + nf_ct_find_l3proto(orig->src.l3num), + nf_ct_find_proto(orig->src.l3num, + orig->dst.protonum)); } /* Would two expected things clash? */ @@ -1216,7 +1096,6 @@ static void nf_conntrack_expect_insert(struct nf_conntrack_expect *exp) exp->timeout.expires = jiffies + exp->master->helper->timeout * HZ; add_timer(&exp->timeout); - exp->id = ++nf_conntrack_expect_next_id; atomic_inc(&exp->use); NF_CT_STAT_INC(expect_create); } @@ -1250,7 +1129,6 @@ static inline int refresh_timer(struct nf_conntrack_expect *i) int nf_conntrack_expect_related(struct nf_conntrack_expect *expect) { struct nf_conntrack_expect *i; - struct nf_conn *master = expect->master; int ret; DEBUGP("nf_conntrack_expect_related %p\n", related_to); @@ -1271,9 +1149,9 @@ int nf_conntrack_expect_related(struct nf_conntrack_expect *expect) } } /* Will be over limit? */ - if (master->helper->max_expected && - master->expecting >= master->helper->max_expected) - evict_oldest_expect(master); + if (expect->master->helper->max_expected && + expect->master->expecting >= expect->master->helper->max_expected) + evict_oldest_expect(expect->master); nf_conntrack_expect_insert(expect); nf_conntrack_expect_event(IPEXP_NEW, expect); @@ -1297,7 +1175,7 @@ void nf_conntrack_alter_reply(struct nf_conn *conntrack, conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply; if (!conntrack->master && conntrack->expecting == 0) - conntrack->helper = __nf_ct_helper_find(newreply); + conntrack->helper = nf_ct_find_helper(newreply); write_unlock_bh(&nf_conntrack_lock); } @@ -1322,19 +1200,6 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me) return 0; } -struct nf_conntrack_helper * -__nf_conntrack_helper_find_byname(const char *name) -{ - struct nf_conntrack_helper *h; - - list_for_each_entry(h, &helpers, list) { - if (!strcmp(h->name, name)) - return h; - } - - return NULL; -} - static inline int unhelp(struct nf_conntrack_tuple_hash *i, const struct nf_conntrack_helper *me) { @@ -1418,51 +1283,6 @@ void __nf_ct_refresh_acct(struct nf_conn *ct, nf_conntrack_event_cache(event, skb); } -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) - -#include -#include - -/* Generic function for tcp/udp/sctp/dccp and alike. This needs to be - * in ip_conntrack_core, since we don't want the protocols to autoload - * or depend on ctnetlink */ -int nf_ct_port_tuple_to_nfattr(struct sk_buff *skb, - const struct nf_conntrack_tuple *tuple) -{ - NFA_PUT(skb, CTA_PROTO_SRC_PORT, sizeof(u_int16_t), - &tuple->src.u.tcp.port); - NFA_PUT(skb, CTA_PROTO_DST_PORT, sizeof(u_int16_t), - &tuple->dst.u.tcp.port); - return 0; - -nfattr_failure: - return -1; -} - -static const size_t cta_min_proto[CTA_PROTO_MAX] = { - [CTA_PROTO_SRC_PORT-1] = sizeof(u_int16_t), - [CTA_PROTO_DST_PORT-1] = sizeof(u_int16_t) -}; - -int nf_ct_port_nfattr_to_tuple(struct nfattr *tb[], - struct nf_conntrack_tuple *t) -{ - if (!tb[CTA_PROTO_SRC_PORT-1] || !tb[CTA_PROTO_DST_PORT-1]) - return -EINVAL; - - if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) - return -EINVAL; - - t->src.u.tcp.port = - *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_SRC_PORT-1]); - t->dst.u.tcp.port = - *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_DST_PORT-1]); - - return 0; -} -#endif - /* Used by ipt_REJECT and ip6t_REJECT. */ void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb) { @@ -1545,11 +1365,6 @@ static void free_conntrack_hash(struct list_head *hash, int vmalloced, int size) get_order(sizeof(struct list_head) * size)); } -void nf_conntrack_flush() -{ - nf_ct_iterate_cleanup(kill_all, NULL); -} - /* Mishearing the voices in his head, our hero wonders how he's supposed to kill the mall. */ void nf_conntrack_cleanup(void) @@ -1563,7 +1378,7 @@ void nf_conntrack_cleanup(void) nf_ct_event_cache_flush(); i_see_dead_people: - nf_conntrack_flush(); + nf_ct_iterate_cleanup(kill_all, NULL); if (atomic_read(&nf_conntrack_count) != 0) { schedule(); goto i_see_dead_people; diff --git a/trunk/net/netfilter/nf_conntrack_ftp.c b/trunk/net/netfilter/nf_conntrack_ftp.c index d5a6eaf4a1de..65080e269f27 100644 --- a/trunk/net/netfilter/nf_conntrack_ftp.c +++ b/trunk/net/netfilter/nf_conntrack_ftp.c @@ -44,7 +44,7 @@ static unsigned int ports_c; module_param_array(ports, ushort, &ports_c, 0400); static int loose; -module_param(loose, bool, 0600); +module_param(loose, int, 0600); unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb, enum ip_conntrack_info ctinfo, diff --git a/trunk/net/netfilter/nf_conntrack_netlink.c b/trunk/net/netfilter/nf_conntrack_netlink.c deleted file mode 100644 index 73ab16bc7d40..000000000000 --- a/trunk/net/netfilter/nf_conntrack_netlink.c +++ /dev/null @@ -1,1653 +0,0 @@ -/* Connection tracking via netlink socket. Allows for user space - * protocol helpers and general trouble making from userspace. - * - * (C) 2001 by Jay Schulist - * (C) 2002-2005 by Harald Welte - * (C) 2003 by Patrick Mchardy - * (C) 2005 by Pablo Neira Ayuso - * - * I've reworked this stuff to use attributes instead of conntrack - * structures. 5.44 am. I need more tea. --pablo 05/07/11. - * - * Initial connection tracking via netlink development funded and - * generally made possible by Network Robots, Inc. (www.networkrobots.com) - * - * Further development of this code funded by Astaro AG (http://www.astaro.com) - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Derived from ip_conntrack_netlink.c: Port by Pablo Neira Ayuso (05/11/14) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -MODULE_LICENSE("GPL"); - -static char __initdata version[] = "0.92"; - -#if 0 -#define DEBUGP printk -#else -#define DEBUGP(format, args...) -#endif - - -static inline int -ctnetlink_dump_tuples_proto(struct sk_buff *skb, - const struct nf_conntrack_tuple *tuple) -{ - struct nf_conntrack_protocol *proto; - int ret = 0; - - NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); - - /* If no protocol helper is found, this function will return the - * generic protocol helper, so proto won't *ever* be NULL */ - proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum); - if (likely(proto->tuple_to_nfattr)) - ret = proto->tuple_to_nfattr(skb, tuple); - - nf_ct_proto_put(proto); - - return ret; - -nfattr_failure: - return -1; -} - -static inline int -ctnetlink_dump_tuples(struct sk_buff *skb, - const struct nf_conntrack_tuple *tuple) -{ - struct nfattr *nest_parms; - struct nf_conntrack_l3proto *l3proto; - int ret = 0; - - l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); - - nest_parms = NFA_NEST(skb, CTA_TUPLE_IP); - if (likely(l3proto->tuple_to_nfattr)) - ret = l3proto->tuple_to_nfattr(skb, tuple); - NFA_NEST_END(skb, nest_parms); - - nf_ct_l3proto_put(l3proto); - - if (unlikely(ret < 0)) - return ret; - - nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); - ret = ctnetlink_dump_tuples_proto(skb, tuple); - NFA_NEST_END(skb, nest_parms); - - return ret; - -nfattr_failure: - return -1; -} - -static inline int -ctnetlink_dump_status(struct sk_buff *skb, const struct nf_conn *ct) -{ - u_int32_t status = htonl((u_int32_t) ct->status); - NFA_PUT(skb, CTA_STATUS, sizeof(status), &status); - return 0; - -nfattr_failure: - return -1; -} - -static inline int -ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct) -{ - long timeout_l = ct->timeout.expires - jiffies; - u_int32_t timeout; - - if (timeout_l < 0) - timeout = 0; - else - timeout = htonl(timeout_l / HZ); - - NFA_PUT(skb, CTA_TIMEOUT, sizeof(timeout), &timeout); - return 0; - -nfattr_failure: - return -1; -} - -static inline int -ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct) -{ - struct nf_conntrack_protocol *proto = nf_ct_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num, ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum); - struct nfattr *nest_proto; - int ret; - - if (!proto->to_nfattr) { - nf_ct_proto_put(proto); - return 0; - } - - nest_proto = NFA_NEST(skb, CTA_PROTOINFO); - - ret = proto->to_nfattr(skb, nest_proto, ct); - - nf_ct_proto_put(proto); - - NFA_NEST_END(skb, nest_proto); - - return ret; - -nfattr_failure: - return -1; -} - -static inline int -ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct) -{ - struct nfattr *nest_helper; - - if (!ct->helper) - return 0; - - nest_helper = NFA_NEST(skb, CTA_HELP); - NFA_PUT(skb, CTA_HELP_NAME, strlen(ct->helper->name), ct->helper->name); - - if (ct->helper->to_nfattr) - ct->helper->to_nfattr(skb, ct); - - NFA_NEST_END(skb, nest_helper); - - return 0; - -nfattr_failure: - return -1; -} - -#ifdef CONFIG_NF_CT_ACCT -static inline int -ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct, - enum ip_conntrack_dir dir) -{ - enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG; - struct nfattr *nest_count = NFA_NEST(skb, type); - u_int32_t tmp; - - tmp = htonl(ct->counters[dir].packets); - NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp); - - tmp = htonl(ct->counters[dir].bytes); - NFA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(u_int32_t), &tmp); - - NFA_NEST_END(skb, nest_count); - - return 0; - -nfattr_failure: - return -1; -} -#else -#define ctnetlink_dump_counters(a, b, c) (0) -#endif - -#ifdef CONFIG_NF_CONNTRACK_MARK -static inline int -ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct) -{ - u_int32_t mark = htonl(ct->mark); - - NFA_PUT(skb, CTA_MARK, sizeof(u_int32_t), &mark); - return 0; - -nfattr_failure: - return -1; -} -#else -#define ctnetlink_dump_mark(a, b) (0) -#endif - -static inline int -ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct) -{ - u_int32_t id = htonl(ct->id); - NFA_PUT(skb, CTA_ID, sizeof(u_int32_t), &id); - return 0; - -nfattr_failure: - return -1; -} - -static inline int -ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct) -{ - u_int32_t use = htonl(atomic_read(&ct->ct_general.use)); - - NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use); - return 0; - -nfattr_failure: - return -1; -} - -#define tuple(ct, dir) (&(ct)->tuplehash[dir].tuple) - -static int -ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq, - int event, int nowait, - const struct nf_conn *ct) -{ - struct nlmsghdr *nlh; - struct nfgenmsg *nfmsg; - struct nfattr *nest_parms; - unsigned char *b; - - b = skb->tail; - - event |= NFNL_SUBSYS_CTNETLINK << 8; - nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg)); - nfmsg = NLMSG_DATA(nlh); - - nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0; - nfmsg->nfgen_family = - ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; - nfmsg->version = NFNETLINK_V0; - nfmsg->res_id = 0; - - nest_parms = NFA_NEST(skb, CTA_TUPLE_ORIG); - if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0) - goto nfattr_failure; - NFA_NEST_END(skb, nest_parms); - - nest_parms = NFA_NEST(skb, CTA_TUPLE_REPLY); - if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0) - goto nfattr_failure; - NFA_NEST_END(skb, nest_parms); - - if (ctnetlink_dump_status(skb, ct) < 0 || - ctnetlink_dump_timeout(skb, ct) < 0 || - ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || - ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0 || - ctnetlink_dump_protoinfo(skb, ct) < 0 || - ctnetlink_dump_helpinfo(skb, ct) < 0 || - ctnetlink_dump_mark(skb, ct) < 0 || - ctnetlink_dump_id(skb, ct) < 0 || - ctnetlink_dump_use(skb, ct) < 0) - goto nfattr_failure; - - nlh->nlmsg_len = skb->tail - b; - return skb->len; - -nlmsg_failure: -nfattr_failure: - skb_trim(skb, b - skb->data); - return -1; -} - -#ifdef CONFIG_NF_CONNTRACK_EVENTS -static int ctnetlink_conntrack_event(struct notifier_block *this, - unsigned long events, void *ptr) -{ - struct nlmsghdr *nlh; - struct nfgenmsg *nfmsg; - struct nfattr *nest_parms; - struct nf_conn *ct = (struct nf_conn *)ptr; - struct sk_buff *skb; - unsigned int type; - unsigned char *b; - unsigned int flags = 0, group; - - /* ignore our fake conntrack entry */ - if (ct == &nf_conntrack_untracked) - return NOTIFY_DONE; - - if (events & IPCT_DESTROY) { - type = IPCTNL_MSG_CT_DELETE; - group = NFNLGRP_CONNTRACK_DESTROY; - } else if (events & (IPCT_NEW | IPCT_RELATED)) { - type = IPCTNL_MSG_CT_NEW; - flags = NLM_F_CREATE|NLM_F_EXCL; - /* dump everything */ - events = ~0UL; - group = NFNLGRP_CONNTRACK_NEW; - } else if (events & (IPCT_STATUS | - IPCT_PROTOINFO | - IPCT_HELPER | - IPCT_HELPINFO | - IPCT_NATINFO)) { - type = IPCTNL_MSG_CT_NEW; - group = NFNLGRP_CONNTRACK_UPDATE; - } else - return NOTIFY_DONE; - - /* FIXME: Check if there are any listeners before, don't hurt performance */ - - skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); - if (!skb) - return NOTIFY_DONE; - - b = skb->tail; - - type |= NFNL_SUBSYS_CTNETLINK << 8; - nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg)); - nfmsg = NLMSG_DATA(nlh); - - nlh->nlmsg_flags = flags; - nfmsg->nfgen_family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; - nfmsg->version = NFNETLINK_V0; - nfmsg->res_id = 0; - - nest_parms = NFA_NEST(skb, CTA_TUPLE_ORIG); - if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0) - goto nfattr_failure; - NFA_NEST_END(skb, nest_parms); - - nest_parms = NFA_NEST(skb, CTA_TUPLE_REPLY); - if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0) - goto nfattr_failure; - NFA_NEST_END(skb, nest_parms); - - /* NAT stuff is now a status flag */ - if ((events & IPCT_STATUS || events & IPCT_NATINFO) - && ctnetlink_dump_status(skb, ct) < 0) - goto nfattr_failure; - if (events & IPCT_REFRESH - && ctnetlink_dump_timeout(skb, ct) < 0) - goto nfattr_failure; - if (events & IPCT_PROTOINFO - && ctnetlink_dump_protoinfo(skb, ct) < 0) - goto nfattr_failure; - if (events & IPCT_HELPINFO - && ctnetlink_dump_helpinfo(skb, ct) < 0) - goto nfattr_failure; - - if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || - ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0) - goto nfattr_failure; - - nlh->nlmsg_len = skb->tail - b; - nfnetlink_send(skb, 0, group, 0); - return NOTIFY_DONE; - -nlmsg_failure: -nfattr_failure: - kfree_skb(skb); - return NOTIFY_DONE; -} -#endif /* CONFIG_NF_CONNTRACK_EVENTS */ - -static int ctnetlink_done(struct netlink_callback *cb) -{ - DEBUGP("entered %s\n", __FUNCTION__); - return 0; -} - -#define L3PROTO(ct) ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num - -static int -ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) -{ - struct nf_conn *ct = NULL; - struct nf_conntrack_tuple_hash *h; - struct list_head *i; - u_int32_t *id = (u_int32_t *) &cb->args[1]; - struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); - u_int8_t l3proto = nfmsg->nfgen_family; - - DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__, - cb->args[0], *id); - - read_lock_bh(&nf_conntrack_lock); - for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++, *id = 0) { - list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) { - h = (struct nf_conntrack_tuple_hash *) i; - if (DIRECTION(h) != IP_CT_DIR_ORIGINAL) - continue; - ct = nf_ct_tuplehash_to_ctrack(h); - /* Dump entries of a given L3 protocol number. - * If it is not specified, ie. l3proto == 0, - * then dump everything. */ - if (l3proto && L3PROTO(ct) != l3proto) - continue; - if (ct->id <= *id) - continue; - if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, - IPCTNL_MSG_CT_NEW, - 1, ct) < 0) - goto out; - *id = ct->id; - } - } -out: - read_unlock_bh(&nf_conntrack_lock); - - DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id); - - return skb->len; -} - -#ifdef CONFIG_NF_CT_ACCT -static int -ctnetlink_dump_table_w(struct sk_buff *skb, struct netlink_callback *cb) -{ - struct nf_conn *ct = NULL; - struct nf_conntrack_tuple_hash *h; - struct list_head *i; - u_int32_t *id = (u_int32_t *) &cb->args[1]; - struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); - u_int8_t l3proto = nfmsg->nfgen_family; - - DEBUGP("entered %s, last bucket=%u id=%u\n", __FUNCTION__, - cb->args[0], *id); - - write_lock_bh(&nf_conntrack_lock); - for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++, *id = 0) { - list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) { - h = (struct nf_conntrack_tuple_hash *) i; - if (DIRECTION(h) != IP_CT_DIR_ORIGINAL) - continue; - ct = nf_ct_tuplehash_to_ctrack(h); - if (l3proto && L3PROTO(ct) != l3proto) - continue; - if (ct->id <= *id) - continue; - if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, - IPCTNL_MSG_CT_NEW, - 1, ct) < 0) - goto out; - *id = ct->id; - - memset(&ct->counters, 0, sizeof(ct->counters)); - } - } -out: - write_unlock_bh(&nf_conntrack_lock); - - DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id); - - return skb->len; -} -#endif - -static inline int -ctnetlink_parse_tuple_ip(struct nfattr *attr, struct nf_conntrack_tuple *tuple) -{ - struct nfattr *tb[CTA_IP_MAX]; - struct nf_conntrack_l3proto *l3proto; - int ret = 0; - - DEBUGP("entered %s\n", __FUNCTION__); - - nfattr_parse_nested(tb, CTA_IP_MAX, attr); - - l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); - - if (likely(l3proto->nfattr_to_tuple)) - ret = l3proto->nfattr_to_tuple(tb, tuple); - - nf_ct_l3proto_put(l3proto); - - DEBUGP("leaving\n"); - - return ret; -} - -static const size_t cta_min_proto[CTA_PROTO_MAX] = { - [CTA_PROTO_NUM-1] = sizeof(u_int8_t), -}; - -static inline int -ctnetlink_parse_tuple_proto(struct nfattr *attr, - struct nf_conntrack_tuple *tuple) -{ - struct nfattr *tb[CTA_PROTO_MAX]; - struct nf_conntrack_protocol *proto; - int ret = 0; - - DEBUGP("entered %s\n", __FUNCTION__); - - nfattr_parse_nested(tb, CTA_PROTO_MAX, attr); - - if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) - return -EINVAL; - - if (!tb[CTA_PROTO_NUM-1]) - return -EINVAL; - tuple->dst.protonum = *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]); - - proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum); - - if (likely(proto->nfattr_to_tuple)) - ret = proto->nfattr_to_tuple(tb, tuple); - - nf_ct_proto_put(proto); - - return ret; -} - -static inline int -ctnetlink_parse_tuple(struct nfattr *cda[], struct nf_conntrack_tuple *tuple, - enum ctattr_tuple type, u_int8_t l3num) -{ - struct nfattr *tb[CTA_TUPLE_MAX]; - int err; - - DEBUGP("entered %s\n", __FUNCTION__); - - memset(tuple, 0, sizeof(*tuple)); - - nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]); - - if (!tb[CTA_TUPLE_IP-1]) - return -EINVAL; - - tuple->src.l3num = l3num; - - err = ctnetlink_parse_tuple_ip(tb[CTA_TUPLE_IP-1], tuple); - if (err < 0) - return err; - - if (!tb[CTA_TUPLE_PROTO-1]) - return -EINVAL; - - err = ctnetlink_parse_tuple_proto(tb[CTA_TUPLE_PROTO-1], tuple); - if (err < 0) - return err; - - /* orig and expect tuples get DIR_ORIGINAL */ - if (type == CTA_TUPLE_REPLY) - tuple->dst.dir = IP_CT_DIR_REPLY; - else - tuple->dst.dir = IP_CT_DIR_ORIGINAL; - - NF_CT_DUMP_TUPLE(tuple); - - DEBUGP("leaving\n"); - - return 0; -} - -#ifdef CONFIG_IP_NF_NAT_NEEDED -static const size_t cta_min_protonat[CTA_PROTONAT_MAX] = { - [CTA_PROTONAT_PORT_MIN-1] = sizeof(u_int16_t), - [CTA_PROTONAT_PORT_MAX-1] = sizeof(u_int16_t), -}; - -static int ctnetlink_parse_nat_proto(struct nfattr *attr, - const struct nf_conn *ct, - struct ip_nat_range *range) -{ - struct nfattr *tb[CTA_PROTONAT_MAX]; - struct ip_nat_protocol *npt; - - DEBUGP("entered %s\n", __FUNCTION__); - - nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr); - - if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) - return -EINVAL; - - npt = ip_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum); - - if (!npt->nfattr_to_range) { - ip_nat_proto_put(npt); - return 0; - } - - /* nfattr_to_range returns 1 if it parsed, 0 if not, neg. on error */ - if (npt->nfattr_to_range(tb, range) > 0) - range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED; - - ip_nat_proto_put(npt); - - DEBUGP("leaving\n"); - return 0; -} - -static const size_t cta_min_nat[CTA_NAT_MAX] = { - [CTA_NAT_MINIP-1] = sizeof(u_int32_t), - [CTA_NAT_MAXIP-1] = sizeof(u_int32_t), -}; - -static inline int -ctnetlink_parse_nat(struct nfattr *cda[], - const struct nf_conn *ct, struct ip_nat_range *range) -{ - struct nfattr *tb[CTA_NAT_MAX]; - int err; - - DEBUGP("entered %s\n", __FUNCTION__); - - memset(range, 0, sizeof(*range)); - - nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]); - - if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat)) - return -EINVAL; - - if (tb[CTA_NAT_MINIP-1]) - range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]); - - if (!tb[CTA_NAT_MAXIP-1]) - range->max_ip = range->min_ip; - else - range->max_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MAXIP-1]); - - if (range->min_ip) - range->flags |= IP_NAT_RANGE_MAP_IPS; - - if (!tb[CTA_NAT_PROTO-1]) - return 0; - - err = ctnetlink_parse_nat_proto(tb[CTA_NAT_PROTO-1], ct, range); - if (err < 0) - return err; - - DEBUGP("leaving\n"); - return 0; -} -#endif - -static inline int -ctnetlink_parse_help(struct nfattr *attr, char **helper_name) -{ - struct nfattr *tb[CTA_HELP_MAX]; - - DEBUGP("entered %s\n", __FUNCTION__); - - nfattr_parse_nested(tb, CTA_HELP_MAX, attr); - - if (!tb[CTA_HELP_NAME-1]) - return -EINVAL; - - *helper_name = NFA_DATA(tb[CTA_HELP_NAME-1]); - - return 0; -} - -static const size_t cta_min[CTA_MAX] = { - [CTA_STATUS-1] = sizeof(u_int32_t), - [CTA_TIMEOUT-1] = sizeof(u_int32_t), - [CTA_MARK-1] = sizeof(u_int32_t), - [CTA_USE-1] = sizeof(u_int32_t), - [CTA_ID-1] = sizeof(u_int32_t) -}; - -static int -ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *cda[], int *errp) -{ - struct nf_conntrack_tuple_hash *h; - struct nf_conntrack_tuple tuple; - struct nf_conn *ct; - struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); - u_int8_t u3 = nfmsg->nfgen_family; - int err = 0; - - DEBUGP("entered %s\n", __FUNCTION__); - - if (nfattr_bad_size(cda, CTA_MAX, cta_min)) - return -EINVAL; - - if (cda[CTA_TUPLE_ORIG-1]) - err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3); - else if (cda[CTA_TUPLE_REPLY-1]) - err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3); - else { - /* Flush the whole table */ - nf_conntrack_flush(); - return 0; - } - - if (err < 0) - return err; - - h = nf_conntrack_find_get(&tuple, NULL); - if (!h) { - DEBUGP("tuple not found in conntrack hash\n"); - return -ENOENT; - } - - ct = nf_ct_tuplehash_to_ctrack(h); - - if (cda[CTA_ID-1]) { - u_int32_t id = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_ID-1])); - if (ct->id != id) { - nf_ct_put(ct); - return -ENOENT; - } - } - if (del_timer(&ct->timeout)) - ct->timeout.function((unsigned long)ct); - - nf_ct_put(ct); - DEBUGP("leaving\n"); - - return 0; -} - -static int -ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *cda[], int *errp) -{ - struct nf_conntrack_tuple_hash *h; - struct nf_conntrack_tuple tuple; - struct nf_conn *ct; - struct sk_buff *skb2 = NULL; - struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); - u_int8_t u3 = nfmsg->nfgen_family; - int err = 0; - - DEBUGP("entered %s\n", __FUNCTION__); - - if (nlh->nlmsg_flags & NLM_F_DUMP) { - u32 rlen; - - if (NFNL_MSG_TYPE(nlh->nlmsg_type) == - IPCTNL_MSG_CT_GET_CTRZERO) { -#ifdef CONFIG_NF_CT_ACCT - if ((*errp = netlink_dump_start(ctnl, skb, nlh, - ctnetlink_dump_table_w, - ctnetlink_done)) != 0) - return -EINVAL; -#else - return -ENOTSUPP; -#endif - } else { - if ((*errp = netlink_dump_start(ctnl, skb, nlh, - ctnetlink_dump_table, - ctnetlink_done)) != 0) - return -EINVAL; - } - - rlen = NLMSG_ALIGN(nlh->nlmsg_len); - if (rlen > skb->len) - rlen = skb->len; - skb_pull(skb, rlen); - return 0; - } - - if (nfattr_bad_size(cda, CTA_MAX, cta_min)) - return -EINVAL; - - if (cda[CTA_TUPLE_ORIG-1]) - err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3); - else if (cda[CTA_TUPLE_REPLY-1]) - err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3); - else - return -EINVAL; - - if (err < 0) - return err; - - h = nf_conntrack_find_get(&tuple, NULL); - if (!h) { - DEBUGP("tuple not found in conntrack hash"); - return -ENOENT; - } - DEBUGP("tuple found\n"); - ct = nf_ct_tuplehash_to_ctrack(h); - - err = -ENOMEM; - skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); - if (!skb2) { - nf_ct_put(ct); - return -ENOMEM; - } - NETLINK_CB(skb2).dst_pid = NETLINK_CB(skb).pid; - - err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, - IPCTNL_MSG_CT_NEW, 1, ct); - nf_ct_put(ct); - if (err <= 0) - goto free; - - err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT); - if (err < 0) - goto out; - - DEBUGP("leaving\n"); - return 0; - -free: - kfree_skb(skb2); -out: - return err; -} - -static inline int -ctnetlink_change_status(struct nf_conn *ct, struct nfattr *cda[]) -{ - unsigned long d; - unsigned status = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_STATUS-1])); - d = ct->status ^ status; - - if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING)) - /* unchangeable */ - return -EINVAL; - - if (d & IPS_SEEN_REPLY && !(status & IPS_SEEN_REPLY)) - /* SEEN_REPLY bit can only be set */ - return -EINVAL; - - - if (d & IPS_ASSURED && !(status & IPS_ASSURED)) - /* ASSURED bit can only be set */ - return -EINVAL; - - if (cda[CTA_NAT-1]) { -#ifndef CONFIG_IP_NF_NAT_NEEDED - return -EINVAL; -#else - unsigned int hooknum; - struct ip_nat_range range; - - if (ctnetlink_parse_nat(cda, ct, &range) < 0) - return -EINVAL; - - DEBUGP("NAT: %u.%u.%u.%u-%u.%u.%u.%u:%u-%u\n", - NIPQUAD(range.min_ip), NIPQUAD(range.max_ip), - htons(range.min.all), htons(range.max.all)); - - /* This is tricky but it works. ip_nat_setup_info needs the - * hook number as parameter, so let's do the correct - * conversion and run away */ - if (status & IPS_SRC_NAT_DONE) - hooknum = NF_IP_POST_ROUTING; /* IP_NAT_MANIP_SRC */ - else if (status & IPS_DST_NAT_DONE) - hooknum = NF_IP_PRE_ROUTING; /* IP_NAT_MANIP_DST */ - else - return -EINVAL; /* Missing NAT flags */ - - DEBUGP("NAT status: %lu\n", - status & (IPS_NAT_MASK | IPS_NAT_DONE_MASK)); - - if (ip_nat_initialized(ct, HOOK2MANIP(hooknum))) - return -EEXIST; - ip_nat_setup_info(ct, &range, hooknum); - - DEBUGP("NAT status after setup_info: %lu\n", - ct->status & (IPS_NAT_MASK | IPS_NAT_DONE_MASK)); -#endif - } - - /* Be careful here, modifying NAT bits can screw up things, - * so don't let users modify them directly if they don't pass - * ip_nat_range. */ - ct->status |= status & ~(IPS_NAT_DONE_MASK | IPS_NAT_MASK); - return 0; -} - - -static inline int -ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[]) -{ - struct nf_conntrack_helper *helper; - char *helpname; - int err; - - DEBUGP("entered %s\n", __FUNCTION__); - - /* don't change helper of sibling connections */ - if (ct->master) - return -EINVAL; - - err = ctnetlink_parse_help(cda[CTA_HELP-1], &helpname); - if (err < 0) - return err; - - helper = __nf_conntrack_helper_find_byname(helpname); - if (!helper) { - if (!strcmp(helpname, "")) - helper = NULL; - else - return -EINVAL; - } - - if (ct->helper) { - if (!helper) { - /* we had a helper before ... */ - nf_ct_remove_expectations(ct); - ct->helper = NULL; - } else { - /* need to zero data of old helper */ - memset(&ct->help, 0, sizeof(ct->help)); - } - } - - ct->helper = helper; - - return 0; -} - -static inline int -ctnetlink_change_timeout(struct nf_conn *ct, struct nfattr *cda[]) -{ - u_int32_t timeout = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_TIMEOUT-1])); - - if (!del_timer(&ct->timeout)) - return -ETIME; - - ct->timeout.expires = jiffies + timeout * HZ; - add_timer(&ct->timeout); - - return 0; -} - -static inline int -ctnetlink_change_protoinfo(struct nf_conn *ct, struct nfattr *cda[]) -{ - struct nfattr *tb[CTA_PROTOINFO_MAX], *attr = cda[CTA_PROTOINFO-1]; - struct nf_conntrack_protocol *proto; - u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; - u_int16_t l3num = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; - int err = 0; - - nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr); - - proto = nf_ct_proto_find_get(l3num, npt); - - if (proto->from_nfattr) - err = proto->from_nfattr(tb, ct); - nf_ct_proto_put(proto); - - return err; -} - -static int -ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[]) -{ - int err; - - DEBUGP("entered %s\n", __FUNCTION__); - - if (cda[CTA_HELP-1]) { - err = ctnetlink_change_helper(ct, cda); - if (err < 0) - return err; - } - - if (cda[CTA_TIMEOUT-1]) { - err = ctnetlink_change_timeout(ct, cda); - if (err < 0) - return err; - } - - if (cda[CTA_STATUS-1]) { - err = ctnetlink_change_status(ct, cda); - if (err < 0) - return err; - } - - if (cda[CTA_PROTOINFO-1]) { - err = ctnetlink_change_protoinfo(ct, cda); - if (err < 0) - return err; - } - -#if defined(CONFIG_IP_NF_CONNTRACK_MARK) - if (cda[CTA_MARK-1]) - ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); -#endif - - DEBUGP("all done\n"); - return 0; -} - -static int -ctnetlink_create_conntrack(struct nfattr *cda[], - struct nf_conntrack_tuple *otuple, - struct nf_conntrack_tuple *rtuple) -{ - struct nf_conn *ct; - int err = -EINVAL; - - DEBUGP("entered %s\n", __FUNCTION__); - - ct = nf_conntrack_alloc(otuple, rtuple); - if (ct == NULL || IS_ERR(ct)) - return -ENOMEM; - - if (!cda[CTA_TIMEOUT-1]) - goto err; - ct->timeout.expires = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_TIMEOUT-1])); - - ct->timeout.expires = jiffies + ct->timeout.expires * HZ; - ct->status |= IPS_CONFIRMED; - - err = ctnetlink_change_status(ct, cda); - if (err < 0) - goto err; - - if (cda[CTA_PROTOINFO-1]) { - err = ctnetlink_change_protoinfo(ct, cda); - if (err < 0) - return err; - } - -#if defined(CONFIG_IP_NF_CONNTRACK_MARK) - if (cda[CTA_MARK-1]) - ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); -#endif - - ct->helper = nf_ct_helper_find_get(rtuple); - - add_timer(&ct->timeout); - nf_conntrack_hash_insert(ct); - - if (ct->helper) - nf_ct_helper_put(ct->helper); - - DEBUGP("conntrack with id %u inserted\n", ct->id); - return 0; - -err: - nf_conntrack_free(ct); - return err; -} - -static int -ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *cda[], int *errp) -{ - struct nf_conntrack_tuple otuple, rtuple; - struct nf_conntrack_tuple_hash *h = NULL; - struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); - u_int8_t u3 = nfmsg->nfgen_family; - int err = 0; - - DEBUGP("entered %s\n", __FUNCTION__); - - if (nfattr_bad_size(cda, CTA_MAX, cta_min)) - return -EINVAL; - - if (cda[CTA_TUPLE_ORIG-1]) { - err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG, u3); - if (err < 0) - return err; - } - - if (cda[CTA_TUPLE_REPLY-1]) { - err = ctnetlink_parse_tuple(cda, &rtuple, CTA_TUPLE_REPLY, u3); - if (err < 0) - return err; - } - - write_lock_bh(&nf_conntrack_lock); - if (cda[CTA_TUPLE_ORIG-1]) - h = __nf_conntrack_find(&otuple, NULL); - else if (cda[CTA_TUPLE_REPLY-1]) - h = __nf_conntrack_find(&rtuple, NULL); - - if (h == NULL) { - write_unlock_bh(&nf_conntrack_lock); - DEBUGP("no such conntrack, create new\n"); - err = -ENOENT; - if (nlh->nlmsg_flags & NLM_F_CREATE) - err = ctnetlink_create_conntrack(cda, &otuple, &rtuple); - return err; - } - /* implicit 'else' */ - - /* we only allow nat config for new conntracks */ - if (cda[CTA_NAT-1]) { - err = -EINVAL; - goto out_unlock; - } - - /* We manipulate the conntrack inside the global conntrack table lock, - * so there's no need to increase the refcount */ - DEBUGP("conntrack found\n"); - err = -EEXIST; - if (!(nlh->nlmsg_flags & NLM_F_EXCL)) - err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), cda); - -out_unlock: - write_unlock_bh(&nf_conntrack_lock); - return err; -} - -/*********************************************************************** - * EXPECT - ***********************************************************************/ - -static inline int -ctnetlink_exp_dump_tuple(struct sk_buff *skb, - const struct nf_conntrack_tuple *tuple, - enum ctattr_expect type) -{ - struct nfattr *nest_parms = NFA_NEST(skb, type); - - if (ctnetlink_dump_tuples(skb, tuple) < 0) - goto nfattr_failure; - - NFA_NEST_END(skb, nest_parms); - - return 0; - -nfattr_failure: - return -1; -} - -static inline int -ctnetlink_exp_dump_expect(struct sk_buff *skb, - const struct nf_conntrack_expect *exp) -{ - struct nf_conn *master = exp->master; - u_int32_t timeout = htonl((exp->timeout.expires - jiffies) / HZ); - u_int32_t id = htonl(exp->id); - - if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0) - goto nfattr_failure; - if (ctnetlink_exp_dump_tuple(skb, &exp->mask, CTA_EXPECT_MASK) < 0) - goto nfattr_failure; - if (ctnetlink_exp_dump_tuple(skb, - &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple, - CTA_EXPECT_MASTER) < 0) - goto nfattr_failure; - - NFA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(timeout), &timeout); - NFA_PUT(skb, CTA_EXPECT_ID, sizeof(u_int32_t), &id); - - return 0; - -nfattr_failure: - return -1; -} - -static int -ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq, - int event, - int nowait, - const struct nf_conntrack_expect *exp) -{ - struct nlmsghdr *nlh; - struct nfgenmsg *nfmsg; - unsigned char *b; - - b = skb->tail; - - event |= NFNL_SUBSYS_CTNETLINK_EXP << 8; - nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg)); - nfmsg = NLMSG_DATA(nlh); - - nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0; - nfmsg->nfgen_family = exp->tuple.src.l3num; - nfmsg->version = NFNETLINK_V0; - nfmsg->res_id = 0; - - if (ctnetlink_exp_dump_expect(skb, exp) < 0) - goto nfattr_failure; - - nlh->nlmsg_len = skb->tail - b; - return skb->len; - -nlmsg_failure: -nfattr_failure: - skb_trim(skb, b - skb->data); - return -1; -} - -#ifdef CONFIG_NF_CONNTRACK_EVENTS -static int ctnetlink_expect_event(struct notifier_block *this, - unsigned long events, void *ptr) -{ - struct nlmsghdr *nlh; - struct nfgenmsg *nfmsg; - struct nf_conntrack_expect *exp = (struct nf_conntrack_expect *)ptr; - struct sk_buff *skb; - unsigned int type; - unsigned char *b; - int flags = 0; - - if (events & IPEXP_NEW) { - type = IPCTNL_MSG_EXP_NEW; - flags = NLM_F_CREATE|NLM_F_EXCL; - } else - return NOTIFY_DONE; - - skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); - if (!skb) - return NOTIFY_DONE; - - b = skb->tail; - - type |= NFNL_SUBSYS_CTNETLINK << 8; - nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg)); - nfmsg = NLMSG_DATA(nlh); - - nlh->nlmsg_flags = flags; - nfmsg->nfgen_family = exp->tuple.src.l3num; - nfmsg->version = NFNETLINK_V0; - nfmsg->res_id = 0; - - if (ctnetlink_exp_dump_expect(skb, exp) < 0) - goto nfattr_failure; - - nlh->nlmsg_len = skb->tail - b; - nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0); - return NOTIFY_DONE; - -nlmsg_failure: -nfattr_failure: - kfree_skb(skb); - return NOTIFY_DONE; -} -#endif - -static int -ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) -{ - struct nf_conntrack_expect *exp = NULL; - struct list_head *i; - u_int32_t *id = (u_int32_t *) &cb->args[0]; - struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); - u_int8_t l3proto = nfmsg->nfgen_family; - - DEBUGP("entered %s, last id=%llu\n", __FUNCTION__, *id); - - read_lock_bh(&nf_conntrack_lock); - list_for_each_prev(i, &nf_conntrack_expect_list) { - exp = (struct nf_conntrack_expect *) i; - if (l3proto && exp->tuple.src.l3num != l3proto) - continue; - if (exp->id <= *id) - continue; - if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, - IPCTNL_MSG_EXP_NEW, - 1, exp) < 0) - goto out; - *id = exp->id; - } -out: - read_unlock_bh(&nf_conntrack_lock); - - DEBUGP("leaving, last id=%llu\n", *id); - - return skb->len; -} - -static const size_t cta_min_exp[CTA_EXPECT_MAX] = { - [CTA_EXPECT_TIMEOUT-1] = sizeof(u_int32_t), - [CTA_EXPECT_ID-1] = sizeof(u_int32_t) -}; - -static int -ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *cda[], int *errp) -{ - struct nf_conntrack_tuple tuple; - struct nf_conntrack_expect *exp; - struct sk_buff *skb2; - struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); - u_int8_t u3 = nfmsg->nfgen_family; - int err = 0; - - DEBUGP("entered %s\n", __FUNCTION__); - - if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) - return -EINVAL; - - if (nlh->nlmsg_flags & NLM_F_DUMP) { - u32 rlen; - - if ((*errp = netlink_dump_start(ctnl, skb, nlh, - ctnetlink_exp_dump_table, - ctnetlink_done)) != 0) - return -EINVAL; - rlen = NLMSG_ALIGN(nlh->nlmsg_len); - if (rlen > skb->len) - rlen = skb->len; - skb_pull(skb, rlen); - return 0; - } - - if (cda[CTA_EXPECT_MASTER-1]) - err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER, u3); - else - return -EINVAL; - - if (err < 0) - return err; - - exp = nf_conntrack_expect_find(&tuple); - if (!exp) - return -ENOENT; - - if (cda[CTA_EXPECT_ID-1]) { - u_int32_t id = *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]); - if (exp->id != ntohl(id)) { - nf_conntrack_expect_put(exp); - return -ENOENT; - } - } - - err = -ENOMEM; - skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); - if (!skb2) - goto out; - NETLINK_CB(skb2).dst_pid = NETLINK_CB(skb).pid; - - err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid, - nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, - 1, exp); - if (err <= 0) - goto free; - - nf_conntrack_expect_put(exp); - - return netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT); - -free: - kfree_skb(skb2); -out: - nf_conntrack_expect_put(exp); - return err; -} - -static int -ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *cda[], int *errp) -{ - struct nf_conntrack_expect *exp, *tmp; - struct nf_conntrack_tuple tuple; - struct nf_conntrack_helper *h; - struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); - u_int8_t u3 = nfmsg->nfgen_family; - int err; - - if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) - return -EINVAL; - - if (cda[CTA_EXPECT_TUPLE-1]) { - /* delete a single expect by tuple */ - err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); - if (err < 0) - return err; - - /* bump usage count to 2 */ - exp = nf_conntrack_expect_find(&tuple); - if (!exp) - return -ENOENT; - - if (cda[CTA_EXPECT_ID-1]) { - u_int32_t id = - *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]); - if (exp->id != ntohl(id)) { - nf_conntrack_expect_put(exp); - return -ENOENT; - } - } - - /* after list removal, usage count == 1 */ - nf_conntrack_unexpect_related(exp); - /* have to put what we 'get' above. - * after this line usage count == 0 */ - nf_conntrack_expect_put(exp); - } else if (cda[CTA_EXPECT_HELP_NAME-1]) { - char *name = NFA_DATA(cda[CTA_EXPECT_HELP_NAME-1]); - - /* delete all expectations for this helper */ - write_lock_bh(&nf_conntrack_lock); - h = __nf_conntrack_helper_find_byname(name); - if (!h) { - write_unlock_bh(&nf_conntrack_lock); - return -EINVAL; - } - list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, - list) { - if (exp->master->helper == h - && del_timer(&exp->timeout)) { - nf_ct_unlink_expect(exp); - nf_conntrack_expect_put(exp); - } - } - write_unlock_bh(&nf_conntrack_lock); - } else { - /* This basically means we have to flush everything*/ - write_lock_bh(&nf_conntrack_lock); - list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, - list) { - if (del_timer(&exp->timeout)) { - nf_ct_unlink_expect(exp); - nf_conntrack_expect_put(exp); - } - } - write_unlock_bh(&nf_conntrack_lock); - } - - return 0; -} -static int -ctnetlink_change_expect(struct nf_conntrack_expect *x, struct nfattr *cda[]) -{ - return -EOPNOTSUPP; -} - -static int -ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3) -{ - struct nf_conntrack_tuple tuple, mask, master_tuple; - struct nf_conntrack_tuple_hash *h = NULL; - struct nf_conntrack_expect *exp; - struct nf_conn *ct; - int err = 0; - - DEBUGP("entered %s\n", __FUNCTION__); - - /* caller guarantees that those three CTA_EXPECT_* exist */ - err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); - if (err < 0) - return err; - err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK, u3); - if (err < 0) - return err; - err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER, u3); - if (err < 0) - return err; - - /* Look for master conntrack of this expectation */ - h = nf_conntrack_find_get(&master_tuple, NULL); - if (!h) - return -ENOENT; - ct = nf_ct_tuplehash_to_ctrack(h); - - if (!ct->helper) { - /* such conntrack hasn't got any helper, abort */ - err = -EINVAL; - goto out; - } - - exp = nf_conntrack_expect_alloc(ct); - if (!exp) { - err = -ENOMEM; - goto out; - } - - exp->expectfn = NULL; - exp->flags = 0; - exp->master = ct; - memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple)); - memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple)); - - err = nf_conntrack_expect_related(exp); - nf_conntrack_expect_put(exp); - -out: - nf_ct_put(nf_ct_tuplehash_to_ctrack(h)); - return err; -} - -static int -ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, - struct nlmsghdr *nlh, struct nfattr *cda[], int *errp) -{ - struct nf_conntrack_tuple tuple; - struct nf_conntrack_expect *exp; - struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); - u_int8_t u3 = nfmsg->nfgen_family; - int err = 0; - - DEBUGP("entered %s\n", __FUNCTION__); - - if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) - return -EINVAL; - - if (!cda[CTA_EXPECT_TUPLE-1] - || !cda[CTA_EXPECT_MASK-1] - || !cda[CTA_EXPECT_MASTER-1]) - return -EINVAL; - - err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); - if (err < 0) - return err; - - write_lock_bh(&nf_conntrack_lock); - exp = __nf_conntrack_expect_find(&tuple); - - if (!exp) { - write_unlock_bh(&nf_conntrack_lock); - err = -ENOENT; - if (nlh->nlmsg_flags & NLM_F_CREATE) - err = ctnetlink_create_expect(cda, u3); - return err; - } - - err = -EEXIST; - if (!(nlh->nlmsg_flags & NLM_F_EXCL)) - err = ctnetlink_change_expect(exp, cda); - write_unlock_bh(&nf_conntrack_lock); - - DEBUGP("leaving\n"); - - return err; -} - -#ifdef CONFIG_NF_CONNTRACK_EVENTS -static struct notifier_block ctnl_notifier = { - .notifier_call = ctnetlink_conntrack_event, -}; - -static struct notifier_block ctnl_notifier_exp = { - .notifier_call = ctnetlink_expect_event, -}; -#endif - -static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = { - [IPCTNL_MSG_CT_NEW] = { .call = ctnetlink_new_conntrack, - .attr_count = CTA_MAX, }, - [IPCTNL_MSG_CT_GET] = { .call = ctnetlink_get_conntrack, - .attr_count = CTA_MAX, }, - [IPCTNL_MSG_CT_DELETE] = { .call = ctnetlink_del_conntrack, - .attr_count = CTA_MAX, }, - [IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack, - .attr_count = CTA_MAX, }, -}; - -static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = { - [IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect, - .attr_count = CTA_EXPECT_MAX, }, - [IPCTNL_MSG_EXP_NEW] = { .call = ctnetlink_new_expect, - .attr_count = CTA_EXPECT_MAX, }, - [IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect, - .attr_count = CTA_EXPECT_MAX, }, -}; - -static struct nfnetlink_subsystem ctnl_subsys = { - .name = "conntrack", - .subsys_id = NFNL_SUBSYS_CTNETLINK, - .cb_count = IPCTNL_MSG_MAX, - .cb = ctnl_cb, -}; - -static struct nfnetlink_subsystem ctnl_exp_subsys = { - .name = "conntrack_expect", - .subsys_id = NFNL_SUBSYS_CTNETLINK_EXP, - .cb_count = IPCTNL_MSG_EXP_MAX, - .cb = ctnl_exp_cb, -}; - -MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK); - -static int __init ctnetlink_init(void) -{ - int ret; - - printk("ctnetlink v%s: registering with nfnetlink.\n", version); - ret = nfnetlink_subsys_register(&ctnl_subsys); - if (ret < 0) { - printk("ctnetlink_init: cannot register with nfnetlink.\n"); - goto err_out; - } - - ret = nfnetlink_subsys_register(&ctnl_exp_subsys); - if (ret < 0) { - printk("ctnetlink_init: cannot register exp with nfnetlink.\n"); - goto err_unreg_subsys; - } - -#ifdef CONFIG_NF_CONNTRACK_EVENTS - ret = nf_conntrack_register_notifier(&ctnl_notifier); - if (ret < 0) { - printk("ctnetlink_init: cannot register notifier.\n"); - goto err_unreg_exp_subsys; - } - - ret = nf_conntrack_expect_register_notifier(&ctnl_notifier_exp); - if (ret < 0) { - printk("ctnetlink_init: cannot expect register notifier.\n"); - goto err_unreg_notifier; - } -#endif - - return 0; - -#ifdef CONFIG_NF_CONNTRACK_EVENTS -err_unreg_notifier: - nf_conntrack_unregister_notifier(&ctnl_notifier); -err_unreg_exp_subsys: - nfnetlink_subsys_unregister(&ctnl_exp_subsys); -#endif -err_unreg_subsys: - nfnetlink_subsys_unregister(&ctnl_subsys); -err_out: - return ret; -} - -static void __exit ctnetlink_exit(void) -{ - printk("ctnetlink: unregistering from nfnetlink.\n"); - -#ifdef CONFIG_NF_CONNTRACK_EVENTS - nf_conntrack_unregister_notifier(&ctnl_notifier_exp); - nf_conntrack_unregister_notifier(&ctnl_notifier); -#endif - - nfnetlink_subsys_unregister(&ctnl_exp_subsys); - nfnetlink_subsys_unregister(&ctnl_subsys); - return; -} - -module_init(ctnetlink_init); -module_exit(ctnetlink_exit); diff --git a/trunk/net/netfilter/nf_conntrack_proto_tcp.c b/trunk/net/netfilter/nf_conntrack_proto_tcp.c index 6167137a5cb5..6035633d8225 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_tcp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_tcp.c @@ -1147,63 +1147,6 @@ static int tcp_new(struct nf_conn *conntrack, receiver->td_scale); return 1; } - -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) - -#include -#include - -static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa, - const struct nf_conn *ct) -{ - struct nfattr *nest_parms; - - read_lock_bh(&tcp_lock); - nest_parms = NFA_NEST(skb, CTA_PROTOINFO_TCP); - NFA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t), - &ct->proto.tcp.state); - read_unlock_bh(&tcp_lock); - - NFA_NEST_END(skb, nest_parms); - - return 0; - -nfattr_failure: - read_unlock_bh(&tcp_lock); - return -1; -} - -static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX] = { - [CTA_PROTOINFO_TCP_STATE-1] = sizeof(u_int8_t), -}; - -static int nfattr_to_tcp(struct nfattr *cda[], struct nf_conn *ct) -{ - struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1]; - struct nfattr *tb[CTA_PROTOINFO_TCP_MAX]; - - /* updates could not contain anything about the private - * protocol info, in that case skip the parsing */ - if (!attr) - return 0; - - nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr); - - if (nfattr_bad_size(tb, CTA_PROTOINFO_TCP_MAX, cta_min_tcp)) - return -EINVAL; - - if (!tb[CTA_PROTOINFO_TCP_STATE-1]) - return -EINVAL; - - write_lock_bh(&tcp_lock); - ct->proto.tcp.state = - *(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_TCP_STATE-1]); - write_unlock_bh(&tcp_lock); - - return 0; -} -#endif struct nf_conntrack_protocol nf_conntrack_protocol_tcp4 = { @@ -1217,13 +1160,6 @@ struct nf_conntrack_protocol nf_conntrack_protocol_tcp4 = .packet = tcp_packet, .new = tcp_new, .error = tcp_error4, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) - .to_nfattr = tcp_to_nfattr, - .from_nfattr = nfattr_to_tcp, - .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, - .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, -#endif }; struct nf_conntrack_protocol nf_conntrack_protocol_tcp6 = @@ -1238,13 +1174,6 @@ struct nf_conntrack_protocol nf_conntrack_protocol_tcp6 = .packet = tcp_packet, .new = tcp_new, .error = tcp_error6, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) - .to_nfattr = tcp_to_nfattr, - .from_nfattr = nfattr_to_tcp, - .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, - .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, -#endif }; EXPORT_SYMBOL(nf_conntrack_protocol_tcp4); diff --git a/trunk/net/netfilter/nf_conntrack_proto_udp.c b/trunk/net/netfilter/nf_conntrack_proto_udp.c index 1a592a556182..3cae7ce420dd 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_udp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_udp.c @@ -196,11 +196,6 @@ struct nf_conntrack_protocol nf_conntrack_protocol_udp4 = .packet = udp_packet, .new = udp_new, .error = udp_error4, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) - .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, - .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, -#endif }; struct nf_conntrack_protocol nf_conntrack_protocol_udp6 = @@ -215,11 +210,6 @@ struct nf_conntrack_protocol nf_conntrack_protocol_udp6 = .packet = udp_packet, .new = udp_new, .error = udp_error6, -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) - .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, - .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, -#endif }; EXPORT_SYMBOL(nf_conntrack_protocol_udp4); diff --git a/trunk/net/netfilter/nf_conntrack_standalone.c b/trunk/net/netfilter/nf_conntrack_standalone.c index d17e42b28c79..5af381f9fe3d 100644 --- a/trunk/net/netfilter/nf_conntrack_standalone.c +++ b/trunk/net/netfilter/nf_conntrack_standalone.c @@ -161,14 +161,14 @@ static int ct_seq_show(struct seq_file *s, void *v) if (NF_CT_DIRECTION(hash)) return 0; - l3proto = __nf_ct_l3proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL] - .tuple.src.l3num); + l3proto = nf_ct_find_l3proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL] + .tuple.src.l3num); NF_CT_ASSERT(l3proto); - proto = __nf_ct_proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL] - .tuple.src.l3num, - conntrack->tuplehash[IP_CT_DIR_ORIGINAL] - .tuple.dst.protonum); + proto = nf_ct_find_proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL] + .tuple.src.l3num, + conntrack->tuplehash[IP_CT_DIR_ORIGINAL] + .tuple.dst.protonum); NF_CT_ASSERT(proto); if (seq_printf(s, "%-8s %u %-8s %u %ld ", @@ -307,9 +307,9 @@ static int exp_seq_show(struct seq_file *s, void *v) expect->tuple.src.l3num, expect->tuple.dst.protonum); print_tuple(s, &expect->tuple, - __nf_ct_l3proto_find(expect->tuple.src.l3num), - __nf_ct_proto_find(expect->tuple.src.l3num, - expect->tuple.dst.protonum)); + nf_ct_find_l3proto(expect->tuple.src.l3num), + nf_ct_find_proto(expect->tuple.src.l3num, + expect->tuple.dst.protonum)); return seq_putc(s, '\n'); } @@ -847,11 +847,7 @@ EXPORT_SYMBOL(nf_conntrack_helper_unregister); EXPORT_SYMBOL(nf_ct_iterate_cleanup); EXPORT_SYMBOL(__nf_ct_refresh_acct); EXPORT_SYMBOL(nf_ct_protos); -EXPORT_SYMBOL(__nf_ct_proto_find); -EXPORT_SYMBOL(nf_ct_proto_find_get); -EXPORT_SYMBOL(nf_ct_proto_put); -EXPORT_SYMBOL(nf_ct_l3proto_find_get); -EXPORT_SYMBOL(nf_ct_l3proto_put); +EXPORT_SYMBOL(nf_ct_find_proto); EXPORT_SYMBOL(nf_ct_l3protos); EXPORT_SYMBOL(nf_conntrack_expect_alloc); EXPORT_SYMBOL(nf_conntrack_expect_put); @@ -871,21 +867,3 @@ EXPORT_SYMBOL(nf_ct_get_tuple); EXPORT_SYMBOL(nf_ct_invert_tuple); EXPORT_SYMBOL(nf_conntrack_in); EXPORT_SYMBOL(__nf_conntrack_attach); -EXPORT_SYMBOL(nf_conntrack_alloc); -EXPORT_SYMBOL(nf_conntrack_free); -EXPORT_SYMBOL(nf_conntrack_flush); -EXPORT_SYMBOL(nf_ct_remove_expectations); -EXPORT_SYMBOL(nf_ct_helper_find_get); -EXPORT_SYMBOL(nf_ct_helper_put); -EXPORT_SYMBOL(__nf_conntrack_helper_find_byname); -EXPORT_SYMBOL(__nf_conntrack_find); -EXPORT_SYMBOL(nf_ct_unlink_expect); -EXPORT_SYMBOL(nf_conntrack_hash_insert); -EXPORT_SYMBOL(__nf_conntrack_expect_find); -EXPORT_SYMBOL(nf_conntrack_expect_find); -EXPORT_SYMBOL(nf_conntrack_expect_list); -#if defined(CONFIG_NF_CT_NETLINK) || \ - defined(CONFIG_NF_CT_NETLINK_MODULE) -EXPORT_SYMBOL(nf_ct_port_tuple_to_nfattr); -EXPORT_SYMBOL(nf_ct_port_nfattr_to_tuple); -#endif diff --git a/trunk/net/netfilter/nfnetlink_queue.c b/trunk/net/netfilter/nfnetlink_queue.c index 18ed9c5d209c..55afdda3d940 100644 --- a/trunk/net/netfilter/nfnetlink_queue.c +++ b/trunk/net/netfilter/nfnetlink_queue.c @@ -345,10 +345,6 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, struct nfqnl_msg_packet_hdr pmsg; struct nlmsghdr *nlh; struct nfgenmsg *nfmsg; - struct nf_info *entinf = entry->info; - struct sk_buff *entskb = entry->skb; - struct net_device *indev; - struct net_device *outdev; unsigned int tmp_uint; QDEBUG("entered\n"); @@ -365,8 +361,6 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, + NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_hw)) + NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_timestamp)); - outdev = entinf->outdev; - spin_lock_bh(&queue->lock); switch (queue->copy_mode) { @@ -376,15 +370,15 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, break; case NFQNL_COPY_PACKET: - if (entskb->ip_summed == CHECKSUM_HW && - (*errp = skb_checksum_help(entskb, - outdev == NULL))) { + if (entry->skb->ip_summed == CHECKSUM_HW && + (*errp = skb_checksum_help(entry->skb, + entry->info->outdev == NULL))) { spin_unlock_bh(&queue->lock); return NULL; } if (queue->copy_range == 0 - || queue->copy_range > entskb->len) - data_len = entskb->len; + || queue->copy_range > entry->skb->len) + data_len = entry->skb->len; else data_len = queue->copy_range; @@ -408,30 +402,29 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, NFNL_SUBSYS_QUEUE << 8 | NFQNL_MSG_PACKET, sizeof(struct nfgenmsg)); nfmsg = NLMSG_DATA(nlh); - nfmsg->nfgen_family = entinf->pf; + nfmsg->nfgen_family = entry->info->pf; nfmsg->version = NFNETLINK_V0; nfmsg->res_id = htons(queue->queue_num); pmsg.packet_id = htonl(entry->id); - pmsg.hw_protocol = htons(entskb->protocol); - pmsg.hook = entinf->hook; + pmsg.hw_protocol = htons(entry->skb->protocol); + pmsg.hook = entry->info->hook; NFA_PUT(skb, NFQA_PACKET_HDR, sizeof(pmsg), &pmsg); - indev = entinf->indev; - if (indev) { - tmp_uint = htonl(indev->ifindex); + if (entry->info->indev) { + tmp_uint = htonl(entry->info->indev->ifindex); #ifndef CONFIG_BRIDGE_NETFILTER NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint); #else - if (entinf->pf == PF_BRIDGE) { + if (entry->info->pf == PF_BRIDGE) { /* Case 1: indev is physical input device, we need to * look for bridge group (when called from * netfilter_bridge) */ NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV, sizeof(tmp_uint), &tmp_uint); /* this is the bridge group "brX" */ - tmp_uint = htonl(indev->br_port->br->dev->ifindex); + tmp_uint = htonl(entry->info->indev->br_port->br->dev->ifindex); NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint); } else { @@ -439,9 +432,9 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, * physical device (when called from ipv4) */ NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint); - if (entskb->nf_bridge - && entskb->nf_bridge->physindev) { - tmp_uint = htonl(entskb->nf_bridge->physindev->ifindex); + if (entry->skb->nf_bridge + && entry->skb->nf_bridge->physindev) { + tmp_uint = htonl(entry->skb->nf_bridge->physindev->ifindex); NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV, sizeof(tmp_uint), &tmp_uint); } @@ -449,19 +442,19 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, #endif } - if (outdev) { - tmp_uint = htonl(outdev->ifindex); + if (entry->info->outdev) { + tmp_uint = htonl(entry->info->outdev->ifindex); #ifndef CONFIG_BRIDGE_NETFILTER NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint); #else - if (entinf->pf == PF_BRIDGE) { + if (entry->info->pf == PF_BRIDGE) { /* Case 1: outdev is physical output device, we need to * look for bridge group (when called from * netfilter_bridge) */ NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV, sizeof(tmp_uint), &tmp_uint); /* this is the bridge group "brX" */ - tmp_uint = htonl(outdev->br_port->br->dev->ifindex); + tmp_uint = htonl(entry->info->outdev->br_port->br->dev->ifindex); NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint); } else { @@ -469,9 +462,9 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, * physical output device (when called from ipv4) */ NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint); - if (entskb->nf_bridge - && entskb->nf_bridge->physoutdev) { - tmp_uint = htonl(entskb->nf_bridge->physoutdev->ifindex); + if (entry->skb->nf_bridge + && entry->skb->nf_bridge->physoutdev) { + tmp_uint = htonl(entry->skb->nf_bridge->physoutdev->ifindex); NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV, sizeof(tmp_uint), &tmp_uint); } @@ -479,27 +472,27 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, #endif } - if (entskb->nfmark) { - tmp_uint = htonl(entskb->nfmark); + if (entry->skb->nfmark) { + tmp_uint = htonl(entry->skb->nfmark); NFA_PUT(skb, NFQA_MARK, sizeof(u_int32_t), &tmp_uint); } - if (indev && entskb->dev - && entskb->dev->hard_header_parse) { + if (entry->info->indev && entry->skb->dev + && entry->skb->dev->hard_header_parse) { struct nfqnl_msg_packet_hw phw; phw.hw_addrlen = - entskb->dev->hard_header_parse(entskb, + entry->skb->dev->hard_header_parse(entry->skb, phw.hw_addr); phw.hw_addrlen = htons(phw.hw_addrlen); NFA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw); } - if (entskb->tstamp.off_sec) { + if (entry->skb->tstamp.off_sec) { struct nfqnl_msg_packet_timestamp ts; - ts.sec = cpu_to_be64(entskb->tstamp.off_sec); - ts.usec = cpu_to_be64(entskb->tstamp.off_usec); + ts.sec = cpu_to_be64(entry->skb->tstamp.off_sec); + ts.usec = cpu_to_be64(entry->skb->tstamp.off_usec); NFA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts); } @@ -517,7 +510,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, nfa->nfa_type = NFQA_PAYLOAD; nfa->nfa_len = size; - if (skb_copy_bits(entskb, 0, NFA_DATA(nfa), data_len)) + if (skb_copy_bits(entry->skb, 0, NFA_DATA(nfa), data_len)) BUG(); } @@ -674,14 +667,12 @@ nfqnl_set_mode(struct nfqnl_instance *queue, static int dev_cmp(struct nfqnl_queue_entry *entry, unsigned long ifindex) { - struct nf_info *entinf = entry->info; - - if (entinf->indev) - if (entinf->indev->ifindex == ifindex) + if (entry->info->indev) + if (entry->info->indev->ifindex == ifindex) return 1; - if (entinf->outdev) - if (entinf->outdev->ifindex == ifindex) + if (entry->info->outdev) + if (entry->info->outdev->ifindex == ifindex) return 1; return 0;