/*
 *	Handle incoming frames
 *	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/slab.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/netfilter_bridge.h>
#include <linux/neighbour.h>
#include <net/arp.h>
#include <linux/export.h>
#include <linux/rculist.h>
#include <linux/igmp.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/if_ether.h>
#include <qtn/iputil.h>
#include "br_private.h"

#ifndef ETH_P_80211_RAW
# define ETH_P_80211_RAW 0x0019
#endif

static int br_vlan_promisc = 0;

void br_vlan_set_promisc(int enable)
{
	printk("%s vlan promiscuous mode\n", enable ? "Enabling" : "Disabling");
	br_vlan_promisc = enable;
}
EXPORT_SYMBOL(br_vlan_set_promisc); 

/* Hook for brouter */
br_should_route_hook_t __rcu *br_should_route_hook __read_mostly;
EXPORT_SYMBOL(br_should_route_hook);

#ifndef CONFIG_QTN_PLATFORM_MISALIGN_WAR
static struct sk_buff *skb_aligned(struct sk_buff *skb)
{
	if ((unsigned int)skb->data & 0x3) {
		int clen = 4 - ((unsigned int)skb->data & 0x3);
		int err;

		err = pskb_expand_head(skb, clen, 0, GFP_ATOMIC);
		if (err)
			panic("%s: skb alignment failure\n", __func__);
	}

	return skb;
}
#endif

static int
br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb)
{
	return netif_receive_skb(skb);
}

static int br_pass_frame_up(struct sk_buff *skb)
{
	struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev;
	struct net_bridge *br = netdev_priv(brdev);
	struct net_bridge_vlan_group *vg;
	struct pcpu_sw_netstats *brstats = this_cpu_ptr(br->stats);

	u64_stats_update_begin(&brstats->syncp);
	brstats->rx_packets++;
	brstats->rx_bytes += skb->len;
	u64_stats_update_end(&brstats->syncp);

	vg = br_vlan_group_rcu(br);
	/* Bridge is just like any other port.  Make sure the
	 * packet is allowed except in promisc modue when someone
	 * may be running packet capture.
	 */
	if (!(brdev->flags & IFF_PROMISC) &&
	    !br_allowed_egress(vg, skb)) {
		kfree_skb(skb);
		return NET_RX_DROP;
	}

	indev = skb->dev;
	skb->dev = brdev;
	skb = br_handle_vlan(br, vg, skb);
	if (!skb)
		return NET_RX_DROP;

#ifndef CONFIG_QTN_PLATFORM_MISALIGN_WAR
	skb = skb_aligned(skb);
#endif
	return NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN,
		       dev_net(indev), NULL, skb, indev, NULL,
		       br_netif_receive_skb);
}

static int br_handle_to_protoclstack(const unsigned char *dest, void *data)
{
	int retval;

	retval = !iputil_mac_is_v4_multicast(dest) ||
		iputil_is_v4_ssdp(dest, data) ||
		iputil_is_lncb(dest, data);

#ifdef CONFIG_IPV6
	if (retval)
		retval = (!iputil_mac_is_v6_multicast(dest) ||
			iputil_mac_is_v6_local((struct ipv6hdr *)data));
#endif

	return retval;
}

static int br_handle_mcast_mgmt_frame(struct sk_buff *skb, struct net_bridge *br)
{
	uint8_t igmp_snoop;

	igmp_snoop = (br->igmp_snoop_enabled == BR_IGMP_SNOOP_ENABLED ||
					br->igmp_snoop_enabled == BR_IGMP_SNOOP_HYBRID);

	return igmp_snoop && (!BR_INPUT_SKB_CB(skb)->igmp ||
			BR_INPUT_SKB_CB_MROUTERS_ONLY(skb));
}

