Skip to content

Commit abc2109

Browse files
liyanguoCoriginedavem330
authored andcommitted
nfp: flower: tunnel neigh support bond offload
Support hardware offload when tunnel neigh out port is bond. These feature work with the nfp firmware. If the firmware supports the NFP_FL_FEATS_TUNNEL_NEIGH_LAG feature, nfp driver write the bond information to the firmware neighbor table or do nothing for bond. when neighbor MAC changes, nfp driver need to update the neighbor information too. Signed-off-by: Yanguo Li <[email protected]> Reviewed-by: Louis Peens <[email protected]> Signed-off-by: Simon Horman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 04d63e6 commit abc2109

File tree

4 files changed

+114
-21
lines changed

4 files changed

+114
-21
lines changed

drivers/net/ethernet/netronome/nfp/flower/lag_conf.c

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -154,34 +154,64 @@ nfp_fl_lag_find_group_for_master_with_lag(struct nfp_fl_lag *lag,
154154
return NULL;
155155
}
156156

157-
int nfp_flower_lag_populate_pre_action(struct nfp_app *app,
158-
struct net_device *master,
159-
struct nfp_fl_pre_lag *pre_act,
160-
struct netlink_ext_ack *extack)
157+
static int nfp_fl_lag_get_group_info(struct nfp_app *app,
158+
struct net_device *netdev,
159+
__be16 *group_id,
160+
u8 *batch_ver,
161+
u8 *group_inst)
161162
{
162163
struct nfp_flower_priv *priv = app->priv;
163164
struct nfp_fl_lag_group *group = NULL;
164165
__be32 temp_vers;
165166

166167
mutex_lock(&priv->nfp_lag.lock);
167168
group = nfp_fl_lag_find_group_for_master_with_lag(&priv->nfp_lag,
168-
master);
169+
netdev);
169170
if (!group) {
170171
mutex_unlock(&priv->nfp_lag.lock);
171-
NL_SET_ERR_MSG_MOD(extack, "invalid entry: group does not exist for LAG action");
172172
return -ENOENT;
173173
}
174174

175-
pre_act->group_id = cpu_to_be16(group->group_id);
176-
temp_vers = cpu_to_be32(priv->nfp_lag.batch_ver <<
177-
NFP_FL_PRE_LAG_VER_OFF);
178-
memcpy(pre_act->lag_version, &temp_vers, 3);
179-
pre_act->instance = group->group_inst;
175+
if (group_id)
176+
*group_id = cpu_to_be16(group->group_id);
177+
178+
if (batch_ver) {
179+
temp_vers = cpu_to_be32(priv->nfp_lag.batch_ver <<
180+
NFP_FL_PRE_LAG_VER_OFF);
181+
memcpy(batch_ver, &temp_vers, 3);
182+
}
183+
184+
if (group_inst)
185+
*group_inst = group->group_inst;
186+
180187
mutex_unlock(&priv->nfp_lag.lock);
181188

182189
return 0;
183190
}
184191

