cregit-Linux how code gets into the kernel

Release 4.18 net/ipv4/inet_fragment.c

Directory: net/ipv4
/*
 * inet fragments management
 *
 *              This program is free software; you can redistribute it and/or
 *              modify it under the terms of the GNU General Public License
 *              as published by the Free Software Foundation; either version
 *              2 of the License, or (at your option) any later version.
 *
 *              Authors:        Pavel Emelyanov <xemul@openvz.org>
 *                              Started as consolidation of ipv4/ip_fragment.c,
 *                              ipv6/reassembly. and ipv6 nf conntrack reassembly
 */

#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/random.h>
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
#include <linux/slab.h>

#include <net/sock.h>
#include <net/inet_frag.h>
#include <net/inet_ecn.h>

/* Given the OR values of all fragments, apply RFC 3168 5.3 requirements
 * Value : 0xff if frame should be dropped.
 *         0 or INET_ECN_CE value, to be ORed in to final iph->tos field
 */

const u8 ip_frag_ecn_table[16] = {
	/* at least one fragment had CE, and others ECT_0 or ECT_1 */
	[IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0]			= INET_ECN_CE,
	[IPFRAG_ECN_CE | IPFRAG_ECN_ECT_1]			= INET_ECN_CE,
	[IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1]	= INET_ECN_CE,

	/* invalid combinations : drop frame */
	[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE] = 0xff,
	[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_0] = 0xff,
	[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_1] = 0xff,
	[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = 0xff,
	[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0] = 0xff,
	[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_1] = 0xff,
	[IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = 0xff,
};
EXPORT_SYMBOL(ip_frag_ecn_table);


int inet_frags_init(struct inet_frags *f) { f->frags_cachep = kmem_cache_create(f->frags_cache_name, f->qsize, 0, 0, NULL); if (!f->frags_cachep) return -ENOMEM; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet2760.00%133.33%
Florian Westphal1840.00%266.67%
Total45100.00%3100.00%

EXPORT_SYMBOL(inet_frags_init);
void inet_frags_fini(struct inet_frags *f) { /* We must wait that all inet_frag_destroy_rcu() have completed. */ rcu_barrier(); kmem_cache_destroy(f->frags_cachep); f->frags_cachep = NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet1244.44%133.33%
Pavel Emelyanov1140.74%133.33%
Florian Westphal414.81%133.33%
Total27100.00%3100.00%

EXPORT_SYMBOL(inet_frags_fini);
static void inet_frags_free_cb(void *ptr, void *arg) { struct inet_frag_queue *fq = ptr; /* If we can not cancel the timer, it means this frag_queue * is already disappearing, we have nothing to do. * Otherwise, we own a refcount until the end of this function. */ if (!del_timer(&fq->timer)) return; spin_lock_bh(&fq->lock); if (!(fq->flags & INET_FRAG_COMPLETE)) { fq->flags |= INET_FRAG_COMPLETE; refcount_dec(&fq->refcnt); } spin_unlock_bh(&fq->lock); inet_frag_put(fq); }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet4959.76%120.00%
Pavel Emelyanov1619.51%120.00%
Florian Westphal1619.51%240.00%
Jesper Dangaard Brouer11.22%120.00%
Total82100.00%5100.00%


void inet_frags_exit_net(struct netns_frags *nf) { nf->high_thresh = 0; /* prevent creation of new frags */ rhashtable_free_and_destroy(&nf->rhashtable, inet_frags_free_cb, NULL); }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet1965.52%125.00%
Florian Westphal931.03%250.00%
Paolo Abeni13.45%125.00%
Total29100.00%4100.00%

EXPORT_SYMBOL(inet_frags_exit_net);
void inet_frag_kill(struct inet_frag_queue *fq) { if (del_timer(&fq->timer)) refcount_dec(&fq->refcnt); if (!(fq->flags & INET_FRAG_COMPLETE)) { struct netns_frags *nf = fq->net; fq->flags |= INET_FRAG_COMPLETE; rhashtable_remove_fast(&nf->rhashtable, &fq->node, nf->f->rhash_params); refcount_dec(&fq->refcnt); } }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet4554.22%225.00%
Florian Westphal2125.30%337.50%
Kirill Tkhai78.43%112.50%
Pavel Emelyanov67.23%112.50%
Jesper Dangaard Brouer44.82%112.50%
Total83100.00%8100.00%

EXPORT_SYMBOL(inet_frag_kill);
static void inet_frag_destroy_rcu(struct rcu_head *head) { struct inet_frag_queue *q = container_of(head, struct inet_frag_queue, rcu); struct inet_frags *f = q->net->f; if (f->destructor) f->destructor(q); kmem_cache_free(f->frags_cachep, q); }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet3864.41%150.00%
Pavel Emelyanov2135.59%150.00%
Total59100.00%2100.00%


void inet_frag_destroy(struct inet_frag_queue *q) { struct sk_buff *fp; struct netns_frags *nf; unsigned int sum, sum_truesize = 0; struct inet_frags *f; WARN_ON(!(q->flags & INET_FRAG_COMPLETE)); WARN_ON(del_timer(&q->timer) != 0); /* Release all fragment data. */ fp = q->fragments; nf = q->net; f = nf->f; while (fp) { struct sk_buff *xp = fp->next; sum_truesize += fp->truesize; kfree_skb(fp); fp = xp; } sum = sum_truesize + f->qsize; call_rcu(&q->rcu, inet_frag_destroy_rcu); sub_frag_mem_limit(nf, sum); }

Contributors

PersonTokensPropCommitsCommitProp
Pavel Emelyanov8060.61%333.33%
Eric Dumazet3022.73%222.22%
Jesper Dangaard Brouer1410.61%111.11%
Ilpo Järvinen64.55%111.11%
Nikolay Aleksandrov10.76%111.11%
Joe Perches10.76%111.11%
Total132100.00%9100.00%

EXPORT_SYMBOL(inet_frag_destroy);
static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf, struct inet_frags *f, void *arg) { struct inet_frag_queue *q; q = kmem_cache_zalloc(f->frags_cachep, GFP_ATOMIC); if (!q) return NULL; q->net = nf; f->constructor(q, arg); add_frag_mem_limit(nf, f->qsize); timer_setup(&q->timer, f->frag_expire, 0); spin_lock_init(&q->lock); refcount_set(&q->refcnt, 3); return q; }

Contributors

PersonTokensPropCommitsCommitProp
Pavel Emelyanov8984.76%327.27%
Gao Feng65.71%19.09%
Nikolay Aleksandrov21.90%19.09%
Kees Cook21.90%19.09%
Jesper Dangaard Brouer21.90%19.09%
Elena Reshetova10.95%19.09%
Ian Morris10.95%19.09%
Florian Westphal10.95%19.09%
Eric Dumazet10.95%19.09%
Total105100.00%11100.00%


static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf, void *arg) { struct inet_frags *f = nf->f; struct inet_frag_queue *q; int err; q = inet_frag_alloc(nf, f, arg); if (!q) return NULL; mod_timer(&q->timer, jiffies + nf->timeout); err = rhashtable_insert_fast(&nf->rhashtable, &q->node, f->rhash_params); if (err < 0) { q->flags |= INET_FRAG_COMPLETE; inet_frag_kill(q); inet_frag_destroy(q); return NULL; } return q; }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet6757.76%120.00%
Pavel Emelyanov4841.38%360.00%
Ian Morris10.86%120.00%
Total116100.00%5100.00%

/* TODO : call from rcu_read_lock() and no longer use refcount_inc_not_zero() */
struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, void *key) { struct inet_frag_queue *fq; if (!nf->high_thresh || frag_mem_limit(nf) > nf->high_thresh) return NULL; rcu_read_lock(); fq = rhashtable_lookup(&nf->rhashtable, key, nf->f->rhash_params); if (fq) { if (!refcount_inc_not_zero(&fq->refcnt)) fq = NULL; rcu_read_unlock(); return fq; } rcu_read_unlock(); return inet_frag_create(nf, key); }

Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet4747.47%228.57%
Pavel Emelyanov4444.44%228.57%
Jesper Dangaard Brouer66.06%114.29%
Hannes Frederic Sowa11.01%114.29%
Florian Westphal11.01%114.29%
Total99100.00%7100.00%

EXPORT_SYMBOL(inet_frag_find);

Overall Contributors

PersonTokensPropCommitsCommitProp
Eric Dumazet35537.21%38.82%
Pavel Emelyanov35136.79%1029.41%
Hannes Frederic Sowa11612.16%25.88%
Florian Westphal707.34%617.65%
Jesper Dangaard Brouer303.14%25.88%
Kirill Tkhai70.73%12.94%
Gao Feng60.63%12.94%
Ilpo Järvinen60.63%12.94%
Tejun Heo30.31%12.94%
Nikolay Aleksandrov30.31%25.88%
Kees Cook20.21%12.94%
Ian Morris20.21%12.94%
Elena Reshetova10.10%12.94%
Paolo Abeni10.10%12.94%
Joe Perches10.10%12.94%
Total954100.00%34100.00%
Directory: net/ipv4
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.