MAC 주소가 변경된 경우 ifconfig가 종료된 후 시작하는 데 지연이 걸리는 이유는 무엇입니까?

MAC 주소가 변경된 경우 ifconfig가 종료된 후 시작하는 데 지연이 걸리는 이유는 무엇입니까?

안녕하세요, 인터페이스를 삭제하고 MAC 주소를 변경한 후 다시 불러오는 bash 스크립트를 만들었습니다.

#!/bin/bash

INTERFACE_STATUS=$( cat /sys/class/net/eth0/operstate )

echo "$INTERFACE_STATUS"

if [ "$INTERFACE_STATUS" == "up" ]
then
    echo  "Putting down eth0"
    sudo ifconfig eth0 down
    # putting down eth0 works only when I sleep 10 seconds after using command
    #sleep 10
    echo "$( cat /sys/class/net/eth0/operstate )"
#     TRIES=0
#     while [ "$( cat /sys/class/net/eth0/operstate )" == "up" ]
#     do
#         sleep 1
#         TRIES=$(($TRIES + 1))
#         if [ "$TRIES" == "7" ]
#         then
#             echo Could not put down eth0
#             exit 1
#         fi
#     done
fi

sudo ifconfig eth0 hw ether "91:91:91:91:91:91"

sudo ifconfig eth0 up

문제는 그것이 작동하지 않는다는 것입니다. drop 후 바로 eth0 /sys/class/net/eth0/operstate으로 바뀌었는데 down아직 닫히지 않은 것 같습니다. 인터페이스 eth0을 삭제하는 데 약 10초가 걸렸으므로 이를 작동하게 하는 유일한 방법은 sleep 10eth0을 삭제한 후 추가하는 것이었습니다.

그래서 내 질문은 eht0이 실제로 닫혔는지 확인하는 방법입니다.

//편집하다

ifconfig eth0 up새로운 MAC 주소를 얻지 못하기 때문에 명령이 매우 초기에 사용된 것과 같습니다 . 내려놓고 10초 정도 기다렸다가 MAC를 변경한 다음 다시 내려놔야 합니다. eth0을 삭제하는 데 몇 초가 걸릴 것으로 생각되며 너무 일찍 다시 삭제하면 작동하지 않습니다.

//편집 2

MAC 주소를 다시 확인해 보니 바뀐 것 같은데, 구글에서 ping을 해보니 알 수 없는 호스트가 나오니까 지금은 DNS 관련이 아닐까 싶습니다. 그러나 동일한 접근 방식이 sleep 10작동합니다.

// 편집 3

스크립트를 사용한 후 sleep 10ping을 사용해 보았습니다.

piotrek@piotrek-Vostro-2520:~$ ping 212.77.100.101
connect: Network is unreachable
piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101
connect: Network is unreachable
piotrek@piotrek-Vostro-2520:~$ ifconfig 
eth0      Link encap:Ethernet  HWaddr 08:3e:8e:2d:36:55  
        inet addr:10.36.253.122  Bcast:10.36.253.255  Mask:255.255.255.0
        inet6 addr: fe80::a3e:8eff:fe2d:3655/64 Scope:Link
        UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
        RX packets:74297 errors:0 dropped:0 overruns:0 frame:0
        TX packets:38597 errors:0 dropped:0 overruns:0 carrier:0                                                                                           
        collisions:0 txqueuelen:1000                                                                                                                       
        RX bytes:32417366 (32.4 MB)  TX bytes:5201537 (5.2 MB)0                                                                                           
      collisions:0 txqueuelen:1000                                                                                                                       
      RX bytes:32417366 (32.4 MB)  TX bytes:5201537 (5.2 MB)

//4개 요약 편집

piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up
piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101
connect: Network is unreachable
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sleep 10; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up
piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101
PING 212.77.100.101 (212.77.100.101) 56(84) bytes of data.
64 bytes from 212.77.100.101: icmp_req=1 ttl=246 time=8.91 ms
64 bytes from 212.77.100.101: icmp_req=2 ttl=246 time=8.76 ms
64 bytes from 212.77.100.101: icmp_req=3 ttl=246 time=8.52 ms
^C
--- 212.77.100.101 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 8.523/8.734/8.917/0.194 ms

sleep 10중요 함?

// 편집 5

