X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fipv4%2Fnetfilter%2Fnf_conntrack_l3proto_ipv4.c;h=5a955c440364728d3002a09213790273bb924339;hb=3988ba0708e98b4bafc9034aa476775520bee708;hp=c91725a85789e480256a4b6ffcf5b89ef1038e37;hpb=6e23ae2a48750bda407a4a58f52a4865d7308bf5;p=linux-2.6 diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index c91725a857..5a955c4403 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -23,29 +23,36 @@ #include #include #include +#include -static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, - struct nf_conntrack_tuple *tuple) +int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, + struct nf_conn *ct, + enum ip_conntrack_info ctinfo); +EXPORT_SYMBOL_GPL(nf_nat_seq_adjust_hook); + +static bool ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, + struct nf_conntrack_tuple *tuple) { - __be32 _addrs[2], *ap; + const __be32 *ap; + __be32 _addrs[2]; ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr), sizeof(u_int32_t) * 2, _addrs); if (ap == NULL) - return 0; + return false; tuple->src.u3.ip = ap[0]; tuple->dst.u3.ip = ap[1]; - return 1; + return true; } -static int ipv4_invert_tuple(struct nf_conntrack_tuple *tuple, - const struct nf_conntrack_tuple *orig) +static bool ipv4_invert_tuple(struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_tuple *orig) { tuple->src.u3.ip = orig->dst.u3.ip; tuple->dst.u3.ip = orig->src.u3.ip; - return 1; + return true; } static int ipv4_print_tuple(struct seq_file *s, @@ -56,12 +63,6 @@ static int ipv4_print_tuple(struct seq_file *s, NIPQUAD(tuple->dst.u3.ip)); } -static int ipv4_print_conntrack(struct seq_file *s, - const struct nf_conn *conntrack) -{ - return 0; -} - /* Returns new sk_buff, or NULL */ static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user) { @@ -82,7 +83,8 @@ static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user) static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, unsigned int *dataoff, u_int8_t *protonum) { - struct iphdr _iph, *iph; + const struct iphdr *iph; + struct iphdr _iph; iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph); if (iph == NULL) @@ -104,36 +106,42 @@ static unsigned int ipv4_confirm(unsigned int hooknum, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) -{ - /* We've seen it coming out the other side: confirm it */ - return nf_conntrack_confirm(skb); -} - -static unsigned int ipv4_conntrack_help(unsigned int hooknum, - struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) { struct nf_conn *ct; enum ip_conntrack_info ctinfo; - struct nf_conn_help *help; - struct nf_conntrack_helper *helper; + const struct nf_conn_help *help; + const struct nf_conntrack_helper *helper; + unsigned int ret; /* This is where we call the helper: as the packet goes out. */ ct = nf_ct_get(skb, &ctinfo); if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY) - return NF_ACCEPT; + goto out; help = nfct_help(ct); if (!help) - return NF_ACCEPT; + goto out; + /* rcu_read_lock()ed by nf_hook_slow */ helper = rcu_dereference(help->helper); if (!helper) - return NF_ACCEPT; - return helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb), - ct, ctinfo); + goto out; + + ret = helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb), + ct, ctinfo); + if (ret != NF_ACCEPT) + return ret; + + if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) { + typeof(nf_nat_seq_adjust_hook) seq_adjust; + + seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook); + if (!seq_adjust || !seq_adjust(skb, ct, ctinfo)) + return NF_DROP; + } +out: + /* We've seen it coming out the other side: confirm it */ + return nf_conntrack_confirm(skb); } static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, @@ -185,7 +193,7 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum, /* Connection tracking may drop packets, but never alters them, so make it the first hook. */ -static struct nf_hook_ops ipv4_conntrack_ops[] = { +static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { { .hook = ipv4_conntrack_defrag, .owner = THIS_MODULE, @@ -214,20 +222,6 @@ static struct nf_hook_ops ipv4_conntrack_ops[] = { .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP_PRI_CONNTRACK, }, - { - .hook = ipv4_conntrack_help, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_INET_POST_ROUTING, - .priority = NF_IP_PRI_CONNTRACK_HELPER, - }, - { - .hook = ipv4_conntrack_help, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_INET_LOCAL_IN, - .priority = NF_IP_PRI_CONNTRACK_HELPER, - }, { .hook = ipv4_confirm, .owner = THIS_MODULE, @@ -305,11 +299,11 @@ static ctl_table ip_ct_sysctl_table[] = { static int getorigdst(struct sock *sk, int optval, void __user *user, int *len) { - struct inet_sock *inet = inet_sk(sk); - struct nf_conntrack_tuple_hash *h; + const struct inet_sock *inet = inet_sk(sk); + const struct nf_conntrack_tuple_hash *h; struct nf_conntrack_tuple tuple; - NF_CT_TUPLE_U_BLANK(&tuple); + memset(&tuple, 0, sizeof(tuple)); tuple.src.u3.ip = inet->rcv_saddr; tuple.src.u.tcp.port = inet->sport; tuple.dst.u3.ip = inet->daddr; @@ -363,10 +357,8 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len) static int ipv4_tuple_to_nlattr(struct sk_buff *skb, const struct nf_conntrack_tuple *tuple) { - NLA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), - &tuple->src.u3.ip); - NLA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t), - &tuple->dst.u3.ip); + NLA_PUT_BE32(skb, CTA_IP_V4_SRC, tuple->src.u3.ip); + NLA_PUT_BE32(skb, CTA_IP_V4_DST, tuple->dst.u3.ip); return 0; nla_put_failure: @@ -384,8 +376,8 @@ static int ipv4_nlattr_to_tuple(struct nlattr *tb[], if (!tb[CTA_IP_V4_SRC] || !tb[CTA_IP_V4_DST]) return -EINVAL; - t->src.u3.ip = *(__be32 *)nla_data(tb[CTA_IP_V4_SRC]); - t->dst.u3.ip = *(__be32 *)nla_data(tb[CTA_IP_V4_DST]); + t->src.u3.ip = nla_get_be32(tb[CTA_IP_V4_SRC]); + t->dst.u3.ip = nla_get_be32(tb[CTA_IP_V4_DST]); return 0; } @@ -405,7 +397,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = { .pkt_to_tuple = ipv4_pkt_to_tuple, .invert_tuple = ipv4_invert_tuple, .print_tuple = ipv4_print_tuple, - .print_conntrack = ipv4_print_conntrack, .get_l4proto = ipv4_get_l4proto, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) .tuple_to_nlattr = ipv4_tuple_to_nlattr,