~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to net/netfilter/nf_conntrack_core.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
43
43
#include <net/netfilter/nf_conntrack_acct.h>
44
44
#include <net/netfilter/nf_conntrack_ecache.h>
45
45
#include <net/netfilter/nf_conntrack_zones.h>
 
46
#include <net/netfilter/nf_conntrack_timestamp.h>
46
47
#include <net/netfilter/nf_nat.h>
47
48
#include <net/netfilter/nf_nat_core.h>
48
49
 
282
283
static void death_by_timeout(unsigned long ul_conntrack)
283
284
{
284
285
        struct nf_conn *ct = (void *)ul_conntrack;
 
286
        struct nf_conn_tstamp *tstamp;
 
287
 
 
288
        tstamp = nf_conn_tstamp_find(ct);
 
289
        if (tstamp && tstamp->stop == 0)
 
290
                tstamp->stop = ktime_to_ns(ktime_get_real());
285
291
 
286
292
        if (!test_bit(IPS_DYING_BIT, &ct->status) &&
287
293
            unlikely(nf_conntrack_event(IPCT_DESTROY, ct) < 0)) {
419
425
        struct nf_conntrack_tuple_hash *h;
420
426
        struct nf_conn *ct;
421
427
        struct nf_conn_help *help;
 
428
        struct nf_conn_tstamp *tstamp;
422
429
        struct hlist_nulls_node *n;
423
430
        enum ip_conntrack_info ctinfo;
424
431
        struct net *net;
446
453
           REJECT will give spurious warnings here. */
447
454
        /* NF_CT_ASSERT(atomic_read(&ct->ct_general.use) == 1); */
448
455
 
449
 
        /* No external references means noone else could have
 
456
        /* No external references means no one else could have
450
457
           confirmed us. */
451
458
        NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
452
459
        pr_debug("Confirming conntrack %p\n", ct);
486
493
        ct->timeout.expires += jiffies;
487
494
        add_timer(&ct->timeout);
488
495
        atomic_inc(&ct->ct_general.use);
489
 
        set_bit(IPS_CONFIRMED_BIT, &ct->status);
490
 
 
 
496
        ct->status |= IPS_CONFIRMED;
 
497
 
 
498
        /* set conntrack timestamp, if enabled. */
 
499
        tstamp = nf_conn_tstamp_find(ct);
 
500
        if (tstamp) {
 
501
                if (skb->tstamp.tv64 == 0)
 
502
                        __net_timestamp((struct sk_buff *)skb);
 
503
 
 
504
                tstamp->start = ktime_to_ns(skb->tstamp);
 
505
        }
491
506
        /* Since the lookup is lockless, hash insertion must be done after
492
507
         * starting the timer and setting the CONFIRMED bit. The RCU barriers
493
508
         * guarantee that no other CPU can find the conntrack before the above
655
670
         * and ct->tuplehash[IP_CT_DIR_REPLY].hnnode.next unchanged.
656
671
         */
657
672
        memset(&ct->tuplehash[IP_CT_DIR_MAX], 0,
658
 
               sizeof(*ct) - offsetof(struct nf_conn, tuplehash[IP_CT_DIR_MAX]));
 
673
               offsetof(struct nf_conn, proto) -
 
674
               offsetof(struct nf_conn, tuplehash[IP_CT_DIR_MAX]));
659
675
        spin_lock_init(&ct->lock);
660
676
        ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
661
677
        ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.pprev = NULL;
745
761
        }
746
762
 
747
763
        nf_ct_acct_ext_add(ct, GFP_ATOMIC);
 
764
        nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
748
765
 
749
766
        ecache = tmpl ? nf_ct_ecache_find(tmpl) : NULL;
750
767
        nf_ct_ecache_ext_add(ct, ecache ? ecache->ctmask : 0,
833
850
 
834
851
        /* It exists; we have (non-exclusive) reference. */
835
852
        if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) {
836
 
                *ctinfo = IP_CT_ESTABLISHED + IP_CT_IS_REPLY;
 
853
                *ctinfo = IP_CT_ESTABLISHED_REPLY;
837
854
                /* Please set reply bit if this packet OK */
838
855
                *set_reply = 1;
839
856
        } else {
884
901
        ret = l3proto->get_l4proto(skb, skb_network_offset(skb),
885
902
                                   &dataoff, &protonum);
886
903
        if (ret <= 0) {
887
 
                pr_debug("not prepared to track yet or error occured\n");
 
904
                pr_debug("not prepared to track yet or error occurred\n");
888
905
                NF_CT_STAT_INC_ATOMIC(net, error);
889
906
                NF_CT_STAT_INC_ATOMIC(net, invalid);
890
907
                ret = -ret;
905
922
                        ret = -ret;
906
923
                        goto out;
907
924
                }
 
925
                /* ICMP[v6] protocol trackers may assign one conntrack. */
 
926
                if (skb->nfct)
 
927
                        goto out;
908
928
        }
909
929
 
