/*
 *	Forwarding decision
 *	Linux ethernet bridge
 *
 *	Authors:
 *	Lennert Buytenhek		<buytenh@gnu.org>
 *
 *	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.
 */

#include <linux/err.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/netpoll.h>
#include <linux/skbuff.h>
#include <linux/if_vlan.h>
#include <linux/netfilter_bridge.h>
#include "br_private.h"

static int br_ap_isolate_enabled = 0;
static br_get_node_port_cbk br_forward_get_node_port_hook = NULL;

static int deliver_clone(const struct net_bridge_port *prev,
			 struct sk_buff *skb,
			 void (*__packet_hook)(const struct net_bridge_port *p,
					       struct sk_buff *skb));

void br_set_ap_isolate(int enable) {
        
	br_ap_isolate_enabled = !!enable;
}
EXPORT_SYMBOL(br_set_ap_isolate);

int br_get_ap_isolate(void) {
	return br_ap_isolate_enabled;
}
EXPORT_SYMBOL(br_get_ap_isolate);

static int is_wireless_interface(const struct net_device *dev)
{
	const char *ifname = "wifi";
	const char *wdsname = "wds";
	if (!dev)
		return 0;

	return ((strncmp(dev->name, ifname, strlen(ifname)) == 0) ||
			(strncmp(dev->name, wdsname, strlen(wdsname)) == 0));
}

static inline int br_ap_isolate_should_forward(const struct net_bridge_port *p,
		const struct sk_buff *skb) {
	if (br_ap_isolate_enabled &&
			is_wireless_interface(p->dev) &&
			is_wireless_interface(skb->dev)) {
		return 0;
	}

	if (skb->dev == p->dev)
		return !QTN_FLAG_IS_INTRA_BSS(skb->dev->qtn_flags);

	if ((QTN_FLAG_IS_BSS_ISOLATE(skb->dev->qtn_flags) &&
		(p->dev->qtn_flags & QTN_FLAG_WIFI_DEVICE)) ||
		((skb->dev->qtn_flags & QTN_FLAG_WIFI_DEVICE)
		&& QTN_FLAG_IS_BSS_ISOLATE(p->dev->qtn_flags)))
			return 0;

	return 1;
}

static inline int br_src_port_filter_check(const struct net_bridge_port *p,
		 const struct sk_buff *skb)
{
	return (p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev ||
		(skb->dest_port && skb->src_port && skb->src_port != skb->dest_port);
}

/* Don't forward packets to originating port or forwarding disabled */
static inline int should_deliver(const struct net_bridge_port *p,
				 const struct sk_buff *skb)
{
	struct net_bridge_vlan_group *vg;

	vg = nbp_vlan_group_rcu(p);

	return br_src_port_filter_check(p, skb) &&
		br_allowed_egress(vg, skb) &&
		p->state == BR_STATE_FORWARDING &&
		br_ap_isolate_should_forward(p, skb);
}

int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb)
{
	if (!is_skb_forwardable(skb->dev, skb))
		goto drop;

	skb_push(skb, ETH_HLEN);
	br_drop_fake_rtable(skb);

	if (skb->ip_summed == CHECKSUM_PARTIAL &&
	    (skb->protocol == htons(ETH_P_8021Q) ||
	     skb->protocol == htons(ETH_P_8021AD))) {
		int depth;

		if (!__vlan_get_protocol(skb, skb->protocol, &depth))
			goto drop;

		skb_set_network_header(skb, depth);
	}

	dev_queue_xmit(skb);

	return 0;

drop:
	kfree_skb(skb);
	return 0;
}
EXPORT_SYMBOL_GPL(br_dev_queue_push_xmit);

int br_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
	return NF_HOOK(NFPROTO_BRIDGE, NF_BR_POST_ROUTING,
		       net, sk, skb, NULL, skb->dev,
		       br_dev_queue_push_xmit);

}
EXPORT_SYMBOL_GPL(br_forward_finish);

