레이블이 네트워크인 게시물을 표시합니다. 모든 게시물 표시
레이블이 네트워크인 게시물을 표시합니다. 모든 게시물 표시

2013년 6월 27일 목요일

TCP/IP Fundamentals for Microsoft Windows

윈도우 시스템에서 TCP/IP 를 잘 기술해 놓은 온라인 문서가 있기에 공유합니다.
아래 경로로 가시면 PDF 파일로 다운로드 받을 수 있고, 560 페이지나 됩니다.

http://www.microsoft.com/en-us/download/details.aspx?id=8781

윈도우 환경에서 네트워크 환경을 이해하는데 좋은 것 같고, 윈도우 뿐만 아니라
TCP/IP 의 기본적인 내용, 서브네팅, 라우팅등 많은 내용이 기술되어 있습니다.

총 16 Chapter 까지 있고 목차만 봐도 내용이 튼실합니다.

추천드립니다.



2013년 2월 19일 화요일

패킷 전송 크기를 지정하는 MTU(Maximum Transmission Unit)를 알아봅시다!

최근 저에게 질문을 주신분인 계신데 그와 관련하여 몇 가지 글들을 써보고자 합니다. 저도 깊게는 생각해 보지 않다가 네트워크 전송 과정을 좀더 깊게 들여다 볼 수 있을거 같아 적어보고자 합니다. 오늘은 그 첫번째로 MTU 에 대해서 알아보도록 하겠습니다.

MTU 란 무엇인가?


MTU(Maximum Transmission Unit)는 네트워크 인터페이스에서 세그먼트 없이 보낼수 있는 최대 데이터그램 크기 값입니다. 만약 데이터가 MTU 값 이상이라면 여러개의 패킷으로 분할이 될 것입니다. 간단하게 보자면 MTU 는 패킷이 한번에 보낼 수 있는 최대 크기라고 볼 수 있습니다.

우리가 주로 사용하는 이더넷의 MTU 값은 일반적으로 1500 바이트이며 옛날에 모뎀을 통해 접속하던 PPPoE 연결은 1492 바이트를 가지고 있습니다. 블로그에서 다뤘던 점보프레임은 9000 바이트의 큰 크기를 가지고 있기도 합니다. MTU 는 각 패킷 프레임안에 최대 전송할 수 있는 값 MSS(Maximum segment size) 가 정의되어 있습니다. 그렇다면 MTU는 MSS + TCP/IP 헤더 크기가 될 것이고 반대로 MSS 는 MTU - 40  바이트가 됩니다. 40 바이트는 IP 와 TCP 헤더 20 바이트씩을 뜻합니다.

그러므로 일반적으로 우리가 사용하는 TCP 환경에서 애플리케이션이 사용할 수 있는 크기는 헤더를 제외한 1460 바이트 입니다. RFC1323 에서 정의한 타임스탬프 옵션이 확장되어 사용되면 12바이트가 늘어 1448 바이트가 됩니다. 자 그럼 MSS 를 조금더 들여다 보죠. TCP 프로토콜 연결시 SYN 패킷을 보내고 함께 MSS 를 포함하게 됩니다. SYN 패킷을 들여다 보면

0x0204 0x05B4


값을 볼 수가 있습니다. 02 는 MSS 옵션의 시작정의 부분을 뜻하고 04는 옵션의 크기(4바이트) 그리고 0x05B4 는 크기를 뜻합니다. 05B4 값이 1460 바이트 입니다. 이렇게 MSS 크기를 전송하면 받는 측에서도 어떤 크기로 전송해야 할지 알고 준비하게 됩니다.


MTU 와 속도상관관계를 한번 알아볼까요. 전용선 라인 T1 을 사용한다고 가정해 봅니다. T1 은 1.544Mbps (1,544,000 bits/sec) 가 됩니다. 여기서 MTU 가 1500 바이트라고 보면

(1460 + 40 ) * 8 / 1544000 = 7.772ms 가 됩니다. 여러분이 1Mbytes 의 파일을 전송한다고 봅니다. 1Mbyte 는 1024KB 이고 바이트로는 1,048,576 바이트입니다.

1Mbyte / MSS 로 나눠 봅니다 : 1048576bytes / 1460 = 718.2 가 나옵니다. 1M 를 T1 라인에서 전송한다고 보면 718.2 * 7.772 = 5581ms 가 나오네요. T1 라인에서는 1M 전송하는데 이 정도의 속도가 될 것이라고 생각해 볼 수 있는 것입니다. 물론 이것은 이론적인 것이므로 네트워크 환경에 따라 달라집니다.

윈도우 MTU 확인


윈도우에서는 netsh 명령어를 통해 인터페이스 정보를 확인할 수 있습니다.


C:\>netsh interface ip show interface

The Routing and Remote Access Service is not currently running on the local mach
ine.
Please use 'net start remoteaccess' on the machine to start the service.

그런데 서비스가 시작되어 있지 않다고 remoteaccess 서비스를 시작하라고 하네요.

C:\>net start remoteaccess
System error 1058 has occurred.

The service cannot be started, either because it is disabled or because it has n
o enabled devices associated with it.

위와 같이 나오는 경우는 해당 서비스가 disabled 되어 있는 경우입니다. 제어판->관리도구->서비스 에서 Routing and Remote Access 를 찾아보면 disabled 되어 있을 것이고, Startup Type 을 자동 또는 수동으로 변경후 시작해 주면 다음과 같이 인터페이스 결과를 얻을 수 있습니다. 윈도우 비스타 7의 경우라면 netsh interface ipv4 show subinterfaces 를 사용하면 됩니다.

C:\>netsh interface ip show interface

MIB-II Interface Information
------------------------------------------------------
Index:                              1
User-friendly Name:                 Loopback
GUID Name:                          Loopback
Type:                               Loopback
MTU:                                32768
Speed:                              10000000
Physical Address:
Admin Status:                       Up
Operational Status:                 Operational
Last Change:                        0
In Octets:                          0
In Unicast Packets:                 0
In Non-unicast Packets:             0
In Packets Discarded:               0
In Erroneous Packets:               0
In Unknown Protocol Packets:        0
Out Octets:                         0
Out Unicast Packets:                0
Out Non-unicast Packets:            0
Out Packets Discarded:              0
Out Erroneous Packets:              0
Output Queue Length:                0
Description:                        Internal loopback interface for 127.0.0 netw
ork

Index:                              2
User-friendly Name:                 Local Area Connection
GUID Name:                          {6D963098-CA8B-43EA-XXXXX}
Type:                               Ethernet
MTU:                                1500
Speed:                              1000000000
Physical Address:                   00-1F-D0-XX-XX-XX
Admin Status:                       Up
Operational Status:                 Operational
Last Change:                        3481341758
In Octets:                          164176737
In Unicast Packets:                 436671
In Non-unicast Packets:             31746
In Packets Discarded:               0
In Erroneous Packets:               0
In Unknown Protocol Packets:        516
Out Octets:                         1062079118
Out Unicast Packets:                952955
Out Non-unicast Packets:            349
Out Packets Discarded:              0
Out Erroneous Packets:              1
Output Queue Length:                0
Description:                        Realtek RTL8168/8111 PCI-E Gigabit Ethernet
NIC - Packet Scheduler Miniport