이상해집니다. 제가 사용하면 아주 잘 작동합니다 sleep. 없이 시도해보니 sleepIP는 괜찮은 것 같고 인터페이스도 뜬 것 같은데 네트워크가 안되네요. 몇 초 후에 삭제하려고 하면 eth0sudo ifconfig eth0 downOS(ubuntu 12.10)가 자동으로 내 장치에 다시 연결됩니다.이전 MAC 주소새로운 IP를 얻었습니다. 두 번째 사용 후에 sudo ifconfig eth0 down는 완전히 내려놓을 수 있었습니다 eth0.

piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sleep 10; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig
eth0      Link encap:Ethernet  HWaddr 08:3e:8e:2d:36:55  
        inet addr:10.36.253.241  Bcast:10.36.253.255  Mask:255.255.255.0
        inet6 addr: fe80::a3e:8eff:fe2d:3655/64 Scope:Link
        UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
        RX packets:439341 errors:0 dropped:0 overruns:0 frame:0
        TX packets:224187 errors:0 dropped:0 overruns:0 carrier:0
        collisions:0 txqueuelen:1000 
        RX bytes:400718780 (400.7 MB)  TX bytes:26246307 (26.2 MB)

piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up
piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101
connect: Network is unreachable
piotrek@piotrek-Vostro-2520:~$ ifconfig
eth0      Link encap:Ethernet  HWaddr 08:3e:8e:2d:36:55  
        inet addr:10.36.253.241  Bcast:10.36.253.255  Mask:255.255.255.0
        inet6 addr: fe80::a3e:8eff:fe2d:3655/64 Scope:Link
        UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
        RX packets:439656 errors:0 dropped:0 overruns:0 frame:0
        TX packets:224321 errors:0 dropped:0 overruns:0 carrier:0
        collisions:0 txqueuelen:1000 
        RX bytes:400827185 (400.8 MB)  TX bytes:26267012 (26.2 MB)

piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down
piotrek@piotrek-Vostro-2520:~$ ifconfig
eth0      Link encap:Ethernet  HWaddr e0:db:55:97:de:cc  
        inet addr:10.36.253.122  Bcast:10.36.253.255  Mask:255.255.255.0
        inet6 addr: fe80::e2db:55ff:fe97:decc/64 Scope:Link
        UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
        RX packets:440302 errors:0 dropped:0 overruns:0 frame:0
        TX packets:224862 errors:0 dropped:0 overruns:0 carrier:0
        collisions:0 txqueuelen:1000 
        RX bytes:401129508 (401.1 MB)  TX bytes:26323176 (26.3 MB)

piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down
piotrek@piotrek-Vostro-2520:~$ ifconfig eth0
eth0      Link encap:Ethernet  HWaddr e0:db:55:97:de:cc  
        BROADCAST MULTICAST  MTU:1500  Metric:1
        RX packets:440437 errors:0 dropped:0 overruns:0 frame:0
        TX packets:224881 errors:0 dropped:0 overruns:0 carrier:0
        collisions:0 txqueuelen:1000 
        RX bytes:401147424 (401.1 MB)  TX bytes:26326068 (26.3 MB)

//편집 6

@Moreaki가 제안한 솔루션을 시도했지만 동일한 현상이 발생합니다. 스크립트는 약 1초 동안 실행되지만 사용 후 네트워크에 액세스할 수 없습니다. @Moreaki의 코드는 다음과 같습니다.

#!/usr/bin/env bash

INTF=eth0
INTERFACE_STATUS=$(cat /sys/class/net/${INTF}/operstate)
echo "$INTERFACE_STATUS"

if [ "$INTERFACE_STATUS" == "up" ]; then
    echo "Putting down ${INTF}"
    # if you need to remove all IP addresses associated with ${INTF}
    sudo ip addr flush dev ${INTF}
    # set the interface status down
    sudo ip link set dev ${INTF} down
    # flush neighbour cache
    sudo ip neigh flush dev ${INTF}
    # flush routing cache entries pertaining to ${INTF}
    sudo ip route flush table cache dev ${INTF}
    echo "New state: $(cat /sys/class/net/${INTF}/operstate)"
fi

sudo ip link set dev ${INTF} address "08:3e:8e:2d:36:55"
sudo ip link set dev ${INTF} up

그것을 사용하고 나면 다음과 같은 결과를 얻습니다.

piotrek@piotrek-Vostro-2520:~$ ./mac_test.sh 
up
Putting down eth0
New state: down

