// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Handle bridge arp/nd proxy/suppress
 *
 *  Copyright (C) 2017 Cumulus Networks
 *  Copyright (c) 2017 Roopa Prabhu <roopa@cumulusnetworks.com>
 *
 *  Authors:
 *	Roopa Prabhu <roopa@cumulusnetworks.com>
 */

#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/neighbour.h>
#include <net/arp.h>
#include <linux/if_vlan.h>
#include <linux/inetdevice.h>
#include <net/addrconf.h>
#if IS_ENABLED(CONFIG_IPV6)
#include <net/ip6_checksum.h>
#include <net/ndisc.h>
#endif

#include "br_private.h"

void br_recalculate_neigh_suppress_enabled(struct net_bridge *br)
{
	struct net_bridge_port *p;
	bool neigh_suppress = false;

	list_for_each_entry(p, &br->port_list, list) {
		if (READ_ONCE(p->flags) & (BR_NEIGH_SUPPRESS | BR_NEIGH_VLAN_SUPPRESS)) {
			neigh_suppress = true;
			break;
		}
	}

	br_opt_toggle(br, BROPT_NEIGH_SUPPRESS_ENABLED, neigh_suppress);
}

#if IS_ENABLED(CONFIG_INET)
static void br_arp_send(struct net_bridge *br, struct net_bridge_port *p,
			struct net_device *dev, __be32 dest_ip, __be32 src_ip,
			const unsigned char *dest_hw,
			const unsigned char *src_hw,
			const unsigned char *target_hw,
			__be16 vlan_proto, u16 vlan_tci)
{
	struct net_bridge_vlan_group *vg;
	struct sk_buff *skb;
	u16 pvid;

	netdev_dbg(dev, "arp send dev %s dst %pI4 dst_hw %pM src %pI4 src_hw %pM\n",
		   dev->name, &dest_ip, dest_hw, &src_ip, src_hw);

	if (!vlan_tci) {
		arp_send(ARPOP_REPLY, ETH_P_ARP, dest_ip, dev, src_ip,
			 dest_hw, src_hw, target_hw);
		return;
	}

	skb = arp_create(ARPOP_REPLY, ETH_P_ARP, dest_ip, dev, src_ip,
			 dest_hw, src_hw, target_hw);
	if (!skb)
		return;

	if (p)
		vg = nbp_vlan_group_rcu(p);
	else
		vg = br_vlan_group_rcu(br);
	pvid = br_get_pvid(vg);
	if (pvid == (vlan_tci & VLAN_VID_MASK))
		vlan_tci = 0;

	if (vlan_tci)
		__vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci);

	if (p) {
		arp_xmit(skb);
	} else {
		skb_reset_mac_header(skb);
		__skb_pull(skb, skb_network_offset(skb));
		skb->ip_summed = CHECKSUM_UNNECESSARY;
		skb->pkt_type = PACKET_HOST;

		netif_rx(skb);
	}
}

static int br_chk_addr_ip(struct net_device *dev,
			  struct netdev_nested_priv *priv)
{
	__be32 ip = *(__be32 *)priv->data;
	struct in_device *in_dev;
	__be32 addr = 0;

	in_dev = __in_dev_get_rcu(dev);
	if (in_dev)
		addr = inet_confirm_addr(dev_net(dev), in_dev, 0, ip,
					 RT_SCOPE_HOST);

	if (addr == ip)
		return 1;

	return 0;
}

