|
@@ -602,9 +602,27 @@ struct net_device * alloc_netdev ( size_t priv_len ) {
|
602
|
602
|
int register_netdev ( struct net_device *netdev ) {
|
603
|
603
|
struct ll_protocol *ll_protocol = netdev->ll_protocol;
|
604
|
604
|
struct net_driver *driver;
|
|
605
|
+ struct net_device *duplicate;
|
605
|
606
|
uint32_t seed;
|
606
|
607
|
int rc;
|
607
|
608
|
|
|
609
|
+ /* Set initial link-layer address, if not already set */
|
|
610
|
+ if ( ! netdev_has_ll_addr ( netdev ) ) {
|
|
611
|
+ ll_protocol->init_addr ( netdev->hw_addr, netdev->ll_addr );
|
|
612
|
+ }
|
|
613
|
+
|
|
614
|
+ /* Reject network devices that are already available via a
|
|
615
|
+ * different hardware device.
|
|
616
|
+ */
|
|
617
|
+ duplicate = find_netdev_by_ll_addr ( ll_protocol, netdev->ll_addr );
|
|
618
|
+ if ( duplicate && ( duplicate->dev != netdev->dev ) ) {
|
|
619
|
+ DBGC ( netdev, "NETDEV rejecting duplicate (phys %s) of %s "
|
|
620
|
+ "(phys %s)\n", netdev->dev->name, duplicate->name,
|
|
621
|
+ duplicate->dev->name );
|
|
622
|
+ rc = -EEXIST;
|
|
623
|
+ goto err_duplicate;
|
|
624
|
+ }
|
|
625
|
+
|
608
|
626
|
/* Record device index and create device name */
|
609
|
627
|
netdev->index = netdev_index++;
|
610
|
628
|
if ( netdev->name[0] == '\0' ) {
|
|
@@ -612,11 +630,6 @@ int register_netdev ( struct net_device *netdev ) {
|
612
|
630
|
netdev->index );
|
613
|
631
|
}
|
614
|
632
|
|
615
|
|
- /* Set initial link-layer address, if not already set */
|
616
|
|
- if ( ! netdev_has_ll_addr ( netdev ) ) {
|
617
|
|
- ll_protocol->init_addr ( netdev->hw_addr, netdev->ll_addr );
|
618
|
|
- }
|
619
|
|
-
|
620
|
633
|
/* Use least significant bits of the link-layer address to
|
621
|
634
|
* improve the randomness of the (non-cryptographic) random
|
622
|
635
|
* number generator.
|
|
@@ -660,6 +673,7 @@ int register_netdev ( struct net_device *netdev ) {
|
660
|
673
|
clear_settings ( netdev_settings ( netdev ) );
|
661
|
674
|
unregister_settings ( netdev_settings ( netdev ) );
|
662
|
675
|
err_register_settings:
|
|
676
|
+ err_duplicate:
|
663
|
677
|
return rc;
|
664
|
678
|
}
|
665
|
679
|
|
|
@@ -852,6 +866,27 @@ struct net_device * find_netdev_by_location ( unsigned int bus_type,
|
852
|
866
|
return NULL;
|
853
|
867
|
}
|
854
|
868
|
|
|
869
|
+/**
|
|
870
|
+ * Get network device by link-layer address
|
|
871
|
+ *
|
|
872
|
+ * @v ll_protocol Link-layer protocol
|
|
873
|
+ * @v ll_addr Link-layer address
|
|
874
|
+ * @ret netdev Network device, or NULL
|
|
875
|
+ */
|
|
876
|
+struct net_device * find_netdev_by_ll_addr ( struct ll_protocol *ll_protocol,
|
|
877
|
+ const void *ll_addr ) {
|
|
878
|
+ struct net_device *netdev;
|
|
879
|
+
|
|
880
|
+ list_for_each_entry ( netdev, &net_devices, list ) {
|
|
881
|
+ if ( ( netdev->ll_protocol == ll_protocol ) &&
|
|
882
|
+ ( memcmp ( netdev->ll_addr, ll_addr,
|
|
883
|
+ ll_protocol->ll_addr_len ) == 0 ) )
|
|
884
|
+ return netdev;
|
|
885
|
+ }
|
|
886
|
+
|
|
887
|
+ return NULL;
|
|
888
|
+}
|
|
889
|
+
|
855
|
890
|
/**
|
856
|
891
|
* Get most recently opened network device
|
857
|
892
|
*
|