cregit-Linux how code gets into the kernel

Release 4.8 net/netfilter/xt_physdev.c

Directory: net/netfilter
/* Kernel module to match the bridge port in and
 * out device for IP packets coming into contact with a bridge. */

/* (C) 2001-2003 Bart De Schuymer <>
 * 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/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter_bridge.h>
#include <linux/netfilter/xt_physdev.h>
#include <linux/netfilter/x_tables.h>
#include <net/netfilter/br_netfilter.h>

MODULE_AUTHOR("Bart De Schuymer <>");
MODULE_DESCRIPTION("Xtables: Bridge physical device match");

static bool physdev_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_physdev_info *info = par->matchinfo; const struct net_device *physdev; unsigned long ret; const char *indev, *outdev; /* Not a bridged IP packet or no info available yet: * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if * the destination device will be a bridge. */ if (!skb->nf_bridge) { /* Return MATCH if the invert flags of the used options are on */ if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) && !(info->invert & XT_PHYSDEV_OP_BRIDGED)) return false; if ((info->bitmask & XT_PHYSDEV_OP_ISIN) && !(info->invert & XT_PHYSDEV_OP_ISIN)) return false; if ((info->bitmask & XT_PHYSDEV_OP_ISOUT) && !(info->invert & XT_PHYSDEV_OP_ISOUT)) return false; if ((info->bitmask & XT_PHYSDEV_OP_IN) && !(info->invert & XT_PHYSDEV_OP_IN)) return false; if ((info->bitmask & XT_PHYSDEV_OP_OUT) && !(info->invert & XT_PHYSDEV_OP_OUT)) return false; return true; } physdev = nf_bridge_get_physoutdev(skb); outdev = physdev ? physdev->name : NULL; /* This only makes sense in the FORWARD and POSTROUTING chains */ if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) && (!!outdev ^ !(info->invert & XT_PHYSDEV_OP_BRIDGED))) return false; physdev = nf_bridge_get_physindev(skb); indev = physdev ? physdev->name : NULL; if ((info->bitmask & XT_PHYSDEV_OP_ISIN && (!indev ^ !!(info->invert & XT_PHYSDEV_OP_ISIN))) || (info->bitmask & XT_PHYSDEV_OP_ISOUT && (!outdev ^ !!(info->invert & XT_PHYSDEV_OP_ISOUT)))) return false; if (!(info->bitmask & XT_PHYSDEV_OP_IN)) goto match_outdev; if (indev) { ret = ifname_compare_aligned(indev, info->physindev, info->in_mask); if (!ret ^ !(info->invert & XT_PHYSDEV_OP_IN)) return false; } match_outdev: if (!(info->bitmask & XT_PHYSDEV_OP_OUT)) return true; if (!outdev) return false; ret = ifname_compare_aligned(outdev, info->physoutdev, info->out_mask); return (!!ret ^ !(info->invert & XT_PHYSDEV_OP_OUT)); }


bart de schuymerbart de schuymer28172.05%110.00%
florian westphalflorian westphal5514.10%110.00%
harald welteharald welte215.38%110.00%
jan engelhardtjan engelhardt174.36%440.00%
eric dumazeteric dumazet164.10%330.00%

static int physdev_mt_check(const struct xt_mtchk_param *par) { const struct xt_physdev_info *info = par->matchinfo; br_netfilter_enable(); if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || info->bitmask & ~XT_PHYSDEV_OP_MASK) return -EINVAL; if (info->bitmask & (XT_PHYSDEV_OP_OUT | XT_PHYSDEV_OP_ISOUT) && (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) || info->invert & XT_PHYSDEV_OP_BRIDGED) && par->hook_mask & ((1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) | (1 << NF_INET_POST_ROUTING))) { pr_info("using --physdev-out and --physdev-is-out are only" "supported in the FORWARD and POSTROUTING chains with" "bridged traffic.\n"); if (par->hook_mask & (1 << NF_INET_LOCAL_OUT)) return -EINVAL; } return 0; }


patrick mchardypatrick mchardy6651.56%430.77%
bart de schuymerbart de schuymer3325.78%17.69%
jan engelhardtjan engelhardt1612.50%538.46%
hangbin liuhangbin liu75.47%17.69%
harald welteharald welte32.34%17.69%
pablo neira ayusopablo neira ayuso32.34%17.69%

static struct xt_match physdev_mt_reg __read_mostly = { .name = "physdev", .revision = 0, .family = NFPROTO_UNSPEC, .checkentry = physdev_mt_check, .match = physdev_mt, .matchsize = sizeof(struct xt_physdev_info), .me = THIS_MODULE, };
static int __init physdev_mt_init(void) { return xt_register_match(&physdev_mt_reg); }


bart de schuymerbart de schuymer1062.50%120.00%
jan engelhardtjan engelhardt425.00%240.00%
harald welteharald welte16.25%120.00%
patrick mchardypatrick mchardy16.25%120.00%

static void __exit physdev_mt_exit(void) { xt_unregister_match(&physdev_mt_reg); }


bart de schuymerbart de schuymer853.33%120.00%
jan engelhardtjan engelhardt426.67%240.00%
harald welteharald welte213.33%120.00%
patrick mchardypatrick mchardy16.67%120.00%

module_init(physdev_mt_init); module_exit(physdev_mt_exit);

Overall Contributors

bart de schuymerbart de schuymer37857.45%13.70%
patrick mchardypatrick mchardy8112.31%725.93%
jan engelhardtjan engelhardt578.66%1037.04%
florian westphalflorian westphal558.36%13.70%
harald welteharald welte538.05%13.70%
eric dumazeteric dumazet162.43%311.11%
pablo neira ayusopablo neira ayuso81.22%27.41%
hangbin liuhangbin liu71.06%13.70%
andrew mortonandrew morton30.46%13.70%
Directory: net/netfilter
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.