em(4) в RELENG_4: link flapping

From
Eugene Grosbein (2:5006/1)
To
All (2:5054/37.63)
Date
2006-09-08T12:29:44Z
Area
RU.UNIX.BSD
Reply-To: eugen@grosbein.pp.ru

Привет!

Как известно, em(4) при добавлении адреса/алиаса на интерфейс
переинициализирует сетевушку, в результате, во-первых, происходит
переинициализация линка и довольно большой таймаут,
а во-вторых, не отсылается ARP-пакет с новым IP, который должен обновлять
ARP-кеш соседей по сегменту. В CURRENT это починено в ревизии 1.119
if_em.c, в 6-STABLE был MFC починено месяц назад. Вот бекпорт фикса
для свежей 4.11-STABLE. Проверено, работает.

ftp://www.kuzbass.ru/pub/freebsd/patches/if_em.c.linkflap.RELENG_4.diff

- --- sys/dev/em/if_em.c.orig	Fri Sep  8 10:36:26 2006
+++ sys/dev/em/if_em.c	Fri Sep  8 12:19:50 2006
@@ -61,6 +61,7 @@
 
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
+#include <netinet/if_ether.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
 #include <netinet/udp.h>
@@ -729,6 +730,7 @@
 {
 	struct adapter	*adapter = ifp->if_softc;
 	struct ifreq *ifr = (struct ifreq *)data;
+	struct ifaddr *ifa = (struct ifaddr *)data;
 	int error = 0;
 	int s;
 
@@ -741,7 +743,21 @@
 	case SIOCSIFADDR:
 	case SIOCGIFADDR:
 		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCxIFADDR (Get/Set Interface Addr)");
-		ether_ioctl(ifp, command, data);
+		if (ifa->ifa_addr->sa_family == AF_INET) {
+			/*
+			 * XXX
+			 * Since resetting hardware takes a very long time
+			 * and results in link renegotiation we only
+			 * initialize the hardware only when it is absolutely
+			 * required.
+			 */
+			ifp->if_flags |= IFF_UP;
+			if (!(ifp->if_flags & IFF_RUNNING)) {
+				em_init(adapter);
+			}
+			arp_ifinit(ifp, ifa);
+		} else
+			error = ether_ioctl(ifp, command, data);
 		break;
 	case SIOCSIFMTU:
 	    {
@@ -790,12 +806,13 @@
 	case SIOCSIFFLAGS:
 		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFFLAGS (Set Interface Flags)");
 		if (ifp->if_flags & IFF_UP) {
-			if (!(ifp->if_flags & IFF_RUNNING)) {
+			if ((ifp->if_flags & IFF_RUNNING)) {
+				if (ifp->if_flags & IFF_PROMISC) {
+					em_disable_promisc(adapter);
+					em_set_promisc(adapter);
+				}
+			} else
 				em_init(adapter);
-			}
-
-			em_disable_promisc(adapter);
-			em_set_promisc(adapter);
 		} else {
 			if (ifp->if_flags & IFF_RUNNING) {
 				em_stop(adapter);


Eugene
-- 
А ученый уподобляется обученному слону, которого погонщик поставил перед
преградой. Он пользуется силой разума, как слон --- силой мышц, подчиняясь
приказу. Это необычайно удобно: ученый отныне готов на все, так как ни за
что уже не отвечает.
--- slrn/0.9.8.0 (FreeBSD)
 * Origin: Svyaz Service JSC (2:5006/1@fidonet)
SEEN-BY: 50/12 203 400/814 450/159 186 1024 451/30 461/43 132 640 469/999
SEEN-BY: 550/196 4616/3 4625/8 4635/4 4641/444 5000/76 5000 5006/1 8 9 10 14
SEEN-BY: 5006/15 16 17 5007/1 5010/70 352 5011/13 5012/46 5015/28 5019/31
SEEN-BY: 5020/18 154 175 194 400 545 549 715 758 982 1057 1523 1604 1630 1909
SEEN-BY: 5020/1922 2142 2238 2395 2450 2590 2871 4441 5021/3 29 5022/128
SEEN-BY: 5025/3 750 5026/45 5027/12 5029/32 5030/49 500 556 966 1063 1080 1900
SEEN-BY: 5030/1957 2828 5031/47 70 5034/10 13 5035/3 38 5036/1 5040/47 5042/13
SEEN-BY: 5045/7 5049/1 50 97 5051/15 5054/1 4 8 9 11 28 35 36 37 45 63 66 67
SEEN-BY: 5054/70 75 84 85 5055/95 5057/1 5059/9 5060/88 5061/15 5062/1 10
SEEN-BY: 5063/3 5064/7 5066/18 5074/9 5075/5 5077/70 5080/80 1003 5082/6
SEEN-BY: 5083/21 5085/13 5090/108 5094/4 5095/20 5096/18 5099/11 6001/3 10
PATH: 5006/1 5020/400 4441 545 5054/1 37