virtual network interface 설정 변경시 arping 을 broadcast 하는 방법
글쓴이: idrukawa / 작성시간: 수, 2014/10/22 - 3:51오후
안녕하세요.
리눅스상에 다음과 같이 network interface가 설정되어 있습니다.
bond0 Link encap:Ethernet HWaddr 40:A8:F0:23:4E:3C inet addr:10.16.102.11 Bcast:172.16.102.255 Mask:255.255.255.0 inet6 addr: fe80::42a8:f0ff:fe23:4e3c/64 Scope:Link UP BROADCAST RUNNING MASTER MULTICAST MTU:1500 Metric:1 RX packets:54195418 errors:0 dropped:0 overruns:0 frame:0 TX packets:40755082 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:9572671639 (8.9 GiB) TX bytes:16996307838 (15.8 GiB) bond0:1 Link encap:Ethernet HWaddr 40:A8:F0:23:4E:3C inet addr:10.16.102.10 Bcast:172.16.102.255 Mask:255.255.255.0 UP BROADCAST RUNNING MASTER MULTICAST MTU:1500 Metric:1 eth0 Link encap:Ethernet HWaddr 40:A8:F0:23:4E:3C UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1 RX packets:45670233 errors:0 dropped:0 overruns:0 frame:0 TX packets:40755082 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:9007131774 (8.3 GiB) TX bytes:16996307838 (15.8 GiB) Interrupt:32
eth0 이 실제 nif 이고
bond0 이 bonding 구성해서 생성한 것이고,
bond0:1 은 virtual 로 어플리캐이션에서 생성한 것입니다.
3개의 nif의 mac 이 일치하는것을 확인바랍니다.
여기서 동작상태에 따라 bond0:1 이 생성되기도 하고 없어지기도 합니다.
이렇게 되었을 때, 이 서버에 연결된 스위치에서 nif의 변경을 인지하는 것이 늦습니다.
스위치의 arp 수집주기에 따라 지연정도가 다르기 때문인데요.
nif를 변경하고 바로 arping을 보내서
스위치가 변경된 nif 구성을 바로 인식할 수 있도록 하려고합니다.
ioctl을 이용해서 구현했는데
실제 물리 nif(eth0)에는 잘동작하는것이 bond0:1 에서는 동작하지 않습니다.
arp packet을 구성하고 sendto() 할 때
[No such device] 를 출력합니다.
실행결과 error 출력
[test.cpp:sendArping:310] p_cIfName[bond0:1] [test.cpp:sendArping:320] a_cIp[10.16.102.10] [test.cpp:sendArping:327] a_cMac[40:A8:F0:23:4E:3C] [test.cpp:sendArping:334] a_cBroad[10.16.102.255] [test.cpp:sendArping:364] sendto() --ERR [test.cpp:sendArping:365] errno[19] errstr[No such device] [test.cpp:main:441] sendArping() interface name[bond0:1] --ERR
아래 코드에서 [sendto()] 부분입니다.
struct in_addr stInAddrSrc, stInAddrDst; stInAddrSrc.s_addr = inet_addr(a_cIp); stInAddrDst.s_addr = inet_addr(a_cIp); struct arp_packet pkt; pkt.frame_type = htons(ARP_FRAME_TYPE); pkt.hw_type = htons(ETHER_HW_TYPE); pkt.prot_type = htons(IP_PROTO_TYPE); pkt.hw_addr_size = ETH_HW_ADDR_LEN; pkt.prot_addr_size = IP_ADDR_LEN; pkt.op = htons(OP_ARP_REQUEST); memcpy(pkt.sndr_ip_addr, &stInAddrSrc, sizeof(pkt.sndr_ip_addr)); memcpy(pkt.rcpt_ip_addr, &stInAddrDst, sizeof(pkt.rcpt_ip_addr)); bzero(pkt.padding,18); struct sockaddr sa; strcpy(sa.sa_data, p_cIfName); int iSock = socket( AF_INET, SOCK_PACKET, htons(ETH_P_RARP) ); if( iSock < 0 ) { PRINT(LL_ERR,"socket() --ERR"); PERR(errno); return -1; } if( sendto( iSock, &pkt, sizeof(pkt), 0, &sa, sizeof(sa) ) < 0 ) { PRINT(LL_ERR,"sendto() --ERR"); PERR(errno); return -1; }
잘못된 부분이 있는지 조언 부탁드립니다.
Forums:
자답입니다.
arping에서 network interface name은 virtual 을 쓸수 없습니다.
다음과 같이 대표 인터페이스명을 넣어주니 동작합니다.
코드에도 적용해봐야겠습니다.
댓글 달기