/* 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 <bdschuym@pandora.be>
 *
 * 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.
 */

#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter_ipv4/ipt_physdev.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_bridge.h>
#define MATCH   1
#define NOMATCH 0

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
MODULE_DESCRIPTION("iptables bridge physical device match module");

static int
match(const struct sk_buff *skb,
      const struct net_device *in,
      const struct net_device *out,
      const void *matchinfo,
      int offset,
      int *hotdrop)
{
	int i;
	static const char nulldevname[IFNAMSIZ];
	const struct ipt_physdev_info *info = matchinfo;
	unsigned int ret;
	const char *indev, *outdev;
	struct nf_bridge_info *nf_bridge;

	/* 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 (!(nf_bridge = skb->nf_bridge)) {
		/* Return MATCH if the invert flags of the used options are on */
		if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) &&
		    !(info->invert & IPT_PHYSDEV_OP_BRIDGED))
			return NOMATCH;
		if ((info->bitmask & IPT_PHYSDEV_OP_ISIN) &&
		    !(info->invert & IPT_PHYSDEV_OP_ISIN))
			return NOMATCH;
		if ((info->bitmask & IPT_PHYSDEV_OP_ISOUT) &&
		    !(info->invert & IPT_PHYSDEV_OP_ISOUT))
			return NOMATCH;
		if ((info->bitmask & IPT_PHYSDEV_OP_IN) &&
		    !(info->invert & IPT_PHYSDEV_OP_IN))
			return NOMATCH;
		if ((info->bitmask & IPT_PHYSDEV_OP_OUT) &&
		    !(info->invert & IPT_PHYSDEV_OP_OUT))
			return NOMATCH;
		return MATCH;
	}

	/* This only makes sense in the FORWARD and POSTROUTING chains */
	if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) &&
	    (!!(nf_bridge->mask & BRNF_BRIDGED) ^
	    !(info->invert & IPT_PHYSDEV_OP_BRIDGED)))
		return NOMATCH;

	if ((info->bitmask & IPT_PHYSDEV_OP_ISIN &&
	    (!nf_bridge->physindev ^ !!(info->invert & IPT_PHYSDEV_OP_ISIN))) ||
	    (info->bitmask & IPT_PHYSDEV_OP_ISOUT &&
	    (!nf_bridge->physoutdev ^ !!(info->invert & IPT_PHYSDEV_OP_ISOUT))))
		return NOMATCH;

	if (!(info->bitmask & IPT_PHYSDEV_OP_IN))
		goto match_outdev;
	indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname;
	for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
		ret |= (((const unsigned int *)indev)[i]
			^ ((const unsigned int *)info->physindev)[i])
			& ((const unsigned int *)info->in_mask)[i];
	}

	if ((ret == 0) ^ !(info->invert & IPT_PHYSDEV_OP_IN))
		return NOMATCH;

match_outdev:
	if (!(info->bitmask & IPT_PHYSDEV_OP_OUT))
		return MATCH;
	outdev = nf_bridge->physoutdev ?
		 nf_bridge->physoutdev->name : nulldevname;
	for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) {
		ret |= (((const unsigned int *)outdev)[i]
			^ ((const unsigned int *)info->physoutdev)[i])
			& ((const unsigned int *)info->out_mask)[i];
	}

	return (ret != 0) ^ !(info->invert & IPT_PHYSDEV_OP_OUT);
}

static int
checkentry(const char *tablename,
		       const struct ipt_ip *ip,
		       void *matchinfo,
		       unsigned int matchsize,
		       unsigned int hook_mask)
{
	const struct ipt_physdev_info *info = matchinfo;

	if (matchsize != IPT_ALIGN(sizeof(struct ipt_physdev_info)))
		return 0;
	if (!(info->bitmask & IPT_PHYSDEV_OP_MASK) ||
	    info->bitmask & ~IPT_PHYSDEV_OP_MASK)
		return 0;
	return 1;
}

static struct ipt_match physdev_match = {
	.name		= "physdev",
	.match		= &match,
	.checkentry	= &checkentry,
	.me		= THIS_MODULE,
};

static int __init init(void)
{
	return ipt_register_match(&physdev_match);
}

static void __exit fini(void)
{
	ipt_unregister_match(&physdev_match);
}

module_init(init);
module_exit(fini);