static int br_handle_mcast_exception(struct net_bridge *br,
		const unsigned char *dest, void *data)
{
	struct iphdr *iph;
	int retval;
	int ssdp_check;
#ifdef CONFIG_IPV6
	struct ipv6hdr *ip6hdr;
#endif

	iph = data;
	ssdp_check = (br->ssdp_flood_state == BR_SSDP_FLOOD_DISABLED);

	retval = iputil_mac_is_v4_multicast(dest) &&
			(!iputil_is_v4_ssdp(dest, iph) || ssdp_check);
#ifdef CONFIG_IPV6
	if (!retval) {
		ip6hdr = data;
		retval = iputil_mac_is_v6_multicast(dest) &&
				(!iputil_is_v6_ssdp(dest, ip6hdr) || ssdp_check) &&
				!iputil_mac_is_v6_local(ip6hdr);
	}
#endif

	return retval;
}

int br_handle_frame_finish_multicast(struct sk_buff *skb, struct net_bridge *br,
			const unsigned char *dest, u16 vid)
{
	struct net_bridge_mdb_entry *mdst;
	struct sk_buff *skb2 = NULL;
	struct ethhdr *eth = eth_hdr(skb);
	void *data;

	if (eth->h_proto != __constant_htons(ETH_P_8021Q))
		data = (void *)(eth + 1);
	else
		data = (void *)((struct vlan_ethhdr *)eth + 1);

	br->dev->stats.multicast++;
	if (br_handle_to_protoclstack(dest, data))
		skb2 = skb;

	if (!iputil_is_lncb(dest, data) &&
			br_handle_mcast_mgmt_frame(skb, br) &&
			br_handle_mcast_exception(br, dest, data)) {
		if (BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) {
			mdst = br_mdb_get(br, skb, vid);
			br_report_flood(br, mdst, skb);
			br_multicast_forward(mdst, skb, skb2);
			skb = NULL;
		} else if(BR_INPUT_SKB_CB_UCAST_FWD(skb)) {
			mdst = br_mdb_get_ext(br, skb, vid);
			if (mdst) {
				br_multicast_copy_to_sub_ports(br, mdst, skb);
				if (skb2 == NULL)
					kfree_skb(skb);
				skb = NULL;
			} else if (br->igmp_snoop_enabled == BR_IGMP_SNOOP_ENABLED) {
				goto drop;
			}
		} else {
			mdst = br_mdb_get(br, skb, vid);
			if (mdst) {
				br_multicast_forward(mdst, skb, skb2);
				skb = NULL;
			} else if (br->igmp_snoop_enabled == BR_IGMP_SNOOP_ENABLED) {
				goto drop;
			} else if (br->igmp_snoop_enabled == BR_IGMP_SNOOP_ENABLED) {
				goto drop;
			}
		}
	}

	if (skb) {
		bool unicast = true;
		if (is_broadcast_ether_addr(dest))
			unicast = false;
		skb->dest_port = 0;
		br_flood_forward(br, skb, skb2, unicast);
	}
	if (skb2)
		return br_pass_frame_up(skb2);

out:
	return 0;
drop:
	kfree_skb(skb);
	goto out;
}

static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br,
			    u16 vid, struct net_bridge_port *p)
{
	struct net_device *dev = br->dev;
	struct neighbour *n;
	struct arphdr *parp;
	u8 *arpptr, *sha;
	__be32 sip, tip;

	BR_INPUT_SKB_CB(skb)->proxyarp_replied = false;

	if (dev->flags & IFF_NOARP)
		return;

	if (!pskb_may_pull(skb, arp_hdr_len(dev))) {
		dev->stats.tx_dropped++;
		return;
	}
	parp = arp_hdr(skb);

	if (parp->ar_pro != htons(ETH_P_IP) ||
	    parp->ar_op != htons(ARPOP_REQUEST) ||
	    parp->ar_hln != dev->addr_len ||
	    parp->ar_pln != 4)
		return;

	arpptr = (u8 *)parp + sizeof(struct arphdr);
	sha = arpptr;
	arpptr += dev->addr_len;	/* sha */
	memcpy(&sip, arpptr, sizeof(sip));
	arpptr += sizeof(sip);
	arpptr += dev->addr_len;	/* tha */
	memcpy(&tip, arpptr, sizeof(tip));

	if (ipv4_is_loopback(tip) ||
	    ipv4_is_multicast(tip))
		return;

	n = neigh_lookup(&arp_tbl, &tip, dev);
	if (n) {
		struct net_bridge_fdb_entry *f;

		if (!(n->nud_state & NUD_VALID)) {
			neigh_release(n);
			return;
		}

		f = __br_fdb_get(br, n->ha, vid);
		if (f && ((p->flags & BR_PROXYARP) ||
			  (f->dst && (f->dst->flags & BR_PROXYARP_WIFI)))) {
			arp_send(ARPOP_REPLY, ETH_P_ARP, sip, skb->dev, tip,
				 sha, n->ha, sha);
			BR_INPUT_SKB_CB(skb)->proxyarp_replied = true;
		}

		neigh_release(n);
	}
}