핑을 시도한 후:

piotrek@piotrek-Vostro-2520:~$ ping google.com
ping: unknown host google.com
piotrek@piotrek-Vostro-2520:~$ ping 8.8.8.8
connect: Network is unreachable

//편집 7

@Moreaki의 라우팅 스크립트를 사용하여 Mac 주소를 변경하기 전의 라우팅은 다음과 같습니다.

piotrek@piotrek-Vostro-2520:~$ ./routing.sh 
Destination        Gateway         Source             Iface    R_Type RT_table  
default            10.36.253.1     10.36.253.122      eth0            main      
10.36.253.0/24     0.0.0.0         10.36.253.122      eth0            main      
169.254.0.0/16     0.0.0.0         10.36.253.122      eth0            main

다음을 사용하여 MAC 주소를 변경한 후내 스크립트가 10초 지연되었습니다.:

piotrek@piotrek-Vostro-2520:~$ ./routing.sh 
Destination        Gateway         Source             Iface    R_Type RT_table  
default            10.36.253.1     10.36.253.241      eth0            main      
10.36.253.0/24     0.0.0.0         10.36.253.241      eth0            main      
169.254.0.0/16     0.0.0.0         10.36.253.241      eth0            main

@Moreaki 스크립트를 사용한 후 라우팅:

piotrek@piotrek-Vostro-2520:~$ ./routing.sh
Destination        Gateway         Source             Iface    R_Type RT_table

@Moreaki도 해당 줄에 주석을 달 것을 제안했지만 sudo ip addr flush dev ${INTF}여전히 이해가 됩니다 connect: Network is unreachable. 주석 처리된 줄이 포함된 스크립트를 사용한 후 내 라우팅은 다음과 같습니다.

piotrek@piotrek-Vostro-2520:~$ ./routing.sh
Destination        Gateway         Source             Iface    R_Type RT_table  
10.36.253.0/24     0.0.0.0         10.36.253.122      eth0

답변1

인터페이스 닫기 지연은 인터페이스의 드라이버 및/또는 하드웨어와 관련이 있을 수 있습니다. 이것이 맞다면 드라이버나 하드웨어가 실제로 인터페이스를 닫았는지 알 수 있는 표준 방법은 없습니다.

문제 해결의 나머지 부분을 읽어 보면 경쟁 프로세스가 있는 것처럼 들립니다. 특히 인터페이스 자체를 "복구"하는 부분이 그렇습니다. 인터페이스를 닫은 후 인터페이스를 실행하고 복원할 수 있는 도구가 있을까요?

감지하기가 약간 까다롭지만 불가능하지는 않습니다. 나는 당신이 그것을 감지할 수 있다고 제안하는 빠르고 쉬운 방법을 생각할 수 없습니다.

답변2

나는 지체할 필요가 없다고 생각한다. 인터페이스를 종료하기 전에 이전 MAC 주소에서 물리적으로 연결을 끊을 수 있어야 합니다. 무선 연결 중이므로 지금은 테스트할 수 없습니다. ifconfig --help를 확인하세요. 이 같은? :

ifconfig <interface> del <address>

무선 네트워크에서 연결을 끊을 때 AP의 MAC 주소를 포함한 모든 것을 지우는 작은 스크립트를 실행합니다.

sudo dhcpcd --release "$INTERFACE"
sudo iwconfig "$INTERFACE" essid off
sudo iwconfig "$INTERFACE" ap off
sudo ifconfig "$INTERFACE" down

답변3

아직 논평할 수 없으므로 내 관점이 당신이 관찰하는 행동에 대해 어느 정도 밝혀지길 바랍니다. 일반적으로 Linux에서는 인터페이스 설정을 수정하기 위해 ifconfig를 사용하지 않는 것이 좋습니다. 사실, 이 기능은 10여년 전에 "더 이상 사용되지 않습니다". 그럼에도 불구하고 배포판에서 ifconfig 및 라우팅을 계속 제공하므로 여전히 작동해야 합니다.

이 접근 방식이 현재 보고 있는 동작을 변경하는지 확인할 수 있습니까?

#!/usr/bin/env bash

INTF=eth0
INTERFACE_STATUS=$(cat /sys/class/net/${INTF}/operstate)
echo "$INTERFACE_STATUS"

