Preface
當使用 ovs-vsctl add-port br0 eth1的時候,實際上會做什麼事情,這邊分成兩個層面來看
- User space
- Kernel space
而這之中則會透過 generic netlink來溝通
User space
這部分還有點卡住,對 ovsdb 有更瞭解後再補充
bridge_reconfigure
bridge_refresh_ofp_port
bridge_refresh_one_ofp_port
iface_create
iface_do_create
ofproto_port_add
VLOG_INFO
1 | static int |
1 | int |
1 | static void |
- 這邊會去註冊每個 base_dipf_classes.
1 | struct dpif_class { |
- dpif_class是一個base class,裡面存放的都是function pointer.
1 | static const struct dpif_class *base_dpif_classes[] = { |
- 這邊會根據type去實例化不同類型的 dpif_class,這邊我們關心的是 dpif_linux_class.
1 | const struct dpif_class dpif_linux_class = { |
- 這邊定義了 dpif_class的一些操作function.
- 我們關心的 port_add 實際上對應的是 dpif_linux_port_add
1 | static int |
- 這邊會呼叫 dpif_linux_port_add__去創立vport.
1 | static int |
- 這邊會設定request的cmd為 OVS_VPORT_CMD_NEW
- 使用 dpif_linux_vport_transact 把這個request透過netlink的方式送到kernel端,kernel端會再根據這個request的cmd來執行特定的function.
Gereric netlink
1 | static int dp_register_genl(void) |
- 當 datapath kernel module被載入的時候,會執行對應的 init,裡面會執行 dp_register_genl.
- 這邊會呼叫所有的 dp_genl_families 來註冊 generic netlink相關的function.
1 | static const struct genl_family_and_ops dp_genl_families[] = { |
- 這邊定義了所有 gerneric netlink相關type的結構成員 (dp,vport,flow,packet)
1 | static struct genl_ops dp_vport_genl_ops[] = { |
- 這邊定義了 gerneric netlink 相關的vport operation.
- 當 cmd 是 OVS_VPORT_CMD_NEW的時候,就會執行對應的 function handler ovs_vport_cmd_new
Kernel space
1 | static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info) |
- struct vport_parms parms 用來記錄一些vport的資訊
- 填寫相關訊息後,就呼叫 new_vport來創立 vport
1 | static struct vport *new_vport(const struct vport_parms *parms) |
- 這邊會呼叫 *ovs_vport_add 來創立該vport
1 | struct vport *ovs_vport_add(const struct vport_parms *parms) |
- 掃過所有 vport_ops_list, 如果那個ops的 type跟傳進來的type是一樣的,那就呼叫對應的 create function.
1 | static const struct vport_ops *vport_ops_list[] = { |
- vport_ops 有多種type.這邊我們專注於 ovs_netdev_vport_ops這種type.
1 | const struct vport_ops ovs_netdev_vport_ops = { |
- vport當type是 netdev的時候,成員的function pointer就會按此設定為各個function.
- 可以看到他的 create 對應到 netdev_create
1 | static struct vport *netdev_create(const struct vport_parms *parms) |
- 這邊註冊netdevice的receive handler, handler為 netdev_frame_hook
1 | int netdev_rx_handler_register(struct net_device *dev, |
- 這邊會把設定該 net_device中的兩個pointer
- rx_handler_data 這邊就設定成該vport.
- rx_handler 接收到封包的處理函式,這邊就是netdev_frame_hook。
個人資訊
我目前於 Hiskio 平台上面有開設 Kubernetes 相關課程,歡迎有興趣的人參考並分享,裡面有我從底層到實戰中對於 Kubernetes 的各種想法
線上課程詳細資訊: https://course.hwchiu.com/
另外,歡迎按讚加入我個人的粉絲專頁,裡面會定期分享各式各樣的文章,有的是翻譯文章,也有部分是原創文章,主要會聚焦於 CNCF 領域
https://www.facebook.com/technologynoteniu
如果有使用 Telegram 的也可以訂閱下列頻道來,裡面我會定期推播通知各類文章
https://t.me/technologynote
你的捐款將給予我文章成長的動力