/* note: already called with rcu_read_lock */
int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
	const unsigned char *dest = eth_hdr(skb)->h_dest;
	struct net_bridge_port *p = br_port_get_rcu(skb->dev);
	struct net_bridge *br;
	struct net_bridge_fdb_entry *dst;
	struct sk_buff *skb2;
	bool unicast = true;
	u16 vid = 0;

	if (!p || p->state == BR_STATE_DISABLED)
		goto drop;

	if (!br_allowed_ingress(p->br, nbp_vlan_group_rcu(p), skb, &vid))
		goto out;

	vid = skb->hw_vlan_id;

	/* insert into forwarding database after filtering to avoid spoofing */
	br = p->br;
        /* ETH_P_80211_RAW */
        /* This type of frame should be passed up the stack, not forwarded or flooded.
         * Note that due to the nature of the skb with this protocol, the header is an
         * 802.11 header, not an Ethernet header.
         */
        if (skb->protocol == __constant_htons(ETH_P_80211_RAW))
        {
                /* Pass it up, do not forward or add entries to the bridge table */
                BR_INPUT_SKB_CB(skb)->brdev = br->dev;
                br_pass_frame_up(skb);
                goto out;
        }

	if (p->flags & BR_LEARNING)
		br_fdb_update(br, p, eth_hdr(skb)->h_source, vid, false, 0);
	br_handle_fwt_capacity(br);

	if (!is_broadcast_ether_addr(dest) && is_multicast_ether_addr(dest) &&
	    br_multicast_rcv(br, p, skb, vid))
		goto drop;

#ifndef CONFIG_QTN_PLATFORM_MISALIGN_WAR
	if (M_FLAG_ISSET(skb, M_HAS_MISALIGN))
		dest = eth_hdr(skb)->h_dest;
#endif

	if (p->state == BR_STATE_LEARNING)
		goto drop;

	BR_INPUT_SKB_CB(skb)->brdev = br->dev;

	/* The packet skb2 goes to the local host (NULL to skip). */
	skb2 = NULL;

	if (br->dev->flags & IFF_PROMISC)
		skb2 = skb;
	else if (unlikely(br_vlan_promisc && skb->protocol == __constant_htons(ETH_P_8021Q)))
		skb2 = skb;

	dst = NULL;

#ifdef CONFIG_IPV6
	if ((eth_hdr(skb)->h_proto == __constant_htons(ETH_P_IPV6)) &&
		(skb->len < sizeof(struct ipv6hdr))) {
		goto drop;
	}
#endif
	if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP))
		br_do_proxy_arp(skb, br, vid, p);

	if (is_broadcast_ether_addr(dest)) {
		skb2 = skb;
		unicast = false;
	} else if (is_multicast_ether_addr(dest)) {
		return br_handle_frame_finish_multicast(skb, br, dest, vid);
	} else if ((dst = __br_fdb_get(br, dest, vid)) &&
			dst->is_local) {
		skb2 = skb;
		/* Do not forward the packet since it's local. */
		skb = NULL;
	}

	if (skb) {
		if (dst) {
			dst->used = jiffies;
			skb->dest_port = dst->sub_port;
			br_forward(dst->dst, skb, skb2);
		} else {
			skb->dest_port = 0;
			br_flood_forward(br, skb, skb2, unicast);
		}
	}

	if (skb2)
		return br_pass_frame_up(skb2);

out:
	return 0;
drop:
	kfree_skb(skb);
	goto out;
}
EXPORT_SYMBOL_GPL(br_handle_frame_finish);