1500 트로 확인이 됩니다. 이외 간단히 ping 을 이용해 알아볼 수 도 있습니다. -l 로 데이터 크기를 지정할 수가 있는데, MTU 크기 값 이상이 되면 Fragment 메시지를 볼 수 있게 되어 이걸로 MTU 를 알아볼 수 있는 것이죠.

C:\>ping -f -l 1472 packetinside.com

Pinging packetinside.com [216.239.36.21] with 1472 bytes of data:

Reply from 216.239.36.21: bytes=64 (sent 1472) time=62ms TTL=43
Reply from 216.239.36.21: bytes=64 (sent 1472) time=62ms TTL=43
Reply from 216.239.36.21: bytes=64 (sent 1472) time=62ms TTL=43
Reply from 216.239.36.21: bytes=64 (sent 1472) time=62ms TTL=43

Ping statistics for 216.239.36.21:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 62ms, Maximum = 62ms, Average = 62ms

1473 크기를 지정하니 Fragment 되어야 한다고 나타납니다. 그런데 왜 1472 바이트 일까요 ? 위에서 본것과 같이 인터페이스에 설정된 값은 1500 바이트 입니다. IP 헤더가 20 바이트이고 ICMP 헤더가 8바이트( TYPE, CODE, CHECKSUM, DATA) 이죠.  즉 1500 - 28 = 1472 바이트가 되는 것입니다.

1472 바이트보다 크게 1 바이트를 늘려서 전송해 보았더니 fragment 가 필요하다고 나타납니다. 그러므로 한번에 전송할 수 있는 값이 1472 바이트 이구나 하고 생각할 수 있죠.

C:\>ping -f -l 1473 packetinside.com

Pinging packetinside.com [216.239.36.21] with 1473 bytes of data:

Packet needs to be fragmented but DF set.
Packet needs to be fragmented but DF set.
Packet needs to be fragmented but DF set.
Packet needs to be fragmented but DF set.

Ping statistics for 216.239.36.21:
    Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),


추가로 윈도우 XP 의 경우는 다음의 도구를 이용해서 MTU 값을 조금 더 쉽게 바꿀수도 있으니 참고해 보세요.

1) DrTCP
http://www.dslreports.com/drtcp
2) How to change the PPPoE MTU size in Windows XP
http://support.microsoft.com/kb/283165

리눅스의 MTU 값 확인 


ifconfig 를 이용하면 쉽게 확인이 가능합니다.


$ ifconfig eth0
eth0      Link encap:Ethernet  HWaddr bc:ae:c5:xx:xx:xx
          inet addr:192.168.xx.xx Bcast:192.168.xx.255  Mask:255.255.255.0
          inet6 addr: fe80::beae:xxxx:xxxx:b436/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:22530399 errors:0 dropped:0 overruns:0 frame:0
          TX packets:16150847 errors:0 dropped:1 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:10308945022 (10.3 GB)  TX bytes:3971757833 (3.9 GB)
          Interrupt:45 Base address:0x2000


mtu 값 변경도 아주 쉽게 ifconfig eth0 mtu 9000 과 같이 하면 됩니다.

이상으로 MTU 에 대해서 알아보았는데, 점보프레임과 같이 큰 MTU 값이 나오는 이유를 아시겠나요? 점보프레임 같은 경우는 로컬 네트워크 상에서는 사용하는데 큰 이슈가 없지만, 인터넷 구간으로 넘어가면 거치게 되는 디바이스들이 많아지다보니 9000 바이트와 같은 큰 값을 사용한다고 보장할수가 없습니다.

오늘은 여기에서 마무리 하고 다음번에 궁금해 할것 같은 다른 이야기를 다뤄볼께요?
MTU 에 의하면 패킷 데이터가 1500 바이트 이상으로 커질 수 없는데 패킷 덤프에서 보다보면 몇천바이트도 보이기 하는데 이건 무엇일까요? 다음 글에서 알아볼께요 :-)

2013년 2월 8일 금요일

GPU를 이용한 고성능 처리 PacketShader 와 Packet I/O

내일이면 2013년 구정의 시작이네요. 생각해 보면 시간은 참으로 빨리도 흘러갑니다. 오늘은 가볍게 GPU 기반의 소프트웨어 라우터 PacketShader 를 소개해 봅니다. PC 기반의 소프트웨어 플랫폼에서 GPU 를 이용해 코어 패킷 프로세싱을 구현하겠다는 것입니다. GPU 는 패킷인사이드에서도 몇번 언급했듯이 연산처리에 있어서 상당히 뛰어납니다. 그래서 암호해독 같은 것에 GPU 를 이용하면 속도가 크게 좋아지죠.

초기 프로젝트의 시작은 초당 10Gbps 를 목표로 했는데 40Gbps 에 도달했다고 합니다. (현재상황에서 구조적으로 40Gbps 이상의 성능을 만들어내는 것은 어렵다고 하네요) 프로토타입 시스템은 2개의 4 코어 Nehalem CPU (2.66GHz) 를 이용하고 4개의 듀얼포트 10Gbe 인텔 NIC 카드 그리고 2개의 NVIDIA GTX 480 카드를 이용했습니다.

몇가지 성능 측정 결과가 있는데, CPU 만을 이용한 것보다 연산처리가 보다 많이 들어가는 OpenFlow 스위치나 IPsec 터널링에서 상당히 좋은 성능 결과를 보여주고 있습니다.


Figure : IPv4 forwarding


Figure :  OpenFlow switch


Figure : IPsec tunneling (AES-CTR and SHA1)

유저레벨 단에서 고성능을 구현하기 위한 Packet I/O 엔진이라는 것을 공개하고 있습니다. Intel 82598/82599 기반의 네트워크 카드의 디바이스 드라이버입니다. 기존 인텔 IXGBE 드라이버를 많이 뜯어고친 것입니다. libpcap 를 이용하는 것보다 고 성능을 원한다면 해당 드라이버를 한번 이용해 보는 것도 좋을것 같습니다.

고성능에 관심있으신 분은 참고해 보세요.

그리고, KAIST 분들에게 응원을 보냅니다. 마지막으로 구정 연휴 잘 보내고 오세요 :-)

[참고]
1. Packet Shader
http://shader.kaist.edu/packetshader/
2. Packet I/O
http://shader.kaist.edu/packetshader/io_engine/index.html

2013년 1월 30일 수요일

TCP 응답속도를 체크하여 성능 측정을 해보자.

네트워크 트래픽의 요청과 응답의 지연되는 속도를 계산하여 퍼포먼스 성능 개선에 이용할 수 있는 'tcprstat' 도구를 소개한다. tcprstat 는 Percona 에서 개발한 것으로 무료로 사용할 수 있다. 출력되는 내용은 *NIX 시스템에서 사용하던 vmstat, iostat 와 비슷한 형태이다.
tcprstat 는 tcpstat 도구와 비슷하기도 하지만, 이것은 응답 시간 측정에 포커스를 두고 개발되어있으므로, 전체 네트워크 트래픽에 대한 것은 반영되어 있지 않다.

파일은 다음 경로에서 다운로드 받을 수 있다:
https://launchpad.net/tcprstat