192+
int nfp_flower_lag_populate_pre_action(struct nfp_app *app,
193+
struct net_device *master,
194+
struct nfp_fl_pre_lag *pre_act,
195+
struct netlink_ext_ack *extack)
196+
{
197+
if (nfp_fl_lag_get_group_info(app, master, &pre_act->group_id,
198+
pre_act->lag_version,
199+
&pre_act->instance)) {
200+
NL_SET_ERR_MSG_MOD(extack, "invalid entry: group does not exist for LAG action");
201+
return -ENOENT;
202+
}
203+
204+
return 0;
205+
}
206+
207+
void nfp_flower_lag_get_info_from_netdev(struct nfp_app *app,
208+
struct net_device *netdev,
209+
struct nfp_tun_neigh_lag *lag)
210+
{
211+
nfp_fl_lag_get_group_info(app, netdev, NULL,
212+
lag->lag_version, &lag->lag_instance);
213+
}
214+
185215
int nfp_flower_lag_get_output_id(struct nfp_app *app, struct net_device *master)
186216
{
187217
struct nfp_flower_priv *priv = app->priv;

drivers/net/ethernet/netronome/nfp/flower/main.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ nfp_flower_get_internal_port_id(struct nfp_app *app, struct net_device *netdev)
7676
u32 nfp_flower_get_port_id_from_netdev(struct nfp_app *app,
7777
struct net_device *netdev)
7878
{
79+
struct nfp_flower_priv *priv = app->priv;
7980
int ext_port;
81+
int gid;
8082

8183
if (nfp_netdev_is_nfp_repr(netdev)) {
8284
return nfp_repr_get_port_id(netdev);
@@ -86,6 +88,13 @@ u32 nfp_flower_get_port_id_from_netdev(struct nfp_app *app,
8688
return 0;
8789

8890
return nfp_flower_internal_port_get_port_id(ext_port);
91+
} else if (netif_is_lag_master(netdev) &&
92+
priv->flower_ext_feats & NFP_FL_FEATS_TUNNEL_NEIGH_LAG) {
93+
gid = nfp_flower_lag_get_output_id(app, netdev);
94+
if (gid < 0)
95+
return 0;
96+
97+
return (NFP_FL_LAG_OUT | gid);
8998
}
9099

91100
return 0;

drivers/net/ethernet/netronome/nfp/flower/main.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ struct nfp_app;
5252
#define NFP_FL_FEATS_QOS_PPS BIT(9)
5353
#define NFP_FL_FEATS_QOS_METER BIT(10)
5454
#define NFP_FL_FEATS_DECAP_V2 BIT(11)
55+
#define NFP_FL_FEATS_TUNNEL_NEIGH_LAG BIT(12)
5556
#define NFP_FL_FEATS_HOST_ACK BIT(31)
5657

5758
#define NFP_FL_ENABLE_FLOW_MERGE BIT(0)
@@ -69,7 +70,8 @@ struct nfp_app;
6970
NFP_FL_FEATS_VLAN_QINQ | \
7071
NFP_FL_FEATS_QOS_PPS | \
7172
NFP_FL_FEATS_QOS_METER | \
72-
NFP_FL_FEATS_DECAP_V2)
73+
NFP_FL_FEATS_DECAP_V2 | \
74+
NFP_FL_FEATS_TUNNEL_NEIGH_LAG)
7375

7476
struct nfp_fl_mask_id {
7577
struct circ_buf mask_id_free_list;
@@ -103,6 +105,16 @@ struct nfp_fl_tunnel_offloads {
103105
struct notifier_block neigh_nb;
104106
};
105107

108+
/**
109+
* struct nfp_tun_neigh_lag - lag info
110+
* @lag_version: lag version
111+
* @lag_instance: lag instance
112+
*/
113+
struct nfp_tun_neigh_lag {
114+
u8 lag_version[3];
115+
u8 lag_instance;
116+
};
117+
106118
/**
107119
* struct nfp_tun_neigh - basic neighbour data
108120
* @dst_addr: Destination MAC address
@@ -133,12 +145,14 @@ struct nfp_tun_neigh_ext {
133145
* @src_ipv4: Source IPv4 address
134146
* @common: Neighbour/route common info
135147
* @ext: Neighbour/route extended info
148+
* @lag: lag port info
136149
*/
137150
struct nfp_tun_neigh_v4 {
138151
__be32 dst_ipv4;
139152
__be32 src_ipv4;
140153
struct nfp_tun_neigh common;
141154
struct nfp_tun_neigh_ext ext;
155+
struct nfp_tun_neigh_lag lag;
142156
};
143157

144158
/**
@@ -147,12 +161,14 @@ struct nfp_tun_neigh_v4 {
147161
* @src_ipv6: Source IPv6 address
148162
* @common: Neighbour/route common info
149163
* @ext: Neighbour/route extended info
164+
* @lag: lag port info
150165
*/
151166
struct nfp_tun_neigh_v6 {
152167
struct in6_addr dst_ipv6;
153168
struct in6_addr src_ipv6;
154169
struct nfp_tun_neigh common;
155170
struct nfp_tun_neigh_ext ext;
171+
struct nfp_tun_neigh_lag lag;
156172
};
157173

158174
/**
@@ -647,6 +663,9 @@ int nfp_flower_lag_populate_pre_action(struct nfp_app *app,
647663
struct netlink_ext_ack *extack);
648664
int nfp_flower_lag_get_output_id(struct nfp_app *app,
649665
struct net_device *master);
666+
void nfp_flower_lag_get_info_from_netdev(struct nfp_app *app,
667+
struct net_device *netdev,
668+
struct nfp_tun_neigh_lag *lag);
650669
void nfp_flower_qos_init(struct nfp_app *app);
651670
void nfp_flower_qos_cleanup(struct nfp_app *app);
652671
int nfp_flower_setup_qos_offload(struct nfp_app *app, struct net_device *netdev,

drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,11 @@ nfp_flower_xmit_tun_conf(struct nfp_app *app, u8 mtype, u16 plen, void *pdata,
290290
mtype == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6))
291291
plen -= sizeof(struct nfp_tun_neigh_ext);
292292

293+
if (!(priv->flower_ext_feats & NFP_FL_FEATS_TUNNEL_NEIGH_LAG) &&
294+
(mtype == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH ||
295+
mtype == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6))
296+
plen -= sizeof(struct nfp_tun_neigh_lag);
297+
293298
skb = nfp_flower_cmsg_alloc(app, plen, mtype, flag);
294299
if (!skb)
295300
return -ENOMEM;
@@ -468,6 +473,7 @@ nfp_tun_write_neigh(struct net_device *netdev, struct nfp_app *app,
468473
neigh_table_params);
469474
if (!nn_entry && !neigh_invalid) {
470475
struct nfp_tun_neigh_ext *ext;
476+
struct nfp_tun_neigh_lag *lag;
471477
struct nfp_tun_neigh *common;
472478

473479
nn_entry = kzalloc(sizeof(*nn_entry) + neigh_size,
@@ -488,6 +494,7 @@ nfp_tun_write_neigh(struct net_device *netdev, struct nfp_app *app,
488494
payload->dst_ipv6 = flowi6->daddr;
489495
common = &payload->common;
490496
ext = &payload->ext;
497+
lag = &payload->lag;
491498
mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6;
492499
} else {
493500
struct flowi4 *flowi4 = (struct flowi4 *)flow;
@@ -498,13 +505,17 @@ nfp_tun_write_neigh(struct net_device *netdev, struct nfp_app *app,
498505
payload->dst_ipv4 = flowi4->daddr;
499506
common = &payload->common;
500507
ext = &payload->ext;
508+
lag = &payload->lag;
501509
mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH;
502510
}
503511
ext->host_ctx = cpu_to_be32(U32_MAX);
504512
ext->vlan_tpid = cpu_to_be16(U16_MAX);
505513
ext->vlan_tci = cpu_to_be16(U16_MAX);
506514
ether_addr_copy(common->src_addr, netdev->dev_addr);
507515
neigh_ha_snapshot(common->dst_addr, neigh, netdev);
516+
517+
if ((port_id & NFP_FL_LAG_OUT) == NFP_FL_LAG_OUT)
518+
nfp_flower_lag_get_info_from_netdev(app, netdev, lag);
508519
common->port_id = cpu_to_be32(port_id);
509520

510521
if (rhashtable_insert_fast(&priv->neigh_table,
@@ -547,13 +558,38 @@ nfp_tun_write_neigh(struct net_device *netdev, struct nfp_app *app,
547558
if (nn_entry->flow)
548559
list_del(&nn_entry->list_head);
549560
kfree(nn_entry);
550-
} else if (nn_entry && !neigh_invalid && override) {
551-
mtype = is_ipv6 ? NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6 :
552-
NFP_FLOWER_CMSG_TYPE_TUN_NEIGH;
553-
nfp_tun_link_predt_entries(app, nn_entry);
554-
nfp_flower_xmit_tun_conf(app, mtype, neigh_size,
555-
nn_entry->payload,
556-
GFP_ATOMIC);
561+
} else if (nn_entry && !neigh_invalid) {
562+
struct nfp_tun_neigh *common;
563+
u8 dst_addr[ETH_ALEN];
564+
bool is_mac_change;
565+
566+
if (is_ipv6) {
567+
struct nfp_tun_neigh_v6 *payload;
568+
569+
payload = (struct nfp_tun_neigh_v6 *)nn_entry->payload;
570+
common = &payload->common;
571+
mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH_V6;
572+
} else {
573+
struct nfp_tun_neigh_v4 *payload;
574+
575+
payload = (struct nfp_tun_neigh_v4 *)nn_entry->payload;
576+
common = &payload->common;
577+
mtype = NFP_FLOWER_CMSG_TYPE_TUN_NEIGH;
578+
}
579+
580+
ether_addr_copy(dst_addr, common->dst_addr);
581+
neigh_ha_snapshot(common->dst_addr, neigh, netdev);
582+
is_mac_change = !ether_addr_equal(dst_addr, common->dst_addr);
583+
if (override || is_mac_change) {
584+
if (is_mac_change && nn_entry->flow) {
585+
list_del(&nn_entry->list_head);
586+
nn_entry->flow = NULL;
587+
}
588+
nfp_tun_link_predt_entries(app, nn_entry);
589+
nfp_flower_xmit_tun_conf(app, mtype, neigh_size,
590+
nn_entry->payload,
591+
GFP_ATOMIC);
592+
}
557593
}
558594

559595
spin_unlock_bh(&priv->predt_lock);
@@ -593,8 +629,7 @@ nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event,
593629
app_priv = container_of(nb, struct nfp_flower_priv, tun.neigh_nb);
594630
app = app_priv->app;
595631

596-
if (!nfp_netdev_is_nfp_repr(n->dev) &&
597-
!nfp_flower_internal_port_can_offload(app, n->dev))
632+
if (!nfp_flower_get_port_id_from_netdev(app, n->dev))
598633
return NOTIFY_DONE;
599634

600635
#if IS_ENABLED(CONFIG_INET)

0 commit comments

Comments
 (0)