Commit 9ea9bfa1 authored by John Hurley's avatar John Hurley Committed by David S. Miller
Browse files

nfp: flower: support ipv6 tunnel keep-alive messages from fw



FW sends an update of IPv6 tunnels that are active in a given period. Use
this information to update the kernel table so that neighbour entries do
not time out when active on the NIC.

Signed-off-by: default avatarJohn Hurley <john.hurley@netronome.com>
Reviewed-by: default avatarSimon Horman <simon.horman@netronome.com>
Reviewed-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6c463a05
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -278,6 +278,9 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb)
	case NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS:
		nfp_tunnel_keep_alive(app, skb);
		break;
	case NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS_V6:
		nfp_tunnel_keep_alive_v6(app, skb);
		break;
	case NFP_FLOWER_CMSG_TYPE_QOS_STATS:
		nfp_flower_stats_rlim_reply(app, skb);
		break;
+1 −0
Original line number Diff line number Diff line
@@ -574,6 +574,7 @@ enum nfp_flower_cmsg_type_port {
	NFP_FLOWER_CMSG_TYPE_TUN_IPS_V6 =	22,
	NFP_FLOWER_CMSG_TYPE_NO_NEIGH_V6 =	23,
	NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6 =	24,
	NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS_V6 =	25,
	NFP_FLOWER_CMSG_TYPE_MAX =		32,
};

+1 −0
Original line number Diff line number Diff line
@@ -425,6 +425,7 @@ nfp_tunnel_add_ipv6_off(struct nfp_app *app, struct in6_addr *ipv6);
void nfp_tunnel_request_route_v4(struct nfp_app *app, struct sk_buff *skb);
void nfp_tunnel_request_route_v6(struct nfp_app *app, struct sk_buff *skb);
void nfp_tunnel_keep_alive(struct nfp_app *app, struct sk_buff *skb);
void nfp_tunnel_keep_alive_v6(struct nfp_app *app, struct sk_buff *skb);
void nfp_flower_lag_init(struct nfp_fl_lag *lag);
void nfp_flower_lag_cleanup(struct nfp_fl_lag *lag);
int nfp_flower_lag_reset(struct nfp_fl_lag *lag);
+62 −0
Original line number Diff line number Diff line
@@ -54,6 +54,25 @@ struct nfp_tun_active_tuns {
	} tun_info[];
};

/**
 * struct nfp_tun_active_tuns_v6 - periodic message of active IPv6 tunnels
 * @seq:		sequence number of the message
 * @count:		number of tunnels report in message
 * @flags:		options part of the request
 * @tun_info.ipv6:		dest IPv6 address of active route
 * @tun_info.egress_port:	port the encapsulated packet egressed
 * @tun_info:		tunnels that have sent traffic in reported period
 */
struct nfp_tun_active_tuns_v6 {
	__be32 seq;
	__be32 count;
	__be32 flags;
	struct route_ip_info_v6 {
		struct in6_addr ipv6;
		__be32 egress_port;
	} tun_info[];
};

/**
 * struct nfp_tun_neigh - neighbour/route entry on the NFP
 * @dst_ipv4:	destination IPv4 address
@@ -244,6 +263,49 @@ void nfp_tunnel_keep_alive(struct nfp_app *app, struct sk_buff *skb)
	rcu_read_unlock();
}

void nfp_tunnel_keep_alive_v6(struct nfp_app *app, struct sk_buff *skb)
{
#if IS_ENABLED(CONFIG_IPV6)
	struct nfp_tun_active_tuns_v6 *payload;
	struct net_device *netdev;
	int count, i, pay_len;
	struct neighbour *n;
	void *ipv6_add;
	u32 port;

	payload = nfp_flower_cmsg_get_data(skb);
	count = be32_to_cpu(payload->count);
	if (count > NFP_FL_IPV6_ADDRS_MAX) {
		nfp_flower_cmsg_warn(app, "IPv6 tunnel keep-alive request exceeds max routes.\n");
		return;
	}

	pay_len = nfp_flower_cmsg_get_data_len(skb);
	if (pay_len != struct_size(payload, tun_info, count)) {
		nfp_flower_cmsg_warn(app, "Corruption in tunnel keep-alive message.\n");
		return;
	}

	rcu_read_lock();
	for (i = 0; i < count; i++) {
		ipv6_add = &payload->tun_info[i].ipv6;
		port = be32_to_cpu(payload->tun_info[i].egress_port);
		netdev = nfp_app_dev_get(app, port, NULL);
		if (!netdev)
			continue;

		n = neigh_lookup(&nd_tbl, ipv6_add, netdev);
		if (!n)
			continue;

		/* Update the used timestamp of neighbour */
		neigh_event_send(n, NULL);
		neigh_release(n);
	}
	rcu_read_unlock();
#endif
}

static int
nfp_flower_xmit_tun_conf(struct nfp_app *app, u8 mtype, u16 plen, void *pdata,
			 gfp_t flag)