바이너리 64비트 버전:
http://github.com/downloads/Lowercases/tcprstat/tcprstat-static.v0.3.1.x86_64

실행하면 다음과 같은 형태로 출력된다.

# ./tcprstat -p 27017 -t 1 -n 0
timestamp count max min avg med stddev 95_max 95_avg 95_std 99_max 99_avg 99_std
1355270619 669 3116 202 298 290 143 445 284 84 475 291 88
1355270620 727 719 200 263 227 73 424 253 57 454 261 63
1355270621 714 802 201 286 291 81 434 276 69 448 283 73
1355270622 720 570 201 280 271 45 367 275 30 387 279 34
1355270623 729 2441 261 282 270 92 361 273 20 379 277 25
1355270624 713 906 261 290 273 53 371 282 29 390 286 32
1355270625 718 759 261 287 273 47 369 280 29 399 284 33
^C1355270626 419 811 263 298 274 58 374 292 42 388 295 47

-n 을 통해 얼마동안 반복할지 정의한 것으로 0은 무한대를 뜻한다. -t 로 1초마다 측정하고 -p 로 포트번호를 지정하였다. 응답된 쿼리 시간과 종료시간 정보를 포함하고 있다. 각 컬럼의 응답시간은 마이크로세컨드 단위이며, 95/99th percentile 정보도 포함되어 있다. 95 퍼센트의 평균 응답값이 계산된다면, 상위 5%는 제외되는 것으로 자세한 내용은 아래 참고를 살펴보기 바란다.

tcprstat 의 위키페이지에서 소개하고 있는 예를 살펴보면,

# tcprstat -f '%M\t%95M\t%99M\n' -p 3306 -t 1 -n 0
max 95_max 99_max
31221 411 3001
52721 495 2828
12173 507 1513

응답시간이 계산되어 출력되는데 처음 가장 긴 응답시간은 31221 마이크로세컨드 이다. 95% 응답시간은 411 마이크로세컨드 이하이며 99%는 3001 이다.

가장 기본적인 옵션은 -p, -i, -n 정도이며 다음과 같은 포맷코드를 이용하여 출력을 정의할 수 있다.


Format CodeHeaderDefaultMeaning
%ncountyCount of requests that completed during this iteration
%aavgyAverage response time
%ssumySum of response times
%xsqsSum of squares of response times
%mminyMinimum response time
%MmaxyMaximum response time
%hmedyMedian response time
%SstddevyStandard deviation of response times
%vvarVariance of response times
%Iiter#Iteration number
%telapsedSeconds elapsed since the first iteration
%TtimestampyUnix timestamp
%%A literal %
\tA tab character
\nA newline character
95,99Adds a prefixyA percentile indicator; see later in this section for more


이외 -r 옵션을 이용해 PCAP 파일을 바로 분석할 수도 있다. 여러분들이 운영하는 서비스가 있다면 이 도구를 이용해 퍼포먼스 측정을 해보는 것도 유용할 것이다.

[참고]
1. Percona Tcprstat
http://www.percona.com/docs/wiki/tcprstat:start
2. Tcprstat 다운로드
https://github.com/Lowercases/tcprstat/downloads
3. Wikipedia Percentile
http://en.wikipedia.org/wiki/Percentile

2013년 1월 7일 월요일

NetEM을 이용한 Traffic Shaping (패킷 지연,유실,대역폭 제한등)


NetEM(Network Emulation)기능을 활용한 패킷의 지연, 중복, 유실 등을 테스트해보자. 에뮬레이션은 다양한 관점에서 활용될 수 있다. 애플리케이션의 벤치마크라든지 제품의 테스트 또는 대역폭의 제한으로까지 이용할 수 있다.

NetEM 은 크게 2개의 컴포넌트로 구성되어 있다. 큐를 위한 커널 모듈과 설정을 위한 커맨드라인 도구인 tc 가 있다. 커널모듈은 2.6.8 이후부터 통합되었고, iproute2 패키지의 한 부분이다. 여기서는 Traffic Shaping 과 관련하여 소개를 해 보고자 한다. Traffic Shaping 은 네트워크 트래픽을 제한하여 자원에 대한 우선순위를 조정한다. 사전에 정의된 분류, 정책, 큐 등을 이용하여 네트워크 자원을 필요에 따라 효과적으로 정의하는 것이다. 이것을 통해 여러분들은

- 네트워크 서비스 조절
- 대역폭의 제한
- 서비스에 대한 QoS(Quality of Service) 보장

을 통해 네트워크의 안정적인 운영, 서비스 가용성등을 확보할 수도 있다.

기본적으로 큐는 FIFO 패킷 큐 형태로 동작한다. 학교 수업때 한번쯤 들어보았을 만한 이 것은 먼저 들어온 것이 먼저 나간다는 First In First Out 개념이다.

이제 몇 가지 사용 예제를 알아볼 것인데, 여러분들이 사용하는 커널이 2.6.8 이상 이라면 특별한 설치는 필요하지 않다. 아마 대부분의 경우 사용할 수 있을 것이다.

해당 기능은 커널 컴파일 옵션시 다음 그림과 같이 선택되어 있으면 된다.



예제를 설명하기 전에 주로 'tc' 커맨드 도구를 이용하여 설명을 할 것이다. tc 의 기본적인 사용방법은 아래와 같다:




 tc  qdisc [ add | change | replace | link ] dev DEV [ parent qdisc-id |
       root ] [ handle qdisc-id ] qdisc [ qdisc specific parameters ]

       tc class [ add | change | replace ] dev DEV parent qdisc-id  [  classid
       class-id ] qdisc [ qdisc specific parameters ]

       tc filter [ add | change | replace ] dev DEV [ parent qdisc-id | root ]
       protocol protocol prio priority filtertype [ filtertype specific param‐
       eters ] flowid flow-id

       tc [ FORMAT ] qdisc show [ dev DEV ]

       tc [ FORMAT ] class show dev DEV


qdisc 는 Queue Discipline (qdisc) 로 패킷을 받고 서비스하기 위한 순서를 정하기 위한 어떤 룰들의 집합이라고 보면 된다. 즉, 이것은 패킷 큐로 패킷을 전송할때 어떤 알고리즘을 사용해 패킷을 보낼지 정하는 것이다. qdisc 는 Classless, Classful, Root, egress, ingress 등이 있다. Root 는 classful/classless 랑 상관없이 각 네트워크 인터페이스의 상위 qdisc 이고 egress 는 밖으로 나가는 패킷에 대해서만 동작하고 ingress 는 내부로 들어오는 트래픽에 대해서 동작한다.

- 패킷 80ms 지연하기 


# tc qdisc add dev eth0 root netem delay 80ms

add 를 통해 dev 로 네트워크 인터페이스를 정의해 주고 qdisc 를 처리하기 위한 이름을 netem 로 지정하였다. 그리고 마지막으로 delay 를 80ms 주었다.

일단 정상적인 지연을 적용하기 전에 Ping 을 해 보았다. 평균적으로 0-1ms 속도가 나왔다. 하지만, 지연을 적용하고서는 다음과 같이 81ms 정도로 지연되었다.