static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
{
	struct net_bridge_vlan_group *vg;

	vg = nbp_vlan_group_rcu(to);
	skb = br_handle_vlan(to->br, vg, skb);
	if (!skb)
		return;

	skb->dev = to->dev;

	if (unlikely(netpoll_tx_running(to->br->dev))) {
		if (!is_skb_forwardable(skb->dev, skb))
			kfree_skb(skb);
		else {
			skb_push(skb, ETH_HLEN);
			br_netpoll_send_skb(to, skb);
		}
		return;
	}

	NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT,
		dev_net(skb->dev), NULL, skb,NULL, skb->dev,
		br_forward_finish);
}

static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
{
	struct net_bridge_vlan_group *vg;
	struct net_device *indev;

	if (skb_warn_if_lro(skb)) {
		kfree_skb(skb);
		return;
	}

	vg = nbp_vlan_group_rcu(to);
	skb = br_handle_vlan(to->br, vg, skb);
	if (!skb)
		return;

	indev = skb->dev;
	skb->dev = to->dev;
	skb_forward_csum(skb);

	NF_HOOK(NFPROTO_BRIDGE, NF_BR_FORWARD,
		dev_net(indev), NULL, skb, indev, skb->dev,
		br_forward_finish);
}

/* called with rcu_read_lock */
void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
{
	if (to && should_deliver(to, skb)) {
		__br_deliver(to, skb);
		return;
	}

	kfree_skb(skb);
}
EXPORT_SYMBOL_GPL(br_deliver);

/* called with rcu_read_lock */
void br_forward(const struct net_bridge_port *to, struct sk_buff *skb, struct sk_buff *skb0)
{
	if (to && should_deliver(to, skb)) {
		if (skb0)
			deliver_clone(to, skb, __br_forward);
		else
			__br_forward(to, skb);
		return;
	}

	if (!skb0)
		kfree_skb(skb);
}

static int deliver_clone(const struct net_bridge_port *prev,
			 struct sk_buff *skb,
			 void (*__packet_hook)(const struct net_bridge_port *p,
					       struct sk_buff *skb))
{
	struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;

	skb = skb_clone(skb, GFP_ATOMIC);
	if (!skb) {
		dev->stats.tx_dropped++;
		return -ENOMEM;
	}

	__packet_hook(prev, skb);
	return 0;
}

static struct net_bridge_port *maybe_deliver(
	struct net_bridge_port *prev, struct net_bridge_port *p,
	struct sk_buff *skb,
	void (*__packet_hook)(const struct net_bridge_port *p,
			      struct sk_buff *skb))
{
	int err;

	if (!should_deliver(p, skb))
		return prev;

	if (!prev)
		goto out;

	err = deliver_clone(prev, skb, __packet_hook);
	if (err)
		return ERR_PTR(err);

out:
	return p;
}

/* called under bridge lock */
static void br_flood(struct net_bridge *br, struct sk_buff *skb,
		     struct sk_buff *skb0,
		     void (*__packet_hook)(const struct net_bridge_port *p,
					   struct sk_buff *skb),
		     bool unicast)
{
	struct net_bridge_port *p;
	struct net_bridge_port *prev;

	prev = NULL;

	skb->dest_port = 0;
	list_for_each_entry_rcu(p, &br->port_list, list) {
		/* Do not flood unicast traffic to ports that turn it off */
		if (unicast && !(p->flags & BR_FLOOD))
			continue;

		/* Do not flood to ports that enable proxy ARP */
		if (p->flags & BR_PROXYARP)
			continue;
		if ((p->flags & BR_PROXYARP_WIFI) &&
		    BR_INPUT_SKB_CB(skb)->proxyarp_replied)
			continue;

		prev = maybe_deliver(prev, p, skb, __packet_hook);
		if (IS_ERR(prev))
			goto out;
	}

	if (!prev)
		goto out;

	if (skb0)
		deliver_clone(prev, skb, __packet_hook);
	else
		__packet_hook(prev, skb);
	return;

out:
	if (!skb0)
		kfree_skb(skb);
}

