1 / 29

Interface between the Kernel and User space for Traffic Controller on Linux

Interface between the Kernel and User space for Traffic Controller on Linux. softgear@dcn.ssu.ac.kr. Overview. tc. 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

dinh
Download Presentation

Interface between the Kernel and User space for Traffic Controller on Linux

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Interface between the Kernel and User space for Traffic Controller on Linux softgear@dcn.ssu.ac.kr

  2. Overview tc 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. Boot Time __initfunc net/core/dev.c pktsched_init net/sched/sch_api.c • declarations • binding

  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. User level Application • Create netlink socket • sendto • netlink_sendmsg net/netlink/af_netlink.c • rtnetlink_rcv_msg • call function in rtnetlink_link net/core/rtnetlink.c

  6. nl_table : array of INET socket linked list nl_table

  7. rtnetlink_links • rtnetlink_links : array of pointers to rtnetlink_link • rtnetlink_link : command

  8. TC program do_qdisc tc_qdisc_modify tc_qdisc_list do_class usage do_filter

  9. tc_qdisc_modify • allocate “req” • initialize it

  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. rtnl_talk • allocate “msghdr msg” • call “sendmsg” • sys_sendmsg

  12. sys_sendmsg User space Kernel Space req msg Copy req msg • sock_sendmsg • scm_cookie scm • call ‘scm_send’ • call socket’s ‘sendmsg’ = netlink_ops • netlink_sendmsg

  13. netlink_sendmsg skbuff memcpy_from_iovec msg msg • netlink_broadcast • netlink_unicast dstgroups

  14. netlink_unicast pid socket’s protocol • find ‘linked list’ in nl_tablel • add_wait_queue skbuff socket’s receive queue • call ‘data_ready’ = rtnetlink_rcv

  15. rtnetlink_rcv socket’s receive queue skbuff • invoke ‘rtnetlink_rcv_skb’

  16. rtnetlink_rcv_skb nlh skbuff • invoke ‘rtnetlink_rcv_msg’ • passing ‘nlh’

  17. rtnetlink_rcv_msg • invoke ‘doit’ in ‘rtnetlink_link’ • In this case, doit = tc_modify_qdisc

  18. middle summary User Space tc nlmsghdr, tcmsg netlink, rtnetlink Kernel Space rtnetlink_rcv tc_get_qdisc tc_ctl_tfilter tc_modify_qdisc

  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. tc_modify_qdisc (con’t) • if tcm->tcm_handle is not empty, call ‘qdisc_lookup’ for band Q fail create_n_graft graft

  21. tc_modify_qdisc (con’t) • if tcm->tcm_handle is empty, if q is empty else create_n_graft create graft

  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. create_n_graft dev, tcm->tcm_handle, tca, &err qdisc_create

  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. 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. 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. prio_get • get minor class ID prio_graft • using minor class ID as index which band

  28. qdisc_chage • directly call ‘sch->ops->change’ chage = prio_tune

  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’

More Related