# ping 203.255.xxx.xxx
PING 203.255.xxx.xxx (203.255.xxx.xxx) 56(84) bytes of data.
64 bytes from 203.255.xxx.xxx: icmp_req=1 ttl=244 time=81.0 ms
64 bytes from 203.255.xxx.xxx: icmp_req=2 ttl=244 time=81.0 ms
64 bytes from 203.255.xxx.xxx: icmp_req=3 ttl=244 time=81.2 ms
^C
--- 203.255.xxx.xxx ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 81.067/81.117/81.208/0.064 ms

- 패킷을 랜덤하게 지연시키기 (30ms ~ 80ms)


특정 값으로 정하기 보다는 지정된 범위안에서 랜덤하게 지연하는 것이다. 명령어 마지막에 추가적으로 값을 하나 더 지정해 주면 된다.

# tc qdisc change dev eth0 root netem delay 80ms 30ms
# ping 203.255.xxx.xxx
PING 203.255.xxx.xxx (203.255.xxx.xxx) 56(84) bytes of data.
64 bytes from 203.255.xxx.xxx: icmp_req=1 ttl=244 time=77.1 ms
64 bytes from 203.255.xxx.xxx: icmp_req=2 ttl=244 time=93.7 ms
64 bytes from 203.255.xxx.xxx: icmp_req=3 ttl=244 time=78.8 ms
64 bytes from 203.255.xxx.xxx: icmp_req=4 ttl=244 time=100 ms
^C
--- 203.255.xxx.xxx ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 77.131/87.483/100.138/9.756 ms

- 기존에 정의된 지연을 다른 값으로 변경


처음 add 를 사용한 것과 달리 change 라고만 바꿔주고 delay 시킬 값을 지정해 주면된다.

# tc qdisc change dev eth0 root netem delay 30ms
# ping 203.255.xxx.xxx
PING 203.255.xxx.xxx (203.255.xxx.xxx) 56(84) bytes of data.
64 bytes from 203.255.xxx.xxx: icmp_req=1 ttl=244 time=31.0 ms
64 bytes from 203.255.xxx.xxx: icmp_req=2 ttl=244 time=31.0 ms
64 bytes from 203.255.xxx.xxx: icmp_req=3 ttl=244 time=31.0 ms
^C
--- 203.255.xxx.xxx ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 31.024/31.062/31.090/0.205 ms

- 현재 정의된 네트워크 인터페이스의 설정 값 확인


# tc qdisc show dev eth0
qdisc netem 8001: root refcnt 2 limit 1000 delay 30.0ms

- 패킷 유실 15% 설정하기 


loss 라는 파리미터를 주고 값을 입력한다. 여기서는 약 15% 정도 유실을 설정하였다.

# tc qdisc change dev eth0 root netem loss 15%
# tc qdisc show dev eth0
qdisc netem 8001: root refcnt 2 limit 1000 loss 15%
# ping 203.255.xxx.xxx
PING 203.255.xxx.xxx (203.255.xxx.xxx) 56(84) bytes of data.
64 bytes from 203.255.xxx.xxx: icmp_req=1 ttl=244 time=0.935 ms
64 bytes from 203.255.xxx.xxx: icmp_req=3 ttl=244 time=1.36 ms
64 bytes from 203.255.xxx.xxx: icmp_req=4 ttl=244 time=1.10 ms
64 bytes from 203.255.xxx.xxx: icmp_req=6 ttl=244 time=1.01 ms
64 bytes from 203.255.xxx.xxx: icmp_req=7 ttl=244 time=1.00 ms
64 bytes from 203.255.xxx.xxx: icmp_req=8 ttl=244 time=1.57 ms
^C
--- 203.255.xxx.xxx ping statistics ---
8 packets transmitted, 6 received, 25% packet loss, time 7011ms
rtt min/avg/max/mdev = 0.935/1.164/1.570/0.227 ms

ping 을 해보면 패킷이 유실되는 것 같이 지연이 발생한다.
예를들어 0.1% 라면 대략 1000개중에 1개 정도가 랜덤하게 Drop 된다고 볼 수 있다.

- 패킷 중복 


# tc qdisc change dev eth0 root netem duplicate 1%

duplicate 를 이용하여 정의하면 된다.

- 패킷 깨트리기 


# tc qdisc change dev eth0 root netem corrupt 0.1%

- 정의된 설정정보 제거하기 


# tc qdisc del dev eth0 root
# tc qdisc show dev eth0
qdisc pfifo_fast 0: root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1

- 특정 IP 목적지 우선순위 조정 


203.255.xxx.xxx 로 나가는 것은 Priority 를 3으로 조정하는 것이다.

# tc qdisc add dev eth0 root handle 1: prio
# tc filter add dev eth0 protocol ip parent 1:0 prio 3 u32 match ip dst 203.255.xxx.xxx/32 flowid 1:3
# tc qdisc show dev eth0
qdisc prio 1: root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1

- 패킷 대역폭 정의하기 


# tc qdisc add dev eth0 root handle 1:0 netem delay 100ms
# tc qdisc add dev eth0 parent 1:1 handle 10: tbf rate 256kbit buffer 1600 limit 3000
# tc -s qdisc ls dev eth0
qdisc netem 1: root refcnt 2 limit 1000 delay 100.0ms
 Sent 306774 bytes 4269 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 5p requeues 0
qdisc tbf 10: parent 1:1 rate 256000bit burst 1600b lat 43.8ms
 Sent 305784 bytes 4254 pkt (dropped 0, overlimits 3 requeues 0)
 backlog 0b 5p requeues 0

지연을 100ms 로 지정하였고, 대역폭을 256Kbit 로 설정하였다.

이상 여기까지 간단히 NetEM 을 이용한 트래픽 제어를 살펴보았다. 간단하게만 언급하였으니 세부적인 것은 Man Page 등을 살펴보길 바란다.



[참고]
http://www.linuxfoundation.org/collaborate/workgroups/networking/netem

2012년 7월 13일 금요일

여러개의 네트워크 인터페이스를 하나로! Bonding 하기

오늘은 bonding 기술에 대해서 다뤄보고자 한다. 이것은 여러개의 네트워크 인터페이스를 하나로 만들어 이더넷 카드 장애 또는 링크 Fail 에 대해 대비를 할 수 있다. 또한 로드발랜스를 구현할 수 있으며, 자연스럽게 Fault tolerance 를 보장해주어 고장 허용한계를 최소화 할 수도 있겠다.  스위치 장비 같은것에서 보면 "채널본딩", "트렁킹" 같은 기술들이 이와 이론적으로는 유사하다고 할 수 있다.

여기서는 리눅스를 기반으로 설정하는 방법을 다뤄볼 것이다. 대부분의 배포용 리눅스에는 이미 본딩 드라이버를 이용할 수 있다. 가장 쉽게 설치해 볼 수 있는 방법은 각 배포판에서 제공해주는 패키지 도구를 이용하면 된다. 데비안, 우분투의 경우는 apt-get 를 이용해 설치할 수 있다.


# apt-cache search ifenslave
ifenslave-2.6 - Attach and detach slave interfaces to a bonding device
# apt-get install ifenslave-2.6

설치가 되었으면, bonding 모듈이 올라가 있는 것을 확인할 수 있다.

# lsmod | grep bon
bonding                73991  0