910
930
        ct = resolve_normal_ct(net, tmpl, skb, dataoff, pf, protonum,
1126
1146
        /* This ICMP is in reverse direction to the packet which caused it */
1127
1147
        ct = nf_ct_get(skb, &ctinfo);
1128
1148
        if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
1129
 
                ctinfo = IP_CT_RELATED + IP_CT_IS_REPLY;
 
1149
                ctinfo = IP_CT_RELATED_REPLY;
1130
1150
        else
1131
1151
                ctinfo = IP_CT_RELATED;
1132
1152
 
1192
1212
static int kill_report(struct nf_conn *i, void *data)
1193
1213
{
1194
1214
        struct __nf_ct_flush_report *fr = (struct __nf_ct_flush_report *)data;
 
1215
        struct nf_conn_tstamp *tstamp;
 
1216
 
 
1217
        tstamp = nf_conn_tstamp_find(i);
 
1218
        if (tstamp && tstamp->stop == 0)
 
1219
                tstamp->stop = ktime_to_ns(ktime_get_real());
1195
1220
 
1196
1221
        /* If we fail to deliver the event, death_by_timeout() will retry */
1197
1222
        if (nf_conntrack_event_report(IPCT_DESTROY, i,
1208
1233
        return 1;
1209
1234
}
1210
1235
 
1211
 
void nf_ct_free_hashtable(void *hash, int vmalloced, unsigned int size)
 
1236
void nf_ct_free_hashtable(void *hash, unsigned int size)
1212
1237
{
1213
 
        if (vmalloced)
 
1238
        if (is_vmalloc_addr(hash))
1214
1239
                vfree(hash);
1215
1240
        else
1216
1241
                free_pages((unsigned long)hash,
1277
1302
                goto i_see_dead_people;
1278
1303
        }
1279
1304
 
1280
 
        nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
1281
 
                             net->ct.htable_size);
 
1305
        nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size);
1282
1306
        nf_conntrack_ecache_fini(net);
 
1307
        nf_conntrack_tstamp_fini(net);
1283
1308
        nf_conntrack_acct_fini(net);
1284
1309
        nf_conntrack_expect_fini(net);
1285
1310
        kmem_cache_destroy(net->ct.nf_conntrack_cachep);
1307
1332
        }
1308
1333
}
1309
1334
 
1310
 
void *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced, int nulls)
 
1335
void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
1311
1336
{
1312
1337
        struct hlist_nulls_head *hash;
1313
1338
        unsigned int nr_slots, i;
1314
1339
        size_t sz;
1315
1340
 
1316
 
        *vmalloced = 0;
1317
 
 
1318
1341
        BUILD_BUG_ON(sizeof(struct hlist_nulls_head) != sizeof(struct hlist_head));
1319
1342
        nr_slots = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_nulls_head));
1320
1343
        sz = nr_slots * sizeof(struct hlist_nulls_head);
1321
1344
        hash = (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO,
1322
1345
                                        get_order(sz));
1323
1346
        if (!hash) {
1324
 
                *vmalloced = 1;
1325
1347
                printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n");
1326
1348
                hash = __vmalloc(sz, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
1327
1349
                                 PAGE_KERNEL);
1337
1359
 
1338
1360
int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
1339
1361
{
1340
 
        int i, bucket, vmalloced, old_vmalloced;
 
1362
        int i, bucket;
1341
1363
        unsigned int hashsize, old_size;
1342
1364
        struct hlist_nulls_head *hash, *old_hash;
1343
1365
        struct nf_conntrack_tuple_hash *h;
1354
1376
        if (!hashsize)
1355
1377
                return -EINVAL;
1356
1378
 
1357
 
        hash = nf_ct_alloc_hashtable(&hashsize, &vmalloced, 1);
 
1379
        hash = nf_ct_alloc_hashtable(&hashsize, 1);
1358
1380
        if (!hash)
1359
1381
                return -ENOMEM;
1360
1382
 
1376
1398
                }
1377
1399
        }
1378
1400
        old_size = init_net.ct.htable_size;
1379
 
        old_vmalloced = init_net.ct.hash_vmalloc;
1380
1401
        old_hash = init_net.ct.hash;
1381
1402
 
1382
1403
        init_net.ct.htable_size = nf_conntrack_htable_size = hashsize;
1383
 
        init_net.ct.hash_vmalloc = vmalloced;
1384
1404
        init_net.ct.hash = hash;
1385
1405
        spin_unlock_bh(&nf_conntrack_lock);
1386
1406
 
1387
 
        nf_ct_free_hashtable(old_hash, old_vmalloced, old_size);
 
1407
        nf_ct_free_hashtable(old_hash, old_size);
1388
1408
        return 0;
1389
1409
}
1390
1410
EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize);
1497
1517
        }
1498
1518
 
1499
1519
        net->ct.htable_size = nf_conntrack_htable_size;
1500
 
        net->ct.hash = nf_ct_alloc_hashtable(&net->ct.htable_size,
1501
 
                                             &net->ct.hash_vmalloc, 1);
 
1520
        net->ct.hash = nf_ct_alloc_hashtable(&net->ct.htable_size, 1);
1502
1521
        if (!net->ct.hash) {
1503
1522
                ret = -ENOMEM;
1504
1523
                printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
1510
1529
        ret = nf_conntrack_acct_init(net);
1511
1530
        if (ret < 0)
1512
1531
                goto err_acct;
 
1532
        ret = nf_conntrack_tstamp_init(net);
 
1533
        if (ret < 0)
 
1534
                goto err_tstamp;
1513
1535
        ret = nf_conntrack_ecache_init(net);
1514
1536
        if (ret < 0)
1515
1537
                goto err_ecache;
1517
1539
        return 0;
1518
1540
 
1519
1541
err_ecache:
 
1542
        nf_conntrack_tstamp_fini(net);
 
1543
err_tstamp:
1520
1544
        nf_conntrack_acct_fini(net);
1521
1545
err_acct:
1522
1546
        nf_conntrack_expect_fini(net);
1523
1547
err_expect:
1524
 
        nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
1525
 
                             net->ct.htable_size);
 
1548
        nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size);
1526
1549
err_hash:
1527
1550
        kmem_cache_destroy(net->ct.nf_conntrack_cachep);
1528
1551
err_cache: