/*
 *	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);

#ifdef CONFIG_ARC_PLAT_QTN
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;

#ifdef CONFIG_ARC_PLAT_QTN
	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_wlan_report_flood(struct net_bridge *br)
{
	return !!br->wlan_report_flood_enable;
}

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)) {
			if (!br_is_wlan_dev(skb->dev) ||
				br_wlan_report_flood(br)) {
				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, skb->src_port);

	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;

#ifdef CONFIG_ARC_PLAT_QTN
	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;

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

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

	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 */
		if (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; /* consumed by filter */
		} else {
			*pskb = skb;
			return RX_HANDLER_PASS;	/* continue processing */
		}
	}

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;
}