Bonding 인터페이스 설정 


이제 사용할 준비는 되었으니 설정만 해 주면 된다. 수동으로 명령어를 통해 다음과 같은 형태로 잡아줄 수도 있으나,

# modprobe bonding
# ifconfig bond0 192.168.0.1 netmask 255.255.0.0
# ifenslave bond0 eth0 eth1

아래와 같은 방법을 통해 설정파일에 내용을 기록해 두고 사용하는 편이 훨씬 수월하다. bond0 라는 이름이 이제 우리가 설정할 bonding 인터페이스이다.



# cat /etc/network/interface
auto bond0
iface bond0 inet static
 address 192.168.0.1
 netmask 255.255.255.0
 gateway 192.168.0.254
 bond_mode balance-tlb
 bond_miimon 100
 bond_downdelay 200
 bond_updelay 200
 slaves eth0 eth1


위 내용중에서 아래 5라인 정도가 실제 bonding 과 관련된 내용이다. 인터페이스 bond0 에 192.168.0.1 IP 를 설정하고 동작모드로 balance-tlb 를 설정하였다. 이 모드는 Active slave 모드로 슬레이브로 설정된 인터페이스에서 들어오는 트래픽을 받는다.
bond-miimon 은 링크 모니터링 주기를 설정하는 것으로 100 밀리세컨드로 지정하였다.
bond-downdelay 는 링크 Fail 이 감지된 후 Slave 를 중지시키기전 대기할 시간을 정의한 것이다. bond-updelay 는 downdelay 와 반대로 링크가 복구된 후 slave 를 재 동작하기까지 대기할 시간이다.  그리고 마지막으로 slaves 를 통해 실제 본딩에 사용될 인터페이스 eth0 과 eth1 을 지정했다.

커널상에서는 가상의 bond0 를 통해 통신되며 실제 모든 통신은 slave 를 통해서 이뤄진다는 점이다.

bond-mode 는 다양하게 존재하는데 몇 가지를 알아보면 다음과 같다.

  •  balance-rr 
전달되는 패킷에 대해 sequential 하게 라운드로빈 형태로 동작하게 된다. 설정된 인터페이스로 나눠 전달되므로 로드 발랜싱 역할을 하게 된다.
  • active-backup
본딩 인터페이스중 오직 한개 슬레이브만 엑티브로 동작한다. Active 로 동작하는 슬레이브가 Fail 되면 다른 슬레이브가 대체하게 된다. Fault Tolerance 형태로 보면 된다.
  • balance-xor
선택된 해쉬 정책에 따라 트래픽이 전달된다. (기본 정책은 출발지 맥 주소와 목적지 맥 주소를 XOR 한다)

  • broadcast

모든 슬레이브 인터페이스로 전송한다

  •  balance-tlb

적절하게 로드 발랜싱 역할을 수행한다. Outbound 트래픽은 각 슬래이브의 로드를 고려해 분산되며, Incoming 트래픽은 현재 설정된 슬레이브로 받게 된다. 만약 트래픽을 받고 있는 슬레이브가 Fail 되면 다른 슬레이브가 MAC 주소를 이어받아 계속 트래픽을 전달 받을 수 있다.

  • balance-alb

적절하게 로드 발랜싱 역할을 수행한다는 측면에서 balance-tlb 와 같다. 그런데 여기에 추가로 트래픽을 받는 부분에 있어서도 로드발랜싱을 수행한다. 이것은 ARP negotiation 을 통해서 동작하게 된다.


Bonding 이 잘 동작하고 있는지의 확인은 ?



내가 설정한 Bonding 이 잘 동작하고 있는지 확인하려면 간단하게는 /proc/net/bonding/bond0 를 살펴보면 된다. 그러면 현재 설정된 정보를 볼 수 있는데, Bonding mode 는 transmit load balancing 으로 되어 있고 Up Delay 나 Down Delay 등이 위 설정파일에 설정한 것과 동일하게 정의되어 있다.


# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.5.0 (November 4, 2008)


Bonding Mode: transmit load balancing
Primary Slave: None
Currently Active Slave: eth0
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 200
Down Delay (ms): 200


Slave Interface: eth0
MII Status: up
Link Failure Count: 1
Permanent HW addr: 84:XX:XX:XX:10:1c


Slave Interface: eth1
MII Status: up
Link Failure Count: 1
Permanent HW addr: 84:XX:XX:XX:10:1e

또는 ifconfig 를 통해 설정한 bonding 인터페이스인 bond0 가 있는지 확인해 볼 수도 있다.


bond0     Link encap:Ethernet  HWaddr 84:XX:XX:XX:10:1c
          inet addr:192.168.0.1  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::862b:2bff:fefa:101c/64 Scope:Link
          UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
          RX packets:64861 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2542 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:4984737 (4.7 MiB)  TX bytes:176928 (172.7 KiB)

eth0      Link encap:Ethernet  HWaddr 84:XX:XX:XX:10:1c
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
          RX packets:32694 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1278 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2510260 (2.3 MiB)  TX bytes:90488 (88.3 KiB)
          Interrupt:36 Memory:d6000000-d6012800

eth1      Link encap:Ethernet  HWaddr 84:XX:XX:XX:10:1e
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
          RX packets:32167 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1264 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2474477 (2.3 MiB)  TX bytes:86440 (84.4 KiB)
          Interrupt:48 Memory:d8000000-d8012800


여기 인터페이스 정보를 보면 우선 설정한 bond0 가 보이고 그 아래 eth0, eth1 은 RUNNING SLAVE 로 동작하는 것이 보인다. eth0 은 맥 뒷자리가 10:1c 이고 eth1 은 10:1e 이다. bond0 를 보면 10:1c 로 되어 있다. 즉 현 시점에서 Active Slave 는 eth0 이 되는 것이다.

만약 eth0 인터페이스의 링크가 Fail 되면 eth1 이 맥 주소를 넘겨받아 10:1e 가 아닌 10:1c 상태가 되어 버린다. 이것은 bonding 을 구성후 랜 케이블을 뽑아보면 쉽게 살펴볼 수 있다.

링크 Fail 을 감지한다면?


링크 Fail 을 감지하면 앞서 설명한 것과 맥 주소를 넘겨받는 다고 하였는데, 이런 동작 과정이 /var/log/message 에 상세히 기록되어 있다.


