@@ -600,15 +600,13 @@ static void mlxsw_sp_vrs_fini(struct mlxsw_sp *mlxsw_sp)
600
600
}
601
601
602
602
struct mlxsw_sp_neigh_key {
603
- unsigned char addr [sizeof (struct in6_addr )];
604
- struct net_device * dev ;
603
+ struct neighbour * n ;
605
604
};
606
605
607
606
struct mlxsw_sp_neigh_entry {
608
607
struct rhash_head ht_node ;
609
608
struct mlxsw_sp_neigh_key key ;
610
609
u16 rif ;
611
- struct neighbour * n ;
612
610
bool offloaded ;
613
611
struct delayed_work dw ;
614
612
struct mlxsw_sp_port * mlxsw_sp_port ;
@@ -646,19 +644,15 @@ mlxsw_sp_neigh_entry_remove(struct mlxsw_sp *mlxsw_sp,
646
644
static void mlxsw_sp_router_neigh_update_hw (struct work_struct * work );
647
645
648
646
static struct mlxsw_sp_neigh_entry *
649
- mlxsw_sp_neigh_entry_create (const void * addr , size_t addr_len ,
650
- struct net_device * dev , u16 rif ,
651
- struct neighbour * n )
647
+ mlxsw_sp_neigh_entry_create (struct neighbour * n , u16 rif )
652
648
{
653
649
struct mlxsw_sp_neigh_entry * neigh_entry ;
654
650
655
651
neigh_entry = kzalloc (sizeof (* neigh_entry ), GFP_ATOMIC );
656
652
if (!neigh_entry )
657
653
return NULL ;
658
- memcpy (neigh_entry -> key .addr , addr , addr_len );
659
- neigh_entry -> key .dev = dev ;
654
+ neigh_entry -> key .n = n ;
660
655
neigh_entry -> rif = rif ;
661
- neigh_entry -> n = n ;
662
656
INIT_DELAYED_WORK (& neigh_entry -> dw , mlxsw_sp_router_neigh_update_hw );
663
657
INIT_LIST_HEAD (& neigh_entry -> nexthop_list );
664
658
return neigh_entry ;
@@ -671,13 +665,11 @@ mlxsw_sp_neigh_entry_destroy(struct mlxsw_sp_neigh_entry *neigh_entry)
671
665
}
672
666
673
667
static struct mlxsw_sp_neigh_entry *
674
- mlxsw_sp_neigh_entry_lookup (struct mlxsw_sp * mlxsw_sp , const void * addr ,
675
- size_t addr_len , struct net_device * dev )
668
+ mlxsw_sp_neigh_entry_lookup (struct mlxsw_sp * mlxsw_sp , struct neighbour * n )
676
669
{
677
- struct mlxsw_sp_neigh_key key = {{ 0 } } ;
670
+ struct mlxsw_sp_neigh_key key ;
678
671
679
- memcpy (key .addr , addr , addr_len );
680
- key .dev = dev ;
672
+ key .n = n ;
681
673
return rhashtable_lookup_fast (& mlxsw_sp -> router .neigh_ht ,
682
674
& key , mlxsw_sp_neigh_ht_params );
683
675
}
@@ -689,26 +681,20 @@ int mlxsw_sp_router_neigh_construct(struct net_device *dev,
689
681
struct mlxsw_sp * mlxsw_sp = mlxsw_sp_port -> mlxsw_sp ;
690
682
struct mlxsw_sp_neigh_entry * neigh_entry ;
691
683
struct mlxsw_sp_rif * r ;
692
- u32 dip ;
693
684
int err ;
694
685
695
686
if (n -> tbl != & arp_tbl )
696
687
return 0 ;
697
688
698
- dip = ntohl (* ((__be32 * ) n -> primary_key ));
699
- neigh_entry = mlxsw_sp_neigh_entry_lookup (mlxsw_sp , & dip , sizeof (dip ),
700
- n -> dev );
701
- if (neigh_entry ) {
702
- WARN_ON (neigh_entry -> n != n );
689
+ neigh_entry = mlxsw_sp_neigh_entry_lookup (mlxsw_sp , n );
690
+ if (neigh_entry )
703
691
return 0 ;
704
- }
705
692
706
693
r = mlxsw_sp_rif_find_by_dev (mlxsw_sp , n -> dev );
707
694
if (WARN_ON (!r ))
708
695
return - EINVAL ;
709
696
710
- neigh_entry = mlxsw_sp_neigh_entry_create (& dip , sizeof (dip ), n -> dev ,
711
- r -> rif , n );
697
+ neigh_entry = mlxsw_sp_neigh_entry_create (n , r -> rif );
712
698
if (!neigh_entry )
713
699
return - ENOMEM ;
714
700
err = mlxsw_sp_neigh_entry_insert (mlxsw_sp , neigh_entry );
@@ -727,14 +713,11 @@ void mlxsw_sp_router_neigh_destroy(struct net_device *dev,
727
713
struct mlxsw_sp_port * mlxsw_sp_port = netdev_priv (dev );
728
714
struct mlxsw_sp * mlxsw_sp = mlxsw_sp_port -> mlxsw_sp ;
729
715
struct mlxsw_sp_neigh_entry * neigh_entry ;
730
- u32 dip ;
731
716
732
717
if (n -> tbl != & arp_tbl )
733
718
return ;
734
719
735
- dip = ntohl (* ((__be32 * ) n -> primary_key ));
736
- neigh_entry = mlxsw_sp_neigh_entry_lookup (mlxsw_sp , & dip , sizeof (dip ),
737
- n -> dev );
720
+ neigh_entry = mlxsw_sp_neigh_entry_lookup (mlxsw_sp , n );
738
721
if (!neigh_entry )
739
722
return ;
740
723
mlxsw_sp_neigh_entry_remove (mlxsw_sp , neigh_entry );
@@ -862,7 +845,7 @@ static void mlxsw_sp_router_neighs_update_nh(struct mlxsw_sp *mlxsw_sp)
862
845
* is active regardless of the traffic.
863
846
*/
864
847
if (!list_empty (& neigh_entry -> nexthop_list ))
865
- neigh_event_send (neigh_entry -> n , NULL );
848
+ neigh_event_send (neigh_entry -> key . n , NULL );
866
849
}
867
850
rtnl_unlock ();
868
851
}
@@ -908,9 +891,9 @@ static void mlxsw_sp_router_probe_unresolved_nexthops(struct work_struct *work)
908
891
rtnl_lock ();
909
892
list_for_each_entry (neigh_entry , & mlxsw_sp -> router .nexthop_neighs_list ,
910
893
nexthop_neighs_list_node ) {
911
- if (!(neigh_entry -> n -> nud_state & NUD_VALID ) &&
894
+ if (!(neigh_entry -> key . n -> nud_state & NUD_VALID ) &&
912
895
!list_empty (& neigh_entry -> nexthop_list ))
913
- neigh_event_send (neigh_entry -> n , NULL );
896
+ neigh_event_send (neigh_entry -> key . n , NULL );
914
897
}
915
898
rtnl_unlock ();
916
899
@@ -927,7 +910,7 @@ static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work)
927
910
{
928
911
struct mlxsw_sp_neigh_entry * neigh_entry =
929
912
container_of (work , struct mlxsw_sp_neigh_entry , dw .work );
930
- struct neighbour * n = neigh_entry -> n ;
913
+ struct neighbour * n = neigh_entry -> key . n ;
931
914
struct mlxsw_sp_port * mlxsw_sp_port = neigh_entry -> mlxsw_sp_port ;
932
915
struct mlxsw_sp * mlxsw_sp = mlxsw_sp_port -> mlxsw_sp ;
933
916
char rauht_pl [MLXSW_REG_RAUHT_LEN ];
@@ -1030,11 +1013,8 @@ int mlxsw_sp_router_netevent_event(struct notifier_block *unused,
1030
1013
1031
1014
mlxsw_sp = mlxsw_sp_port -> mlxsw_sp ;
1032
1015
dip = ntohl (* ((__be32 * ) n -> primary_key ));
1033
- neigh_entry = mlxsw_sp_neigh_entry_lookup (mlxsw_sp ,
1034
- & dip ,
1035
- sizeof (__be32 ),
1036
- dev );
1037
- if (WARN_ON (!neigh_entry ) || WARN_ON (neigh_entry -> n != n )) {
1016
+ neigh_entry = mlxsw_sp_neigh_entry_lookup (mlxsw_sp , n );
1017
+ if (WARN_ON (!neigh_entry )) {
1038
1018
mlxsw_sp_port_dev_put (mlxsw_sp_port );
1039
1019
return NOTIFY_DONE ;
1040
1020
}
@@ -1343,33 +1323,26 @@ static int mlxsw_sp_nexthop_init(struct mlxsw_sp *mlxsw_sp,
1343
1323
struct fib_nh * fib_nh )
1344
1324
{
1345
1325
struct mlxsw_sp_neigh_entry * neigh_entry ;
1346
- u32 gwip = ntohl (fib_nh -> nh_gw );
1347
1326
struct net_device * dev = fib_nh -> nh_dev ;
1348
1327
struct neighbour * n ;
1349
1328
u8 nud_state ;
1350
1329
1351
- neigh_entry = mlxsw_sp_neigh_entry_lookup (mlxsw_sp , & gwip ,
1352
- sizeof (gwip ), dev );
1353
- if (!neigh_entry ) {
1354
- __be32 gwipn = htonl (gwip );
1355
-
1356
- n = neigh_create (& arp_tbl , & gwipn , dev );
1330
+ /* Take a reference of neigh here ensuring that neigh would
1331
+ * not be detructed before the nexthop entry is finished.
1332
+ * The reference is taken either in neigh_lookup() or
1333
+ * in neith_create() in case n is not found.
1334
+ */
1335
+ n = neigh_lookup (& arp_tbl , & fib_nh -> nh_gw , dev );
1336
+ if (!n ) {
1337
+ n = neigh_create (& arp_tbl , & fib_nh -> nh_gw , dev );
1357
1338
if (IS_ERR (n ))
1358
1339
return PTR_ERR (n );
1359
1340
neigh_event_send (n , NULL );
1360
- neigh_entry = mlxsw_sp_neigh_entry_lookup (mlxsw_sp , & gwip ,
1361
- sizeof (gwip ), dev );
1362
- if (!neigh_entry ) {
1363
- neigh_release (n );
1364
- return - EINVAL ;
1365
- }
1366
- } else {
1367
- /* Take a reference of neigh here ensuring that neigh would
1368
- * not be detructed before the nexthop entry is finished.
1369
- * The second branch takes the reference in neith_create()
1370
- */
1371
- n = neigh_entry -> n ;
1372
- neigh_clone (n );
1341
+ }
1342
+ neigh_entry = mlxsw_sp_neigh_entry_lookup (mlxsw_sp , n );
1343
+ if (!neigh_entry ) {
1344
+ neigh_release (n );
1345
+ return - EINVAL ;
1373
1346
}
1374
1347
1375
1348
/* If that is the first nexthop connected to that neigh, add to
@@ -1403,7 +1376,7 @@ static void mlxsw_sp_nexthop_fini(struct mlxsw_sp *mlxsw_sp,
1403
1376
if (list_empty (& nh -> neigh_entry -> nexthop_list ))
1404
1377
list_del (& nh -> neigh_entry -> nexthop_neighs_list_node );
1405
1378
1406
- neigh_release (neigh_entry -> n );
1379
+ neigh_release (neigh_entry -> key . n );
1407
1380
}
1408
1381
1409
1382
static struct mlxsw_sp_nexthop_group *
@@ -1463,11 +1436,11 @@ static bool mlxsw_sp_nexthop_match(struct mlxsw_sp_nexthop *nh,
1463
1436
1464
1437
for (i = 0 ; i < fi -> fib_nhs ; i ++ ) {
1465
1438
struct fib_nh * fib_nh = & fi -> fib_nh [i ];
1466
- u32 gwip = ntohl ( fib_nh -> nh_gw ) ;
1439
+ struct neighbour * n = nh -> neigh_entry -> key . n ;
1467
1440
1468
- if (memcmp (nh -> neigh_entry -> key . addr ,
1469
- & gwip , sizeof (u32 )) == 0 &&
1470
- nh -> neigh_entry -> key . dev == fib_nh -> nh_dev )
1441
+ if (memcmp (n -> primary_key , & fib_nh -> nh_gw ,
1442
+ sizeof (fib_nh -> nh_gw )) == 0 &&
1443
+ n -> dev == fib_nh -> nh_dev )
1471
1444
return true;
1472
1445
}
1473
1446
return false;
@@ -1958,6 +1931,9 @@ static int mlxsw_sp_router_fib_event(struct notifier_block *nb,
1958
1931
struct fib_entry_notifier_info * fen_info = ptr ;
1959
1932
int err ;
1960
1933
1934
+ if (!net_eq (fen_info -> info .net , & init_net ))
1935
+ return NOTIFY_DONE ;
1936
+
1961
1937
switch (event ) {
1962
1938
case FIB_EVENT_ENTRY_ADD :
1963
1939
err = mlxsw_sp_router_fib4_add (mlxsw_sp , fen_info );
0 commit comments