[NETFILTER]: Introduce NF_INET_ hook values
[safe/jmp/linux-2.6] / net / ipv4 / raw.c
index c3757bb..b80987d 100644 (file)
@@ -59,6 +59,7 @@
 #include <linux/in_route.h>
 #include <linux/route.h>
 #include <linux/skbuff.h>
+#include <net/net_namespace.h>
 #include <net/dst.h>
 #include <net/sock.h>
 #include <linux/gfp.h>
@@ -132,7 +133,7 @@ static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb)
        if (!pskb_may_pull(skb, sizeof(struct icmphdr)))
                return 1;
 
-       type = skb->h.icmph->type;
+       type = icmp_hdr(skb)->type;
        if (type < 32) {
                __u32 data = raw_sk(sk)->filter.data;
 
@@ -184,8 +185,8 @@ out:
 void raw_err (struct sock *sk, struct sk_buff *skb, u32 info)
 {
        struct inet_sock *inet = inet_sk(sk);
-       int type = skb->h.icmph->type;
-       int code = skb->h.icmph->code;
+       const int type = icmp_hdr(skb)->type;
+       const int code = icmp_hdr(skb)->code;
        int err = 0;
        int harderr = 0;
 
@@ -240,7 +241,7 @@ static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb)
        /* Charge it to the socket. */
 
        if (sock_queue_rcv_skb(sk, skb) < 0) {
-               /* FIXME: increment a raw drops counter here */
+               atomic_inc(&sk->sk_drops);
                kfree_skb(skb);
                return NET_RX_DROP;
        }
@@ -251,6 +252,7 @@ static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb)
 int raw_rcv(struct sock *sk, struct sk_buff *skb)
 {
        if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) {
+               atomic_inc(&sk->sk_drops);
                kfree_skb(skb);
                return NET_RX_DROP;
        }
@@ -270,6 +272,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
        int hh_len;
        struct iphdr *iph;
        struct sk_buff *skb;
+       unsigned int iphlen;
        int err;
 
        if (length > rt->u.dst.dev->mtu) {
@@ -292,18 +295,19 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
        skb->dst = dst_clone(&rt->u.dst);
 
        skb_reset_network_header(skb);
-       iph = skb->nh.iph;
+       iph = ip_hdr(skb);
        skb_put(skb, length);
 
        skb->ip_summed = CHECKSUM_NONE;
 
-       skb->h.raw = skb->nh.raw;
+       skb->transport_header = skb->network_header;
        err = memcpy_fromiovecend((void *)iph, from, 0, length);
        if (err)
                goto error_fault;
 
        /* We don't modify invalid header */
-       if (length >= sizeof(*iph) && iph->ihl * 4U <= length) {
+       iphlen = iph->ihl * 4;
+       if (iphlen >= sizeof(*iph) && iphlen <= length) {
                if (!iph->saddr)
                        iph->saddr = rt->rt_src;
                iph->check   = 0;
@@ -313,8 +317,11 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
 
                iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
        }
+       if (iph->protocol == IPPROTO_ICMP)
+               icmp_out_count(((struct icmphdr *)
+                       skb_transport_header(skb))->type);
 
-       err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
+       err = NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
                      dst_output);
        if (err > 0)
                err = inet->recverr ? net_xmit_errno(err) : 0;
@@ -615,7 +622,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        /* Copy the address. */
        if (sin) {
                sin->sin_family = AF_INET;
-               sin->sin_addr.s_addr = skb->nh.iph->saddr;
+               sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
                sin->sin_port = 0;
                memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
        }
@@ -756,6 +763,8 @@ static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg)
        }
 }
 
+DEFINE_PROTO_INUSE(raw)
+
 struct proto raw_prot = {
        .name              = "RAW",
        .owner             = THIS_MODULE,
@@ -777,6 +786,7 @@ struct proto raw_prot = {
        .compat_setsockopt = compat_raw_setsockopt,
        .compat_getsockopt = compat_raw_getsockopt,
 #endif
+       REF_PROTO_INUSE(raw)
 };
 
 #ifdef CONFIG_PROC_FS
@@ -862,28 +872,30 @@ static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i)
              srcp  = inet->num;
 
        sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
-               " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
+               " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d",
                i, src, srcp, dest, destp, sp->sk_state,
                atomic_read(&sp->sk_wmem_alloc),
                atomic_read(&sp->sk_rmem_alloc),
                0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
-               atomic_read(&sp->sk_refcnt), sp);
+               atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
        return tmpbuf;
 }
 
+#define TMPSZ 128
+
 static int raw_seq_show(struct seq_file *seq, void *v)
 {
-       char tmpbuf[129];
+       char tmpbuf[TMPSZ+1];
 
        if (v == SEQ_START_TOKEN)
-               seq_printf(seq, "%-127s\n",
+               seq_printf(seq, "%-*s\n", TMPSZ-1,
                               "  sl  local_address rem_address   st tx_queue "
                               "rx_queue tr tm->when retrnsmt   uid  timeout "
-                              "inode");
+                              "inode  drops");
        else {
                struct raw_iter_state *state = raw_seq_private(seq);
 
-               seq_printf(seq, "%-127s\n",
+               seq_printf(seq, "%-*s\n", TMPSZ-1,
                           get_raw_sock(v, tmpbuf, state->bucket));
        }
        return 0;
@@ -898,24 +910,8 @@ static const struct seq_operations raw_seq_ops = {
 
 static int raw_seq_open(struct inode *inode, struct file *file)
 {
-       struct seq_file *seq;
-       int rc = -ENOMEM;
-       struct raw_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
-
-       if (!s)
-               goto out;
-       rc = seq_open(file, &raw_seq_ops);
-       if (rc)
-               goto out_kfree;
-
-       seq = file->private_data;
-       seq->private = s;
-       memset(s, 0, sizeof(*s));
-out:
-       return rc;
-out_kfree:
-       kfree(s);
-       goto out;
+       return seq_open_private(file, &raw_seq_ops,
+                       sizeof(struct raw_iter_state));
 }
 
 static const struct file_operations raw_seq_fops = {
@@ -928,13 +924,13 @@ static const struct file_operations raw_seq_fops = {
 
 int __init raw_proc_init(void)
 {
-       if (!proc_net_fops_create("raw", S_IRUGO, &raw_seq_fops))
+       if (!proc_net_fops_create(&init_net, "raw", S_IRUGO, &raw_seq_fops))
                return -ENOMEM;
        return 0;
 }
 
 void __init raw_proc_exit(void)
 {
-       proc_net_remove("raw");
+       proc_net_remove(&init_net, "raw");
 }
 #endif /* CONFIG_PROC_FS */