static bool br_is_local_ip(struct net_device *dev, __be32 ip)
{
	struct netdev_nested_priv priv = {
		.data = (void *)&ip,
	};

	if (br_chk_addr_ip(dev, &priv))
		return true;

	/* check if ip is configured on upper dev */
	if (netdev_walk_all_upper_dev_rcu(dev, br_chk_addr_ip, &priv))
		return true;

	return false;
}

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

	BR_INPUT_SKB_CB(skb)->proxyarp_replied = 0;
	BR_INPUT_SKB_CB(skb)->grat_arp = 0;

	if ((dev->flags & IFF_NOARP) ||
	    !pskb_may_pull(skb, arp_hdr_len(dev)))
		return;

	parp = arp_hdr(skb);

	if (parp->ar_pro != htons(ETH_P_IP) ||
	    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;

	if (br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED)) {
		if (br_is_neigh_suppress_enabled(p, vid))
			return;
		if (is_unicast_ether_addr(eth_hdr(skb)->h_dest) &&
		    parp->ar_op == htons(ARPOP_REQUEST))
			return;
		if (parp->ar_op != htons(ARPOP_RREQUEST) &&
		    parp->ar_op != htons(ARPOP_RREPLY) &&
		    sip == tip) {
			/* prevent flooding to neigh suppress ports */
			BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1;
			BR_INPUT_SKB_CB(skb)->grat_arp = 1;
			return;
		}
	}

	if (parp->ar_op != htons(ARPOP_REQUEST))
		return;

	if (vid != 0) {
		vlandev = __vlan_find_dev_deep_rcu(br->dev, skb->vlan_proto,
						   vid);
		if (!vlandev)
			return;
	}

	if (br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED) &&
	    br_is_local_ip(vlandev, tip)) {
		/* its our local ip, so don't proxy reply
		 * and don't forward to neigh suppress ports
		 */
		BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1;
		return;
	}

	n = neigh_lookup(&arp_tbl, &tip, vlandev);
	if (n) {
		struct net_bridge_fdb_entry *f;
		u8 ha[ETH_ALEN] __aligned(2);

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

		neigh_ha_snapshot(ha, n, n->dev);
		f = br_fdb_find_rcu(br, ha, vid);
		if (f) {
			const struct net_bridge_port *dst = READ_ONCE(f->dst);
			bool replied = false;

			if ((p && test_bit(BR_PROXYARP_BIT, &p->flags)) ||
			    (dst && test_bit(BR_PROXYARP_WIFI_BIT, &dst->flags)) ||
			    br_is_neigh_suppress_enabled(dst, vid)) {
				if (!vid)
					br_arp_send(br, p, skb->dev, sip, tip,
						    sha, ha, sha, 0, 0);
				else
					br_arp_send(br, p, skb->dev, sip, tip,
						    sha, ha, sha,
						    skb->vlan_proto,
						    skb_vlan_tag_get(skb));
				replied = true;
			}

			/* If we have replied or as long as we know the
			 * mac, indicate to arp replied
			 */
			if (replied ||
			    br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED))
				BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1;
		}

		neigh_release(n);
	}
}
#endif

#if IS_ENABLED(CONFIG_IPV6)
/* Validate skb as an NS/NA and linearize it for br_nd_send()'s ND
 * option parsing; returns the nd_msg, or NULL on failure.
 */
struct nd_msg *br_is_nd_neigh_msg(struct sk_buff *skb)
{
	if (ndisc_check_ns_na(skb))
		return NULL;

	if (skb_linearize(skb))
		return NULL;

	return (struct nd_msg *)skb_transport_header(skb);
}

