softgear@dcn.ssu.ac.kr
tc

Overview
User Space

include/linux/pkt_cls.h
include/linux/pkt_sched.h
net/netlink

struct sockaddr_nl
struct nlmsghdr...
Boot Time
__initfunc
pktsched_init
• declarations
• binding

net/core/dev.c
net/sched/sch_api.c
pktsched_init
struct rtnetlink_link *link_p;
if (link_p) {
link_p[RTM_NEWQDISC-RTM_BASE].doit = tc_ctl_qdisc;
link_p[RTM_D...
User level Application
Create netlink socket
sendto
netlink_sendmsg

net/netlink/af_netlink.c

rtnetlink_rcv_msg
net/core/...
nl_table
nl_table :

array of

INET socket linked list
rtnetlink_links
rtnetlink_links : array of
pointers to rtnetlink_link
rtnetlink_link : command
TC program
do_qdisc

tc_qdisc_modify

do_class

tc_qdisc_list

do_filter

usage
tc_qdisc_modify
allocate “req”
initialize it
tc_qdisc_modify (con’t)
rtnl_open : create ‘rtnetlink’ socket
family = AF_NETLINK
type = SOCK_RAW
protocol = NETLINK_ROUTE...
rtnl_talk
allocate “msghdr msg”

call “sendmsg”

sys_sendmsg
sys_sendmsg
User space
req
msg

• sock_sendmsg

Kernel Space
Copy

req
msg

scm_cookie scm
call ‘scm_send’
call socket’s ‘...
netlink_sendmsg
memcpy_from_iovec
msg

dstgroups

skbuff
msg

• netlink_broadcast
• netlink_unicast
netlink_unicast
socket’s protocol

pid

find ‘linked list’ in nl_tablel
add_wait_queue
skbuff

socket’s receive queue

cal...
rtnetlink_rcv
socket’s receive queue

invoke ‘rtnetlink_rcv_skb’

skbuff
rtnetlink_rcv_skb

skbuff

nlh

invoke ‘rtnetlink_rcv_msg’
passing ‘nlh’
rtnetlink_rcv_msg

invoke ‘doit’ in ‘rtnetlink_link’
In this case, doit = tc_modify_qdisc
middle summary
User Space
tc
nlmsghdr, tcmsg
netlink, rtnetlink
Kernel Space
rtnetlink_rcv
tc_get_qdisc
tc_modify_qdisc

t...
tc_modify_qdisc
dev_get_by_index
index = tcm->tcm_ifindex
if qdisc parent is set,
call ‘qdisc_lookup’ : Find parent Q
call...
tc_modify_qdisc (con’t)
if tcm->tcm_handle is not empty,
call ‘qdisc_lookup’ for band Q
fail

create_n_graft

graft
tc_modify_qdisc (con’t)
if tcm->tcm_handle is empty,
if q is empty
create_n_graft

else

create

graft
tc_modify_qdisc (con’t)
if (tcm->tcm_parent is not specified),
if (tcm->tcm->handle is not empty)
then call ‘qdisc_lookup’...
create_n_graft

dev, tcm->tcm_handle, tca, &err

qdisc_create
qdisc_create
find qdisc’s kind
using kind, get ‘Qdisc_ops’
allocate space for Q displine
call ‘skb_queue_head_init’
set up...
graft
call ‘qdisc_graft’
connect ‘new’ to parent’s class
or dev
if parent Q displine is empty,
call ‘dev_graft_qdisc(dev,n...
dev_graft_qdisc
dev_deactive
put old ‘qdisc_sleeping’ to ‘oqdisc’
if new Q is empty,
set new Q to noop_qdisc
then, set dev...
prio_get
get minor class ID

prio_graft
using minor class ID as index which band
qdisc_chage
directly call ‘sch->ops->change’
chage = prio_tune
prio_tune
argument opt contains ‘bands’
outside band is set by ‘noop_qdisc’
update child Q by ‘prio2band array’
if Q == no...
Upcoming SlideShare
Loading in …5
×

Interface between kernel and user space

1,219 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,219
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
16
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Interface between kernel and user space

  1. 1. softgear@dcn.ssu.ac.kr
  2. 2. tc Overview User Space include/linux/pkt_cls.h include/linux/pkt_sched.h net/netlink struct sockaddr_nl struct nlmsghdr netlink socket rtnetlink socket net/core/rtnetlink.c linux/include/rtnetlink.h Kernel Space
  3. 3. Boot Time __initfunc pktsched_init • declarations • binding net/core/dev.c net/sched/sch_api.c
  4. 4. pktsched_init struct rtnetlink_link *link_p; if (link_p) { link_p[RTM_NEWQDISC-RTM_BASE].doit = tc_ctl_qdisc; link_p[RTM_DELQDISC-RTM_BASE].doit = tc_ctl_qdisc; link_p[RTM_GETQDISC-RTM_BASE].doit = tc_ctl_qdisc; link_p[RTM_GETQDISC-RTM_BASE].dumpit = tc_dump_qdisc; link_p[RTM_NEWTCLASS-RTM_BASE].doit = tc_ctl_tclass; link_p[RTM_DELTCLASS-RTM_BASE].doit = tc_ctl_tclass; link_p[RTM_GETTCLASS-RTM_BASE].doit = tc_ctl_tclass; link_p[RTM_GETTCLASS-RTM_BASE].dumpit = tc_dump_tclass; }
  5. 5. User level Application Create netlink socket sendto netlink_sendmsg net/netlink/af_netlink.c rtnetlink_rcv_msg net/core/rtnetlink.c call function in rtnetlink_link
  6. 6. nl_table nl_table : array of INET socket linked list
  7. 7. rtnetlink_links rtnetlink_links : array of pointers to rtnetlink_link rtnetlink_link : command
  8. 8. TC program do_qdisc tc_qdisc_modify do_class tc_qdisc_list do_filter usage
  9. 9. tc_qdisc_modify allocate “req” initialize it
  10. 10. tc_qdisc_modify (con’t) rtnl_open : create ‘rtnetlink’ socket family = AF_NETLINK type = SOCK_RAW protocol = NETLINK_ROUTE setup and bind local address, sockaddr_nl local call “rtnl_talk”
  11. 11. rtnl_talk allocate “msghdr msg” call “sendmsg” sys_sendmsg
  12. 12. sys_sendmsg User space req msg • sock_sendmsg Kernel Space Copy req msg scm_cookie scm call ‘scm_send’ call socket’s ‘sendmsg’ = netlink_ops netlink_sendmsg
  13. 13. netlink_sendmsg memcpy_from_iovec msg dstgroups skbuff msg • netlink_broadcast • netlink_unicast
  14. 14. netlink_unicast socket’s protocol pid find ‘linked list’ in nl_tablel add_wait_queue skbuff socket’s receive queue call ‘data_ready’ = rtnetlink_rcv
  15. 15. rtnetlink_rcv socket’s receive queue invoke ‘rtnetlink_rcv_skb’ skbuff
  16. 16. rtnetlink_rcv_skb skbuff nlh invoke ‘rtnetlink_rcv_msg’ passing ‘nlh’
  17. 17. rtnetlink_rcv_msg invoke ‘doit’ in ‘rtnetlink_link’ In this case, doit = tc_modify_qdisc
  18. 18. middle summary User Space tc nlmsghdr, tcmsg netlink, rtnetlink Kernel Space rtnetlink_rcv tc_get_qdisc tc_modify_qdisc tc_ctl_tfilter
  19. 19. tc_modify_qdisc dev_get_by_index index = tcm->tcm_ifindex if qdisc parent is set, call ‘qdisc_lookup’ : Find parent Q call ‘qdisc_leaf’
  20. 20. tc_modify_qdisc (con’t) if tcm->tcm_handle is not empty, call ‘qdisc_lookup’ for band Q fail create_n_graft graft
  21. 21. tc_modify_qdisc (con’t) if tcm->tcm_handle is empty, if q is empty create_n_graft else create graft
  22. 22. tc_modify_qdisc (con’t) if (tcm->tcm_parent is not specified), if (tcm->tcm->handle is not empty) then call ‘qdisc_lookup’ call qdisc_change(q,tca) ‘qdisc_change’ call ‘prio_tune’
  23. 23. create_n_graft dev, tcm->tcm_handle, tca, &err qdisc_create
  24. 24. qdisc_create find qdisc’s kind using kind, get ‘Qdisc_ops’ allocate space for Q displine call ‘skb_queue_head_init’ set up ‘enqueue’, ‘dequeue’ call ‘ops->init’ = prio_init insert new Q into qdisc_list
  25. 25. graft call ‘qdisc_graft’ connect ‘new’ to parent’s class or dev if parent Q displine is empty, call ‘dev_graft_qdisc(dev,new)’ else call ‘get’ from class call ‘qdisc_notify’
  26. 26. dev_graft_qdisc dev_deactive put old ‘qdisc_sleeping’ to ‘oqdisc’ if new Q is empty, set new Q to noop_qdisc then, set dev’s qdisc_sleeping to new Q, dev->qdisc to noop_qdisc Reactive device
  27. 27. prio_get get minor class ID prio_graft using minor class ID as index which band
  28. 28. qdisc_chage directly call ‘sch->ops->change’ chage = prio_tune
  29. 29. prio_tune argument opt contains ‘bands’ outside band is set by ‘noop_qdisc’ update child Q by ‘prio2band array’ if Q == noop_qdisc qdisc_create_dflt qdisc_creat_dflt set up child Q set up operator to ‘pfifo_qdisc_ops’

×