X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=net%2Fnetfilter%2Fnf_conntrack_proto_udplite.c;h=458655bb2106851b12d1dca6875af6b40c837fc5;hb=38ff3e6bb987ec583268da8eb22628293095d43b;hp=070056d9bcd6f52dd7459c98df33ce8585d24f52;hpb=c71e9167081a6a0d2a076cda674b696b89bb31c2;p=safe%2Fjmp%2Flinux-2.6 diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c index 070056d..458655b 100644 --- a/net/netfilter/nf_conntrack_proto_udplite.c +++ b/net/netfilter/nf_conntrack_proto_udplite.c @@ -27,27 +27,28 @@ static unsigned int nf_ct_udplite_timeout __read_mostly = 30*HZ; static unsigned int nf_ct_udplite_timeout_stream __read_mostly = 180*HZ; -static int udplite_pkt_to_tuple(const struct sk_buff *skb, - unsigned int dataoff, - struct nf_conntrack_tuple *tuple) +static bool udplite_pkt_to_tuple(const struct sk_buff *skb, + unsigned int dataoff, + struct nf_conntrack_tuple *tuple) { - struct udphdr _hdr, *hp; + const struct udphdr *hp; + struct udphdr _hdr; hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr); if (hp == NULL) - return 0; + return false; tuple->src.u.udp.port = hp->source; tuple->dst.u.udp.port = hp->dest; - return 1; + return true; } -static int udplite_invert_tuple(struct nf_conntrack_tuple *tuple, - const struct nf_conntrack_tuple *orig) +static bool udplite_invert_tuple(struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_tuple *orig) { tuple->src.u.udp.port = orig->dst.u.udp.port; tuple->dst.u.udp.port = orig->src.u.udp.port; - return 1; + return true; } /* Print out the per-protocol part of the tuple. */ @@ -60,48 +61,50 @@ static int udplite_print_tuple(struct seq_file *s, } /* Returns verdict for packet, and may modify conntracktype */ -static int udplite_packet(struct nf_conn *conntrack, +static int udplite_packet(struct nf_conn *ct, const struct sk_buff *skb, unsigned int dataoff, enum ip_conntrack_info ctinfo, - int pf, + u_int8_t pf, unsigned int hooknum) { /* If we've seen traffic both ways, this is some kind of UDP stream. Extend timeout. */ - if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) { - nf_ct_refresh_acct(conntrack, ctinfo, skb, + if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { + nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udplite_timeout_stream); /* Also, more likely to be important, and not a probe */ - if (!test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status)) - nf_conntrack_event_cache(IPCT_STATUS, skb); + if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status)) + nf_conntrack_event_cache(IPCT_STATUS, ct); } else - nf_ct_refresh_acct(conntrack, ctinfo, skb, - nf_ct_udplite_timeout); + nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udplite_timeout); return NF_ACCEPT; } /* Called when a new connection for this protocol found. */ -static int udplite_new(struct nf_conn *conntrack, const struct sk_buff *skb, - unsigned int dataoff) +static bool udplite_new(struct nf_conn *ct, const struct sk_buff *skb, + unsigned int dataoff) { - return 1; + return true; } -static int udplite_error(struct sk_buff *skb, unsigned int dataoff, +static int udplite_error(struct net *net, + struct sk_buff *skb, + unsigned int dataoff, enum ip_conntrack_info *ctinfo, - int pf, + u_int8_t pf, unsigned int hooknum) { unsigned int udplen = skb->len - dataoff; - struct udphdr _hdr, *hdr; + const struct udphdr *hdr; + struct udphdr _hdr; unsigned int cscov; /* Header is too small? */ hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr); if (hdr == NULL) { - if (LOG_INVALID(IPPROTO_UDPLITE)) + if (LOG_INVALID(net, IPPROTO_UDPLITE)) nf_log_packet(pf, 0, skb, NULL, NULL, NULL, "nf_ct_udplite: short packet "); return -NF_ACCEPT; @@ -111,7 +114,7 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff, if (cscov == 0) cscov = udplen; else if (cscov < sizeof(*hdr) || cscov > udplen) { - if (LOG_INVALID(IPPROTO_UDPLITE)) + if (LOG_INVALID(net, IPPROTO_UDPLITE)) nf_log_packet(pf, 0, skb, NULL, NULL, NULL, "nf_ct_udplite: invalid checksum coverage "); return -NF_ACCEPT; @@ -119,39 +122,20 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff, /* UDPLITE mandates checksums */ if (!hdr->check) { - if (LOG_INVALID(IPPROTO_UDPLITE)) + if (LOG_INVALID(net, IPPROTO_UDPLITE)) nf_log_packet(pf, 0, skb, NULL, NULL, NULL, "nf_ct_udplite: checksum missing "); return -NF_ACCEPT; } /* Checksum invalid? Ignore. */ - if (nf_conntrack_checksum && !skb_csum_unnecessary(skb) && - hooknum == NF_INET_PRE_ROUTING) { - if (pf == PF_INET) { - struct iphdr *iph = ip_hdr(skb); - - skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr, - udplen, IPPROTO_UDPLITE, 0); - } else { - struct ipv6hdr *ipv6h = ipv6_hdr(skb); - __wsum hsum = skb_checksum(skb, 0, dataoff, 0); - - skb->csum = ~csum_unfold( - csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, - udplen, IPPROTO_UDPLITE, - csum_sub(0, hsum))); - } - - skb->ip_summed = CHECKSUM_NONE; - if (__skb_checksum_complete_head(skb, dataoff + cscov)) { - if (LOG_INVALID(IPPROTO_UDPLITE)) - nf_log_packet(pf, 0, skb, NULL, NULL, NULL, - "nf_ct_udplite: bad UDPLite " - "checksum "); - return -NF_ACCEPT; - } - skb->ip_summed = CHECKSUM_UNNECESSARY; + if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && + nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_UDP, + pf)) { + if (LOG_INVALID(net, IPPROTO_UDPLITE)) + nf_log_packet(pf, 0, skb, NULL, NULL, NULL, + "nf_ct_udplite: bad UDPLite checksum "); + return -NF_ACCEPT; } return NF_ACCEPT; @@ -162,24 +146,20 @@ static unsigned int udplite_sysctl_table_users; static struct ctl_table_header *udplite_sysctl_header; static struct ctl_table udplite_sysctl_table[] = { { - .ctl_name = CTL_UNNUMBERED, .procname = "nf_conntrack_udplite_timeout", .data = &nf_ct_udplite_timeout, .maxlen = sizeof(unsigned int), .mode = 0644, - .proc_handler = &proc_dointvec_jiffies, + .proc_handler = proc_dointvec_jiffies, }, { - .ctl_name = CTL_UNNUMBERED, .procname = "nf_conntrack_udplite_timeout_stream", .data = &nf_ct_udplite_timeout_stream, .maxlen = sizeof(unsigned int), .mode = 0644, - .proc_handler = &proc_dointvec_jiffies, + .proc_handler = proc_dointvec_jiffies, }, - { - .ctl_name = 0 - } + { } }; #endif /* CONFIG_SYSCTL */ @@ -196,6 +176,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly = .error = udplite_error, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, + .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size, .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, .nla_policy = nf_ct_port_nla_policy, #endif @@ -219,6 +200,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly = .error = udplite_error, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, + .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size, .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, .nla_policy = nf_ct_port_nla_policy, #endif