/* called with rcu_read_lock */
void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb, bool unicast)
{
	br_flood(br, skb, NULL, __br_deliver, unicast);
}

/* called under bridge lock */
void br_flood_forward(struct net_bridge *br, struct sk_buff *skb,
		      struct sk_buff *skb2, bool unicast)
{
	br_flood(br, skb, skb2, __br_forward, unicast);
}

#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
static void br_multicast_bitmap_flood(struct net_bridge_port *port,
                uint32_t *port_bitmap, struct sk_buff *skb, void (*__packet_hook)(
                                const struct net_bridge_port *p, struct sk_buff *skb))
{
        int idx;
        int bit_idx;
        uint32_t sub_port_bitmap;
	uint8_t multiple_ports = (port == NULL);

        for (idx = 0; idx < BR_SUB_PORT_BITMAP_SIZE; idx++) {
                bit_idx = 0;
                sub_port_bitmap = port_bitmap[idx];
                while (sub_port_bitmap) {
                        if (sub_port_bitmap & 0x1) {
                                skb->dest_port = BR_SUBPORT_MAP(BR_SUBPORT(idx, bit_idx));
				if (multiple_ports) {
					if (br_forward_get_node_port_hook)
						port = br_forward_get_node_port_hook(skb->dest_port);
					else
						port = NULL;
				}
				if (port)
					maybe_deliver(port, port, skb, __packet_hook);
                        }
                        sub_port_bitmap >>= 1;
                        bit_idx++;
                }
        }
}

static inline int br_get_sub_port(const struct net_bridge_port *port,
               uint32_t *sub_port_bitmap, int size)
{
	int is_active;

        if (unlikely(!port || !port->dev))
                return 0;

        if (!br_is_wlan_dev(port->dev))
                return 0;

        if (!br_fdb_get_active_sub_port_hook)
                return 0;

	is_active = br_fdb_get_active_sub_port_hook(port, sub_port_bitmap, size);

	return is_active;
}

/* called with rcu_read_lock */
static void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
			       struct sk_buff *skb, struct sk_buff *skb0,
			       void (*__packet_hook)(
					const struct net_bridge_port *p,
					struct sk_buff *skb))
{
	struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
	struct net_bridge *br = netdev_priv(dev);
	struct net_bridge_port *prev = NULL;
	struct net_bridge_port_group *p;
	struct hlist_node *rp;

	rp = rcu_dereference(hlist_first_rcu(&br->router_list));
	p = mdst ? rcu_dereference(mdst->ports) : NULL;
	while (p || rp) {
		struct net_bridge_port *port, *lport, *rport;

		lport = p ? p->port : NULL;
		rport = rp ? hlist_entry(rp, struct net_bridge_port, rlist) :
			     NULL;

		port = (unsigned long)lport > (unsigned long)rport ?
		       lport : rport;

                if (port == lport) {
                        if (p)
                                skb->dest_port = p->sub_port;
                        else
                                skb->dest_port = 0;
                        prev = maybe_deliver(prev, port, skb, __packet_hook);
                } else if (BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) {
                        if (port && br_is_wlan_dev(port->dev)) {
                                br_multicast_bitmap_flood(port, port->router_port_bitmap,
                                                skb, __packet_hook);
                        } else {
                                skb->dest_port = 0;
                                prev = maybe_deliver(prev, port, skb, __packet_hook);
                        }
                }

		if (IS_ERR(prev))
			goto out;

		if ((unsigned long)lport >= (unsigned long)port)
			p = rcu_dereference(p->next);
		if ((unsigned long)rport >= (unsigned long)port)
			rp = rcu_dereference(hlist_next_rcu(rp));
	}

	if (!prev)
		goto out;

	if (skb0)
		deliver_clone(prev, skb, __packet_hook);
	else
		__packet_hook(prev, skb);
	return;

out:
	if (!skb0)
		kfree_skb(skb);
}

