From: Simon Horman <simon.horman@corigine.com>
To: David Miller <davem@davemloft.net>, Jakub Kicinski <kuba@kernel.org>
Cc: netdev@vger.kernel.org, oss-drivers@corigine.com
Subject: [PATCH net-next 6/9] nfp: flower: rework tunnel neighbour configuration
Date: Thu, 5 May 2022 14:43:45 +0900 [thread overview]
Message-ID: <20220505054348.269511-7-simon.horman@corigine.com> (raw)
In-Reply-To: <20220505054348.269511-1-simon.horman@corigine.com>
From: Louis Peens <louis.peens@corigine.com>
This patch updates the way in which the tunnel neighbour entries
are handled. Previously they were mostly send-and-forget, with
just the destination IP's cached in a list. This update changes
to a scheme where the neighbour entry information is stored in
a hash table.
The reason for this is that the neighbour table will now also
be used on the decapsulation path, whereas previously it was
only used for encapsulation. We need to save more of the neighbour
information in order to link them with flower flows in follow
up patches.
Updating of the neighbour table is now also handled by the same
function, instead of separate *_write_neigh_vX functions.
Signed-off-by: Louis Peens <louis.peens@corigine.com>
Signed-off-by: Yinjun Zhang <yinjun.zhang@corigine.com>
Signed-off-by: Simon Horman <simon.horman@corigine.com>
---
.../netronome/nfp/flower/tunnel_conf.c | 174 ++++++++++++------
1 file changed, 115 insertions(+), 59 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
index 174888272a30..4ca149501409 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
@@ -419,75 +419,131 @@ nfp_tun_del_route_from_cache_v6(struct nfp_app *app, struct in6_addr *ipv6_addr)
}
static void
-nfp_tun_write_neigh_v4(struct net_device *netdev, struct nfp_app *app,
- struct flowi4 *flow, struct neighbour *neigh, gfp_t flag)
+nfp_tun_write_neigh(struct net_device *netdev, struct nfp_app *app,
+ void *flow, struct neighbour *neigh, bool is_ipv6)
{
- struct nfp_tun_neigh_v4 payload;
+ bool neigh_invalid = !(neigh->nud_state & NUD_VALID) || neigh->dead;
+ size_t neigh_size = is_ipv6 ? sizeof(struct nfp_tun_neigh_v6) :
+ sizeof(struct nfp_tun_neigh_v4);
+ unsigned long cookie = (unsigned long)neigh;
+ struct nfp_flower_priv *priv = app->priv;
+ struct nfp_neigh_entry *nn_entry;
u32 port_id;
+ u8 mtype;
port_id = nfp_flower_get_port_id_from_netdev(app, netdev);
if (!port_id)
return;
- memset(&payload, 0, sizeof(struct nfp_tun_neigh_v4));
- payload.dst_ipv4 = flow->daddr;
+ spin_lock_bh(&priv->predt_lock);
+ nn_entry = rhashtable_lookup_fast(&priv->neigh_table, &cookie,
+ neigh_table_params);
+ if (!nn_entry && !neigh_invalid) {
+ struct nfp_tun_neigh_ext *ext;
+ struct nfp_tun_neigh *common;
+
+ nn_entry = kzalloc(sizeof(*nn_entry) + neigh_size,
+ GFP_ATOMIC);
+ if (!nn_entry)
+ goto err;
+
+ nn_entry->payload = (char *)&nn_entry[1];
+ nn_entry->neigh_cookie = cookie;
+ nn_entry->is_ipv6 = is_ipv6;
+ nn_entry->flow = NULL;
+ if (is_ipv6) {
+ struct flowi6 *flowi6 = (struct flowi6 *)flow;
+ struct nfp_tun_neigh_v6 *payload;
+
+ payload = (struct nfp_tun_neigh_v6 *)nn_entry->payload;
+ payload->src_ipv6 = flowi6->saddr;
+ payload->dst_ipv6 = flowi6->daddr;
+ common = &payload->common;
+ ext = &payload->ext;
+ mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6;
+ } else {
+ struct flowi4 *flowi4 = (struct flowi4 *)flow;
+ struct nfp_tun_neigh_v4 *payload;
+
+ payload = (struct nfp_tun_neigh_v4 *)nn_entry->payload;
+ payload->src_ipv4 = flowi4->saddr;
+ payload->dst_ipv4 = flowi4->daddr;
+ common = &payload->common;
+ ext = &payload->ext;
+ mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH;
+ }
+ ext->host_ctx = cpu_to_be32(U32_MAX);
+ ext->vlan_tpid = cpu_to_be16(U16_MAX);
+ ext->vlan_tci = cpu_to_be16(U16_MAX);
+ ether_addr_copy(common->src_addr, netdev->dev_addr);
+ neigh_ha_snapshot(common->dst_addr, neigh, netdev);
+ common->port_id = cpu_to_be32(port_id);
+
+ if (rhashtable_insert_fast(&priv->neigh_table,
+ &nn_entry->ht_node,
+ neigh_table_params))
+ goto err;
+
+ /* Add entries to the relevant route cache */
+ if (is_ipv6) {
+ struct nfp_tun_neigh_v6 *payload;
+
+ payload = (struct nfp_tun_neigh_v6 *)nn_entry->payload;
+ nfp_tun_add_route_to_cache_v6(app, &payload->dst_ipv6);
+ } else {
+ struct nfp_tun_neigh_v4 *payload;
+
+ payload = (struct nfp_tun_neigh_v4 *)nn_entry->payload;
+ nfp_tun_add_route_to_cache_v4(app, &payload->dst_ipv4);
+ }
- /* If entry has expired send dst IP with all other fields 0. */
- if (!(neigh->nud_state & NUD_VALID) || neigh->dead) {
- nfp_tun_del_route_from_cache_v4(app, &payload.dst_ipv4);
+ nfp_flower_xmit_tun_conf(app, mtype, neigh_size,
+ nn_entry->payload,
+ GFP_ATOMIC);
+ } else if (nn_entry && neigh_invalid) {
+ if (is_ipv6) {
+ struct flowi6 *flowi6 = (struct flowi6 *)flow;
+ struct nfp_tun_neigh_v6 *payload;
+
+ payload = (struct nfp_tun_neigh_v6 *)nn_entry->payload;
+ memset(payload, 0, sizeof(struct nfp_tun_neigh_v6));
+ payload->dst_ipv6 = flowi6->daddr;
+ mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6;
+ nfp_tun_del_route_from_cache_v6(app,
+ &payload->dst_ipv6);
+ } else {
+ struct flowi4 *flowi4 = (struct flowi4 *)flow;
+ struct nfp_tun_neigh_v4 *payload;
+
+ payload = (struct nfp_tun_neigh_v4 *)nn_entry->payload;
+ memset(payload, 0, sizeof(struct nfp_tun_neigh_v4));
+ payload->dst_ipv4 = flowi4->daddr;
+ mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH;
+ nfp_tun_del_route_from_cache_v4(app,
+ &payload->dst_ipv4);
+ }
/* Trigger ARP to verify invalid neighbour state. */
neigh_event_send(neigh, NULL);
- goto send_msg;
- }
-
- /* Have a valid neighbour so populate rest of entry. */
- payload.src_ipv4 = flow->saddr;
- ether_addr_copy(payload.common.src_addr, netdev->dev_addr);
- neigh_ha_snapshot(payload.common.dst_addr, neigh, netdev);
- payload.common.port_id = cpu_to_be32(port_id);
- /* Add destination of new route to NFP cache. */
- nfp_tun_add_route_to_cache_v4(app, &payload.dst_ipv4);
-
-send_msg:
- nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_NEIGH,
- sizeof(struct nfp_tun_neigh_v4),
- (unsigned char *)&payload, flag);
-}
+ rhashtable_remove_fast(&priv->neigh_table,
+ &nn_entry->ht_node,
+ neigh_table_params);
-static void
-nfp_tun_write_neigh_v6(struct net_device *netdev, struct nfp_app *app,
- struct flowi6 *flow, struct neighbour *neigh, gfp_t flag)
-{
- struct nfp_tun_neigh_v6 payload;
- u32 port_id;
+ nfp_flower_xmit_tun_conf(app, mtype, neigh_size,
+ nn_entry->payload,
+ GFP_ATOMIC);
- port_id = nfp_flower_get_port_id_from_netdev(app, netdev);
- if (!port_id)
- return;
-
- memset(&payload, 0, sizeof(struct nfp_tun_neigh_v6));
- payload.dst_ipv6 = flow->daddr;
-
- /* If entry has expired send dst IP with all other fields 0. */
- if (!(neigh->nud_state & NUD_VALID) || neigh->dead) {
- nfp_tun_del_route_from_cache_v6(app, &payload.dst_ipv6);
- /* Trigger probe to verify invalid neighbour state. */
- neigh_event_send(neigh, NULL);
- goto send_msg;
+ if (nn_entry->flow)
+ list_del(&nn_entry->list_head);
+ kfree(nn_entry);
}
- /* Have a valid neighbour so populate rest of entry. */
- payload.src_ipv6 = flow->saddr;
- ether_addr_copy(payload.common.src_addr, netdev->dev_addr);
- neigh_ha_snapshot(payload.common.dst_addr, neigh, netdev);
- payload.common.port_id = cpu_to_be32(port_id);
- /* Add destination of new route to NFP cache. */
- nfp_tun_add_route_to_cache_v6(app, &payload.dst_ipv6);
-
-send_msg:
- nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6,
- sizeof(struct nfp_tun_neigh_v6),
- (unsigned char *)&payload, flag);
+ spin_unlock_bh(&priv->predt_lock);
+ return;
+
+err:
+ kfree(nn_entry);
+ spin_unlock_bh(&priv->predt_lock);
+ nfp_flower_cmsg_warn(app, "Neighbour configuration failed.\n");
}
static int
@@ -556,7 +612,7 @@ nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event,
dst_release(dst);
}
- nfp_tun_write_neigh_v6(n->dev, app, &flow6, n, GFP_ATOMIC);
+ nfp_tun_write_neigh(n->dev, app, &flow6, n, true);
#else
return NOTIFY_DONE;
#endif /* CONFIG_IPV6 */
@@ -576,7 +632,7 @@ nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event,
ip_rt_put(rt);
}
- nfp_tun_write_neigh_v4(n->dev, app, &flow4, n, GFP_ATOMIC);
+ nfp_tun_write_neigh(n->dev, app, &flow4, n, false);
}
#else
return NOTIFY_DONE;
@@ -619,7 +675,7 @@ void nfp_tunnel_request_route_v4(struct nfp_app *app, struct sk_buff *skb)
ip_rt_put(rt);
if (!n)
goto fail_rcu_unlock;
- nfp_tun_write_neigh_v4(n->dev, app, &flow, n, GFP_ATOMIC);
+ nfp_tun_write_neigh(n->dev, app, &flow, n, false);
neigh_release(n);
rcu_read_unlock();
return;
@@ -661,7 +717,7 @@ void nfp_tunnel_request_route_v6(struct nfp_app *app, struct sk_buff *skb)
if (!n)
goto fail_rcu_unlock;
- nfp_tun_write_neigh_v6(n->dev, app, &flow, n, GFP_ATOMIC);
+ nfp_tun_write_neigh(n->dev, app, &flow, n, true);
neigh_release(n);
rcu_read_unlock();
return;
--
2.30.2
next prev parent reply other threads:[~2022-05-05 5:44 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-05 5:43 [PATCH net-next 0/9] nfp: flower: decap neighbour table rework Simon Horman
2022-05-05 5:43 ` [PATCH net-next 1/9] nfp: flower: add infrastructure for pre_tun rework Simon Horman
2022-05-05 5:43 ` [PATCH net-next 2/9] nfp: flower: add/remove predt_list entries Simon Horman
2022-05-05 5:43 ` [PATCH net-next 3/9] nfp: flower: enforce more strict pre_tun checks Simon Horman
2022-05-05 5:43 ` [PATCH net-next 4/9] nfp: flower: fixup ipv6/ipv4 route lookup for neigh events Simon Horman
2022-05-05 5:43 ` [PATCH net-next 5/9] nfp: flower: update nfp_tun_neigh structs Simon Horman
2022-05-05 5:43 ` Simon Horman [this message]
2022-05-05 5:43 ` [PATCH net-next 7/9] nfp: flower: link pre_tun flow rules with neigh entries Simon Horman
2022-05-05 5:43 ` [PATCH net-next 8/9] nfp: flower: remove unused neighbour cache Simon Horman
2022-05-05 5:43 ` [PATCH net-next 9/9] nfp: flower: enable decap_v2 bit Simon Horman
2022-05-06 10:40 ` [PATCH net-next 0/9] nfp: flower: decap neighbour table rework patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220505054348.269511-7-simon.horman@corigine.com \
--to=simon.horman@corigine.com \
--cc=davem@davemloft.net \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=oss-drivers@corigine.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).