Skip to content

Commit 04f24a1

Browse files
OrlovEIkuba-moo
authored andcommitted
net: marvell: prestera: Add heplers to interact with fib_notifier_info
This will be used to implement nexthops related logic in next patches. Also try to keep ipv4/6 abstraction to be able to reuse helpers for ipv6 in the future. Co-developed-by: Taras Chornyi <[email protected]> Signed-off-by: Taras Chornyi <[email protected]> Co-developed-by: Oleksandr Mazur <[email protected]> Signed-off-by: Oleksandr Mazur <[email protected]> Signed-off-by: Yevhen Orlov <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 59b44ea commit 04f24a1

File tree

1 file changed

+65
-34
lines changed

1 file changed

+65
-34
lines changed

drivers/net/ethernet/marvell/prestera/prestera_router.c

Lines changed: 65 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <net/inet_dscp.h>
88
#include <net/switchdev.h>
99
#include <linux/rhashtable.h>
10+
#include <net/nexthop.h>
1011

1112
#include "prestera.h"
1213
#include "prestera_router_hw.h"
@@ -26,9 +27,10 @@ struct prestera_kern_fib_cache {
2627
} lpm_info; /* hold prepared lpm info */
2728
/* Indicate if route is not overlapped by another table */
2829
struct rhash_head ht_node; /* node of prestera_router */
29-
struct fib_info *fi;
30-
dscp_t kern_dscp;
31-
u8 kern_type;
30+
union {
31+
struct fib_notifier_info info; /* point to any of 4/6 */
32+
struct fib_entry_notifier_info fen4_info;
33+
};
3234
bool reachable;
3335
};
3436

@@ -51,15 +53,41 @@ static u32 prestera_fix_tb_id(u32 tb_id)
5153
}
5254