/* called with rcu_read_lock */
void br_multicast_deliver(struct net_bridge_mdb_entry *mdst,
			  struct sk_buff *skb)
{
	br_multicast_flood(mdst, skb, NULL, __br_deliver);
}

/* called with rcu_read_lock */
void br_multicast_forward(struct net_bridge_mdb_entry *mdst,
			  struct sk_buff *skb, struct sk_buff *skb2)
{
	br_multicast_flood(mdst, skb, skb2, __br_forward);
}

static int br_should_exclude_mcast_member(struct net_bridge *br,
                struct net_bridge_mdb_entry *mp)
{
        if (!mp)
                return 0;

        if (br->report_flood_interval == BR_ALWAYS_FLOOD_REPORT)
                return 0;

	if (time_after(jiffies, mp->report_target_jiffies))
                return 0;

        if (mp->report_flood_indicator >= br->report_flood_interval &&
		!mp->rx_specific_query)
                return 0;

        return 1;
}

static int br_exclude_mcast_member(struct net_bridge_mdb_entry *mp,
                struct net_bridge_port *port, uint32_t* sub_port_bitmap)
{
        struct net_bridge_port_group *p;
        struct net_bridge *br = port->br;
        int is_wlan_dev;
        int ret = 0;

        is_wlan_dev = br_is_wlan_dev(port->dev);
        spin_lock(&br->multicast_lock);
        for (p = mp->ports; p; p = p->next) {
                if (p->port == port) {
                        if (!is_wlan_dev) {
                                ret = 1;
                                break;
                        }
                        br_reset_sub_port_bitmap(sub_port_bitmap, p->sub_port);
                }
        }
        spin_unlock(&br->multicast_lock);

        return ret;
}

void br_report_flood(struct net_bridge *br, struct net_bridge_mdb_entry *mp,
                struct sk_buff *skb)
{
        struct net_bridge_port *port;
        uint32_t sub_port_bitmap[BR_SUB_PORT_BITMAP_SIZE];
        int is_wlan_dev;
        int idx;
	uint8_t got_sub_port_bitmap = 0;

        list_for_each_entry_rcu(port, &br->port_list, list) {
                is_wlan_dev = br_is_wlan_dev(port->dev);
                if (!hlist_unhashed(&port->rlist) && !is_wlan_dev)
                        continue;

                if (is_wlan_dev) {
			if (!got_sub_port_bitmap) {
				if (!br_get_sub_port(port, sub_port_bitmap, sizeof(sub_port_bitmap)))
					continue;
				got_sub_port_bitmap = 1;
			}
		}

                if (br_should_exclude_mcast_member(br, mp)) {
                        if (br_exclude_mcast_member(mp, port, sub_port_bitmap))
                                continue;
                }

                if (is_wlan_dev) {
                        if (!hlist_unhashed(&port->rlist)) {
				/* Skip sub-ports handled by br_multicast_forward */
                                for (idx = 0; idx < ARRAY_SIZE(sub_port_bitmap); idx++) {
                                        sub_port_bitmap[idx] |= port->router_port_bitmap[idx];
                                        sub_port_bitmap[idx] ^= port->router_port_bitmap[idx];
                                }
                        }
                } else {
                        skb->dest_port = 0;
                        maybe_deliver(port, port, skb, __br_forward);
                }
        }

	if (got_sub_port_bitmap)
		br_multicast_bitmap_flood(NULL, sub_port_bitmap, skb, __br_forward);
}

void br_multicast_copy_to_sub_ports(struct net_bridge *br, struct net_bridge_mdb_entry *mdst,
		struct sk_buff *skb)
{
	struct net_bridge_port_group *pg;

	for (pg = mdst->ports; pg != NULL; pg = pg->next) {
		skb->dest_port = pg->sub_port;
		maybe_deliver(pg->port, pg->port, skb, __br_forward);
	}
}

void br_register_node_hooks_cbk_t(br_get_node_port_cbk get_node_port_func)
{
        br_forward_get_node_port_hook = get_node_port_func;
}
EXPORT_SYMBOL(br_register_node_hooks_cbk_t);

#endif
