rte_ipv4_frag_reassemble_packet()
ip_frag_find() 기존에 존재하는 flow면 해당 flow를 저장한 entry 정보를(ip_frag_pkt *pkg) 신규 flow인 경우 해당 신규 flow를 저장할 신규 혹은 재사용된 entry를 return함 추가할 수 있는 통계 신규 flow? 기존 flow에 정상 추가 기존 flow에 비정상 추가(기존 flow가 timeouted) 이도 저도 아닌 상황(할당 실패) LRU entry free tbl->max_entries tbl->use_entries return 기존 존재하는 flow, 신규 할당한 flow entry 혹은 NULL 만일 NULL을 return하면 현재 수신한 mbuf를 death row에 추가한다. 불쌍한… ip_frag_lookup() if matched entry is exist return flow entry return &stale if time-outed entry is exist if new entry return NULL return free for new empty entry return &stale if time-outed entry is exist ip_frag_key_cmp() return 0 if key matched if ip_frag_lookup() returns NULL if stale entry is not NULL, remove it with ip_frag_tbl_del() and save to free for reuse even if free is not NULL, check if tbl->use_entries does not exceed tbl->max_entries.
l2_len, l3_len, l4_len 등을 사용하는 라이브러리가 존재함
reassembly Tx checksum offload Reassembly rte_ipv6_frag_reassemble_packet(), rte_ipv4_frag_reassemble_packet() Incoming mbuf should have its l2_len and l3_len fields setup correctly.
L4 checksum HW offloading To use hardware L4 checksum offload, the user needs to
fill l2_len and l3_len in mbuf set the flags PKT_TX_TCP_CKSUM, PKT_TX_SCTP_CKSUM or PKT_TX_UDP_CKSUM set the flag PKT_TX_IPV4 or PKT_TX_IPV6 calculate the pseudo header checksum and set it in the L4 header (only for TCP or UDP).
DPDK to KNI RX KNI는 rx_q로부터 mbuf를 수신한 후 data_len 크기의 skb를 할당하여 데이터를 복사한 후 netif_rx를 호출한다. 그러므로 mbuf는 KNI kernel module까지만 사용되고, 커널 networking stack에서는 사용되지는 않는다.
kni_net.c의 kni_net_rx_normal() 함수가 DPDK application으로부터 mbuf를 받아 커널에 전달하는 함수인데 실제 함수는 batch processing을 위해 한번에 여러 개의 패킷을 rx_q로부터 읽어 처리하도록 구현되어 있다.
아래는 하나의 패킷에 대해 수행되는 코드를 간략화 한 것이다(예외 처리 부분도 제외)
num_rx = kni_fifo_get(kni->rx_q, (void **)va, num_rx); kva = (void *)va[i] - kni->mbuf_va + kni->mbuf_kva; len = kva->data_len; data_kva = kva->buf_addr + kva->data_off - kni->mbuf_va + kni->mbuf_kva; skb = dev_alloc_skb(len + 2); /* Align IP on 16B boundary */ skb_reserve(skb, 2); memcpy(skb_put(skb, len), data_kva, len); skb->dev = dev; skb->protocol = eth_type_trans(skb, dev); skb->ip_summed = CHECKSUM_UNNECESSARY; /* Call netif interface */ netif_rx(skb); /* Update statistics */ kni->stats.
Without Suppressing Scapy IPv6 warning cychong@ubuntu:~$ python Python 2.7.6 (default, Jun 22 2015, 17:58:13) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from scapy.all import * WARNING: No route found for IPv6 destination :: (no default route?) >>> Suppress scapy IPv6 warning cychong@ubuntu:~$ python Python 2.7.6 (default, Jun 22 2015, 17:58:13) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import logging >>> logging.
import modules $ python >>> from scapy.all import * >>> from scapy.layers.ipsec import * build plaintext packet >>> p = IP(src='1.1.1.1', dst='2.2.2.2') / TCP(sport=45012, dport=80) / Raw('testdata') >>> p = IP(str(p)) setup SA >>> sa = SecurityAssociation(ESP, spi=0xdeadbeef, crypt_algo='AES-CBC',crypt_key='sixteenbytes key') Encrypt w/o IV >>> e = sa.encrypt(p, 5) >>> e <IP version=4L ihl=5L tos=0x0 len=76 id=1 flags= frag=0L ttl=64 proto=esp chksum=0x747a src=1.1.1.1 dst=2.2.2.2 |<ESP spi=0xdeadbeef seq=5 data='uD\x7fdj19\xe7\xc4\xff8\x10\xcdQ\xf0\xa6\x1e!\x84\xc3>!\x18\xa6\xf6\xb8\x93\xc6it\x9a\xfc\x1c\xee\xe5C\xcd\xf0\x7fD\xca\x8d\xadKh\xa8\xe5x' |>> >>> e.show() ###[ IP ]### version = 4L ihl = 5L tos = 0x0 len = 76 id = 1 flags = frag = 0L ttl = 64 proto = esp chksum = 0x747a src = 1.
다음과 같이 scapy를 이용해서 fragment를 쉽게 만들 수 있다.
from scapy.all import * dip="10.0.0.1" payload=" "*1000 packet=IP(dst=dip)/UDP(dport=0x1234)/payload frag_list=fragment(packet,fragsize=500) counter=1 for fragment in frag_list: print "Packet no%d" %counter print fragment.show() counter+=1 send(fragment) frag_list에서 counter 변수를 확인해서 전송하지 않으면 간단하게 fragment가 수신되지 않은 경우에 시험할 수 있음.
필요하면 frag_list의 순서를 뒤집는 것도 가능하고, 각 fragment의 offset값을 조정하거나 패킷 크기를 변경하면 다른 비정상 경우도 쉽게 시험할 수 있다.
scapy interactive tutorial
Vagrant
fd.io의 개발 환경 구성하는 문서를 보니 vagrant를 사용한다. 그런데 또 virtualbox니 vmware 이야기를 한다. 이전에도 vagrant라는 단어를 들어본적이 있었는데 이번 기회에 좀 알아보기로
Why Vagrant를 보면 다음과 같이 설명하고 있다.
Vagrant provides easy to configure, reproducible, and portable work environments built on top of industry-standard technology and controlled by a single consistent workflow to help maximize the productivity and flexibility of you and your team.
To achieve its magic, Vagrant stands on the shoulders of giants.
├── build-data │ ├── packages │ └── platforms ├── build-root │ ├── deb │ │ └── debian │ │ └── source │ ├── emacs-lisp │ ├── packages │ ├── rpm │ ├── scripts │ └── vagrant ├── dpdk │ ├── dkms │ ├── dpdk-2.1.0_patches │ └── dpdk-2.2.0_patches ├── g2 ├── gmod │ └── gmod ├── perftool ├── sample-plugin │ └── sample ├── svm ├── test │ ├── resources │ │ ├── libraries │ │ │ ├── bash │ │ │ ├── python │ │ │ └── robot │ │ │ └── vat │ │ └── templates │ │ └── vat │ └── tests │ └── suites │ ├── bridge_domain │ └── vhost_user_dummy ├── vlib │ ├── example │ └── vlib │ └── unix ├── vlib-api │ ├── vlibapi │ ├── vlibmemory │ └── vlibsocket ├── vnet │ ├── etc │ │ └── scripts │ │ ├── dhcp │ │ ├── ludd-cluster-1 │ │ ├── ludd-cluster-3 │ │ ├── mpls-o-ethernet │ │ ├── mpls-o-gre │ │ ├── sr │ │ └── virl │ └── vnet │ ├── cdp │ ├── classify │ ├── devices │ │ ├── dpdk │ │ ├── ssvm │ │ └── virtio │ ├── dhcp │ ├── dhcpv6 │ ├── ethernet │ ├── flow │ ├── gre │ ├── hdlc │ ├── ip │ ├── ipsec │ ├── l2 │ ├── l2tp │ ├── lawful-intercept │ ├── lisp-gpe │ ├── llc │ ├── map │ │ └── examples │ ├── mcast │ ├── mpls-gre │ ├── nsh-gre │ ├── nsh-vxlan-gpe │ ├── osi │ ├── pg │ ├── plugin │ ├── policer │ ├── ppp │ ├── snap │ ├── sr │ ├── srp │ ├── unix │ ├── vcgn │ └── vxlan ├── vpp │ ├── api │ ├── app │ ├── conf │ ├── oam │ ├── stats │ └── vnet ├── vpp-api-test │ ├── scripts │ └── vat ├── vpp-japi │ ├── japi │ │ ├── org │ │ │ └── openvpp │ │ │ └── vppjapi │ │ └── test │ └── m4 ├── vppapigen └── vppinfra ├── config ├── tools └── vppinfra
2016년 2월 11일 공개된 CISCO 주도의 프로젝트. 무려 2002년부터 개발한 것으로 현재 버전은 3번째 revision이라고 한다.
간만에 dpdk.org mailing list에 들어갔다 가장 최근에 올라온 글 제목이 눈에 띄었다.
[dpdk-dev] [dpdk-announce] new project using DPDK - FD.io Vincent JARDIN
“new project”?
그래서 내용을 봤더니 이게 다 였다는
A new project using DPDK is available, http://FD.io said FiDo You can clone it from: http://gerrit.fd.io/ Best regards, Vincent 그래도 첫 번째 링크를 따라가 보니 화려하다.
왜 공부해야 하는가
사회의 변화속도는 우리의 변화속도를 압도하기 때문입니다.
<누가 내 치즈를 옮겼을까>에 잘 묘사되어 있지요.
따라잡지 않으면 뒤쳐지기 때문에 우리는 늘 공부해야 합니다.
https://brunch.co.kr/@choihs0228/4