Jul  6 00:18:36 test kernel: [    4.227038] bonding: bond0: Setting down delay to 200.
Jul  6 00:18:36 test kernel: [    4.233007] bonding: bond0: doing slave updates when interface is down.
Jul  6 00:18:36 test kernel: [    4.233012] bonding: bond0: Adding slave eth0.
Jul  6 00:18:36 test kernel: [    4.233014] bonding bond0: master_dev is not up in bond_enslave
Jul  6 00:18:36 test kernel: [    4.335328] bnx2: eth0: using MSIX
Jul  6 00:18:36 test kernel: [    4.337600] bonding: bond0: enslaving eth0 as an active interface with a down link.
Jul  6 00:18:36 test kernel: [    4.380870] bonding: bond0: doing slave updates when interface is down.
Jul  6 00:18:36 test kernel: [    4.380875] bonding: bond0: Adding slave eth1.
Jul  6 00:18:36 test kernel: [    4.380878] bonding bond0: master_dev is not up in bond_enslave
Jul  6 00:18:36 test kernel: [    4.463151] bnx2: eth1: using MSIX
Jul  6 00:18:36 test kernel: [    4.465304] bonding: bond0: enslaving eth1 as an active interface with a down link.
Jul  6 00:18:36 test kernel: [    4.470976] ADDRCONF(NETDEV_UP): bond0: link is not ready
Jul  6 00:18:38 test kernel: [    7.540376] bnx2: eth0 NIC Copper Link is Up, 1000 Mbps full duplex
Jul  6 00:18:38 test kernel: [    7.560033] bonding: bond0: link status up for interface eth0, enabling it in 0 ms.
Jul  6 00:18:38 test kernel: [    7.560037] bonding: bond0: link status definitely up for interface eth0.
Jul  6 00:18:38 test kernel: [    7.560041] bonding: bond0: making interface eth0 the new active one.
Jul  6 00:18:38 test kernel: [    7.560065] bonding: bond0: first active interface up!
Jul  6 00:18:38 test kernel: [    7.562122] ADDRCONF(NETDEV_CHANGE): bond0: link becomes ready
Jul  6 00:18:39 test kernel: [    7.668144] bnx2: eth1 NIC Copper Link is Up, 1000 Mbps full duplex
Jul  6 00:18:39 test kernel: [    7.759691] bonding: bond0: link status up for interface eth1, enabling it in 200 ms.
Jul  6 00:18:39 test kernel: [    7.959351] bonding: bond0: link status definitely up for interface eth1.


위 로그를 보면 알 수 있듯이 eth0 링크가 문제 생기면서 eth1 으로 slave 가 변경되는 과정을 알 수 있다.

Bonding 구성을 완료후에는, 정상적으로 잘 동작하는지 랜 케이블 선을 제거해 보는 것과 같이 테스트 과정을 거치는 것이 필요하다. 최근의 서버급 장비들은 하나의 랜 카드에 4개의 이더넷 포트가 달려 있는 경우도 많이 있다. 시스템의 사용용도에 따라 이와 같이 설정해 사용해 보는 것은 어떨까 한다.

실제로 사용해 보면 아주 간단하고도 쉽게 구성할 수가 있다.

[참고]
1. 리눅스 파운데이션 : bonding
http://www.linuxfoundation.org/collaborate/workgroups/networking/bonding

2012년 5월 25일 금요일

윈도우에서 네트워크 드라이버 설정 정보 보기 (TOE, 점보프레임등 확인)

저번 TOE(TCP Offload Engine) 포스팅 이후 윈도우에서 TOE 를 사용하고 있는지 확인할 수 있는 방법에 대한 문의가 있었다. 이에 기본적으로 윈도우에서 네트워크 드라이버 설정 정보를 보는 방법에 대해 간단히 알아보고, TOE 설정 유무도 알아보고자 한다.

우선 네트워크 연결 속성에서 이더넷 카드를 선택해야 하는데, 다음 화면과 같이 로컬영역 연결 상태에서 '속성'을 눌러서 로컬 영역 연결 속성을 보거나 또는 제어판에서 네트워크 및 공유 센터의 메뉴를 통해서 접근할 수 있다.


로컬 영역 연결 속성에서 연결에 사용할 장치가 보인다. 이미지에서는 RealTek PCIe 콘트롤러가 보인다. '구성 (C) ' 을 누르면 아래와 같은 창이 보이고 여기서 '고급' 탭을 누르면 해당 이더넷 카드에 대한 속성을 볼 수 가 있다.

여기서는 이더넷 카드에 대한 몇 가지 속성을 변경할 수 있는 오프로드 뿐만 아니라, WakeOn 및 일전에 언급하였던 점보 프레임에 대한 값 등을 정의할 수 있다.


여기서 각 오프로드 값 속성을 변경하면 된다. 또 netsh 를 통해 TCP 글로벌 매개 변수도 아래와 같이 살펴볼 수 있다.


C:\>netsh int tcp show global
활성 상태 쿼리하는 중...


TCP 글로벌 매개 변수
----------------------------------------------
받는 쪽 배율 상태                    : enabled
Chimney 오프로드 상태                : automatic
NetDMA 상태                          : enabled
DCA(직접 캐시 액세스)                : disabled
수신 창 자동 조정 수준               : normal
추가 정체 제어 공급자                : none
ECN 기능                             : disabled
RFC 1323 타임스탬프                  : disabled
** 위의 autotuninglevel 설정은 하나 이상의 프로필에 대한 로컬/정책 구성이 Window
s 배율
추론으로 다시 정의된 데 따른 결과입니다.
결과중 Chimney 오프로드 상태가 TOE 를 가르킨다고 보면 된다. 윈도우 7 환경에서는 자동으로 설정이 되어 있지만 만약 항상 활성화 시키기 위해서는 enabled 값을 사용하면 된다. 물론 중지하기 위해서는 disabled 로도 재 설정이 가능하다. 다음과 같이 설정하면 되는데, 일반 사용자 권한으로 실행시에는 다음과 같은 실행 에러를 만나게 된다.

C:\>netsh int tcp set global chimney=enabled


IPv4에서 global 설정 명령을 실행하지 못했습니다. 요청한 작업을 수행하려면 권한
상승(관리자 권한으로 실행)이 필요합니다.

도스 실행창을 관리자 권한으로 실행 후 다시 값을 설정한다.

C:\Windows\system32>netsh int tcp set global chimney=enabled
확인됨


C:\Windows\system32>netsh int tcp show global
활성 상태 쿼리하는 중...


TCP 글로벌 매개 변수
----------------------------------------------
받는 쪽 배율 상태                    : enabled
Chimney 오프로드 상태                : enabled

자 이렇게 설정을 하였는데, TOE 가 정말 이용되고 있는 것일까에 대한 의문이 생긴다. 이때는 'netstat -t' 명령어로 오프로드 상태를 볼 수 있다.  오프로드 상태에 InHost 라고 보이는 것은 현재 오프로드 상태가 아니라는 것이다. 오프로드의 상태라면 Offload 라고 표시될 것이다.


C:\>netstat -t


활성 연결


  프로토콜  로컬 주소              외부 주소              상태            오프로
드 상태


  TCP    192.168.40.2:1032      222.122.199.23:http    CLOSE_WAIT      InHost


  TCP    192.168.40.2:1038      tx-in-f125:5222        ESTABLISHED     InHost


  TCP    192.168.40.2:1039      38.126.11.28:http      CLOSE_WAIT      InHost


  TCP    192.168.40.2:2261      tb-in-f191:http        ESTABLISHED     InHost  (이하 삭제) 

필자의 데스크탑의 인터페이스는 부분적으로만 오프로드를 지원하여 InHost 상태로만 나오고 있다. 또는 여러 서비스와의 종속되는 다른 이슈들로 인하여 오프로드 상태가 Fail 될 수도 있다고 한다. 오프로드를 지원하는데도 불구하고 안된다면 BFE(Base Filtering Engine) 서비스를 중지해 보기를 바란다. 다만 서비스 중지로 인한 다른 것들은 감수해야 한다.

C:\> net stop BFE