static void __br_handle_local_finish(struct sk_buff *skb)
{
	struct net_bridge_port *p = br_port_get_rcu(skb->dev);
	u16 vid = 0;

	/* check if vlan is allowed, to avoid spoofing */
	if (p->flags & BR_LEARNING && br_should_learn(p, skb, &vid))
		br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid, false, 0);
}

/* note: already called with rcu_read_lock */
static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
	struct net_bridge_port *p = br_port_get_rcu(skb->dev);

	__br_handle_local_finish(skb);

	BR_INPUT_SKB_CB(skb)->brdev = p->br->dev;
	br_pass_frame_up(skb);
	return 0;
}

/*
 * Return NULL if skb is handled
 * note: already called with rcu_read_lock
 */
rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
{
	struct net_bridge_port *p;
	struct sk_buff *skb = *pskb;
	const unsigned char *dest = eth_hdr(skb)->h_dest;
	br_should_route_hook_t *rhook;

	if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
		return RX_HANDLER_PASS;

	/*
	 * EAP frames destined for a bridge port need no bridge
	 * handling.
	 */
	if (unlikely(skb->protocol == __constant_htons(ETH_P_PAE)
			&& skb->pkt_type == PACKET_HOST))
		return RX_HANDLER_PASS;

	skb = skb_share_check(skb, GFP_ATOMIC);
	if (!skb)
		return RX_HANDLER_CONSUMED;

	if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
		goto drop;

	p = br_port_get_rcu(skb->dev);

	/* For ETH_P_80211_RAW, any pointers to addresses are invalid, so
         * simply pass the packet onto the br_handle_frame_finish to pass
         * it up the stack.
         */

	if (skb->protocol == __constant_htons(ETH_P_80211_RAW)) {
		if (p->state == BR_STATE_FORWARDING || p->state == BR_STATE_LEARNING) {
			NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, dev_net(skb->dev), NULL, skb, skb->dev,
				NULL, br_handle_frame_finish);
		} else {
			goto drop;
		}
		return RX_HANDLER_CONSUMED;
	}

	if (unlikely(is_link_local_ether_addr(dest))) {
		u16 fwd_mask = p->br->group_fwd_mask_required;

		/*
		 * See IEEE 802.1D Table 7-10 Reserved addresses
		 *
		 * Assignment		 		Value
		 * Bridge Group Address		01-80-C2-00-00-00
		 * (MAC Control) 802.3		01-80-C2-00-00-01
		 * (Link Aggregation) 802.3	01-80-C2-00-00-02
		 * 802.1X PAE address		01-80-C2-00-00-03
		 *
		 * 802.1AB LLDP 		01-80-C2-00-00-0E
		 *
		 * Others reserved for future standardization
		 */
		switch (dest[5]) {
		case 0x00:	/* Bridge Group Address */
			/* If STP is turned off,
			   then must forward to keep loop detection */
			if (p->br->stp_enabled == BR_NO_STP ||
			    fwd_mask & (1u << dest[5]))
				goto forward;
			*pskb = skb;
			__br_handle_local_finish(skb);
			return RX_HANDLER_PASS;

		case 0x01:	/* IEEE MAC (Pause) */
			goto drop;

		default:
			/* Allow selective forwarding for most other protocols */
			fwd_mask |= p->br->group_fwd_mask;
			if (fwd_mask & (1u << dest[5]))
				goto forward;
		}

		/* Deliver packet to local host only */
		NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, dev_net(skb->dev),
			NULL, skb, skb->dev, NULL, br_handle_local_finish);
		return RX_HANDLER_CONSUMED;
	}

forward:
	switch (p->state) {
	case BR_STATE_FORWARDING:
		rhook = rcu_dereference(br_should_route_hook);
		if (rhook) {
			if ((*rhook)(skb)) {
				*pskb = skb;
				return RX_HANDLER_PASS;
			}
			dest = eth_hdr(skb)->h_dest;
		}
		/* fall through */
	case BR_STATE_LEARNING:
		if (ether_addr_equal(p->br->dev->dev_addr, dest))
			skb->pkt_type = PACKET_HOST;

		NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING,
			dev_net(skb->dev), NULL, skb, skb->dev, NULL,
			br_handle_frame_finish);
		break;
	default:
drop:
		kfree_skb(skb);
	}
	return RX_HANDLER_CONSUMED;
}