if [ "$INTERFACE_STATUS" == "up" ]; then
    echo "Putting down ${INTF}"
    # if you need to remove all IP addresses associated with ${INTF}
    sudo ip addr flush dev ${INTF}
    # set the interface status down
    sudo ip link set dev ${INTF} down
    # flush neighbour cache
    sudo ip neigh flush dev ${INTF}
    # flush routing cache entries pertaining to ${INTF}
    sudo ip route flush table cache dev ${INTF}
    echo "New state: $(cat /sys/class/net/${INTF}/operstate)"
fi

sudo ip link set dev ${INTF} address "91:91:91:91:91:91"
sudo ip link set dev ${INTF} up

부록 1: 피드백을 읽은 후 라우팅 설정에 대한 추가 정보를 제공할 수 있습니다. 나는 10년 전에 썼던 오래된 스크립트를 찾아냈습니다. 그러면 다음과 유사한 라우팅 테이블 출력이 표시됩니다 netstat(이 명령을 실행하려면 루트가 필요함).

#!/usr/bin/env bash

# 08/2000: Initial code to beautify iproute2 routing table output
# 08/2013: Updated it for the new decade and removed swearing.

: ${IPTOOL:=/sbin/ip}
: ${DEBUG:=0}

print_format="%-18s %-15s %-18s %-8s %-6s %-10s\n"

if [ "x$1" == "x-v" -o "x$1" == "x--verbose" ]; then
    DEBUG=1
fi

dbg_log(){
    if [ $DEBUG -eq 1 ]; then
        echo "$*"
    fi
}

printme(){
    if [ "x$via" == "x" -a $src_route -eq 0 ]; then
        via="0.0.0.0"
    fi
    if [ "x$src" == "x" ]; then
        src=$(${IPTOOL} addr show dev $dev label $dev | awk '/inet/ {print $2}')
        src=${src%%/*}
    fi
    printf "$print_format" "$net" "$via" "$src" "$dev" "$type" "$table_id"
}

eval_route(){
    not_parsed=0

    while read net rest; do
        if [ $src_route -eq 0 ]; then
            src=
            type=
        fi
        table_id="${TABLE_ID}"
        dev=
        via=
        set -- $rest
        while [ $# -ne 0 ]; do
            case $1 in
                proto)  shift 1;;
                scope)  shift 1;;
                metric) shift 1;;
                dev)    shift 1; dev=$1;;
                via)    shift 1; via=$1;;
                src)    shift 1; src=$1
                   # As soon as I've figured out, how to get back the
                   # interface/label definition from a given src IP
                   # I will adjust this ugly hack. --rn, 08/2000
                   if [ "x${src%.*}" != "x${net%.*}" ]; then
                       dev=$(${IPTOOL} addr show dev $dev to $src | \
                           awk -v check_ip=${temp_ip%%/*} 'BEGIN {/$check_ip/} END {print $7}')
                   fi
                   ;;
                *) dbg_log "option $1 not parsed"; not_parsed=1;;
            esac
            shift 1
        done
        # Check for 'throw, blackhole, unreachable, prohibit'
        # Since we only check for non-numeric strings, we have
        # to exclude the default target too.
        if [ "x${net//[0-9.]/}" == "x$net" -a "x$net" != "xdefault" ]; then
            type=${net:0:2}
            type=${type~~}
            net=$rest
            dev="all"
            src="0.0.0.0/0"
            not_parsed=0
        fi
        [ $not_parsed -eq 0 ] && printme
        not_parsed=0
    done < <(${IPTOOL} route show table $TABLE_ID)
}

src_route=0
printf "$print_format" "Destination" "Gateway" "Source" "Iface" "R_Type" "RT_table"
while read RULE_ID rest; do
    RULE_ID=${RULE_ID//:/}
    fromIP=
    toIP=
    TABLE_ID=
    set -- ${rest}
    while [ $# -ne 0 ]; do
        case $1 in
            from)   fromIP=$2  ; shift 2;;
            to)     toIP=$2    ; shift 2;;
            lookup) TABLE_ID=$2; shift 2;;
            *)                   shift 1;;
        esac
    done
    if [ $RULE_ID -ne 0 ]; then
        dbg_log "+------------------[RULE: $RULE_ID]------------------+"
        if [ "x$fromIP" != "xall" ]; then
            src_route=1
            src="$IP"
            type=SR
        fi
        eval_route
        src_route=0
    fi
done < <(${IPTOOL} rule show)

관련 정보