윈도우 환경에서 TOE 상태가 잘 나타나는 분들은 경험을 댓글로 공유해 주길 부탁드립니다.


[참고]
1. Using Netsh Commands to Enable or Disable TCP Chimney Offload
2. Windows Server 2008 TCP Chimney 오프로드, 수신측 배율 및 네트워크 직접 메모리 액세스 기능에 대한 정보

2012년 5월 24일 목요일

네트워크 스캐닝의 강자 Nmap 6.0 버전 릴리즈


네트워크 스캔 도구로 유명한 Nmap (Network Mapper) 이 최근 새로운 6.0 버전을 릴리즈 하였다. 2009년 7월 Nmap 5 버전 이후로 3년 여만에 새롭게 선보인 것으로 3,924 개의 코드가 새롭게 반영되었고 더욱 파워풀 해진 NSE(Nmap Scripting Engine) 과 289 개의 새로운 스크립트등 이전 보다 더욱 기능이 풍성해 졌다.

주요 기능은
- NSE 기능 향상과 많아진 스크립트 (Nmap 5 버전에서 59 개였던것에 비해 6 버전에서는 348 개로 증가)
- 더 나아진 웹 스캐닝
- IPv6 완벽지원
- 새로운 Nping 도구
- 더욱 나아진 Zenmap GUI 와 결과 뷰
- 더욱 빨라진 스캔  ( traceroute 시스템 코드 재 작성)

세부적인 기능 및 설명은 다음 경로를 참고하면 된다.

http://nmap.org/6/

5 버전을 사용하였던 사용자들은 6 버전으로 점프업 해보자!

[참고]
1. 이미지출처
http://nmap.org

2012년 5월 16일 수요일

TOE(TCP offload engine)란 무엇인가?

이더넷 인터페이스 스펙을 유심히 들여다 본 사용자라면 지원 기능중에 TOE(TCP offload engine)를 본적이 있을 것이다. TOE 는 NIC(Network Interface Cards)에서 사용되는 기술로, 보통 운영체제 상에서 처리되는 TCP/IP 스택을 네트워크 컨트롤러로 내려서 처리하는 것이다. 네트워크 처리가 크게 필요한 기가비트나 10G 기가비트같은 고속네트워크에서 유용하게 사용된다.


처음 TCP는 저속의 네트워크 속도에서 이용되었는데, 지금의 통신속도와 비교해 보면 통신속도는 크게 증가했다. 일반 PC 들도 기가비트 환경이 대중화되었고, 그 만큼 TCP 통신을 필요로 하는 데이터를 처리를 위해 컴퓨팅 파워 사용이 증가하게 되었다. 위키피디아에 기술되어 있는 정보를 보면, Full Duplex 기가비트의 TCP 통신은 2.4GHz 펜티엄 4 프로세스의 80% 이상의 자원을 쓰게된다고 한다. 그래서 시스템에서 동작할 수 있는 여유자원은 상당히 제한적이게 된다. 하지만, 지금의 CPU 스펙을 보면 크게 증가하였다. 대중적인 것이 i3, i5, i7 이 되었으니 말이다. 다시 TCP 프로토콜을 처리하는데 있어서 오버헤드를 가져오는 요소를 살펴보면 다음과 같다:

- 3 way 핸드쉐이크 과정을 통한 연결
- 체크섬, 시퀀스 넘버 계산
- Packet acknowledgement 와 congestion 제어를 위한 슬라이딩 윈도우 계산
- 연결 해제

이러한 기능들을 전용하드웨어로 구현하게 되었고 그것이 TCP offload 엔진이다. 즉, CPU 는 다른 작업을 할 수 있도록 여유를 주자는 것이다. 2008년에는 몇몇 제한적인 NIC 만이 TOE 를 지원하였지만 지금은 상황이 달라졌다. TOE 구현은 오프로드 정도에 따라 부분적 오프로딩과 전체(Full offloading)오프로딩으로 구분된다. 부분적 오프로딩은 체크섬 및 데이터 송수신 관련한 기능만을 구현한 것이다. 이에 반해 전체 오프로딩은 TCP/IP 패킷을 처리하기 위한 TCP연결설정, 타임아웃,오류처리 등과 같이 TCP/IP 스택을 하드웨어로 구현한 것이다.

일반적으로 TCP/IP 의 1bit/s 를 처리하는데는 CPU 1 헤르츠가 필요한 것으로 알려져 있다. 예를 들어 5Gbit/s (메가로 환산하면 625MB/s) 네트워크 트래픽을 처리하기 위해서는 5GHz CPU 가 필요하다. 이 뜻은 5Gbit/s 를 처리하기 위해서는 2.5GHz 듀얼코어 CPU 가 필요하다는 것이다. 이렇게 TOE 기능을 이용해 CPU 자원 사용을 줄여주게 되어 TCP/IP 처리가 많은 경우에는 TOE 를 지원하는 기능이 그렇지 않은 경우보다 더 많은 작업(시스템 관점에서)을 처리할 수 있게 된다.

기본적으로 리눅스 커널에서는 TOE 하드웨어를 지원하고 있지 않다. 패치를 통해서 가능하지만, 커널상에서 직접 지원하지 않는 이유는 다음과 같은 몇 가지 이유들이 있다.

TOE 펌웨어는 소스가 공개되어 있지 않아, 보안적으로 문제가 발생할 경우 해결할 방법을 제시할 수 없기 때문에 보안적 이슈가 있다. 또한 복잡성도 증가되고, 하드웨어적인 여러 제약이 있다. 이러한 여러 이유는 다음의 경로에 잘 정리되어 있다.

http://www.linuxfoundation.org/collaborate/workgroups/networking/toe

지금 한번 여러분들의 NIC 을 체크해 보는 것은 어떨까?
이전에 포스팅한 ethtool 을 통해 오프로드를 살펴볼 수 있으므로, 다음 '참고' 글을 확인해 보기 바란다.

[참고]
1. 위키피디아 TCP Offload Engine
http://en.wikipedia.org/wiki/TCP_offload_engine
2. Ethtool 을 통해 네트워크 카드(NIC) 정보 확인 또는 설정하기
http://www.packetinside.com/2012/04/ethtool-nic.html

2012년 4월 20일 금요일

Ethtool 을 통해 네트워크 카드(NIC) 정보 확인 또는 설정하기

패킷과 밀접한 관련이 있는 것이 네트워크 이더넷 카드이다. 오늘은 이더넷 디바이스에 대한 정보를 살펴볼까 한다. 네트워크 디바이스 드라이버와 하드웨어 셋팅을 보거나 설정할 수 있는 'ethtool' 을 통해서 말이다.
우리가 흔히 이더넷 정보를 확인할 때 대표적인 도구가 ifconfig 다. ifconfig 를 통해 링크상태, IP 주소, 맥 주소, 통신 상태 현황등을 살펴볼 수 있다. ethtool 은 이보다 더 많은 부분을 살펴볼 수 있고, 설정도 가능하다.

기본적으로 사용방법은

ethtool [옵션] [ethX] [파라미터]  와 같이 사용할 수 있다.

다음은 기본 정보를 살펴본 것으로 지원되는 링크 모드와 속도, Duplex 상태 등이 나온다.

