ソースを参照

[netdevice] Separate out the concept of hardware and link-layer addresses

The hardware address is an intrinsic property of the hardware, while
the link-layer address can be changed at runtime.  This separation is
exposed via APIs such as PXE and EFI, but is currently elided by gPXE.

Expose the hardware and link-layer addresses as separate properties
within a net device.  Drivers should now fill in hw_addr, which will
be used to initialise ll_addr at the time of calling
register_netdev().
tags/v0.9.8
Michael Brown 15年前
コミット
37a0aab4ff

+ 2
- 2
src/arch/i386/drivers/net/undinet.c ファイルの表示

@@ -689,7 +689,7 @@ int undinet_probe ( struct undi_device *undi ) {
689 689
 	if ( ( rc = undinet_call ( undinic, PXENV_UNDI_GET_INFORMATION,
690 690
 				   &undi_info, sizeof ( undi_info ) ) ) != 0 )
691 691
 		goto err_undi_get_information;
692
-	memcpy ( netdev->ll_addr, undi_info.PermNodeAddress, ETH_ALEN );
692
+	memcpy ( netdev->hw_addr, undi_info.PermNodeAddress, ETH_ALEN );
693 693
 	undinic->irq = undi_info.IntNumber;
694 694
 	if ( undinic->irq > IRQ_MAX ) {
695 695
 		DBGC ( undinic, "UNDINIC %p invalid IRQ %d\n",
@@ -697,7 +697,7 @@ int undinet_probe ( struct undi_device *undi ) {
697 697
 		goto err_bad_irq;
698 698
 	}
699 699
 	DBGC ( undinic, "UNDINIC %p is %s on IRQ %d\n",
700
-	       undinic, eth_ntoa ( netdev->ll_addr ), undinic->irq );
700
+	       undinic, eth_ntoa ( netdev->hw_addr ), undinic->irq );
701 701
 
702 702
 	/* Get interface information */
703 703
 	memset ( &undi_iface, 0, sizeof ( undi_iface ) );

+ 1
- 5
src/arch/i386/interface/pxe/pxe_undi.c ファイルの表示

@@ -421,15 +421,11 @@ PXENV_EXIT_t pxenv_undi_get_information ( struct s_PXENV_UNDI_GET_INFORMATION
421 421
 	undi_get_information->MaxTranUnit = ETH_MAX_MTU;
422 422
 	undi_get_information->HwType = ntohs ( ll_protocol->ll_proto );
423 423
 	undi_get_information->HwAddrLen = ll_protocol->ll_addr_len;
424
-	/* Cheat: assume card is always configured with its permanent
425
-	 * node address.  This is a valid assumption within Etherboot
426
-	 * at the time of writing.
427
-	 */
428 424
 	memcpy ( &undi_get_information->CurrentNodeAddress,
429 425
 		 pxe_netdev->ll_addr,
430 426
 		 sizeof ( undi_get_information->CurrentNodeAddress ) );
431 427
 	memcpy ( &undi_get_information->PermNodeAddress,
432
-		 pxe_netdev->ll_addr,
428
+		 pxe_netdev->hw_addr,
433 429
 		 sizeof ( undi_get_information->PermNodeAddress ) );
434 430
 	undi_get_information->ROMAddress = 0;
435 431
 		/* nic.rom_info->rom_segment; */

+ 1
- 1
src/drivers/net/3c90x.c ファイルの表示

@@ -928,7 +928,7 @@ static int a3c90x_probe(struct pci_device *pci,
928 928
 	/* load eeprom contents to inf_3c90x->eeprom */
929 929
 	a3c90x_internal_ReadEepromContents(inf_3c90x);
930 930
 
931
-	HWAddr = netdev->ll_addr;
931
+	HWAddr = netdev->hw_addr;
932 932
 
933 933
 	/* Retrieve the Hardware address */
934 934
 	HWAddr[0] = inf_3c90x->eeprom[eepromHwAddrOffset + 0] >> 8;

+ 6
- 6
src/drivers/net/b44.c ファイルの表示

@@ -594,12 +594,12 @@ static void b44_load_mac_and_phy_addr(struct b44_private *bp)
594 594
 
595 595
 	/* Load MAC address, note byteswapping */
596 596
 	b44_read_eeprom(bp, &eeprom[0]);
597
-	bp->netdev->ll_addr[0] = eeprom[79];
598
-	bp->netdev->ll_addr[1] = eeprom[78];
599
-	bp->netdev->ll_addr[2] = eeprom[81];
600
-	bp->netdev->ll_addr[3] = eeprom[80];
601
-	bp->netdev->ll_addr[4] = eeprom[83];
602
-	bp->netdev->ll_addr[5] = eeprom[82];
597
+	bp->netdev->hw_addr[0] = eeprom[79];
598
+	bp->netdev->hw_addr[1] = eeprom[78];
599
+	bp->netdev->hw_addr[2] = eeprom[81];
600
+	bp->netdev->hw_addr[3] = eeprom[80];
601
+	bp->netdev->hw_addr[4] = eeprom[83];
602
+	bp->netdev->hw_addr[5] = eeprom[82];
603 603
 
604 604
 	/* Load PHY address */
605 605
 	bp->phy_addr = eeprom[90] & 0x1f;

+ 1
- 1
src/drivers/net/e1000/e1000.c ファイルの表示

@@ -853,7 +853,7 @@ e1000_probe ( struct pci_device *pdev,
853 853
 	if ( e1000_read_mac_addr ( &adapter->hw ) )
854 854
 		DBG ( "EEPROM Read Error\n" );
855 855
 
856
-        memcpy ( netdev->ll_addr, adapter->hw.mac_addr, ETH_ALEN );
856
+        memcpy ( netdev->hw_addr, adapter->hw.mac_addr, ETH_ALEN );
857 857
 
858 858
 	/* print bus type/speed/width info */
859 859
 	{

+ 1
- 1
src/drivers/net/etherfabric.c ファイルの表示

@@ -4181,7 +4181,7 @@ efab_probe ( struct pci_device *pci,
4181 4181
 	if ( rc )
4182 4182
 		goto fail3;
4183 4183
 
4184
-	memcpy ( netdev->ll_addr, efab->mac_addr, ETH_ALEN );
4184
+	memcpy ( netdev->hw_addr, efab->mac_addr, ETH_ALEN );
4185 4185
 
4186 4186
 	netdev_link_up ( netdev );
4187 4187
 	rc = register_netdev ( netdev );

+ 24
- 42
src/drivers/net/ipoib.c ファイルの表示

@@ -607,38 +607,6 @@ static struct net_device_operations ipoib_operations = {
607 607
 	.irq		= ipoib_irq,
608 608
 };
609 609
 
610
-/**
611
- * Update IPoIB dynamic Infiniband parameters
612
- *
613
- * @v ipoib		IPoIB device
614
- *
615
- * The Infiniband port GID and partition key will change at runtime,
616
- * when the link is established (or lost).  The MAC address is based
617
- * on the port GID, and the broadcast GID is based on the partition
618
- * key.  This function recalculates these IPoIB device parameters.
619
- */
620
-static void ipoib_set_ib_params ( struct ipoib_device *ipoib ) {
621
-	struct ib_device *ibdev = ipoib->ibdev;
622
-	struct net_device *netdev = ipoib->netdev;
623
-	struct ipoib_mac *mac;
624
-
625
-	/* Calculate GID portion of MAC address based on port GID */
626
-	mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
627
-	memcpy ( &mac->gid, &ibdev->gid, sizeof ( mac->gid ) );
628
-
629
-	/* Calculate broadcast GID based on partition key */
630
-	memcpy ( &ipoib->broadcast, &ipoib_broadcast,
631
-		 sizeof ( ipoib->broadcast ) );
632
-	ipoib->broadcast.gid.u.words[2] = htons ( ibdev->pkey );
633
-
634
-	/* Set net device link state to reflect Infiniband link state */
635
-	if ( ib_link_ok ( ibdev ) ) {
636
-		netdev_link_up ( netdev );
637
-	} else {
638
-		netdev_link_down ( netdev );
639
-	}
640
-}
641
-
642 610
 /**
643 611
  * Handle link status change
644 612
  *
@@ -647,15 +615,25 @@ static void ipoib_set_ib_params ( struct ipoib_device *ipoib ) {
647 615
 void ipoib_link_state_changed ( struct ib_device *ibdev ) {
648 616
 	struct net_device *netdev = ib_get_ownerdata ( ibdev );
649 617
 	struct ipoib_device *ipoib = netdev->priv;
618
+	struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
650 619
 	int rc;
651 620
 
652 621
 	/* Leave existing broadcast group */
653 622
 	ipoib_leave_broadcast_group ( ipoib );
654 623
 
655
-	/* Update MAC address and broadcast GID based on new port GID
656
-	 * and partition key.
657
-	 */
658
-	ipoib_set_ib_params ( ipoib );
624
+	/* Update MAC address based on potentially-new GID prefix */
625
+	memcpy ( &mac->gid.u.half[0], &ibdev->gid.u.half[0],
626
+		 sizeof ( mac->gid.u.half[0] ) );
627
+
628
+	/* Update broadcast GID based on potentially-new partition key */
629
+	ipoib->broadcast.gid.u.words[2] = htons ( ibdev->pkey );
630
+
631
+	/* Set net device link state to reflect Infiniband link state */
632
+	if ( ib_link_ok ( ibdev ) ) {
633
+		netdev_link_up ( netdev );
634
+	} else {
635
+		netdev_link_down ( netdev );
636
+	}
659 637
 
660 638
 	/* Join new broadcast group */
661 639
 	if ( ib_link_ok ( ibdev ) &&
@@ -675,6 +653,7 @@ void ipoib_link_state_changed ( struct ib_device *ibdev ) {
675 653
 int ipoib_probe ( struct ib_device *ibdev ) {
676 654
 	struct net_device *netdev;
677 655
 	struct ipoib_device *ipoib;
656
+	struct ipoib_mac *mac;
678 657
 	int rc;
679 658
 
680 659
 	/* Allocate network device */
@@ -685,16 +664,19 @@ int ipoib_probe ( struct ib_device *ibdev ) {
685 664
 	ipoib = netdev->priv;
686 665
 	ib_set_ownerdata ( ibdev, netdev );
687 666
 	netdev->dev = ibdev->dev;
688
-	netdev->ll_broadcast = ( ( uint8_t * ) &ipoib->broadcast );
689 667
 	memset ( ipoib, 0, sizeof ( *ipoib ) );
690 668
 	ipoib->netdev = netdev;
691 669
 	ipoib->ibdev = ibdev;
692 670
 
693
-	/* Calculate as much of the broadcast GID and the MAC address
694
-	 * as we can.  We won't know either of these in full until we
695
-	 * have link-up.
696
-	 */
697
-	ipoib_set_ib_params ( ipoib );
671
+	/* Extract hardware address */
672
+	mac = ( ( struct ipoib_mac * ) netdev->hw_addr );
673
+	memcpy ( &mac->gid.u.half[1], &ibdev->gid.u.half[1],
674
+		 sizeof ( mac->gid.u.half[1] ) );
675
+
676
+	/* Set default broadcast address */
677
+	memcpy ( &ipoib->broadcast, &ipoib_broadcast,
678
+		 sizeof ( ipoib->broadcast ) );
679
+	netdev->ll_broadcast = ( ( uint8_t * ) &ipoib->broadcast );
698 680
 
699 681
 	/* Register network device */
700 682
 	if ( ( rc = register_netdev ( netdev ) ) != 0 )

+ 1
- 1
src/drivers/net/legacy.c ファイルの表示

@@ -99,7 +99,7 @@ int legacy_probe ( void *hwdev,
99 99
 	set_drvdata ( hwdev, netdev );
100 100
 	netdev->dev = dev;
101 101
 
102
-	nic.node_addr = netdev->ll_addr;
102
+	nic.node_addr = netdev->hw_addr;
103 103
 	nic.irqno = dev->desc.irq;
104 104
 
105 105
 	if ( ! probe ( &nic, hwdev ) ) {

+ 1
- 1
src/drivers/net/mtnic.c ファイルの表示

@@ -1814,7 +1814,7 @@ mtnic_probe(struct pci_device *pci,
1814 1814
 		/* Program the MAC address */
1815 1815
 		mac = priv->mtnic->fw.mac[port_index];
1816 1816
 		for (mac_idx = 0; mac_idx < MAC_ADDRESS_SIZE; ++mac_idx) {
1817
-			mtnic->netdev[port_index]->ll_addr[MAC_ADDRESS_SIZE - mac_idx - 1] = mac & 0xFF;
1817
+			mtnic->netdev[port_index]->hw_addr[MAC_ADDRESS_SIZE - mac_idx - 1] = mac & 0xFF;
1818 1818
 			mac = mac >> 8;
1819 1819
 		}
1820 1820
 

+ 1
- 1
src/drivers/net/natsemi.c ファイルの表示

@@ -204,7 +204,7 @@ static int natsemi_probe (struct pci_device *pci,
204 204
 	last = prev_bytes[1] >> 7;
205 205
 	for ( i = 0 ; i < ETH_ALEN ; i++ ) {
206 206
 		last1 = ll_addr_encoded[i] >> 7;
207
-	 	netdev->ll_addr[i] = ll_addr_encoded[i] << 1 | last;
207
+		netdev->hw_addr[i] = ll_addr_encoded[i] << 1 | last;
208 208
 		last = last1;
209 209
 	}
210 210
 

+ 5
- 5
src/drivers/net/phantom/phantom.c ファイルの表示

@@ -1897,10 +1897,10 @@ static int phantom_init_cmdpeg ( struct phantom_nic *phantom ) {
1897 1897
  * Read Phantom MAC address
1898 1898
  *
1899 1899
  * @v phanton_port	Phantom NIC
1900
- * @v ll_addr		Buffer to fill with MAC address
1900
+ * @v hw_addr		Buffer to fill with MAC address
1901 1901
  */
1902 1902
 static void phantom_get_macaddr ( struct phantom_nic *phantom,
1903
-				  uint8_t *ll_addr ) {
1903
+				  uint8_t *hw_addr ) {
1904 1904
 	union {
1905 1905
 		uint8_t mac_addr[2][ETH_ALEN];
1906 1906
 		uint32_t dwords[3];
@@ -1917,11 +1917,11 @@ static void phantom_get_macaddr ( struct phantom_nic *phantom,
1917 1917
 
1918 1918
 	/* Copy out the relevant MAC address */
1919 1919
 	for ( i = 0 ; i < ETH_ALEN ; i++ ) {
1920
-		ll_addr[ ETH_ALEN - i - 1 ] =
1920
+		hw_addr[ ETH_ALEN - i - 1 ] =
1921 1921
 			u.mac_addr[ phantom->port & 1 ][i];
1922 1922
 	}
1923 1923
 	DBGC ( phantom, "Phantom %p MAC address is %s\n",
1924
-	       phantom, eth_ntoa ( ll_addr ) );
1924
+	       phantom, eth_ntoa ( hw_addr ) );
1925 1925
 }
1926 1926
 
1927 1927
 /**
@@ -2045,7 +2045,7 @@ static int phantom_probe ( struct pci_device *pci,
2045 2045
 		goto err_init_rcvpeg;
2046 2046
 
2047 2047
 	/* Read MAC addresses */
2048
-	phantom_get_macaddr ( phantom, netdev->ll_addr );
2048
+	phantom_get_macaddr ( phantom, netdev->hw_addr );
2049 2049
 
2050 2050
 	/* Skip if boot disabled on NIC */
2051 2051
 	if ( ( rc = phantom_check_boot_enable ( phantom ) ) != 0 )

+ 1
- 1
src/drivers/net/pnic.c ファイルの表示

@@ -250,7 +250,7 @@ static int pnic_probe ( struct pci_device *pci,
250 250
 
251 251
 	/* Get MAC address */
252 252
 	status = pnic_command ( pnic, PNIC_CMD_READ_MAC, NULL, 0,
253
-				netdev->ll_addr, ETH_ALEN, NULL );
253
+				netdev->hw_addr, ETH_ALEN, NULL );
254 254
 
255 255
 	/* Mark as link up; PNIC has no concept of link state */
256 256
 	netdev_link_up ( netdev );

+ 2
- 2
src/drivers/net/r8169.c ファイルの表示

@@ -2209,9 +2209,9 @@ rtl8169_probe ( struct pci_device *pdev, const struct pci_device_id *ent )
2209 2209
 
2210 2210
 	/* Get MAC address */
2211 2211
 	for ( i = 0; i < MAC_ADDR_LEN; i++ )
2212
-		netdev->ll_addr[i] = RTL_R8 ( MAC0 + i );
2212
+		netdev->hw_addr[i] = RTL_R8 ( MAC0 + i );
2213 2213
 
2214
-	DBG ( "%s\n", eth_ntoa ( netdev->ll_addr ) );
2214
+	DBG ( "%s\n", eth_ntoa ( netdev->hw_addr ) );
2215 2215
 
2216 2216
 	rtl8169_init_phy ( netdev, tp );
2217 2217
 

+ 1
- 1
src/drivers/net/rtl8139.c ファイルの表示

@@ -525,7 +525,7 @@ static int rtl_probe ( struct pci_device *pci,
525 525
 	/* Reset the NIC, set up EEPROM access and read MAC address */
526 526
 	rtl_reset ( netdev );
527 527
 	rtl_init_eeprom ( netdev );
528
-	nvs_read ( &rtl->eeprom.nvs, EE_MAC, netdev->ll_addr, ETH_ALEN );
528
+	nvs_read ( &rtl->eeprom.nvs, EE_MAC, netdev->hw_addr, ETH_ALEN );
529 529
 
530 530
 	/* Mark as link up; we don't yet handle link state */
531 531
 	netdev_link_up ( netdev );

+ 1
- 1
src/drivers/net/rtl818x/rtl818x.c ファイルの表示

@@ -813,7 +813,7 @@ static int rtl818x_probe(struct pci_device *pdev,
813 813
 	free(hwinfo);
814 814
 
815 815
 	DBG("rtl818x: Realtek RTL818%s (RF chip %s) with address %s\n",
816
-	    chip_name, priv->rf->name, netdev_hwaddr(dev->netdev));
816
+	    chip_name, priv->rf->name, netdev_addr(dev->netdev));
817 817
 
818 818
 	return 0;
819 819
 

+ 2
- 2
src/drivers/net/sky2.c ファイルの表示

@@ -2210,14 +2210,14 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw,
2210 2210
 	sky2->port = port;
2211 2211
 
2212 2212
 	/* read the mac address */
2213
-	memcpy(dev->ll_addr, (void *)(hw->regs + B2_MAC_1 + port * 8), ETH_ALEN);
2213
+	memcpy(dev->hw_addr, (void *)(hw->regs + B2_MAC_1 + port * 8), ETH_ALEN);
2214 2214
 
2215 2215
 	return dev;
2216 2216
 }
2217 2217
 
2218 2218
 static void sky2_show_addr(struct net_device *dev)
2219 2219
 {
2220
-	DBG2(PFX "%s: addr %s\n", dev->name, netdev_hwaddr(dev));
2220
+	DBG2(PFX "%s: addr %s\n", dev->name, netdev_addr(dev));
2221 2221
 }
2222 2222
 
2223 2223
 #if DBGLVL_MAX

+ 11
- 4
src/include/gpxe/netdevice.h ファイルの表示

@@ -254,9 +254,16 @@ struct net_device {
254 254
 
255 255
 	/** Link-layer protocol */
256 256
 	struct ll_protocol *ll_protocol;
257
+	/** Hardware address
258
+	 *
259
+	 * This is an address which is an intrinsic property of the
260
+	 * hardware, e.g. an address held in EEPROM.
261
+	 */
262
+	uint8_t hw_addr[MAX_LL_ADDR_LEN];
257 263
 	/** Link-layer address
258 264
 	 *
259
-	 * For Ethernet, this is the MAC address.
265
+	 * This is the current link-layer address assigned to the
266
+	 * device.  It can be changed at runtime.
260 267
 	 */
261 268
 	uint8_t ll_addr[MAX_LL_ADDR_LEN];
262 269
 	/** Link-layer broadcast address */
@@ -337,12 +344,12 @@ static inline void netdev_nullify ( struct net_device *netdev ) {
337 344
 }
338 345
 
339 346
 /**
340
- * Get printable network device hardware address
347
+ * Get printable network device link-layer address
341 348
  *
342 349
  * @v netdev		Network device
343
- * @ret name		Hardware address
350
+ * @ret name		Link-layer address
344 351
  */
345
-static inline const char * netdev_hwaddr ( struct net_device *netdev ) {
352
+static inline const char * netdev_addr ( struct net_device *netdev ) {
346 353
 	return netdev->ll_protocol->ntoa ( netdev->ll_addr );
347 354
 }
348 355
 

+ 1
- 1
src/interface/efi/efi_snp.c ファイルの表示

@@ -130,7 +130,7 @@ static void efi_snp_set_mode ( struct efi_snp_device *snpdev ) {
130 130
 	assert ( ll_addr_len <= sizeof ( mode->CurrentAddress ) );
131 131
 	memcpy ( &mode->CurrentAddress, netdev->ll_addr, ll_addr_len );
132 132
 	memcpy ( &mode->BroadcastAddress, netdev->ll_broadcast, ll_addr_len );
133
-	memcpy ( &mode->PermanentAddress, netdev->ll_addr, ll_addr_len );
133
+	memcpy ( &mode->PermanentAddress, netdev->hw_addr, ll_addr_len );
134 134
 	mode->IfType = ntohs ( netdev->ll_protocol->ll_proto );
135 135
 	mode->MacAddressChangeable = TRUE;
136 136
 	mode->MediaPresentSupported = TRUE;

+ 1
- 1
src/net/80211/net80211.c ファイルの表示

@@ -792,7 +792,7 @@ int net80211_register ( struct net80211_device *dev,
792 792
 		return -ENOMEM;
793 793
 
794 794
 	memcpy ( dev->hw, hw, sizeof ( *hw ) );
795
-	memcpy ( dev->netdev->ll_addr, hw->hwaddr, ETH_ALEN );
795
+	memcpy ( dev->netdev->hw_addr, hw->hwaddr, ETH_ALEN );
796 796
 
797 797
 	/* Set some sensible channel defaults for driver's open() function */
798 798
 	memcpy ( dev->channels, dev->hw->channels,

+ 5
- 1
src/net/netdevice.c ファイルの表示

@@ -357,6 +357,10 @@ int register_netdev ( struct net_device *netdev ) {
357 357
 	snprintf ( netdev->name, sizeof ( netdev->name ), "net%d",
358 358
 		   ifindex++ );
359 359
 
360
+	/* Set initial link-layer address */
361
+	memcpy ( netdev->ll_addr, netdev->hw_addr,
362
+		 netdev->ll_protocol->ll_addr_len );
363
+
360 364
 	/* Register per-netdev configuration settings */
361 365
 	if ( ( rc = register_settings ( netdev_settings ( netdev ),
362 366
 					NULL ) ) != 0 ) {
@@ -370,7 +374,7 @@ int register_netdev ( struct net_device *netdev ) {
370 374
 	list_add_tail ( &netdev->list, &net_devices );
371 375
 	DBGC ( netdev, "NETDEV %p registered as %s (phys %s hwaddr %s)\n",
372 376
 	       netdev, netdev->name, netdev->dev->name,
373
-	       netdev_hwaddr ( netdev ) );
377
+	       netdev_addr ( netdev ) );
374 378
 
375 379
 	return 0;
376 380
 }

+ 1
- 1
src/usr/dhcpmgmt.c ファイルの表示

@@ -48,7 +48,7 @@ int dhcp ( struct net_device *netdev ) {
48 48
 		return rc;
49 49
 
50 50
 	/* Perform DHCP */
51
-	printf ( "DHCP (%s %s)", netdev->name, netdev_hwaddr ( netdev ) );
51
+	printf ( "DHCP (%s %s)", netdev->name, netdev_addr ( netdev ) );
52 52
 	if ( ( rc = start_dhcp ( &monojob, netdev ) ) == 0 )
53 53
 		rc = monojob_wait ( "" );
54 54
 

+ 1
- 1
src/usr/ifmgmt.c ファイルの表示

@@ -89,7 +89,7 @@ static void ifstat_errors ( struct net_device_stats *stats,
89 89
 void ifstat ( struct net_device *netdev ) {
90 90
 	printf ( "%s: %s on %s (%s)\n"
91 91
 		 "  [Link:%s, TX:%d TXE:%d RX:%d RXE:%d]\n",
92
-		 netdev->name, netdev_hwaddr ( netdev ), netdev->dev->name,
92
+		 netdev->name, netdev_addr ( netdev ), netdev->dev->name,
93 93
 		 ( ( netdev->state & NETDEV_OPEN ) ? "open" : "closed" ),
94 94
 		 ( netdev_link_ok ( netdev ) ? "up" : "down" ),
95 95
 		 netdev->tx_stats.good, netdev->tx_stats.bad,

読み込み中…
キャンセル
保存