Release 4.11 net/netfilter/x_tables.c
/*
* x_tables core - Backend for {ip,ip6,arp}_tables
*
* Copyright (C) 2006-2006 Harald Welte <laforge@netfilter.org>
* Copyright (C) 2006-2012 Patrick McHardy <kaber@trash.net>
*
* Based on existing ip_tables code which is
* Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
* Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/socket.h>
#include <linux/net.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <linux/mutex.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/audit.h>
#include <linux/user_namespace.h>
#include <net/net_namespace.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_arp.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter_arp/arp_tables.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
MODULE_DESCRIPTION("{ip,ip6,arp,eb}_tables backend module");
#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
#define XT_PCPU_BLOCK_SIZE 4096
struct compat_delta {
unsigned int offset; /* offset in kernel */
int delta; /* delta in 32bit user land */
};
struct xt_af {
struct mutex mutex;
struct list_head match;
struct list_head target;
#ifdef CONFIG_COMPAT
struct mutex compat_mutex;
struct compat_delta *compat_tab;
unsigned int number; /* number of slots in compat_tab[] */
unsigned int cur; /* number of used slots in compat_tab[] */
#endif
};
static struct xt_af *xt;
static const char *const xt_prefix[NFPROTO_NUMPROTO] = {
[NFPROTO_UNSPEC] = "x",
[NFPROTO_IPV4] = "ip",
[NFPROTO_ARP] = "arp",
[NFPROTO_BRIDGE] = "eb",
[NFPROTO_IPV6] = "ip6",
};
/* Registration hooks for targets. */
int xt_register_target(struct xt_target *target)
{
u_int8_t af = target->family;
mutex_lock(&xt[af].mutex);
list_add(&target->list, &xt[af].target);
mutex_unlock(&xt[af].mutex);
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Harald Welte | 48 | 82.76% | 1 | 20.00% |
Pablo Neira Ayuso | 8 | 13.79% | 2 | 40.00% |
Ingo Molnar | 1 | 1.72% | 1 | 20.00% |
Jan Engelhardt | 1 | 1.72% | 1 | 20.00% |
Total | 58 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL(xt_register_target);
void
xt_unregister_target(struct xt_target *target)
{
u_int8_t af = target->family;
mutex_lock(&xt[af].mutex);
list_del(&target->list);
mutex_unlock(&xt[af].mutex);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Harald Welte | 35 | 74.47% | 1 | 20.00% |
Pablo Neira Ayuso | 6 | 12.77% | 1 | 20.00% |
Patrick McHardy | 3 | 6.38% | 1 | 20.00% |
Ingo Molnar | 2 | 4.26% | 1 | 20.00% |
Jan Engelhardt | 1 | 2.13% | 1 | 20.00% |
Total | 47 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL(xt_unregister_target);
int
xt_register_targets(struct xt_target *target, unsigned int n)
{
unsigned int i;
int err = 0;
for (i = 0; i < n; i++) {
err = xt_register_target(&target[i]);
if (err)
goto err;
}
return err;
err:
if (i > 0)
xt_unregister_targets(target, i);
return err;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Patrick McHardy | 76 | 98.70% | 1 | 50.00% |
Harald Welte | 1 | 1.30% | 1 | 50.00% |
Total | 77 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL(xt_register_targets);
void
xt_unregister_targets(struct xt_target *target, unsigned int n)
{
while (n-- > 0)
xt_unregister_target(&target[n]);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Patrick McHardy | 23 | 76.67% | 1 | 50.00% |
Changli Gao | 7 | 23.33% | 1 | 50.00% |
Total | 30 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL(xt_unregister_targets);
int xt_register_match(struct xt_match *match)
{
u_int8_t af = match->family;
mutex_lock(&xt[af].mutex);
list_add(&match->list, &xt[af].match);
mutex_unlock(&xt[af].mutex);
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Harald Welte | 48 | 82.76% | 1 | 20.00% |
Pablo Neira Ayuso | 8 | 13.79% | 2 | 40.00% |
Ingo Molnar | 1 | 1.72% | 1 | 20.00% |
Jan Engelhardt | 1 | 1.72% | 1 | 20.00% |
Total | 58 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL(xt_register_match);
void
xt_unregister_match(struct xt_match *match)
{
u_int8_t af = match->family;
mutex_lock(&xt[af].mutex);
list_del(&match->list);
mutex_unlock(&xt[af].mutex);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Harald Welte | 35 | 74.47% | 1 | 20.00% |
Pablo Neira Ayuso | 6 | 12.77% | 1 | 20.00% |
Patrick McHardy | 3 | 6.38% | 1 | 20.00% |
Ingo Molnar | 2 | 4.26% | 1 | 20.00% |
Jan Engelhardt | 1 | 2.13% | 1 | 20.00% |
Total | 47 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL(xt_unregister_match);
int
xt_register_matches(struct xt_match *match, unsigned int n)
{
unsigned int i;
int err = 0;
for (i = 0; i < n; i++) {
err = xt_register_match(&match[i]);
if (err)
goto err;
}
return err;
err:
if (i > 0)
xt_unregister_matches(match, i);
return err;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Patrick McHardy | 77 | 100.00% | 1 | 100.00% |
Total | 77 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL(xt_register_matches);
void
xt_unregister_matches(struct xt_match *match, unsigned int n)
{
while (n-- > 0)
xt_unregister_match(&match[n]);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Patrick McHardy | 23 | 76.67% | 1 | 50.00% |
Changli Gao | 7 | 23.33% | 1 | 50.00% |
Total | 30 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL(xt_unregister_matches);
/*
* These are weird, but module loading must not be done with mutex
* held (since they will register), and we have to have a single
* function to use.
*/
/* Find match, grabs ref. Returns ERR_PTR() on error. */
struct xt_match *xt_find_match(u8 af, const char *name, u8 revision)
{
struct xt_match *m;
int err = -ENOENT;
mutex_lock(&xt[af].mutex);
list_for_each_entry(m, &xt[af].match, list) {
if (strcmp(m->name, name) == 0) {
if (m->revision == revision) {
if (try_module_get(m->me)) {
mutex_unlock(&xt[af].mutex);
return m;
}
} else
err = -EPROTOTYPE; /* Found something. */
}
}
mutex_unlock(&xt[af].mutex);
if (af != NFPROTO_UNSPEC)
/* Try searching again in the family-independent list */
return xt_find_match(NFPROTO_UNSPEC, name, revision);
return ERR_PTR(err);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Harald Welte | 117 | 82.98% | 1 | 16.67% |
Jan Engelhardt | 18 | 12.77% | 2 | 33.33% |
Pablo Neira Ayuso | 2 | 1.42% | 1 | 16.67% |
Ingo Molnar | 2 | 1.42% | 1 | 16.67% |
Patrick McHardy | 2 | 1.42% | 1 | 16.67% |
Total | 141 | 100.00% | 6 | 100.00% |
EXPORT_SYMBOL(xt_find_match);
struct xt_match *
xt_request_find_match(uint8_t nfproto, const char *name, uint8_t revision)
{
struct xt_match *match;
match = xt_find_match(nfproto, name, revision);
if (IS_ERR(match)) {
request_module("%st_%s", xt_prefix[nfproto], name);
match = xt_find_match(nfproto, name, revision);
}
return match;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jan Engelhardt | 47 | 68.12% | 1 | 50.00% |
Stephen Hemminger | 22 | 31.88% | 1 | 50.00% |
Total | 69 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL_GPL(xt_request_find_match);
/* Find target, grabs ref. Returns ERR_PTR() on error. */
struct xt_target *xt_find_target(u8 af, const char *name, u8 revision)
{
struct xt_target *t;
int err = -ENOENT;
mutex_lock(&xt[af].mutex);
list_for_each_entry(t, &xt[af].target, list) {
if (strcmp(t->name, name) == 0) {
if (t->revision == revision) {
if (try_module_get(t->me)) {
mutex_unlock(&xt[af].mutex);
return t;
}
} else
err = -EPROTOTYPE; /* Found something. */
}
}
mutex_unlock(&xt[af].mutex);
if (af != NFPROTO_UNSPEC)
/* Try searching again in the family-independent list */
return xt_find_target(NFPROTO_UNSPEC, name, revision);
return ERR_PTR(err);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Harald Welte | 117 | 82.98% | 1 | 16.67% |
Jan Engelhardt | 18 | 12.77% | 2 | 33.33% |
Pablo Neira Ayuso | 2 | 1.42% | 1 | 16.67% |
Patrick McHardy | 2 | 1.42% | 1 | 16.67% |
Ingo Molnar | 2 | 1.42% | 1 | 16.67% |
Total | 141 | 100.00% | 6 | 100.00% |
EXPORT_SYMBOL(xt_find_target);
struct xt_target *xt_request_find_target(u8 af, const char *name, u8 revision)
{
struct xt_target *target;
target = xt_find_target(af, name, revision);
if (IS_ERR(target)) {
request_module("%st_%s", xt_prefix[af], name);
target = xt_find_target(af, name, revision);
}
return target;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Harald Welte | 42 | 60.87% | 1 | 20.00% |
Stephen Hemminger | 22 | 31.88% | 1 | 20.00% |
Jan Engelhardt | 3 | 4.35% | 2 | 40.00% |
Patrick McHardy | 2 | 2.90% | 1 | 20.00% |
Total | 69 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL_GPL(xt_request_find_target);
static int xt_obj_to_user(u16 __user *psize, u16 size,
void __user *pname, const char *name,
u8 __user *prev, u8 rev)
{
if (put_user(size, psize))
return -EFAULT;
if (copy_to_user(pname, name, strlen(name) + 1))
return -EFAULT;
if (put_user(rev, prev))
return -EFAULT;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Willem de Bruijn | 81 | 100.00% | 1 | 100.00% |
Total | 81 | 100.00% | 1 | 100.00% |
#define XT_OBJ_TO_USER(U, K, TYPE, C_SIZE) \
xt_obj_to_user(&U->u.TYPE##_size, C_SIZE ? : K->u.TYPE##_size, \
U->u.user.name, K->u.kernel.TYPE->name, \
&U->u.user.revision, K->u.kernel.TYPE->revision)
int xt_data_to_user(void __user *dst, const void *src,
int usersize, int size)
{
usersize = usersize ? : size;
if (copy_to_user(dst, src, usersize))
return -EFAULT;
if (usersize != size && clear_user(dst + usersize, size - usersize))
return -EFAULT;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Willem de Bruijn | 67 | 100.00% | 1 | 100.00% |
Total | 67 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(xt_data_to_user);
#define XT_DATA_TO_USER(U, K, TYPE, C_SIZE) \
xt_data_to_user(U->data, K->data, \
K->u.kernel.TYPE->usersize, \
C_SIZE ? : K->u.kernel.TYPE->TYPE##size)
int xt_match_to_user(const struct xt_entry_match *m,
struct xt_entry_match __user *u)
{
return XT_OBJ_TO_USER(u, m, match, 0) ||
XT_DATA_TO_USER(u, m, match, 0);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Willem de Bruijn | 40 | 100.00% | 1 | 100.00% |
Total | 40 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(xt_match_to_user);
int xt_target_to_user(const struct xt_entry_target *t,
struct xt_entry_target __user *u)
{
return XT_OBJ_TO_USER(u, t, target, 0) ||
XT_DATA_TO_USER(u, t, target, 0);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Willem de Bruijn | 40 | 100.00% | 1 | 100.00% |
Total | 40 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(xt_target_to_user);
static int match_revfn(u8 af, const char *name, u8 revision, int *bestp)
{
const struct xt_match *m;
int have_rev = 0;
list_for_each_entry(m, &xt[af].match, list) {
if (strcmp(m->name, name) == 0) {
if (m->revision > *bestp)
*bestp = m->revision;
if (m->revision == revision)
have_rev = 1;
}
}
if (af != NFPROTO_UNSPEC && !have_rev)
return match_revfn(NFPROTO_UNSPEC, name, revision, bestp);
return have_rev;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Harald Welte | 86 | 78.90% | 1 | 25.00% |
Patrick McHardy | 21 | 19.27% | 1 | 25.00% |
Jan Engelhardt | 2 | 1.83% | 2 | 50.00% |
Total | 109 | 100.00% | 4 | 100.00% |
static int target_revfn(u8 af, const char *name, u8 revision, int *bestp)
{
const struct xt_target *t;
int have_rev = 0;
list_for_each_entry(t, &xt[af].target, list) {
if (strcmp(t->name, name) == 0) {
if (t->revision > *bestp)
*bestp = t->revision;
if (t->revision == revision)
have_rev = 1;
}
}
if (af != NFPROTO_UNSPEC && !have_rev)
return target_revfn(NFPROTO_UNSPEC, name, revision, bestp);
return have_rev;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Harald Welte | 86 | 78.90% | 1 | 25.00% |
Patrick McHardy | 21 | 19.27% | 1 | 25.00% |
Jan Engelhardt | 2 | 1.83% | 2 | 50.00% |
Total | 109 | 100.00% | 4 | 100.00% |
/* Returns true or false (if no such extension at all) */
int xt_find_revision(u8 af, const char *name, u8 revision, int target,
int *err)
{
int have_rev, best = -1;
mutex_lock(&xt[af].mutex);
if (target == 1)
have_rev = target_revfn(af, name, revision, &best);
else
have_rev = match_revfn(af, name, revision, &best);
mutex_unlock(&xt[af].mutex);
/* Nothing at all? Return 0 to try loading module. */
if (best == -1) {
*err = -ENOENT;
return 0;
}
*err = best;
if (!have_rev)
*err = -EPROTONOSUPPORT;
return 1;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Harald Welte | 123 | 97.62% | 1 | 25.00% |
Ingo Molnar | 1 | 0.79% | 1 | 25.00% |
Pablo Neira Ayuso | 1 | 0.79% | 1 | 25.00% |
Jan Engelhardt | 1 | 0.79% | 1 | 25.00% |
Total | 126 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL_GPL(xt_find_revision);
static char *
textify_hooks(char *buf, size_t size, unsigned int mask, uint8_t nfproto)
{
static const char *const inetbr_names[] = {
"PREROUTING", "INPUT", "FORWARD",
"OUTPUT", "POSTROUTING", "BROUTING",
};
static const char *const arp_names[] = {
"INPUT", "FORWARD", "OUTPUT",
};
const char *const *names;
unsigned int i, max;
char *p = buf;
bool np = false;
int res;
names = (nfproto == NFPROTO_ARP) ? arp_names : inetbr_names;
max = (nfproto == NFPROTO_ARP) ? ARRAY_SIZE(arp_names) :
ARRAY_SIZE(inetbr_names);
*p = '\0';
for (i = 0; i < max; ++i) {
if (!(mask & (1 << i)))
continue;
res = snprintf(p, size, "%s%s", np ? "/" : "", names[i]);
if (res > 0) {
size -= res;
p += res;
}
np = true;
}
return buf;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jan Engelhardt | 195 | 100.00% | 2 | 100.00% |
Total | 195 | 100.00% | 2 | 100.00% |
int xt_check_match(struct xt_mtchk_param *par,
unsigned int size, u_int8_t proto, bool inv_proto)
{
int ret;
if (XT_ALIGN(par->match->matchsize) != size &&
par->match->matchsize != -1) {
/*
* ebt_among is exempt from centralized matchsize checking
* because it uses a dynamic-size data set.
*/
pr_err("%s_tables: %s.%u match: invalid size "
"%u (kernel) != (user) %u\n",
xt_prefix[par->family], par->match->name,
par->match->revision,
XT_ALIGN(par->match->matchsize), size);
return -EINVAL;
}
if (par->match->table != NULL &&
strcmp(par->match->table, par->table) != 0) {
pr_err("%s_tables: %s match: only valid in %s table, not %s\n",
xt_prefix[par->family], par->match->name,
par->match->table, par->table);
return -EINVAL;
}
if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) {
char used[64], allow[64];
pr_err("%s_tables: %s match: used from hooks %s, but only "
"valid from %s\n",
xt_prefix[par->family], par->match->name,
textify_hooks(used, sizeof(used), par->hook_mask,
par->family),
textify_hooks(allow, sizeof(allow), par->match->hooks,
par->family));
return -EINVAL;
}
if (par->match->proto && (par->match->proto != proto || inv_proto)) {
pr_err("%s_tables: %s match: only valid for protocol %u\n",
xt_prefix[par->family], par->match->name,
par->match->proto);
return -EINVAL;
}
if (par->match->checkentry != NULL) {
ret = par->match->checkentry(par);
if (ret < 0)
return ret;
else if (ret > 0)
/* Flag up potential errors. */
return -EIO;
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Patrick McHardy | 173 | 50.73% | 1 | 9.09% |
Jan Engelhardt | 160 | 46.92% | 8 | 72.73% |
Joe Perches | 4 | 1.17% | 1 | 9.09% |
Balazs Scheidler | 4 | 1.17% | 1 | 9.09% |
Total | 341 | 100.00% | 11 | 100.00% |
EXPORT_SYMBOL_GPL(xt_check_match);
/** xt_check_entry_match - check that matches end before start of target
*
* @match: beginning of xt_entry_match
* @target: beginning of this rules target (alleged end of matches)
* @alignment: alignment requirement of match structures
*
* Validates that all matches add up to the beginning of the target,
* and that each match covers at least the base structure size.
*
* Return: 0 on success, negative errno on failure.
*/
static int xt_check_entry_match(const char *match, const char *target,
const size_t alignment)
{
const struct xt_entry_match *pos;
int length = target - match;
if (length == 0) /* no matches */
return 0;
pos = (struct xt_entry_match *)match;
do {
if ((unsigned long)pos % alignment)
return -EINVAL;
if (length < (int)sizeof(struct xt_entry_match))
return -EINVAL;
if (pos->u.match_size < sizeof(struct xt_entry_match))
return -EINVAL;
if (pos->u.match_size > length)
return -EINVAL;
length -= pos->u.match_size;
pos = ((void *)((char *)(pos) + (pos)->u.match_size));
} while (length > 0);
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Florian Westphal | 162 | 100.00% | 1 | 100.00% |
Total | 162 | 100.00% | 1 | 100.00% |
#ifdef CONFIG_COMPAT
int xt_compat_add_offset(u_int8_t af, unsigned int offset, int delta)
{
struct xt_af *xp = &xt[af];
if (!xp->compat_tab) {
if (!xp->number)
return -EINVAL;
xp->compat_tab = vmalloc(sizeof(struct compat_delta) * xp->number);
if (!xp->compat_tab)
return -ENOMEM;
xp->cur = 0;
}
if (xp->cur >= xp->number)
return -EINVAL;
if (xp->cur)
delta += xp->compat_tab[xp->cur - 1].delta;
xp->compat_tab[xp->cur].offset = offset;
xp->compat_tab[xp->cur].delta = delta;
xp->cur++;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Eric Dumazet | 88 | 59.06% | 1 | 33.33% |
Patrick McHardy | 60 | 40.27% | 1 | 33.33% |
Jan Engelhardt | 1 | 0.67% | 1 | 33.33% |
Total | 149 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL_GPL(xt_compat_add_offset);
void xt_compat_flush_offsets(u_int8_t af)
{
if (xt[af].compat_tab) {
vfree(xt[af].compat_tab);
xt[af].compat_tab = NULL;
xt[af].number = 0;
xt[af].cur = 0;
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Patrick McHardy | 32 | 57.14% | 1 | 25.00% |
Eric Dumazet | 23 | 41.07% | 2 | 50.00% |
Jan Engelhardt | 1 | 1.79% | 1 | 25.00% |
Total | 56 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL_GPL(xt_compat_flush_offsets);
int xt_compat_calc_jump(u_int8_t af, unsigned int offset)
{
struct compat_delta *tmp = xt[af].compat_tab;
int mid, left = 0, right = xt[af].cur - 1;
while (left <= right) {
mid = (left + right) >> 1;
if (offset > tmp[mid].offset)
left = mid + 1;
else if (offset < tmp[mid].offset)
right = mid - 1;
else
return mid ? tmp[mid - 1].delta : 0;
}
return left ? tmp[left - 1].delta : 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Eric Dumazet | 88 | 70.97% | 2 | 40.00% |
Patrick McHardy | 33 | 26.61% | 1 | 20.00% |
Florian Westphal | 2 | 1.61% | 1 | 20.00% |
Jan Engelhardt | 1 | 0.81% | 1 | 20.00% |
Total | 124 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL_GPL(xt_compat_calc_jump);
void xt_compat_init_offsets(u_int8_t af, unsigned int number)
{
xt[af].number = number;
xt[af].cur = 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Eric Dumazet | 30 | 100.00% | 1 | 100.00% |
Total | 30 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL(xt_compat_init_offsets);
int xt_compat_match_offset(const struct xt_match *match)
{
u_int16_t csize = match->compatsize ? : match->matchsize;
return XT_ALIGN(match->matchsize) - COMPAT_XT_ALIGN(csize);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Patrick McHardy | 31 | 86.11% | 1 | 33.33% |
Dmitry Mishin | 4 | 11.11% | 1 | 33.33% |
Jan Engelhardt | 1 | 2.78% | 1 | 33.33% |
Total | 36 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL_GPL(