--- zzzz-none-000/linux-2.6.13.1/net/ipv4/netfilter/ip_queue.c 2005-09-10 02:42:58.000000000 +0000 +++ ohio-7170-487/linux-2.6.13.1/net/ipv4/netfilter/ip_queue.c 2007-08-17 12:10:39.000000000 +0000 @@ -11,13 +11,13 @@ * * 2000-03-27: Simplified code (thanks to Andi Kleen for clues). * 2000-05-20: Fixed notifier problems (following Miguel Freitas' report). - * 2000-06-19: Fixed so nfmark is copied to metadata (reported by Sebastian + * 2000-06-19: Fixed so nfmark is copied to metadata (reported by Sebastian * Zander). * 2000-08-01: Added Nick Williams' MAC support. * 2002-06-25: Code cleanup. * 2005-01-10: Added /proc counter for dropped packets; fixed so - * packets aren't delivered to user space if they're going - * to be dropped. + * packets aren't delivered to user space if they're going + * to be dropped. * 2005-05-26: local_bh_{disable,enable} around nf_reinject (Harald Welte) * */ @@ -103,7 +103,7 @@ list_for_each_prev(p, &queue_list) { struct ipq_queue_entry *entry = (struct ipq_queue_entry *)p; - + if (!cmpfn || cmpfn(entry, data)) return entry; } @@ -135,7 +135,7 @@ __ipq_flush(int verdict) { struct ipq_queue_entry *entry; - + while ((entry = __ipq_find_dequeue_entry(NULL, 0))) ipq_issue_verdict(entry, verdict); } @@ -144,21 +144,21 @@ __ipq_set_mode(unsigned char mode, unsigned int range) { int status = 0; - + switch(mode) { case IPQ_COPY_NONE: case IPQ_COPY_META: copy_mode = mode; copy_range = 0; break; - + case IPQ_COPY_PACKET: copy_mode = mode; copy_range = range; if (copy_range > 0xFFFF) copy_range = 0xFFFF; break; - + default: status = -EINVAL; @@ -179,7 +179,7 @@ ipq_find_dequeue_entry(ipq_cmpfn cmpfn, unsigned long data) { struct ipq_queue_entry *entry; - + write_lock_bh(&queue_lock); entry = __ipq_find_dequeue_entry(cmpfn, data); write_unlock_bh(&queue_lock); @@ -205,14 +205,14 @@ struct nlmsghdr *nlh; read_lock_bh(&queue_lock); - + switch (copy_mode) { case IPQ_COPY_META: case IPQ_COPY_NONE: size = NLMSG_SPACE(sizeof(*pmsg)); data_len = 0; break; - + case IPQ_COPY_PACKET: if (entry->skb->ip_summed == CHECKSUM_HW && (*errp = skb_checksum_help(entry->skb, @@ -224,10 +224,10 @@ data_len = entry->skb->len; else data_len = copy_range; - + size = NLMSG_SPACE(sizeof(*pmsg) + data_len); break; - + default: *errp = -EINVAL; read_unlock_bh(&queue_lock); @@ -239,7 +239,7 @@ skb = alloc_skb(size, GFP_ATOMIC); if (!skb) goto nlmsg_failure; - + old_tail= skb->tail; nlh = NLMSG_PUT(skb, 0, 0, IPQM_PACKET, size - sizeof(*nlh)); pmsg = NLMSG_DATA(nlh); @@ -252,17 +252,17 @@ pmsg->mark = entry->skb->nfmark; pmsg->hook = entry->info->hook; pmsg->hw_protocol = entry->skb->protocol; - + if (entry->info->indev) strcpy(pmsg->indev_name, entry->info->indev->name); else pmsg->indev_name[0] = '\0'; - + if (entry->info->outdev) strcpy(pmsg->outdev_name, entry->info->outdev->name); else pmsg->outdev_name[0] = '\0'; - + if (entry->info->indev && entry->skb->dev) { pmsg->hw_type = entry->skb->dev->type; if (entry->skb->dev->hard_header_parse) @@ -270,11 +270,11 @@ entry->skb->dev->hard_header_parse(entry->skb, pmsg->hw_addr); } - + if (data_len) if (skb_copy_bits(entry->skb, 0, pmsg->payload, data_len)) BUG(); - + nlh->nlmsg_len = skb->tail - old_tail; return skb; @@ -316,11 +316,11 @@ nskb = ipq_build_packet_message(entry, &status); if (nskb == NULL) goto err_out_free; - + write_lock_bh(&queue_lock); - + if (!peer_pid) - goto err_out_free_nskb; + goto err_out_free_nskb; if (queue_total >= queue_maxlen) { queue_dropped++; @@ -332,7 +332,7 @@ goto err_out_free_nskb; } - /* netlink_unicast will either free the nskb or attach it to a socket */ + /* netlink_unicast will either free the nskb or attach it to a socket */ status = netlink_unicast(ipqnl, nskb, peer_pid, MSG_DONTWAIT); if (status < 0) { queue_user_dropped++; @@ -345,8 +345,8 @@ return status; err_out_free_nskb: - kfree_skb(nskb); - + kfree_skb(nskb); + err_out_unlock: write_unlock_bh(&queue_lock); @@ -371,7 +371,7 @@ return -EINVAL; if (diff > skb_tailroom(e->skb)) { struct sk_buff *newskb; - + newskb = skb_copy_expand(e->skb, skb_headroom(e->skb), diff, @@ -428,11 +428,11 @@ return -ENOENT; else { int verdict = vmsg->value; - + if (vmsg->data_len && vmsg->data_len == len) if (ipq_mangle_ipv4(vmsg, entry) < 0) verdict = NF_DROP; - + ipq_issue_verdict(entry, verdict); return 0; } @@ -463,7 +463,7 @@ status = ipq_set_mode(pmsg->msg.mode.value, pmsg->msg.mode.range); break; - + case IPQM_VERDICT: if (pmsg->msg.verdict.value > NF_MAX_VERDICT) status = -EINVAL; @@ -483,7 +483,7 @@ if (entry->info->indev) if (entry->info->indev->ifindex == ifindex) return 1; - + if (entry->info->outdev) if (entry->info->outdev->ifindex == ifindex) return 1; @@ -495,7 +495,7 @@ ipq_dev_drop(int ifindex) { struct ipq_queue_entry *entry; - + while ((entry = ipq_find_dequeue_entry(dev_cmp, ifindex)) != NULL) ipq_issue_verdict(entry, NF_DROP); } @@ -519,25 +519,25 @@ pid = nlh->nlmsg_pid; flags = nlh->nlmsg_flags; - + if(pid <= 0 || !(flags & NLM_F_REQUEST) || flags & NLM_F_MULTI) RCV_SKB_FAIL(-EINVAL); - + if (flags & MSG_TRUNC) RCV_SKB_FAIL(-ECOMM); - + type = nlh->nlmsg_type; if (type < NLMSG_NOOP || type >= IPQM_MAX) RCV_SKB_FAIL(-EINVAL); - + if (type <= IPQM_BASE) return; - + if (security_netlink_recv(skb)) RCV_SKB_FAIL(-EPERM); - + write_lock_bh(&queue_lock); - + if (peer_pid) { if (peer_pid != pid) { write_unlock_bh(&queue_lock); @@ -547,14 +547,14 @@ net_enable_timestamp(); peer_pid = pid; } - + write_unlock_bh(&queue_lock); - + status = ipq_receive_peer(NLMSG_DATA(nlh), type, skblen - NLMSG_LENGTH(0)); if (status < 0) RCV_SKB_FAIL(status); - + if (flags & NLM_F_ACK) netlink_ack(skb, nlh, 0); return; @@ -567,13 +567,13 @@ unsigned int qlen; down(&ipqnl_sem); - + for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { skb = skb_dequeue(&sk->sk_receive_queue); ipq_rcv_skb(skb); kfree_skb(skb); } - + up(&ipqnl_sem); } @@ -654,7 +654,7 @@ int len; read_lock_bh(&queue_lock); - + len = sprintf(buffer, "Peer PID : %d\n" "Copy mode : %hu\n" @@ -672,7 +672,7 @@ queue_user_dropped); read_unlock_bh(&queue_lock); - + *start = buffer + offset; len -= offset; if (len > length) @@ -688,7 +688,7 @@ { int status = -ENOMEM; struct proc_dir_entry *proc; - + if (!init) goto cleanup; @@ -699,6 +699,7 @@ goto cleanup_netlink_notifier; } +#if defined(CONFIG_PROC_FS) proc = proc_net_create(IPQ_PROC_FS_NAME, 0, ipq_get_info); if (proc) proc->owner = THIS_MODULE; @@ -706,10 +707,14 @@ printk(KERN_ERR "ip_queue: failed to create proc entry\n"); goto cleanup_ipqnl; } - +#else /*--- #if defined(CONFIG_PROC_FS) ---*/ + proc=NULL; +#warning TODO: CONFIG_PROC_FS ip_queue.c +#endif /*--- #if defined(CONFIG_PROC_FS) ---*/ + register_netdevice_notifier(&ipq_dev_notifier); ipq_sysctl_header = register_sysctl_table(ipq_root_table, 0); - + status = nf_register_queue_handler(PF_INET, ipq_enqueue_packet, NULL); if (status < 0) { printk(KERN_ERR "ip_queue: failed to register queue handler\n"); @@ -721,17 +726,19 @@ nf_unregister_queue_handler(PF_INET); synchronize_net(); ipq_flush(NF_DROP); - + cleanup_sysctl: unregister_sysctl_table(ipq_sysctl_header); unregister_netdevice_notifier(&ipq_dev_notifier); +#if defined(CONFIG_PROC_FS) proc_net_remove(IPQ_PROC_FS_NAME); - + cleanup_ipqnl: +#endif /*--- #if defined(CONFIG_PROC_FS) ---*/ sock_release(ipqnl->sk_socket); down(&ipqnl_sem); up(&ipqnl_sem); - + cleanup_netlink_notifier: netlink_unregister_notifier(&ipq_nl_notifier); return status; @@ -739,7 +746,7 @@ static int __init init(void) { - + return init_or_cleanup(1); }