@@ -372,7 +372,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
372372
373373 ASSERT_RTNL ();
374374
375- if (dev -> mtu < IPV6_MIN_MTU )
375+ if (dev -> mtu < IPV6_MIN_MTU && dev != blackhole_netdev )
376376 return ERR_PTR (- EINVAL );
377377
378378 ndev = kzalloc (sizeof (struct inet6_dev ), GFP_KERNEL );
@@ -400,21 +400,22 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
400400 /* We refer to the device */
401401 dev_hold_track (dev , & ndev -> dev_tracker , GFP_KERNEL );
402402
403- if (snmp6_alloc_dev (ndev ) < 0 ) {
404- netdev_dbg (dev , "%s: cannot allocate memory for statistics\n" ,
405- __func__ );
406- neigh_parms_release (& nd_tbl , ndev -> nd_parms );
407- dev_put_track (dev , & ndev -> dev_tracker );
408- kfree (ndev );
409- return ERR_PTR (err );
410- }
403+ if (dev != blackhole_netdev ) {
404+ if (snmp6_alloc_dev (ndev ) < 0 ) {
405+ netdev_dbg (dev , "%s: cannot allocate memory for statistics\n" ,
406+ __func__ );
407+ neigh_parms_release (& nd_tbl , ndev -> nd_parms );
408+ dev_put_track (dev , & ndev -> dev_tracker );
409+ kfree (ndev );
410+ return ERR_PTR (err );
411+ }
411412
412- if (snmp6_register_dev (ndev ) < 0 ) {
413- netdev_dbg (dev , "%s: cannot create /proc/net/dev_snmp6/%s\n" ,
414- __func__ , dev -> name );
415- goto err_release ;
413+ if (snmp6_register_dev (ndev ) < 0 ) {
414+ netdev_dbg (dev , "%s: cannot create /proc/net/dev_snmp6/%s\n" ,
415+ __func__ , dev -> name );
416+ goto err_release ;
417+ }
416418 }
417-
418419 /* One reference from device. */
419420 refcount_set (& ndev -> refcnt , 1 );
420421
@@ -445,25 +446,28 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
445446
446447 ipv6_mc_init_dev (ndev );
447448 ndev -> tstamp = jiffies ;
448- err = addrconf_sysctl_register (ndev );
449- if (err ) {
450- ipv6_mc_destroy_dev (ndev );
451- snmp6_unregister_dev (ndev );
452- goto err_release ;
449+ if (dev != blackhole_netdev ) {
450+ err = addrconf_sysctl_register (ndev );
451+ if (err ) {
452+ ipv6_mc_destroy_dev (ndev );
453+ snmp6_unregister_dev (ndev );
454+ goto err_release ;
455+ }
453456 }
454457 /* protected by rtnl_lock */
455458 rcu_assign_pointer (dev -> ip6_ptr , ndev );
456459
457- /* Join interface-local all-node multicast group */
458- ipv6_dev_mc_inc (dev , & in6addr_interfacelocal_allnodes );
460+ if (dev != blackhole_netdev ) {
461+ /* Join interface-local all-node multicast group */
462+ ipv6_dev_mc_inc (dev , & in6addr_interfacelocal_allnodes );
459463
460- /* Join all-node multicast group */
461- ipv6_dev_mc_inc (dev , & in6addr_linklocal_allnodes );
462-
463- /* Join all-router multicast group if forwarding is set */
464- if (ndev -> cnf .forwarding && (dev -> flags & IFF_MULTICAST ))
465- ipv6_dev_mc_inc (dev , & in6addr_linklocal_allrouters );
464+ /* Join all-node multicast group */
465+ ipv6_dev_mc_inc (dev , & in6addr_linklocal_allnodes );
466466
467+ /* Join all-router multicast group if forwarding is set */
468+ if (ndev -> cnf .forwarding && (dev -> flags & IFF_MULTICAST ))
469+ ipv6_dev_mc_inc (dev , & in6addr_linklocal_allrouters );
470+ }
467471 return ndev ;
468472
469473err_release :
@@ -7233,26 +7237,8 @@ int __init addrconf_init(void)
72337237 goto out_nowq ;
72347238 }
72357239
7236- /* The addrconf netdev notifier requires that loopback_dev
7237- * has it's ipv6 private information allocated and setup
7238- * before it can bring up and give link-local addresses
7239- * to other devices which are up.
7240- *
7241- * Unfortunately, loopback_dev is not necessarily the first
7242- * entry in the global dev_base list of net devices. In fact,
7243- * it is likely to be the very last entry on that list.
7244- * So this causes the notifier registry below to try and
7245- * give link-local addresses to all devices besides loopback_dev
7246- * first, then loopback_dev, which cases all the non-loopback_dev
7247- * devices to fail to get a link-local address.
7248- *
7249- * So, as a temporary fix, allocate the ipv6 structure for
7250- * loopback_dev first by hand.
7251- * Longer term, all of the dependencies ipv6 has upon the loopback
7252- * device and it being up should be removed.
7253- */
72547240 rtnl_lock ();
7255- idev = ipv6_add_dev (init_net . loopback_dev );
7241+ idev = ipv6_add_dev (blackhole_netdev );
72567242 rtnl_unlock ();
72577243 if (IS_ERR (idev )) {
72587244 err = PTR_ERR (idev );
0 commit comments