aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter/nfnetlink_queue_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/netfilter/nfnetlink_queue_core.c')
-rw-r--r--net/netfilter/nfnetlink_queue_core.c50
1 files changed, 29 insertions, 21 deletions
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
index c0496a55ad0..e12d44e75b2 100644
--- a/net/netfilter/nfnetlink_queue_core.c
+++ b/net/netfilter/nfnetlink_queue_core.c
@@ -44,7 +44,7 @@ struct nfqnl_instance {
44 struct hlist_node hlist; /* global list of queues */ 44 struct hlist_node hlist; /* global list of queues */
45 struct rcu_head rcu; 45 struct rcu_head rcu;
46 46
47 int peer_pid; 47 int peer_portid;
48 unsigned int queue_maxlen; 48 unsigned int queue_maxlen;
49 unsigned int copy_range; 49 unsigned int copy_range;
50 unsigned int queue_dropped; 50 unsigned int queue_dropped;
@@ -92,7 +92,7 @@ instance_lookup(u_int16_t queue_num)
92} 92}
93 93
94static struct nfqnl_instance * 94static struct nfqnl_instance *
95instance_create(u_int16_t queue_num, int pid) 95instance_create(u_int16_t queue_num, int portid)
96{ 96{
97 struct nfqnl_instance *inst; 97 struct nfqnl_instance *inst;
98 unsigned int h; 98 unsigned int h;
@@ -111,7 +111,7 @@ instance_create(u_int16_t queue_num, int pid)
111 } 111 }
112 112
113 inst->queue_num = queue_num; 113 inst->queue_num = queue_num;
114 inst->peer_pid = pid; 114 inst->peer_portid = portid;
115 inst->queue_maxlen = NFQNL_QMAX_DEFAULT; 115 inst->queue_maxlen = NFQNL_QMAX_DEFAULT;
116 inst->copy_range = 0xfffff; 116 inst->copy_range = 0xfffff;
117 inst->copy_mode = NFQNL_COPY_NONE; 117 inst->copy_mode = NFQNL_COPY_NONE;
@@ -225,7 +225,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
225{ 225{
226 sk_buff_data_t old_tail; 226 sk_buff_data_t old_tail;
227 size_t size; 227 size_t size;
228 size_t data_len = 0; 228 size_t data_len = 0, cap_len = 0;
229 struct sk_buff *skb; 229 struct sk_buff *skb;
230 struct nlattr *nla; 230 struct nlattr *nla;
231 struct nfqnl_msg_packet_hdr *pmsg; 231 struct nfqnl_msg_packet_hdr *pmsg;
@@ -247,7 +247,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
247#endif 247#endif
248 + nla_total_size(sizeof(u_int32_t)) /* mark */ 248 + nla_total_size(sizeof(u_int32_t)) /* mark */
249 + nla_total_size(sizeof(struct nfqnl_msg_packet_hw)) 249 + nla_total_size(sizeof(struct nfqnl_msg_packet_hw))
250 + nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp)); 250 + nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp)
251 + nla_total_size(sizeof(u_int32_t))); /* cap_len */
251 252
252 outdev = entry->outdev; 253 outdev = entry->outdev;
253 254
@@ -266,6 +267,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
266 data_len = entskb->len; 267 data_len = entskb->len;
267 268
268 size += nla_total_size(data_len); 269 size += nla_total_size(data_len);
270 cap_len = entskb->len;
269 break; 271 break;
270 } 272 }
271 273
@@ -402,12 +404,14 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
402 if (ct && nfqnl_ct_put(skb, ct, ctinfo) < 0) 404 if (ct && nfqnl_ct_put(skb, ct, ctinfo) < 0)
403 goto nla_put_failure; 405 goto nla_put_failure;
404 406
407 if (cap_len > 0 && nla_put_be32(skb, NFQA_CAP_LEN, htonl(cap_len)))
408 goto nla_put_failure;
409
405 nlh->nlmsg_len = skb->tail - old_tail; 410 nlh->nlmsg_len = skb->tail - old_tail;
406 return skb; 411 return skb;
407 412
408nla_put_failure: 413nla_put_failure:
409 if (skb) 414 kfree_skb(skb);
410 kfree_skb(skb);
411 net_err_ratelimited("nf_queue: error creating packet message\n"); 415 net_err_ratelimited("nf_queue: error creating packet message\n");
412 return NULL; 416 return NULL;
413} 417}
@@ -440,7 +444,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
440 } 444 }
441 spin_lock_bh(&queue->lock); 445 spin_lock_bh(&queue->lock);
442 446
443 if (!queue->peer_pid) { 447 if (!queue->peer_portid) {
444 err = -EINVAL; 448 err = -EINVAL;
445 goto err_out_free_nskb; 449 goto err_out_free_nskb;
446 } 450 }
@@ -459,7 +463,7 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
459 *packet_id_ptr = htonl(entry->id); 463 *packet_id_ptr = htonl(entry->id);
460 464
461 /* nfnetlink_unicast will either free the nskb or add it to a socket */ 465 /* nfnetlink_unicast will either free the nskb or add it to a socket */
462 err = nfnetlink_unicast(nskb, &init_net, queue->peer_pid, MSG_DONTWAIT); 466 err = nfnetlink_unicast(nskb, &init_net, queue->peer_portid, MSG_DONTWAIT);
463 if (err < 0) { 467 if (err < 0) {
464 queue->queue_user_dropped++; 468 queue->queue_user_dropped++;
465 goto err_out_unlock; 469 goto err_out_unlock;
@@ -527,9 +531,13 @@ nfqnl_set_mode(struct nfqnl_instance *queue,
527 531
528 case NFQNL_COPY_PACKET: 532 case NFQNL_COPY_PACKET:
529 queue->copy_mode = mode; 533 queue->copy_mode = mode;
530 /* we're using struct nlattr which has 16bit nla_len */ 534 /* We're using struct nlattr which has 16bit nla_len. Note that
531 if (range > 0xffff) 535 * nla_len includes the header length. Thus, the maximum packet
532 queue->copy_range = 0xffff; 536 * length that we support is 65531 bytes. We send truncated
537 * packets if the specified length is larger than that.
538 */
539 if (range > 0xffff - NLA_HDRLEN)
540 queue->copy_range = 0xffff - NLA_HDRLEN;
533 else 541 else
534 queue->copy_range = range; 542 queue->copy_range = range;
535 break; 543 break;
@@ -616,7 +624,7 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
616 if (event == NETLINK_URELEASE && n->protocol == NETLINK_NETFILTER) { 624 if (event == NETLINK_URELEASE && n->protocol == NETLINK_NETFILTER) {
617 int i; 625 int i;
618 626
619 /* destroy all instances for this pid */ 627 /* destroy all instances for this portid */
620 spin_lock(&instances_lock); 628 spin_lock(&instances_lock);
621 for (i = 0; i < INSTANCE_BUCKETS; i++) { 629 for (i = 0; i < INSTANCE_BUCKETS; i++) {
622 struct hlist_node *tmp, *t2; 630 struct hlist_node *tmp, *t2;
@@ -625,7 +633,7 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
625 633
626 hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) { 634 hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
627 if ((n->net == &init_net) && 635 if ((n->net == &init_net) &&
628 (n->pid == inst->peer_pid)) 636 (n->portid == inst->peer_portid))
629 __instance_destroy(inst); 637 __instance_destroy(inst);
630 } 638 }
631 } 639 }
@@ -650,7 +658,7 @@ static const struct nla_policy nfqa_verdict_batch_policy[NFQA_MAX+1] = {
650 [NFQA_MARK] = { .type = NLA_U32 }, 658 [NFQA_MARK] = { .type = NLA_U32 },
651}; 659};
652 660
653static struct nfqnl_instance *verdict_instance_lookup(u16 queue_num, int nlpid) 661static struct nfqnl_instance *verdict_instance_lookup(u16 queue_num, int nlportid)
654{ 662{
655 struct nfqnl_instance *queue; 663 struct nfqnl_instance *queue;
656 664
@@ -658,7 +666,7 @@ static struct nfqnl_instance *verdict_instance_lookup(u16 queue_num, int nlpid)
658 if (!queue) 666 if (!queue)
659 return ERR_PTR(-ENODEV); 667 return ERR_PTR(-ENODEV);
660 668
661 if (queue->peer_pid != nlpid) 669 if (queue->peer_portid != nlportid)
662 return ERR_PTR(-EPERM); 670 return ERR_PTR(-EPERM);
663 671
664 return queue; 672 return queue;
@@ -698,7 +706,7 @@ nfqnl_recv_verdict_batch(struct sock *ctnl, struct sk_buff *skb,
698 LIST_HEAD(batch_list); 706 LIST_HEAD(batch_list);
699 u16 queue_num = ntohs(nfmsg->res_id); 707 u16 queue_num = ntohs(nfmsg->res_id);
700 708
701 queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).pid); 709 queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).portid);
702 if (IS_ERR(queue)) 710 if (IS_ERR(queue))
703 return PTR_ERR(queue); 711 return PTR_ERR(queue);
704 712
@@ -749,7 +757,7 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
749 queue = instance_lookup(queue_num); 757 queue = instance_lookup(queue_num);
750 if (!queue) 758 if (!queue)
751 759
752 queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).pid); 760 queue = verdict_instance_lookup(queue_num, NETLINK_CB(skb).portid);
753 if (IS_ERR(queue)) 761 if (IS_ERR(queue))
754 return PTR_ERR(queue); 762 return PTR_ERR(queue);
755 763
@@ -832,7 +840,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
832 840
833 rcu_read_lock(); 841 rcu_read_lock();
834 queue = instance_lookup(queue_num); 842 queue = instance_lookup(queue_num);
835 if (queue && queue->peer_pid != NETLINK_CB(skb).pid) { 843 if (queue && queue->peer_portid != NETLINK_CB(skb).portid) {
836 ret = -EPERM; 844 ret = -EPERM;
837 goto err_out_unlock; 845 goto err_out_unlock;
838 } 846 }
@@ -844,7 +852,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
844 ret = -EBUSY; 852 ret = -EBUSY;
845 goto err_out_unlock; 853 goto err_out_unlock;
846 } 854 }
847 queue = instance_create(queue_num, NETLINK_CB(skb).pid); 855 queue = instance_create(queue_num, NETLINK_CB(skb).portid);
848 if (IS_ERR(queue)) { 856 if (IS_ERR(queue)) {
849 ret = PTR_ERR(queue); 857 ret = PTR_ERR(queue);
850 goto err_out_unlock; 858 goto err_out_unlock;
@@ -1016,7 +1024,7 @@ static int seq_show(struct seq_file *s, void *v)
1016 1024
1017 return seq_printf(s, "%5d %6d %5d %1d %5d %5d %5d %8d %2d\n", 1025 return seq_printf(s, "%5d %6d %5d %1d %5d %5d %5d %8d %2d\n",
1018 inst->queue_num, 1026 inst->queue_num,
1019 inst->peer_pid, inst->queue_total, 1027 inst->peer_portid, inst->queue_total,
1020 inst->copy_mode, inst->copy_range, 1028 inst->copy_mode, inst->copy_range,
1021 inst->queue_dropped, inst->queue_user_dropped, 1029 inst->queue_dropped, inst->queue_user_dropped,
1022 inst->id_sequence, 1); 1030 inst->id_sequence, 1);