29
29
#include "smc_ism.h"
30
30
#include "smc_core.h"
31
31
32
+ static struct net_device * __pnet_find_base_ndev (struct net_device * ndev );
32
33
static struct net_device * pnet_find_base_ndev (struct net_device * ndev );
33
34
34
35
static const struct nla_policy smc_pnet_policy [SMC_PNETID_MAX + 1 ] = {
@@ -712,10 +713,115 @@ static struct genl_family smc_pnet_nl_family __ro_after_init = {
712
713
.n_ops = ARRAY_SIZE (smc_pnet_ops )
713
714
};
714
715
716
+ bool smc_pnet_is_ndev_pnetid (struct net * net , u8 * pnetid )
717
+ {
718
+ struct smc_net * sn = net_generic (net , smc_net_id );
719
+ struct smc_pnetids_ndev_entry * pe ;
720
+ bool rc = false;
721
+
722
+ read_lock (& sn -> pnetids_ndev .lock );
723
+ list_for_each_entry (pe , & sn -> pnetids_ndev .list , list ) {
724
+ if (smc_pnet_match (pnetid , pe -> pnetid )) {
725
+ rc = true;
726
+ goto unlock ;
727
+ }
728
+ }
729
+
730
+ unlock :
731
+ read_unlock (& sn -> pnetids_ndev .lock );
732
+ return rc ;
733
+ }
734
+
735
+ static int smc_pnet_add_pnetid (struct net * net , u8 * pnetid )
736
+ {
737
+ struct smc_net * sn = net_generic (net , smc_net_id );
738
+ struct smc_pnetids_ndev_entry * pe , * pi ;
739
+
740
+ pe = kzalloc (sizeof (* pe ), GFP_KERNEL );
741
+ if (!pe )
742
+ return - ENOMEM ;
743
+
744
+ write_lock (& sn -> pnetids_ndev .lock );
745
+ list_for_each_entry (pi , & sn -> pnetids_ndev .list , list ) {
746
+ if (smc_pnet_match (pnetid , pe -> pnetid )) {
747
+ refcount_inc (& pi -> refcnt );
748
+ kfree (pe );
749
+ goto unlock ;
750
+ }
751
+ }
752
+ refcount_set (& pe -> refcnt , 1 );
753
+ memcpy (pe -> pnetid , pnetid , SMC_MAX_PNETID_LEN );
754
+ list_add_tail (& pe -> list , & sn -> pnetids_ndev .list );
755
+
756
+ unlock :
757
+ write_unlock (& sn -> pnetids_ndev .lock );
758
+ return 0 ;
759
+ }
760
+
761
+ static void smc_pnet_remove_pnetid (struct net * net , u8 * pnetid )
762
+ {
763
+ struct smc_net * sn = net_generic (net , smc_net_id );
764
+ struct smc_pnetids_ndev_entry * pe , * pe2 ;
765
+
766
+ write_lock (& sn -> pnetids_ndev .lock );
767
+ list_for_each_entry_safe (pe , pe2 , & sn -> pnetids_ndev .list , list ) {
768
+ if (smc_pnet_match (pnetid , pe -> pnetid )) {
769
+ if (refcount_dec_and_test (& pe -> refcnt )) {
770
+ list_del (& pe -> list );
771
+ kfree (pe );
772
+ }
773
+ break ;
774
+ }
775
+ }
776
+ write_unlock (& sn -> pnetids_ndev .lock );
777
+ }
778
+
779
+ static void smc_pnet_add_base_pnetid (struct net * net , struct net_device * dev ,
780
+ u8 * ndev_pnetid )
781
+ {
782
+ struct net_device * base_dev ;
783
+
784
+ base_dev = __pnet_find_base_ndev (dev );
785
+ if (base_dev -> flags & IFF_UP &&
786
+ !smc_pnetid_by_dev_port (base_dev -> dev .parent , base_dev -> dev_port ,
787
+ ndev_pnetid )) {
788
+ /* add to PNETIDs list */
789
+ smc_pnet_add_pnetid (net , ndev_pnetid );
790
+ }
791
+ }
792
+
793
+ /* create initial list of netdevice pnetids */
794
+ static void smc_pnet_create_pnetids_list (struct net * net )
795
+ {
796
+ u8 ndev_pnetid [SMC_MAX_PNETID_LEN ];
797
+ struct net_device * dev ;
798
+
799
+ rtnl_lock ();
800
+ for_each_netdev (net , dev )
801
+ smc_pnet_add_base_pnetid (net , dev , ndev_pnetid );
802
+ rtnl_unlock ();
803
+ }
804
+
805
+ /* clean up list of netdevice pnetids */
806
+ static void smc_pnet_destroy_pnetids_list (struct net * net )
807
+ {
808
+ struct smc_net * sn = net_generic (net , smc_net_id );
809
+ struct smc_pnetids_ndev_entry * pe , * temp_pe ;
810
+
811
+ write_lock (& sn -> pnetids_ndev .lock );
812
+ list_for_each_entry_safe (pe , temp_pe , & sn -> pnetids_ndev .list , list ) {
813
+ list_del (& pe -> list );
814
+ kfree (pe );
815
+ }
816
+ write_unlock (& sn -> pnetids_ndev .lock );
817
+ }
818
+
715
819
static int smc_pnet_netdev_event (struct notifier_block * this ,
716
820
unsigned long event , void * ptr )
717
821
{
718
822
struct net_device * event_dev = netdev_notifier_info_to_dev (ptr );
823
+ struct net * net = dev_net (event_dev );
824
+ u8 ndev_pnetid [SMC_MAX_PNETID_LEN ];
719
825
720
826
switch (event ) {
721
827
case NETDEV_REBOOT :
@@ -725,6 +831,17 @@ static int smc_pnet_netdev_event(struct notifier_block *this,
725
831
case NETDEV_REGISTER :
726
832
smc_pnet_add_by_ndev (event_dev );
727
833
return NOTIFY_OK ;
834
+ case NETDEV_UP :
835
+ smc_pnet_add_base_pnetid (net , event_dev , ndev_pnetid );
836
+ return NOTIFY_OK ;
837
+ case NETDEV_DOWN :
838
+ event_dev = __pnet_find_base_ndev (event_dev );
839
+ if (!smc_pnetid_by_dev_port (event_dev -> dev .parent ,
840
+ event_dev -> dev_port , ndev_pnetid )) {
841
+ /* remove from PNETIDs list */
842
+ smc_pnet_remove_pnetid (net , ndev_pnetid );
843
+ }
844
+ return NOTIFY_OK ;
728
845
default :
729
846
return NOTIFY_DONE ;
730
847
}
@@ -739,9 +856,14 @@ int smc_pnet_net_init(struct net *net)
739
856
{
740
857
struct smc_net * sn = net_generic (net , smc_net_id );
741
858
struct smc_pnettable * pnettable = & sn -> pnettable ;
859
+ struct smc_pnetids_ndev * pnetids_ndev = & sn -> pnetids_ndev ;
742
860
743
861
INIT_LIST_HEAD (& pnettable -> pnetlist );
744
862
rwlock_init (& pnettable -> lock );
863
+ INIT_LIST_HEAD (& pnetids_ndev -> list );
864
+ rwlock_init (& pnetids_ndev -> lock );
865
+
866
+ smc_pnet_create_pnetids_list (net );
745
867
746
868
return 0 ;
747
869
}
@@ -756,6 +878,7 @@ int __init smc_pnet_init(void)
756
878
rc = register_netdevice_notifier (& smc_netdev_notifier );
757
879
if (rc )
758
880
genl_unregister_family (& smc_pnet_nl_family );
881
+
759
882
return rc ;
760
883
}
761
884
@@ -764,6 +887,7 @@ void smc_pnet_net_exit(struct net *net)
764
887
{
765
888
/* flush pnet table */
766
889
smc_pnet_remove_by_pnetid (net , NULL );
890
+ smc_pnet_destroy_pnetids_list (net );
767
891
}
768
892
769
893
void smc_pnet_exit (void )
@@ -772,16 +896,11 @@ void smc_pnet_exit(void)
772
896
genl_unregister_family (& smc_pnet_nl_family );
773
897
}
774
898
775
- /* Determine one base device for stacked net devices.
776
- * If the lower device level contains more than one devices
777
- * (for instance with bonding slaves), just the first device
778
- * is used to reach a base device.
779
- */
780
- static struct net_device * pnet_find_base_ndev (struct net_device * ndev )
899
+ static struct net_device * __pnet_find_base_ndev (struct net_device * ndev )
781
900
{
782
901
int i , nest_lvl ;
783
902
784
- rtnl_lock ();
903
+ ASSERT_RTNL ();
785
904
nest_lvl = ndev -> lower_level ;
786
905
for (i = 0 ; i < nest_lvl ; i ++ ) {
787
906
struct list_head * lower = & ndev -> adj_list .lower ;
@@ -791,6 +910,18 @@ static struct net_device *pnet_find_base_ndev(struct net_device *ndev)
791
910
lower = lower -> next ;
792
911
ndev = netdev_lower_get_next (ndev , & lower );
793
912
}
913
+ return ndev ;
914
+ }
915
+
916
+ /* Determine one base device for stacked net devices.
917
+ * If the lower device level contains more than one devices
918
+ * (for instance with bonding slaves), just the first device
919
+ * is used to reach a base device.
920
+ */
921
+ static struct net_device * pnet_find_base_ndev (struct net_device * ndev )
922
+ {
923
+ rtnl_lock ();
924
+ ndev = __pnet_find_base_ndev (ndev );
794
925
rtnl_unlock ();
795
926
return ndev ;
796
927
}
0 commit comments