5355
static void
54-
prestera_util_fen_info2fib_cache_key(struct fib_entry_notifier_info *fen_info,
56+
prestera_util_fen_info2fib_cache_key(struct fib_notifier_info *info,
5557
struct prestera_kern_fib_cache_key *key)
5658
{
59+
struct fib_entry_notifier_info *fen_info =
60+
container_of(info, struct fib_entry_notifier_info, info);
61+
5762
memset(key, 0, sizeof(*key));
63+
key->addr.v = PRESTERA_IPV4;
5864
key->addr.u.ipv4 = cpu_to_be32(fen_info->dst);
5965
key->prefix_len = fen_info->dst_len;
6066
key->kern_tb_id = fen_info->tb_id;
6167
}
6268

69+
static unsigned char
70+
prestera_kern_fib_info_type(struct fib_notifier_info *info)
71+
{
72+
struct fib6_entry_notifier_info *fen6_info;
73+
struct fib_entry_notifier_info *fen4_info;
74+
75+
if (info->family == AF_INET) {
76+
fen4_info = container_of(info, struct fib_entry_notifier_info,
77+
info);
78+
return fen4_info->fi->fib_type;
79+
} else if (info->family == AF_INET6) {
80+
fen6_info = container_of(info, struct fib6_entry_notifier_info,
81+
info);
82+
/* TODO: ECMP in ipv6 is several routes.
83+
* Every route has single nh.
84+
*/
85+
return fen6_info->rt->fib6_type;
86+
}
87+
88+
return RTN_UNSPEC;
89+
}
90+
6391
static struct prestera_kern_fib_cache *
6492
prestera_kern_fib_cache_find(struct prestera_switch *sw,
6593
struct prestera_kern_fib_cache_key *key)
@@ -76,7 +104,7 @@ static void
76104
__prestera_kern_fib_cache_destruct(struct prestera_switch *sw,
77105
struct prestera_kern_fib_cache *fib_cache)
78106
{
79-
fib_info_put(fib_cache->fi);
107+
fib_info_put(fib_cache->fen4_info.fi);
80108
}
81109

82110
static void
@@ -96,8 +124,10 @@ prestera_kern_fib_cache_destroy(struct prestera_switch *sw,
96124
static struct prestera_kern_fib_cache *
97125
prestera_kern_fib_cache_create(struct prestera_switch *sw,
98126
struct prestera_kern_fib_cache_key *key,
99-
struct fib_info *fi, dscp_t dscp, u8 type)
127+
struct fib_notifier_info *info)
100128
{
129+
struct fib_entry_notifier_info *fen_info =
130+
container_of(info, struct fib_entry_notifier_info, info);
101131
struct prestera_kern_fib_cache *fib_cache;
102132
int err;
103133

@@ -106,10 +136,8 @@ prestera_kern_fib_cache_create(struct prestera_switch *sw,
106136
goto err_kzalloc;
107137

108138
memcpy(&fib_cache->key, key, sizeof(*key));
109-
fib_info_hold(fi);
110-
fib_cache->fi = fi;
111-
fib_cache->kern_dscp = dscp;
112-
fib_cache->kern_type = type;
139+
fib_info_hold(fen_info->fi);
140+
memcpy(&fib_cache->fen4_info, fen_info, sizeof(*fen_info));
113141

114142
err = rhashtable_insert_fast(&sw->router->kern_fib_cache_ht,
115143
&fib_cache->ht_node,
@@ -120,7 +148,7 @@ prestera_kern_fib_cache_create(struct prestera_switch *sw,
120148
return fib_cache;
121149

122150
err_ht_insert:
123-
fib_info_put(fi);
151+
fib_info_put(fen_info->fi);
124152
kfree(fib_cache);
125153
err_kzalloc:
126154
return NULL;
@@ -133,21 +161,25 @@ __prestera_k_arb_fib_lpm_offload_set(struct prestera_switch *sw,
133161
{
134162
struct fib_rt_info fri;
135163

136-
if (fc->key.addr.v != PRESTERA_IPV4)
164+
switch (fc->key.addr.v) {
165+
case PRESTERA_IPV4:
166+
fri.fi = fc->fen4_info.fi;
167+
fri.tb_id = fc->key.kern_tb_id;
168+
fri.dst = fc->key.addr.u.ipv4;
169+
fri.dst_len = fc->key.prefix_len;
170+
fri.dscp = fc->fen4_info.dscp;
171+
fri.type = fc->fen4_info.type;
172+
/* flags begin */
173+
fri.offload = offload;
174+
fri.trap = trap;
175+
fri.offload_failed = fail;
176+
/* flags end */
177+
fib_alias_hw_flags_set(&init_net, &fri);
137178
return;
138-
139-
fri.fi = fc->fi;
140-
fri.tb_id = fc->key.kern_tb_id;
141-
fri.dst = fc->key.addr.u.ipv4;
142-
fri.dst_len = fc->key.prefix_len;
143-
fri.dscp = fc->kern_dscp;
144-
fri.type = fc->kern_type;
145-
/* flags begin */
146-
fri.offload = offload;
147-
fri.trap = trap;
148-
fri.offload_failed = fail;
149-
/* flags end */
150-
fib_alias_hw_flags_set(&init_net, &fri);
179+
case PRESTERA_IPV6:
180+
/* TODO */
181+
return;
182+
}
151183
}
152184

153185
static int
@@ -156,7 +188,7 @@ __prestera_pr_k_arb_fc_lpm_info_calc(struct prestera_switch *sw,
156188
{
157189
memset(&fc->lpm_info, 0, sizeof(fc->lpm_info));
158190

159-
switch (fc->fi->fib_type) {
191+
switch (prestera_kern_fib_info_type(&fc->info)) {
160192
case RTN_UNICAST:
161193
fc->lpm_info.fib_type = PRESTERA_FIB_TYPE_TRAP;
162194
break;
@@ -283,14 +315,14 @@ __prestera_k_arb_util_fib_overlapped(struct prestera_switch *sw,
283315
static int
284316
prestera_k_arb_fib_evt(struct prestera_switch *sw,
285317
bool replace, /* replace or del */
286-
struct fib_entry_notifier_info *fen_info)
318+
struct fib_notifier_info *info)
287319
{
288320
struct prestera_kern_fib_cache *tfib_cache, *bfib_cache; /* top/btm */
289321
struct prestera_kern_fib_cache_key fc_key;
290322
struct prestera_kern_fib_cache *fib_cache;
291323
int err;
292324

293-
prestera_util_fen_info2fib_cache_key(fen_info, &fc_key);
325+
prestera_util_fen_info2fib_cache_key(info, &fc_key);
294326
fib_cache = prestera_kern_fib_cache_find(sw, &fc_key);
295327
if (fib_cache) {
296328
fib_cache->reachable = false;
@@ -313,10 +345,7 @@ prestera_k_arb_fib_evt(struct prestera_switch *sw,
313345
}
314346

315347
if (replace) {
316-
fib_cache = prestera_kern_fib_cache_create(sw, &fc_key,
317-
fen_info->fi,
318-
fen_info->dscp,
319-
fen_info->type);
348+
fib_cache = prestera_kern_fib_cache_create(sw, &fc_key, info);
320349
if (!fib_cache) {
321350
dev_err(sw->dev->dev, "fib_cache == NULL");
322351
return -ENOENT;
@@ -508,13 +537,15 @@ static void __prestera_router_fib_event_work(struct work_struct *work)
508537

509538
switch (fib_work->event) {
510539
case FIB_EVENT_ENTRY_REPLACE:
511-
err = prestera_k_arb_fib_evt(sw, true, &fib_work->fen_info);
540+
err = prestera_k_arb_fib_evt(sw, true,
541+
&fib_work->fen_info.info);
512542
if (err)
513543
goto err_out;
514544

515545
break;
516546
case FIB_EVENT_ENTRY_DEL:
517-
err = prestera_k_arb_fib_evt(sw, false, &fib_work->fen_info);
547+
err = prestera_k_arb_fib_evt(sw, false,
548+
&fib_work->fen_info.info);
518549
if (err)
519550
goto err_out;
520551

0 commit comments

Comments
 (0)