[이미지 출처] 구글 이미지 (검색어: ethernet card)

# ethtool eth0
Settings for eth0:
 Supported ports: [ TP ]
 Supported link modes:   10baseT/Half 10baseT/Full
                         100baseT/Half 100baseT/Full
                         1000baseT/Full
 Supports auto-negotiation: Yes
 Advertised link modes:  10baseT/Half 10baseT/Full
                         100baseT/Half 100baseT/Full
                         1000baseT/Full
 Advertised pause frame use: No
 Advertised auto-negotiation: Yes
 Speed: 1000Mb/s
 Duplex: Full
 Port: Twisted Pair
 PHYAD: 0
 Transceiver: internal
 Auto-negotiation: on
 MDI-X: Unknown
 Supports Wake-on: umbg
 Wake-on: d
 Current message level: 0x00000007 (7)
          drv probe link
 Link detected: yes
일목요연하게 이더넷 인터페이스에 대한 정보를 한눈에 보여준다. 자, 그럼 몇 가지 주요 옵션들에 대해서 알아보도록 하겠다. -s 옵션은 속도, Duplex 등의 값을 변경할 수 있다. 아래 예는 Auto-negotiation 기능을 Off 하는 것이다.

# ethtool -s eth0 autoneg off
이외 다음과 같은 옵션들이 있으니 설정에 참고하면 된다.

ethtool -s ethX speed N [duplex half|full] [port tp|aui|bnc|mii]
              [autoneg on|off] [advertise N] [phyad N] [xcvr internal|external]
              [wol p|u|m|b|a|g|s|d...]  [sopass xx:yy:zz:aa:bb:cc] [msglvl N |
              msglvl type on|off ...]

그럼 위 예를 참고하여 Speed 및 Duplex 를 조정하기 위해서는 다음과 같이 사용하면 된다:

# ethtool -s eth0 autoneg off speed 100 duplex half

참고로 e1000 드라이버를 사용하고 있는데, 설정이 제대로 반영되지 않았다. 이것은 드라이버의 특성이 있는것 같고 자세히 살펴보지는 않았지만 드라이버의 일부 패치가 필요할 것 같다. 다른 컴퓨터에서 사용하고 있는 r8169 드라이버에서는 변경이 잘 이뤄졌다. 사용하는 네트워크 인터페이스에 따라 차이가 있을 수 있으므로 이점은 참고하길 바란다.

ethtool 외에 modprobe 로 e1000 드라이버에 대한 옵션을 아래와 같은 형태로 설정할 수 가 있다.

modprobe e1000 [<option>=<VAL1>,<VAL2>,...]

다음은 Duplex 를 0 으로 설정한 예이다. 
# modprobe e1000 Duplex=0  (0=auto-negotiate, 1=half, 2=full)
본인이 사용하는 하드웨어가 각자 다르기 때문에 적절한 방법으로 사용하면 될 것이다.

다음은 r8169 를 사용하는 곳에서 변경을 해 본 것이다.


# ethtool -s eth0 autoneg off speed 100 duplex half
# ethtool eth0
Settings for eth0:
 Supported ports: [ TP MII ]
 Supported link modes:   10baseT/Half 10baseT/Full
                         100baseT/Half 100baseT/Full
                         1000baseT/Half 1000baseT/Full
 Supports auto-negotiation: Yes
 Advertised link modes:  Not reported
 Advertised pause frame use: No
 Advertised auto-negotiation: No
 Speed: 100Mb/s
 Duplex: Half
 Port: MII
 PHYAD: 0
 Transceiver: internal
 Auto-negotiation: off
 Supports Wake-on: pumbg
 Wake-on: g
 Current message level: 0x00000033 (51)
          drv probe ifdown ifup
 Link detected: yes

-i 는 드라이버에 대한 정보를 보여주는 것이다. e1000 드라이버를 사용하고 있고, eeprom 접근이 가능한지 여부등이 나온다.

# ethtool -i eth0
driver: e1000
version: 7.3.21-k8-NAPI
firmware-version: N/A
bus-info: 0000:00:03.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes

-S 는 인터페이스 통계 정보를 보여준다. rx,tx 의 패킷 전송 개수, 바이트 정보, 브로드캐스팅 정보들이다. 대문자 S 를 사용했다는 점을 주의하자. 소문자 s 는 설정 할때 사용되는 옵션이다.

# ethtool -S eth0
NIC statistics:
     rx_packets: 10
     tx_packets: 29
     rx_bytes: 2145
     tx_bytes: 4100
     rx_broadcast: 0
     tx_broadcast: 3
     rx_multicast: 0
     tx_multicast: 18
     rx_errors: 0
     tx_errors: 0
     tx_dropped: 0
-a 는 Pause 파라미터에 대한 정보를 보여준다. Auto Negotiation 정보를 좀더 상세히 보여준다고 보면 된다.
# ethtool -a eth0
Pause parameters for eth0:
Autonegotiate: on
RX: on
TX: off
-p 는 어뎁터에서 어떤 포트가 내가 찾고자 하는 것인지 인지할 수 있도록 알려준다. 예를 들어, 어뎁터가 4개의 포트를 가지고 있다고 하자. 여기서 eth3 번이 어떤 포트인지 알고 싶을때 LED 를 깜빡 거리게 하여 알려줄 수 있는 것이다.
# ethtool -p eth3
-k  옵션은 네트워크 디바이스의 Offload 정보를 보여준다. 이 Offload 는 이더넷 카드에서 TOE 기능을 지원하게 되면 사용될 수 있는 기능으로, 여기서는 이렇게 설정 정보를 보여주는 기능이 있다는 정도에서만 설명하고 다음번 포스팅 때 Offload engine 에 대해서 다시 설명하도록 하겠다.
# ethtool -k eth0
Offload parameters for eth0:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: on
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off
rx-vlan-offload: on
tx-vlan-offload: on
ntuple-filters: off
receive-hashing: off

ethtool 외에 lshw 를 이용해 network 관련한 정보를 확인할 수도 있다.
# lshw -C network
  *-network               
       description: Ethernet interface
       product: 82540EM Gigabit Ethernet Controller
       vendor: Intel Corporation
       physical id: 3
       bus info: pci@0000:00:03.0
       logical name: eth0
       version: 02
       serial: 08:00[deleted]:d0
       size: 1Gbit/s
       capacity: 1Gbit/s
       width: 32 bits
       clock: 66MHz
       capabilities: pm pcix bus_master cap_list ethernet physical tp 10bt 10bt-fd 100bt 100bt-fd 1000bt-fd autonegotiation
       configuration: autonegotiation=on broadcast=yes driver=e1000 driverversion=7.3.21-k8-NAPI duplex=full firmware=N/A ip=10.0.2.15 latency=64 link=yes mingnt=255 multicast=yes port=twisted pair speed=1Gbit/s
       resources: irq:10 memory:f0000000-f001ffff ioport:d010(size=8) 
여기서는 일반적인 방법을 설명한 것이므로, 여러분들 환경에 맞는 방법으로 이더넷 카드의 정보를 확인해 보거나 또는 설정할 수 있다. ethtool 에 대한 더 자세한 정보는 MAN 페이지를 참고하길 바란다.