static void br_nd_send(struct net_bridge *br, struct net_bridge_port *p,
		       struct sk_buff *request, struct neighbour *n, u8 *ha,
		       __be16 vlan_proto, u16 vlan_tci)
{
	struct net_device *dev = request->dev;
	struct net_bridge_vlan_group *vg;
	struct ndisc_options ndopts;
	struct nd_msg *na, *ns;
	struct sk_buff *reply;
	struct ipv6hdr *pip6;
	int na_olen = 8; /* opt hdr + ETH_ALEN for target */
	int ns_olen;
	u8 *daddr;
	bool dad;
	u16 pvid;
	int len;

	if (!dev)
		return;

	len = LL_RESERVED_SPACE(dev) + sizeof(struct ipv6hdr) +
		sizeof(*na) + na_olen + dev->needed_tailroom;

	reply = alloc_skb(len, GFP_ATOMIC);
	if (!reply)
		return;

	reply->protocol = htons(ETH_P_IPV6);
	reply->dev = dev;
	skb_reserve(reply, LL_RESERVED_SPACE(dev));
	skb_push(reply, sizeof(struct ethhdr));
	skb_set_mac_header(reply, 0);

	daddr = eth_hdr(request)->h_source;
	ns = (struct nd_msg *)skb_transport_header(request);

	/* Derive the option length from the IPv6 payload length so that any
	 * trailing L2 padding in the skb is not parsed as ND options.
	 */
	ns_olen = ntohs(ipv6_hdr(request)->payload_len) - sizeof(*ns);
	if (!ndisc_parse_options(dev, ns->opt, ns_olen, &ndopts)) {
		kfree_skb(reply);
		return;
	}

	if (ndopts.nd_opts_src_lladdr) {
		u8 *lladdr;

		lladdr = ndisc_opt_addr_data(ndopts.nd_opts_src_lladdr, dev);
		if (lladdr)
			daddr = lladdr;
	}

	dad = ipv6_addr_any(&ipv6_hdr(request)->saddr);

	/* Ethernet header */
	if (dad)
		ipv6_eth_mc_map(&in6addr_linklocal_allnodes, eth_hdr(reply)->h_dest);
	else
		ether_addr_copy(eth_hdr(reply)->h_dest, daddr);
	ether_addr_copy(eth_hdr(reply)->h_source, ha);
	eth_hdr(reply)->h_proto = htons(ETH_P_IPV6);
	reply->protocol = htons(ETH_P_IPV6);

	skb_pull(reply, sizeof(struct ethhdr));
	skb_set_network_header(reply, 0);
	skb_put(reply, sizeof(struct ipv6hdr));

	/* IPv6 header */
	pip6 = ipv6_hdr(reply);
	memset(pip6, 0, sizeof(struct ipv6hdr));
	pip6->version = 6;
	pip6->priority = ipv6_hdr(request)->priority;
	pip6->nexthdr = IPPROTO_ICMPV6;
	pip6->hop_limit = 255;
	pip6->daddr = dad ? in6addr_linklocal_allnodes : ipv6_hdr(request)->saddr;
	pip6->saddr = *(struct in6_addr *)n->primary_key;

	skb_pull(reply, sizeof(struct ipv6hdr));
	skb_set_transport_header(reply, 0);

	na = (struct nd_msg *)skb_put(reply, sizeof(*na) + na_olen);

	/* Neighbor Advertisement */
	memset(na, 0, sizeof(*na) + na_olen);
	na->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
	na->icmph.icmp6_router = (n->flags & NTF_ROUTER) ? 1 : 0;
	na->icmph.icmp6_override = 1;
	na->icmph.icmp6_solicited = dad ? 0 : 1;
	na->target = ns->target;
	ether_addr_copy(&na->opt[2], ha);
	na->opt[0] = ND_OPT_TARGET_LL_ADDR;
	na->opt[1] = na_olen >> 3;

	na->icmph.icmp6_cksum = csum_ipv6_magic(&pip6->saddr,
						&pip6->daddr,
						sizeof(*na) + na_olen,
						IPPROTO_ICMPV6,
						csum_partial(na, sizeof(*na) + na_olen, 0));

	pip6->payload_len = htons(sizeof(*na) + na_olen);

	skb_push(reply, sizeof(struct ipv6hdr));
	skb_push(reply, sizeof(struct ethhdr));

	reply->ip_summed = CHECKSUM_UNNECESSARY;

	if (p)
		vg = nbp_vlan_group_rcu(p);
	else
		vg = br_vlan_group_rcu(br);
	pvid = br_get_pvid(vg);
	if (pvid == (vlan_tci & VLAN_VID_MASK))
		vlan_tci = 0;

	if (vlan_tci)
		__vlan_hwaccel_put_tag(reply, vlan_proto, vlan_tci);

	netdev_dbg(dev, "nd send dev %s dst %pI6 dst_hw %pM src %pI6 src_hw %pM\n",
		   dev->name, &pip6->daddr, daddr, &pip6->saddr, ha);

	if (p) {
		dev_queue_xmit(reply);
	} else {
		skb_reset_mac_header(reply);
		__skb_pull(reply, skb_network_offset(reply));
		reply->ip_summed = CHECKSUM_UNNECESSARY;
		reply->pkt_type = PACKET_HOST;

		netif_rx(reply);
	}
}

static int br_chk_addr_ip6(struct net_device *dev,
			   struct netdev_nested_priv *priv)
{
	struct in6_addr *addr = (struct in6_addr *)priv->data;

	if (ipv6_chk_addr(dev_net(dev), addr, dev, 0))
		return 1;

	return 0;
}

static bool br_is_local_ip6(struct net_device *dev, struct in6_addr *addr)

{
	struct netdev_nested_priv priv = {
		.data = (void *)addr,
	};

	if (br_chk_addr_ip6(dev, &priv))
		return true;

	/* check if ip is configured on upper dev */
	if (netdev_walk_all_upper_dev_rcu(dev, br_chk_addr_ip6, &priv))
		return true;

	return false;
}

