-
Notifications
You must be signed in to change notification settings - Fork 1
Home
Build & Install Instruction
- 11월 4일 ~ 11월 10일
- AP용 학내 IP(WAN) 받기
- 과방에 AP 설치
- OpenWrt & Ath9k 컴파일
- AP에 OpenWrt & Ath9k 설치
- 11월 11일 ~ 11월 17일
- Github 저장소 생성
- base_file 위치 찾기 rc.local 등
- OpenWrt 컴파일 시 kernel 코드 받아오는 방식 파악
- OpenWrt를 qemu로 실행하는 방법 파악
- 11월 18일 ~ 11월 24일
- 네트워크 관련 리눅스 커널 문서 조사
- 리눅스 커널 문서 읽기
- ath9k에서 frame 보내는 곳과 ACK 처리하는 소스코드 위치 확인
- 11월 25일 ~ 12월 1일
- Ath9k 모듈 새로 업로드 하면, AP가 알아서 업데이트 하도록 스크립트 추가 및 서버 구축
- compat-wireless 저장소 분리 (linux-openwrt 저장소의 compat-wireless 브랜치로 관리)
- openwrt build system 이해하고 Makefile 수정해서 local git repository와 연동
- ethernet frame이 만들어져서 ath9k 드라이버까지 오는 경로 파악
- TCP packet 감지할 위치와 ACK packet을 준비할 위치 파악
- 관련 정보는
struct ieee80211_tx_info
에 담아두고 ath9k에서 ACK를 처리할 때 전송함.
- 관련 정보는
- 12월 2일 ~ 12월 8일
- 구현
- 실험
- 아마존 서버에서 다운로드 => 잘 됨.
- 개인 서버에서 다운로드(파일 크기 500KB) 하면서 서버 쪽에서 패킷 캡쳐 => 잘 됨, ACK가 두 개(만들어 준 것과 원래 STA이 보내는 것) 보임.
- 개인 서버에서 큰 파일(100MB 이상) 다운로드 => 1~2MB 받았을 쯤 끊김, STA가 L2 ACK은 보냈지만 TCP 패킷은 손실됨.
- 원인은 실제로 STA에서 받을 수 있는 AWnd를 무시하고 L4 ACK에 AWnd 값을 하드코딩 했기 때문에 실제로는 receive buffer에 여유가 없어서 드랍.
- 12월 9일 ~ 12월 15일
- AP에서 user가 IACK을 껐다 켰다 할 수 있게 작업 중
- STA에서 TCP DATA에 대한 ACK을 안 보내도록 작업 중
- 12월 16일 ~ 12월 22일
- AP에 IACK을 보내는 커널 모듈과 아닌 커널 모듈을 둘 다 올려놓고, IACK 기능을 켜고 끌 수 있는 스크립트 작성
- TCP DATA에 대한 ACK을 보내지 않도록 커널을 수정하고, 수정한 커널과 정상 커널 둘을 준비하여, 노트북에 virtual machine으로 두 개 커널을 바꿔가며 부팅할 수 있게 세팅
- OS는 Ubuntu trusty
- 노트북은 실험용 AP에 Wi-Fi 연결
- VM은 bridged network
- AP에서 IACK을 켰을 때와 껐을 때, STA에서 ACK을 켰을 때와 껐을 때, 총 4가지 설정 조합에 대해, 다운로드(작은 파일 12KB, 큰 파일 175MB) 실험
-
- AP IACK OFF, STA ACK ON: 당연하지만 정상적으로 작동한다.
-
- AP IACK OFF, STA ACK OFF: TCP handshake 이후에 멈춘다.
-
- AP IACK ON, STA ACK ON: 서버에 ACK이 두 개씩 오지만, 다운로드가 된다. 큰 파일은 시작하고 얼마 안돼 멈춘다(AWnd 때문).
-
- AP IACK ON, STA ACK OFF: 서버에 ACK이 한 개씩 오고, 다운로드가 된다. 큰 파일은 시작하고 얼마 안돼 멈춘다(AWnd 때문).
-
- 아마존 서버에서 테스트 클라이언트를 실행 했을 때, 1을 기준으로 한 3, 4의 성능 비교
- 3은 throughput이 0.35% 감소
- 4는 throughput이 0.44% 증가
- 테스트를 너무 짧게(1~2초) 해서 통계적으로 의미 있는 수치는 아닌 것으로 판단된다.
- RTT가 약 200ms인데 ACK을 하나 덜 보내서 아낄 수 있는 시간은 1ms가 채 안되기 때문에 성능 향상을 보기 어려울 것이다.
- RTT를 최대한 줄여서 IACK의 성능 향상 효과를 크게 해보기 위해, 첫번째 숙제에서 구현 했던 서버와 클라이언트로 학내망에서 다시 실험해 볼 계획이다.
- 보고서 작성
- 데모 영상 촬영
- OpenWrt: https://github.com/sim0629/openwrt
- Linux kernel for AP: https://github.com/sim0629/linux-openwrt (master)
- Compat Wireless: https://github.com/sim0629/linux-openwrt/tree/compat-wireless
- Linux kernel for STA: https://github.com/sim0629/linux-openwrt/tree/ubuntu-trusty
- 설치 장소: 301동 314호
- MAC(WAN): C4:6E:1F:ED:41:A7
- MAC(LAN): C4:6E:1F:ED:41:A8
- IP(WAN): 147.46.124.131
- IP(LAN): 192.168.1.1
- ISA: MIPS MIPS 74Kc
- CPU: AR9344 560 MHz
- RAM: 128 MiB
- WLAN 1: SoC-integrated: Atheros AR9340 2x2 MIMO for 2.4GHz 802.11b/g/n
- WLAN 2: separate Chip: Atheros AR9580 3x3 MIMO for 5GHz 802.11a/n
- Switch: Atheros AR8327N
- Bootloader: U-Boot
- 커널 모듈 개발 참고서: http://lwn.net/Kernel/LDD3/
- https://www.kernel.org/doc/Documentation/networking/openvswitch.txt
- https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
- https://www.kernel.org/doc/Documentation/networking/ipvlan.txt
- https://www.kernel.org/doc/Documentation/networking/ipvs-sysctl.txt
- struct sk_buff 관련
- http://www.linuxfoundation.org/collaborate/workgroups/networking/sk_buff
- http://lxr.free-electrons.com/source/include/linux/skbuff.h#L536
- IEEE80211 헤더: http://lxr.free-electrons.com/source/include/linux/ieee80211.h#L220
make menuconfig
- Advanced Configuration Options
- Enter git repository to clone
- Type "https://github.com/sim0629/linux-openwrt.git"
- Ok - Save - Exit
make target/linux/clean && make
make menuconfig
- Network - File Transfer - curl 켜기
다음의 구현이 실제로 활용되고 있는 것 같아서 확인해볼 필요가 있다.
-
drivers/net/wireless/ath/ath9k/xmit.c
의ath_tx_complete()
함수. 여기서 TCP 연결 정보에 접근할 수 있게 세팅해주고 TCP ACK를 만들어서 쏘아주면 될 것 같다.
이미 openwrt repository를 clone했고, 8035b2e39... 를 받아왔다고 가정한다.
cd /somewhere/
git clone --branch compat-wireless [email protected]:sim0629/linux-openwrt.git compat-wireless
cd /some/other/place/openwrt
ln -s /somewhere/compat-wireless/.git package/kernel/mac80211/git-src
make menuconfig
-
여기서
[*] Advanced configuration options (for developers) --->
설정하고 들어간다. -
[*] Enable package source tree override
를 설정한다.
이제 다음을 수행하면, /somewhre/compat-wireless/ repository의 HEAD를 가져와서 커널 모듈을 생성한다.
make package/kernel/mac80211/clean
make package/kernel/mac80211/compile
다음은 모듈을 찾을 수 있는 곳이다. ./staging_dir/target-mips_34kc_uClibc-0.9.33.2/root-ar71xx/lib/modules/3.10.49/
에 있는 것을 사용하면 된다.
{M} kmod-ath
<M> kmod-ath9k
{M} kmod-ath9k-common
{*} kmod-cfg80211
{M} kmod-mac80211
모듈만이 아니라, openwrt image를 컴파일 할 때에는 반드시 ppt에 나온 설정을 따라야 한다.
( )ieee80211_xmit -> update skb
( in )ieee80211_tx
( in )invoke_tx_handlers -> 암호화 (이 이후로는 skb에서 암호화된 내용만 보인다)
(over)__ieee80211_tx
( in )ieee80211_tx_frags
( in )drv_tx() (이것은 ath9k_tx()를 불러주는 함수임)
ath9k_tx()
tcp packet을 실제로 조립하는 건 net/ipv4/tcp_output.c
의 tcp_transmit_skb
에 방법이 있다.
include/uapi/linux/tcp.h
의 struct tcphdr
이 실제 TCP header의 구조.
include/uapi/linux/ip.h
의 struct iphdr
이 실제 IP header 구조.
- ip_input.c
ip_rcv()
- ip_output.c
ip_build_and_send_pkt()
- tcp_input.c
- tcp_output.c
tcp_transmit_skb()
간단히 생각하면, 프레임이 담긴 buffer이다. 커널 모듈 등에서는 패킷 데이터 같은 것들은 다 여기로 담긴다고 생각하면 편하다.
버퍼와 데이터가 담긴 부분을 나타내는 포인터는 head, data, tail, end가 있다. 실제 데이터가 담긴 범위는 [data, tail)이고, 할당된 영역은 [head, end)이다. 각 포인터는 skb->head, skb->data, skb_tail_pointer(skb), skb_end_pointer(skb)로 얻어와야 한다.
http://vger.kernel.org/~davem/skb_data.html 를 참고하면 좋다.
원래는 driver에서 프레임 등을 receive하는 부분에서 호출하는 함수로 netif_rx()
가 있다. 이것의 NAPI 버전은 netif_receive_skb()
이다.
netif_rx()
에서 backlog에 넣어두면, 나중에 process_backlog()
에서 __netif_receive_skb()
로 처리하는데, 여기서는 __netif_receive_skb_core()
를 불러서 본격적으로 패킷을 분석한다.
NAPI인 netif_receive_skb()
에서는 __netif_receive_skb()
가 비교적 일찍 불린다.
이 함수들은 net/core/dev.c
에 있다.
ieee80211_rx_handlers가 온갖 걸 다 함 ieee80211_deliver_skb를 잘 봐두자. netif_receive_skb를 호출해서 마무리
STA에서 TCP DATA에 대한 ACK을 전송하지 않도록 구현해서 테스트 해보기 위한 참고 문서
- Host와 virtual machine사이에 폴더 공유
- Host machine에서 컴파일 (
make menuconfig
,make bzImage
,make modules
) - Virtual machine에서 설치 (
sudo make modules_install
,sudo make installl
)
Custom kernel에서 shared folder 접근하는 기능을 다시 설치해야 됨으로 원 kernel에서 조작하는게 좋음.
sudo vi /etc/default/grub
- Then comment-out
GRUB_HIDDEN_TIMEOUT
, and changeGRUB_TIMEOUT
to -1 - Save & exit
subo update-grub
sudo reboot
by 심규민, 김찬민, 고성빈