네트워크 레이어의 기본적인 역할
Forwarding : 라우터의 input으로 들어온 패킷을 적절한 output으로 내보낸다.
-> 어떤 아웃풋으로 보낼지 택하는것
-> 데이터 영역(data plane)
Routing : source 부터 destination 까지 패킷을 어떤 경로로 보낼지 결정한다.
-> 목적지를 향해 가기 위해 어떤 경로로 갈 것인가(경로 설정, 네비게이션 역할)
-> 컨트롤 영역(control plane)
local, per-router(라우터 개별적으로 수행됨) function이다.
패킷이 들어 오면 ip 헤더의 내용을 바탕으로 어느 쪽으로 내보낼지 판단한다.
Forwarding function
network-wide logic이다.
-> 라우터 하나만 가지고 하는것이 아니라 라우터끼리 협력해야함.
datagram이 어떤 경로로 전달될 지 결정한다.
two control-plane approaches
-> 전통적으로는 라우팅 알고리즘은 라우터에 구현되어 있어서 라우터끼리 메세지를 주고받아서 경로를 결정했다.
-> 최근에는 software-defined networking(SDN) 을 사용하여 서버에서 경로를 계산하고, 라우터들은 서버의 지시에 따라 데이터를 forwading 해 주는 방식을 사용한다.
per-router Control plane
control plane에서 각각의 라우터에서의 라우팅 알고리즘을 통해 경로를 학습한 후 포워딩 테이블을 만들어서 data plane으로 넘겨주면, data plane에서는 이 테이블을 보고 아웃풋 방향을 선택한다.
각각의 라우터가 작업을 하기 때문에, 각각의 라우터들이 수집한 정보들을 정확히 일치하지 않을 수 있다.(일관성이 없다.) -> loop가 발생할 수 있다.
Logically Centralized Control plane -> SDN 형태
서버에 control plane이 있어서 라우터에서는 서버의 지시를 따라 데이터를 포워딩 해 준다.
CA(Control Agent) : 서버와의 통신을 위해 존재하는 프로그램
remote controller가 각각의 라우터에서 사용할 포워딩테이블을 모두 계산하여 CA로 보내어 data plane을 통해서 forwarding하게 된다.
이 형태와 같은 경우에는 Control Plane은 모두 Remote Controller에 모아져있고, 각각의 라우터에는 Control Plane이 없고 CA를 통해서 Data Plane의 역할만 하게 된다.
sender에서 receiver까지 datagram을 transporting하는 "channel"에 대해 어떤 service model을 network service model이라고 한다.
Network Layer의 service model은 Newtork Architecture에 따라서 달라진다.
Internet과 같은 경우에는 Bandwidth를 보장하지 않고, loss가 발생할 수 있고, 순서를 보장하지 않고, 딜레이 보장도 없으며, Congestion이 있는지 없는지를 loss를 통해서 추측한다.(no feedback이 없다. - 최근에는 좀 생겼다고 한다.)
High-level에서 보게 되면, 하나의 Router는 4개의 component로 나뉘어져 있다.
forwarding data plane(hardware)
1. router input ports
2. router output ports
3. high-speed switching fabric
routing, management control plane(software)
4. routing processor(CA의 역할을 하던, routing algorithm을 만드는 역할을 하던)
physical layer(line termination) -> link layer -> queue -> switch fabric 로 datagram이 맨 밑 계층부터 올라옴.
queue에 datagram이 들어가 있는 동안, 맨 첫번째 datagram부터 IP header를 읽어서 어디로 보내야 할지를 찾는다. 그리고 Forwarding을 한다.
decentralized switching
빨간 부분에서 input port에 들어온 것을 header의 field 값들을 이용해서 forwarding table을 보고, 어느 output port로 가야할지 찾는다.
forwarding table : input port memory에 있다. datagram이 switch fabric으로 forward되는 시간보다 더 빠른 속도로 datagram이 도착하게 될 경우 결국 queueing이 된다.
결국 memory를 읽고 forwarding해야 하는데 방법이 두가지가 있다.
generalized forwarding :
header의 모든 필드들을 참조하여 판단한다.
destination-based forwarding은 gernerailized forwarding의 일종이라고 할 수 있다.
destination-based forwarding :
destination IP 주소만 보고 어디로 forwarding할지 판단한다.(전통적)
첫번째 칸은 11001000 … 00000000 부터 11001000 … 11111111까지는 link interface 0번으로 보내라는 것.
routing 알고리즘으로 범위가 설정되고, 어떤 주소에 대해서 어떤 interface를 통해 나가야 빨리 나가는지 학습해 나간다. 즉, router protocol을 통해 학습하는 것이다.
이것은 전세계 수많은 IP들을 전부 다 해준다. 학습해가면서 업데이트한다. IP주소의 범위는 대략적으로 국가적으로 나누어져 있다. 하지만 routing 알고리즘은 오버헤드가 상당히 크다.
저렇게 생긴 range들이 대략 30만개 이상 나오게 되는데, 그것을 다 Matching하는데 시간이 오래 걸리면 안된다. 따라서 hardware(TCAMs, Tenery Content Addressable Memories)를 사용하여 lookup을 진행한다.
TCAM을 사용하면 1 clock cycle만에 output link를 return 시켜준다.(Table size와 관계 없이)
패킷을 input buffer에서 output buffer로 전달하는 부분이다.
-> n개의 input이 있다면 switching rate은 line rate(capacity)보다 n배 정도 커야지 제대로 돌아갈 수 있다.
Memory
가장 전통적인 방식이다.
input port에 data를 memory로 옮기고, output port로 보내는 형태이다. bus를 두번 지난다. (input -> memory, memory -> output)
이 방식은 memory의 bandwidth에 의해서 속도가 제한된다. 메모리(software)의 연산은 느리다. 결국 메모리를 사용한 이 방식은 느리다는 뜻이다.
bus
bus를 통해 스위치되는 방식이다.
어느 output port로 가야할지 결정이 나면, 2번 포트로 보내겠다고 bus에 하드웨어 신호를 보내고, 2번 포트로 이동시키게 된다.
bus contention이 있다. 즉, bus에서는 한번에 하나씩만 데이터가 전송되어야 한다. 결국 switching rate는 bus의 bandwidth에 의해 결정된다.
Cisco에서는 32Gbps의 bus를 붙여놓았다. 그래서 Switching rate가 32Gbps이다. 이 speed로 access network나 enterprise router에서 충분하다고 한다.
bus는 공유된다!!
interconnection network (crossbar)
bus의 bandwidth를 극복하기 위해 등장했다. bus가 line 하나였다면 이 방식은 line을 여러 개 교차시켜 놓는다. 그래서 데이터를 동시에 보낼 수 있다. 그러나 line을 많이 두기 떄문에 Hardware적인 구현비용이 더 들어가게 된다.
Cisco는 이런 crossbar를 이용해서 60Gbps까지 끌어올렸다.
Input port에서 datagram이 들어오는 것이 fabric로 보내는 것보다 빠르다면 input port에서 queueing이 생기게 된다. 심지어 input buffer가 overflow날 경우 드랍해버린다.
output port contention : 만약에 다른 input port에서 같은 output port를 통해서 동시에 나가겠다고 요청이 들어오면, 먼저 하나가 나가고, 기다리다가 나갈 수 있다. 이로 인해 HOL Blocking이 발생할 수 있다.
Head-of-the-Line(HOL) blocking이란 queue 맨 앞에 있는 것이 line의 head부분인데, 이 head가 나가지 못하면 뒤에거까지 못 나감을 말한다.
Output port에서도 Input과 마찬가지로 buffering이 된다. transmission하는 속도보다 들어오는 속도가 빠르면 buffering이 된다. 마찬가지로 손실도 날 수 있다.
그렇다면 buffer를 얼마나 주어야 할까? buffer를 많이 쓰면 delay가 엄청 늘어날 수 있다. 차라리 드랍시키는 게 낫다. 이와 같은 문제로 buffer의 크기는 중요하다.
buffer의 크기는 RTT C(capacity) 로 정한다. 만약 N개의 flow가 있다면 `(RTTC)/sqrt(N)` 이 buffer의 크기가 된다.
이 Output port에는 queueing 되어 있는 것들 중에 어떤 것부터 내보내는지에 대한 Scheduling 이슈가 있다.
FIFO 스케줄링은 간단하게 큐에 도착한 순서대로 전송하는 기법을 뜻한다. 이 때 만약 큐가 가득찼을 때 패킷을 버린다면 어떤 패킷을 버려야 할까? 이것도 다음과 같이 여러가지 방법이 있다.
=> 끝에 오는 얘를 드랍하면, 무거운 파일을 보내면 계속해서 무거운 파일 얘들만 큐를 잡아먹고 있게된다. 이것은 형평성에 어긋난다. flow별로 골고루 드랍이 생기도록 한 것이다.
가장 높은 우선순위의 패킷을 먼저 전송하는 기법을 뜻한다.
우선 두 줄로 세운다. 그리고 high priority, low priority가 있으면, high를 중심으로 보내준다.
multiple class도 가능하다. 높은 순위의 class부터 보내준다.
IP에서는 이런 priority scheduling이 될수 있다고 생각해서 protocol을 설계했었다. 실제 인터넷에서 사용하진 않는다.
Round Robin 스케줄링은 패킷에 class를 부여하여 구분한다. 큐를 스캔하여 보낼 패킷이 있다면 각각의 클래스 별로 번갈아 패킷을 전송한다. 예를 들어 위와 같이 주황색 class 와 파란색 class가 있다고 하자.
WFQ는 Round Robin을 일반화 한 방식이다. 각 클래스 마다 큐를 설정하여, 각각 클라스를 번갈아 패킷을 보내는 방식은 Round Robin과 비슷하다. 다만 다른점은 큐에 가중치(weight)를 둔다는 점이다.
다음은 network layer에서의 기능 들이다.
IP datagram format은 위 그림과 같다. 위에서부터 살펴보자.
Overhead
20 bytes of TCP(header)
20 bytes of IP(header)
= 40 bytes + app layer overhead
network link들은 MTU(Maximum transfer size)를 가지고 있다. 각 link들의 type이 다르고 MTU가 다른 경우가 있어, 크기가 큰 IP datagram을 쪼갤 수 있게 만들었다.
한 개의 datagram을 여러 개의 datagram으로 쪼개는 것. 만약 한 개의 datagram을 3개로 쪼갠다면, 3개의 header와 3개의 payload가 된다. 이 때 header부분은 동일한 부분도 있지만 flagmentation에 관한 부분은 다르다.
쪼개진 datagram을 합치는 것. end host, 즉 최종 목적지에서만 쪼개진 data를 합쳐서 처리할 수도 있다.
4000bytes의 datagram이 있고 link의 MTU가 1500bytes 라고 하자. 각각의 영역들을 살펴보자.
IP address는 각 host와 router들의 interface당 1개씩 결합된 32-bit identifier이다.
host/router - physical link 사이를 연결해주는 디바이스(ex. 랜카드)
router는 특히 여러 개의 인터페이스를 갖고 있다.
host는 일반적으로 1~2개의 인터페이스를 갖고 있다(Ethernet, Wifi)
Subnet은 router를 통과하지 않고 내부에서 물리적으로 연결된 device interface들을 의미한다.
IP address는 subnet part와 host part로 구성된다.
subnet part: 같은 subnet에 있는 device들은 공통된 상위 bit를 갖는다. (115.145.~)
host part: 남은 bits는 host를 구분하기 위해서 사용된다.
Subnet을 결정하기 위해서 router로부터 각각의 interface를 분리한다. (위 그림에서 분리된 각각의 섬모양 네트워크들이 바로 subnet!
만약 subnet의 ip가 223.1.3.0/24라면 상위 24비트 까지가 subnet part임 (이때 /24를 subnet mask라고 부름)
255.255.255.0 -> 옛날 subnet mask 표기 방식
요즘 -> /24
위쪽 그림에서 왼쪽 subnet은 223.1.1까지 같다. 32bit중 24bit가 같고, 8bit가 다르다. 이 24bit는 subnet part로 subnet을 구별하고 나머지 8bit는 host part로 이것으로 host를 구별한다. 총 2^8(256)개의 host를 구분할 수 있는 것이다.
Subnet을 알려주기 위해 IP주소는 233.1.1.0/24 이렇게 표시한다. 즉 앞에서부터 24bit가 subnet을 의미한다는 것을 말해주는 것이다. 그리고 나머지 8bit가 host라는 것을 말해준다.
이 그림에서 subnet은 몇 개일까??
6개이다. 라우터와 라우터의 network도 subnet이다.
address에서 subnet portion이 임의로 주어짐.
class가 있다면 네 종류의 subnet mask(8, 16, 24, 32)만 가능하다.
만약 이때 한 subnet에 5개의 host만 있다면? subnet mask를 24로 지정하게 되고, 256개의 device를 연결할 수 있는 subnet에 5개만 연결되니 낭비가 심한 것!
address format: a.b.c.d/x
x는 address에서 subnet portion의 길이
내가 만약 2000개의 host가 필요하다면, host가 11bit만 있으면 된다. 따라서 서브넷 마스크는 21bit면 충분하다
Question
1. Subnet에 포함된 한 host는 어떻게 IP 주소를 얻을 수 있을까? (address의 host part)
2. network는 그 자체로 IP address를 어떻게 얻을까? (address의 network part)
첫 번째 질문의 답은 아래와 같다.
1. 사람이 직접 sysadmin의 config file에 하나씩 hard-coding하는 방법.
2. DHCP(Dynamic Host Configuration Protocol)을 사용해서 서버가 동적으로 address를 할당하는 방법.
IP주소는 어떤식으로 부여 받을까?
IP주소는 제한적이여서 보통 집에서 사용하는 IP는 유동적으로 받게 된다. 이 유동주소를 할당하는 방법이 DHCP이다. plug-and-play 라고 말하는데, 컴퓨터를 꽂으면 주소를 가져온다는 뜻이다.
IP주소 부족하니까 network에 접속할 때 IP주소를 한 개 주는 방식이다. network의 모든 client는 항상 IP주소가 필요하지 않다. 이 때는 회수하고 다른 사용자에게 부여한다.
이 과정에서 DHCP는 단지 IP address만 할당해주는 것이 아니라 host에게 더 많은 정보를 알려준다.
또한 이 모든 과정은 UDP로 이루어지는데, Client에는 아직 IP address가 없기 때문에 TCP connection을 만들 수 없어서 UDP를 사용한다.
보통 network는 IP주소를 가지고 subnet을 관리한다.
위 예시에서 ISP가 20bits를 subnet part로 사용한다. 기관들의 subnet part 부분은 23이다. 즉, ISP는 21~23번째 bit로, 총 2^3(8)개의 기관을 관리할 수 있게 된다. 각 기관들은 나머지 bit들로 host들을 관리할 수 있다.
이런 식으로 어떤 IP주소를 계층체계로 구성하면 관리가 용이하다.
ISP는 20개 bit가 자기 숫자에 포함되는 것이라면, 우리 ISP에서 관리하는 8개의 기관 중에 하나에 갈 데이터니까, 나한테도 보내라고 요청할 수도 있다. 라우터가 요청을 받고, 20bit가 맞으면 ISP한테 Forwarding하는 것을 라우터의 알고리즘을 업데이트하게 된다.
이런 식으로 각자 ISP들이 알려주고, 라우터들이 이 정보를 가지고 업데이트 하게 된다.
기관1이 아래쪽으로 옮겨간 상황. 기관 1의 IP주소는 200.23.18.0/23. 앞의 23개 bit가 기관1과 일치하면 나한테 보내라고 요청할 수 있다. 즉, 위쪽으로 보내는 것이 아닌, 아래쪽으로 보내게 된다.(Longest prefix matching)
물론 기관들이 모두 위쪽에 있어 한번에 처리하면 좋지만, IP 쪼개다보면 항상 그렇지 않기 때문에 이와 같은 상황이 생기게 된다. 이런 상황들을 감안해서 라우팅 프로토콜을 잘 설계해야 한다.
그렇다면 ISP는 IP주소를 어디서 가져올까?
ICANN(Internet Corporation for Assigned)이라는 글로벌 기구가 있다. 여기서 전체 IP주소에 대한 관리라던지, DNS 등 전체에 대한 관리를 하게 된다.
만약 138.76.29.7이라는 IP주소가 있고, 이 IP를 필요로 하는 사람은 3명이라고 하자. local network(내부망)에서 임의의 IP주소(10.0.0.1, 10.0.0.2, 10.0.0.3)를 부여한다. 실제 네트워크의 IP주소와 겹치면 안되니 내부망에서만 사용한다. 실제 네트워크로 나갈때는 138.76.29.7로 다시 변환해서 나간다. 내부망의 host들은 transport layer의 port number로 구분될 수 있다.
정리하자면, 바깥 네트워크에서는 내부망에서 무슨일이 일어나도 신경 안 쓴다. 단지 바깥 네트워크는 IP주소와 port number를 보고 주고받을 뿐이다. 그리고 내부망에서는 각 호스트들은 임의 IP를 부여받고, 이 임의IP와 port number로 host들을 구분하는 것이다. (port number와 임의 IP를 기록해놓은 table은 라우터가 가지고 있다. 이 table을 이용해 port number를 보고 임의IP에 해당하는 host를 찾아갈 수 있는 것이다.)
우리나라의 LTE, 5G 모두 NAT방식을 사용하고 있다.
바깥으로 나갈때는 138.76.29.7을 사용하고, 내부망에서는 임의 IP를 부여받은 상황.
아래는 IPv6가 단순화를 하기 위해 한 노력들..
전세계 모든 라우터를 한번에 IPv6로 바꾸는 것을 불가능하다. IPv4와 IPv6가 공존해야 하는 상황이 올 것이다. 이에 대비하여 "Tunneling"이라는 방법을 고안했다.
IPv4와 IPv6가 공존하는 상황이라 함은, IPv6를 인식하는 라우터와 인식하지 못하는 라우터가 있을 것이다. IPv6를 인식하지 못하는 라우터가 IPv6 datagram을 받을 때 처리하는 방법이 필요하다. 그래서 IPv4 datagram 내에다가 IPv6 datagram을 집어넣어서 IPv4 형식으로 처리할 수 있게 하는 방법인 tunneling을 고안했다.
IPv6의 datagram을 보내는데, ABEF는 IPv6를 처리할 수 있고 CD는 처리하지 못하는 상황.
이 때 CD 라우터를 지날 때 IPv4의 header를 붙여서 IPv4인 것처럼 보내서 통과하게 한다.
B에서 C로 보낼 때, IPv6 datagram에 IPv4 header를 집어넣고 source IP는 B로, destination IP는 E로 설정해서 전송한다. 이렇게 C와D 라우터는 정상적으로 처리 후, E로 보낸다. E가 받았을 때는 이것을 읽고 IPv4를 떼버린다.