void br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br,
		       u16 vid, struct net_bridge_port *p, struct nd_msg *msg)
{
	struct net_device *dev = br->dev;
	struct net_device *vlandev = NULL;
	struct in6_addr *saddr, *daddr;
	struct ipv6hdr *iphdr;
	struct neighbour *n;

	BR_INPUT_SKB_CB(skb)->proxyarp_replied = 0;
	BR_INPUT_SKB_CB(skb)->grat_arp = 0;

	if (br_is_neigh_suppress_enabled(p, vid))
		return;

	if (is_unicast_ether_addr(eth_hdr(skb)->h_dest) &&
	    msg->icmph.icmp6_type == NDISC_NEIGHBOUR_SOLICITATION)
		return;

	if (msg->icmph.icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT &&
	    !msg->icmph.icmp6_solicited) {
		/* prevent flooding to neigh suppress ports */
		BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1;
		BR_INPUT_SKB_CB(skb)->grat_arp = 1;
		return;
	}

	if (msg->icmph.icmp6_type != NDISC_NEIGHBOUR_SOLICITATION)
		return;

	iphdr = ipv6_hdr(skb);
	saddr = &iphdr->saddr;
	daddr = &iphdr->daddr;

	if (!ipv6_addr_cmp(saddr, daddr)) {
		/* prevent flooding to neigh suppress ports */
		BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1;
		return;
	}

	if (vid != 0) {
		/* build neigh table lookup on the vlan device */
		vlandev = __vlan_find_dev_deep_rcu(br->dev, skb->vlan_proto,
						   vid);
		if (!vlandev)
			return;
	} else {
		vlandev = dev;
	}

	if (br_is_local_ip6(vlandev, &msg->target)) {
		/* its our own ip, so don't proxy reply
		 * and don't forward to arp suppress ports
		 */
		BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1;
		return;
	}

	n = neigh_lookup(&nd_tbl, &msg->target, vlandev);
	if (n) {
		struct net_bridge_fdb_entry *f;
		u8 ha[ETH_ALEN] __aligned(2);

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

		neigh_ha_snapshot(ha, n, n->dev);
		f = br_fdb_find_rcu(br, ha, vid);
		if (f) {
			const struct net_bridge_port *dst = READ_ONCE(f->dst);
			bool replied = false;

			if (br_is_neigh_suppress_enabled(dst, vid)) {
				if (vid != 0)
					br_nd_send(br, p, skb, n, ha,
						   skb->vlan_proto,
						   skb_vlan_tag_get(skb));
				else
					br_nd_send(br, p, skb, n, ha, 0, 0);
				replied = true;
			}

			/* If we have replied or as long as we know the
			 * mac, indicate to NEIGH_SUPPRESS ports that we
			 * have replied
			 */
			if (replied ||
			    br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED))
				BR_INPUT_SKB_CB(skb)->proxyarp_replied = 1;
		}
		neigh_release(n);
	}
}
#endif

bool br_is_neigh_suppress_enabled(const struct net_bridge_port *p, u16 vid)
{
	if (!p)
		return false;

	if (vid && test_bit(BR_NEIGH_VLAN_SUPPRESS_BIT, &p->flags)) {
		struct net_bridge_vlan_group *vg = nbp_vlan_group_rcu(p);
		struct net_bridge_vlan *v;

		v = br_vlan_find(vg, vid);
		if (!v)
			return false;
		return !!(v->priv_flags & BR_VLFLAG_NEIGH_SUPPRESS_ENABLED);
	}
	return test_bit(BR_NEIGH_SUPPRESS_BIT, &p->flags);
}

bool br_is_neigh_forward_grat_enabled(const struct net_bridge_port *p, u16 vid)
{
	if (vid && test_bit(BR_NEIGH_VLAN_SUPPRESS_BIT, &p->flags)) {
		struct net_bridge_vlan_group *vg = nbp_vlan_group_rcu(p);
		struct net_bridge_vlan *v;

		v = br_vlan_find(vg, vid);
		if (!v)
			return false;
		return !!(v->priv_flags & BR_VLFLAG_NEIGH_FORWARD_GRAT_ENABLED);
	}
	return test_bit(BR_NEIGH_FORWARD_GRAT_BIT, &p->flags);
}
