VxWorks 6.6網絡協議棧分析及網絡接口基本知識

本文包含網絡接口的硬件基本原理和VxWorks 6.6網絡協議棧/驅動的分析,適用于VxWorks6.6以及之前的版本,并可用作其他版本協議棧的參考。

0. 概述

0.1 網絡接口

以太網目前有兩種模型,即ISO(國際標準化組織)定義的的OSI七層模型和IETF(互聯網工程任務組)的TCP/IP五層模型,具體可參考TCP/IP協議詳解。目前,TCP/IP為互聯網的事實標準,具體分層如下所示:

OSI TCP/IP 實體
應用層
表示層 應用層 FTP/HTTP等
會話層
傳輸層 傳輸層 TCP/UDP
網絡層 網絡層 IP
鏈路層 鏈路層 MAC(介質訪問控制器)
物理層 物理層 PHY(物理層)

上表中:

  • 以太網報文格式與上表的分層對應:
    物理層 鏈路層 網絡層 傳輸層 應用層 鏈路層
    前導位、起始標志 以太網頭 IP頭 TCP/UDP頭等 FTP/HTTP數據等 CRC校驗
  • MAC又稱為以太網控制器,既具有獨立的鏈路層地址(MAC地址,又稱為以太網地址),也就是通常意義上或者狹義上的網口,用于控制鏈路層數據的傳輸;
  • PHY用于控制物理層傳輸,用于物理鏈路與MAC之間數據的編解碼、物理鏈路控制、載波偵聽、線序交換等功能,通常只包含PCS(物理編碼子層)、PMD(物理介質相關子層)、PMA(物理介質附加子層)等,但是1000Mbps以上的高速鏈路需要更多的子層(DTE XGXS、PHY XGXS);
  • MAC通過MII(狹義上的介質獨立接口)/RGMII(簡化的千兆介質無關接口)/SGMII(串行千兆介質無關接口)/XGMII(超高速介質無關接口)總線等連接到PHY上;
  • 每個MAC通常只需要一個PHY,但是1000Mbps以上的高速網口的PHY設備需要可能還需要先通過內部PHY將TBI接口轉換成SGMII接口或者將XGMII接口轉換成XAUI接口,再連接到外部PHY,從而降低外部PHY的布線難度;
  • TBI、XAUI和MII、RGMII、SGMII、XGMII、GMII、QGMII等接口都屬于廣義上的MII接口,對應于MII總線;
  • PHY必須掛在MII總線上,通過MII控制器訪問;
  • MII接口有MDIO22和MIDO45兩種標準,分別定義在802.3ap clasue22和Clasue 45中, 前者支持5位PHY地址和5位寄存器地址,后者增加了5位設備地址,允許控制PHY的不同子層;因此,每個MII控制器最多通過MII總線支持32個PHY設備
  • 廣義上的網口指的是MAC、MII控制器和PHY的綜合體。

0.2 約定

  1. socket即套接字,是BSD協議棧提出的網絡接口,包含一個接收緩沖區,用于收發數據和控制數據傳輸;
  2. MBLK/Cluster/data是BSD協議棧提出的緩沖區模型,每個數據區data對應一個Cluster,每個Cluster關聯到1個MBLK上;MBLK作為以太網報文的代表,可以將多個以太網報文分片串成一個鏈表,用以提升數據收發效率;
  3. 分析以VxWorks6.6上的MPC5200 FEC網口為例,適用于VxWorks6.6以及之前的版本,并可用作其他版本協議棧的參考;
  4. 流程圖中的非關鍵函數參數和非關鍵流程被省略以突出重點和降低工作量;

1. END驅動架構

END驅動整體架構如下所示:


Snipaste_2022-08-13_11-59-17.png

其中:

  1. 用戶可以通過3種接口訪問協議棧接口:
    • socket:由sockLib庫提供,包括socket/bind/connect/listen/accept/getsockopt/setsockopt/recv/recvfrom/recvmsg/send/sendmsg/sendto()等;其中:
    • 通用IO接口:由sockLib庫提供,包括close/ioctl/write/ioctl()
    • ipcom/ipnet接口:由ipcom/ipnet提供,包括ifconfig等;
  2. sockLib庫位于vxworks-6.6/target/src/wrn/coreip/sysdep/os/vxWorks/socket,提供socket接口,并調用iosDrvInstall()接口安裝IO設備驅動,從而為每個socket套接字創建描述符以提供通用IO接口,其中:
    • socket/accept接口除了調用ipcom/ipnet注冊的socketRtn/acceptRtn()鉤子函數,還需要調用iosLib庫接口創建IO設備作為socket描述符;
    • 其余socket接口在進行簡單的參數檢查后直接調用ipcom/ipnet注冊的對應鉤子函數;
    • 通用IO接口對應于sockLib庫在安裝IO設備驅動時注冊的socketClose/socketRead/socketWrite/socketIoctl()接口,這些接口在進行簡單的參數檢查后直接調用ipcom/ipnet注冊的對應鉤子函數;
  3. ipnet/ipcom位于components/ip_net2-6.6,使用sockLibAdd()將AF_NET/AF_PACKET等協議棧及包含socket/bind/connect/listen/accept/getsockopt/setsockopt/recv/recvfrom/recvmsg/send/sendmsg/sendto()等鉤子的功能列表注冊到sockLib的sockLibMap[];其中:
    • ipcom提供OS封裝層,用于屏蔽OS的不同,并綁定到MUX層,主要代碼位于components/ip_net2-6.6、ipcom/port/vxworks
    • ipnet/ipcom調用muxLib提供的muxDevStart/muxDevStop/muxIoctl/muxSend/muxDevLoad/muxDevUnload/muxBind/muxUnbind()接口來完成協議棧綁定、、驅動加載、網口控制和數據收發功能;
  4. muxLib位于vxworks-6.6/target/src/wrn/coreip/common/mux,用于將協議棧綁定到不同的網口上,并提供網卡控制接口,包括:
    • muxDevStart/muxDevStop/muxIoctl接口:主要通過調用endLib封裝的網口驅動功能列表中相應的start/stop/ioctl鉤子來完成;
    • muxSend接口:首先通過endLib封裝的網口驅動功能列表中的formAddress鉤子生成地址,然后調用endLib封裝的網口驅動功能列表中的packetDataGet鉤子和muxBind接口安裝的stackRcvRtn來過濾本地數據包,最后調用endLib封裝的網口驅動功能列表中的send/formAddress/packetDataGet鉤子來完成發送功能;
    • muxReceive接口:通過muxBind接口安裝的stackRcvRtn將數據上傳到ipnet/ipcom
    • muxDevLoad接口:調用驅動提供的xxxEndLoad接口加載網口驅動,然后調用endLib提供的endFlagsSet設置END_MIB_2233標志(m5200FecEnd不支持2233 MIB),并使用ioctl判斷end類型以設置pEnd->receiveRtnmuxReceivem5200FecEnd類型為END_STYLE_END);
  5. end層用于提供網卡驅動的封裝結構和公用代碼。

2. 網卡驅動全工作流程

2.1 初始化流程

網卡驅動初始化入口為usrNetworkInit():

  1. usrNetworkInit:該位于<工程目錄>/prjConfig.c中,調用usrNetEndLibInit(),用于初始化網卡驅動;
  2. usrNetEndLibInit:該接口位于vxworks-6.6/target/src/config/usrNetwork.cvxworks-6.6/target/config/comps/src/net/coreip/usrNetEndLib.c中,關鍵流程如下所示:
    Snipaste_2022-08-13_11-55-29.png

    其中:
    • vxbDevMethodRun()遍歷VxBus驅動,調用所有提供muxDevConnect接口的網卡驅動,不適用于lite5200b的Legacy網卡驅動;
    • endDevTbl[]數組包含Legacy網卡驅動,定義于BSP目錄的configNet.h中:
      #define FEC_LOAD_FUNC   m5200FecEndLoad
      ...
      #define FEC_LOAD_STR "-1:0x0:-1:-1:0x40:0x30:0x0:0xff:2:0x4:" \
              FEC_CLOCK_SPEED(IPB_CLOCK_LITERAL)
      
      #define FEC_BUFF_LOAN   1
      ...
      END_TBL_ENTRY endDevTbl [] =
      {
      #ifdef INCLUDE_FEC_END
          { 0, FEC_LOAD_FUNC, FEC_LOAD_STR, FEC_BUFF_LOAN, NULL, FALSE},
      #endif /* INCLUDE_FEC_END */
      ...
      };
      
    • endPollStatsInit()用于初始化網口驅動的統計信息。
  3. muxDevLoad():位于vxworks-6.6/target/src/wrn/coreip/common/mux/muxLib.c中,用于調用endDevTbl[]數組中Legacy網口驅動的初始化函數endLoad,關鍵流程如下所示:
    Snipaste_2022-08-13_11-56-17.png

    其中:
    • 第一次調用endLoad時參數為空字符串,用于獲取網口名稱,例如'fec';
    • 第二次調用endLoad時參數為網口單元號與初始化字符串的組合,用于正式加載網口;
  4. muxDevStart():位于vxworks-6.6/target/src/wrn/coreip/common/mux/muxLib.c中,用于調用驅動注冊的pEnd->pFuncTable->start()接口啟動網口,并將網口設置為IFF_UP | IFF_RUNNING狀態
  5. m5200FecEndLoad():驅動接口,主要功能是注冊到endLib:
    • 分配驅動信息結構和PHY信息結構;
    • 調用m5200FecInitParse解析初始化字符串并保存在驅動信息結構中;
    • 調用m5200FecInitMem申請臨時發送緩沖區,并創建netpool網絡緩沖池;
    • 調用m5200FecSdmaTaskInit創建Bestcomm SDMA任務;
    • 調用END_OBJ_INITendObjInit初始化END結構,注冊網口驅動功能列表;
    • 調用END_FLAGS_SET設置多播和廣播標志;
  6. m5200FecStart():驅動接口,主要功能是啟動網口:
    • 調用m5200FecReset復位以太網控制器;
    • 調用m5200FecTbdInit/m5200FecRbdInit初始化收發緩沖區描述符環;
    • 調用SYS_FEC_INT_CONNECTintConnect掛接BestComm發送和接收任務中斷以及通用中斷處理函數;
    • 調用SYS_FEC_INT_ENABLEintEnable使能中斷;
    • 調用m5200FecPrePhyConfig初始化MAC地址、設置中斷事件掩碼、清除中斷事件、配置內部MII控制器接口等;
    • 調用m5200FecPhyPreInit根據驅動信息結構中的標志設置PHY信息結構中的工作模式標志;
    • 調用_func_m5200FecPhyInitm5200FecPhyInit初始化PHY,并根據PHY信息結構中的工作模式標志選擇自協商模式或強制模式;
    • 調用TaskIntClear清除Bsetcomm接收任務中斷;
    • 調用TaskStart啟動Bsetcomm接收任務;
    • 調用FEC_END_ETH_ENABLE使能以太網控制器;
    • 調用END_FLAGS_SET將網口標志為IFF_UP | IFF_RUNNING,即工作狀態;
    • 調用netJobAddmuxTxRestart添加到tNet0任務維護的netJobQueueId隊列,進而調用綁定在網口上的協議棧的stackTxRestartRtn接口以復位協議棧。

2.2 發送流程

發送流程的入口為socket庫提供的send/sendto/sendmsg()和ios子系統提供的write()

  1. send/sendto/sendmsg():調用協議棧利用sockLibAdd()注冊的SOCK_FUNC指針中的sendRtn/sendtoRtn/sendmsgRtn(),即ipcom_windnet_send/sendto/sendmsg()位于vxworks-6.6/target/src/wrn/coreip/sysdep/os/vxWorks/socket/sockLib.c
  2. write():調用socket庫安裝到ios子系統的socket驅設備的socketWrite()鉤子,進而調用協議棧利用sockLibAdd()注冊的SOCK_FUNC指針中的socketwriteRtn(),即ipcom_windnet_socketwrite(),位于vxworks-6.6/target/src/wrn/coreip/sysdep/os/vxWorks/socket/sockLib.c
  3. ipcom_windnet_send/sendto/sendmsg/socketwrite():調用ipcom_send/sendto/sendmsg/send(),位于components/ip_net2-6.6/ipnet2/src/ipnet_sock.c;
  4. ipcom_send/sendto/sendmsg/send():調用ipcom_sendmsg(),位于components/ip_net2-6.6/ipnet2/src/ipnet_sock.c;
  5. ipcom_sendmsg():調用sock->ops->send(),即ipnet_init()注冊并由socket()接口使用ipcom_socket()安裝的iptcp_send和ipnet_sock_udp_send接口;
  6. iptcp_send和ipnet_sock_udp_send():
    • UDP分支:
      • ipnet_sock_udp_send():調用ops->i.network_send(),即ipnet_ip4_sendto(),位于components/ip_net2-6.6/ipnet2/src/ipnet_udp.c
    • TCP分支:
      • iptcp_send():調用iptcp_create_output_seg(),位于components/ip_net2-6.6/ipnet2/src/iptcp.c
      • iptcp_create_output_seg():調用iptcp_output(),位于components/ip_net2-6.6/ipnet2/src/iptcp.c
      • iptcp_output():調用iptcp_sendto(),位于components/ip_net2-6.6/ipnet2/src/iptcp.c
      • iptcp_sendto():調用sock->ops->network_send(),即ipnet_ip4_sendto(),位于components/ip_net2-6.6/ipnet2/src/iptcp.c
        7.ipnet_ip4_sendto():調用netif->link_ip4_output(),即ipnet_eth_if_init安裝的ipnet_eth_ip4_output(),位于components/ip_net2-6.6/ipnet2/src/ipnet_ip4.c
  7. ipnet_eth_ip4_output():調用ipnet_if_output(),位于components/ip_net2-6.6/ipnet2/src/ipnet_eth.c
  8. ipnet_if_output():調用ipnet_if_drv_output(),位于components/ip_net2-6.6/ipnet2/src/ipnet_netif.c
  9. ipnet_if_drv_output():調用netif->ipcom.drv_output(),即ipcom_drv_eth_init安裝的ipcom_drv_eth_output(),位于components/ip_net2-6.6/ipnet2/src/ipnet_netif.c
  10. ipcom_drv_eth_output():調用muxSend(),位于components/ip_net2-6.6/ipcom/port/vxworks/src/ipcom_drv_eth.c
  11. muxSend():位于components/ip_net2-6.6/ipcom/port/vxworks/src/ipcom_drv_eth.c,使用pEnd->pFuncTable->send()作為參數調用_muxTkSendEnd進行通用處理,參數檢查失敗則直接釋放pMBlk發送緩沖區;
  12. _muxTkSendEnd:位于components/ip_net2-6.6/ipcom/port/vxworks/src/ipcom_drv_eth.c,進行通用處理:
    • 更新2233 MIB中的發包統計信息;
    • 如果目的MAC地址非空,則調用pEnd->pFuncTable->formAddressm5200FecEndLoad安裝的endEtherAddressForm構造以太網頭并放到pMBlk發送緩沖區;
    • 如果網口已綁定協議棧,則調用pEnd->pFuncTable->packetDataGetendEtherPacketDataGet獲取pMBlk發送緩沖區的數據指針,然后調用muxEndRcvRtn接收數據到協議棧;
    • 調用muxSend傳遞過來鉤子調用pEnd->pFuncTable->send(),即m5200FecEndLoad函數安裝的m5200FecSend()
    • 如果發送阻塞即網口忙,則從pMBlk發送緩沖區移除以太網頭,返回錯誤信息等待協議棧再次發送;
  13. m5200FecSend():驅動接口,將數據寫入發送緩沖區并發送,
    • 檢查參數和工作模式,失敗則返回;
    • 計算pMBlk發送緩沖區的分片數;
    • 如果發送緩沖區描述符個數為0,則調用m5200FecTbdClean清理發送緩沖區;
    • 如果送緩沖區描述符個數大于pMBlk發送緩沖區的分片數、緩沖區地址滿足對齊要求且m5200FecForceCopy為false,則調用m5200FecPktTransmit;否則,調用m5200FecPktCopyTransmit
  14. m5200FecPktTransmit():驅動接口,使用pMBlk發送緩沖區進行零拷貝傳輸:
    • 調用m5200FecTbdListSet獲取發送緩沖區描述符列表;
    • 使用將pMBlk發送緩沖區各分片對應的數據指針設置發送緩沖區描述符的緩沖區指針并更新發送緩沖區描述符標志;
    • 調用TaskStart啟動BestComm發送任務;
    • 調用CACHE_PIPE_FLUSH刷新寫緩沖;
  15. m5200FecPktCopyTransmit():驅動接口,從驅動創建的netpool中申請新的MBLK用于保存pMBlk發送緩沖區中的所有數據,然后發送:
    • 調用NET_BUF_ALLOC申請cluster即數據緩沖區,申請失敗則使用臨時發送緩沖區,仍然失敗則返回發送阻塞;
    • 對齊發送緩沖區數據地址到32字節;
    • 調用m5200FecTbdListSet獲取發送緩沖區描述符列表;
    • 使用將pMBlk發送緩沖區各分片對應的數據拷貝到申請的新發送緩沖區中;
    • 使用新發送緩沖區的指針設置發送緩沖區描述符的緩沖區指針并更新發送緩沖區描述符標志;
    • 調用TaskStart啟動BestComm發送任務;
    • 調用CACHE_PIPE_FLUSH刷新寫緩沖;
  16. m5200FecWdmaInt():驅動接口,BestComm發送任務完成后會觸發BestComm發送任務中斷,并調用該函數:
    • 調用SDMA_INT_DISABLE關閉BestComm發送任務中斷;
    • 調用TaskIntClear清除BestComm發送任務中斷;
    • 調用CACHE_PIPE_FLUSH刷新寫緩沖;
    • 調用netJobAddm5200FecTxHandle添加到tNet0任務維護的netJobQueueId隊列,失敗則調用SDMA_INT_ENABLE使能BestComm發送任務退出;
  17. m5200FecTxHandle():清理發送緩沖區描述符和BestComm發送任務:
    • 調用m5200FecTbdClean清理發送緩沖區;
    • 調用intLock鎖中斷;
    • 如果BestComm發送任務狀態非空,則清除當前BestComm發送任務狀態,調用intUnlock解鎖中斷,再次回到調用m5200FecTbdClean清理發送緩沖區,直到BestComm發送任務狀態為空再調用intUnlock解鎖中斷并退出。

2.3 接收流程

接收流程的用戶程序入口為socket庫提供的recv/recvfrom/recvmsg()和ios子系統提供的read()

  1. recv/recvfrom/recvmsg():調用協議棧利用sockLibAdd()注冊的SOCK_FUNC指針中的recvRtn/recvfromRtn/recvmsgRtn(),即ipcom_windnet_recv/recvfrom/recvmsg()位于vxworks-6.6/target/src/wrn/coreip/sysdep/os/vxWorks/socket/sockLib.c
  2. read():調用socket庫安裝到ios子系統的socket驅設備的socketRead()鉤子,進而調用協議棧利用sockLibAdd()注冊的SOCK_FUNC指針中的socketresdRtn(),即ipcom_windnet_socketread(),位于vxworks-6.6/target/src/wrn/coreip/sysdep/os/vxWorks/socket/sockLib.c
  3. ipcom_windnet_recv/socketread():調用ipcom_recv(),進而調用ipcom_recvfrom,位于components/ip_net2-6.6/ipnet2/src/ipnet_sock.c;
  4. ipcom_windnet_recvfrom/recvmsg():調用ipcom_recvfrom/recvmsg(),位于components/ip_net2-6.6/ipnet2/src/ipnet_sock.c;
  5. ipcom_recvfrom():調用ipcom_recvmsg(),位于components/ip_net2-6.6/ipnet2/src/ipnet_sock.c;
  6. ipcom_recvmsg():調用sock->ops->recv(),即ipnet_init()注冊并由socket()接口使用ipcom_socket()安裝的iptcp_recv和ipnet_sock_pkt_recv接口;
  7. iptcp_recv/ipnet_sock_pkt_recv():如果socket的接收緩沖區中沒有報文,則根據用戶傳入的標志決定直接返回或者掛起任務等待報文到來;否則,則取出報文,處理后返還給用戶程序入口。

接收流程的驅動程序入口為驅動的m5200FecRdmaInt

  1. m5200FecRdmaInt():調用m5200FecRxHandle接收數據:
    • 讀取接收FIFO狀態并打印調試信息;
    • 調用intLock鎖中斷;
    • 調用SDMA_INT_DISABLE關閉接收DMA任務中斷;
    • 調用TaskIntClear清除BestComm接收任務中斷;
    • 調用intUnlock解鎖中斷;
    • 調用CACHE_PIPE_FLUSH刷新寫緩沖;
    • 調用netJobAddm5200FecRxHandle添加到tNet0任務維護的netJobQueueId隊列并退出;
  2. m5200FecRxHandle():處理BestComm接收任務中斷,
    • 調用m5200FecHandleRecvInt接收數據;
    • 調用intLock鎖中斷;
    • 如果仍有BestComm接收任務中斷待處理,則調用TaskIntClear清除BestComm接收任務中斷,調用intUnlock解鎖中斷,調用netJobAddm5200FecRxHandle添加到tNet0任務維護的netJobQueueId隊列,調用intLock鎖中斷,并再次回到第一步調用m5200FecHandleRecvInt接收數據,直到沒有BestComm接收任務中斷需要處理,才調用SDMA_INT_ENABLE使能BestComm接收任務中斷并退出;
  3. m5200FecHandleRecvInt():遍歷接收緩沖區描述符環形隊列,調用m5200FecReceive接收數據并上送協議棧;
  4. m5200FecReceive():接收數據并上送協議棧,
    • 如果接收緩沖區描述符有錯誤,則調用m5200FecRbdClean清除接收緩沖區描述符并退出;
    • 從驅動的netpool緩沖池申請MBLK和cluster,并關聯到接收緩沖區描述符的緩沖區指針,同時從驅動的netpool緩沖池申請新的緩沖區用以更新接收緩沖描述符的緩沖區指針;
    • 調用m5200FecRbdClean清除接收緩沖區描述符;
    • 調用END_RCV_RTN_CALL上傳數據到協議棧。
  5. END_RCV_RTN_CALL:調用pEnd->receiveRtnmuxReceive,失敗則調用netMblkClChainFree釋放發送緩沖區pMBLK;
  6. muxReceive():接收數據上傳協議棧:
    • 調用pEnd->pFuncTable->packetDataGetendEtherPacketDataGet獲取pMBlk接收緩沖區的數據指針;
    • 獲取以太網頭中的報文類型;
    • 遍歷綁定在網口上的協議棧,若匹配則調用協議棧的接收函數pProto->rr.endRcvmuxEndRcvRtn將數據放入協議棧的緩沖區;
    • 更新2233 MIB接收統計信息;
    • 調用netMblkClChainFree釋放發送緩沖區`pMBLK。
  7. muxEndRcvRtn():調用pBinding->stackRcvRtn,即協議棧調用muxBind綁定的deng stackRcvRtn函數指針將數據上傳到協議棧的緩沖區。

3. ifconfig up/down流程

ifconfig的入口位于vxworks-6.6/target/src/wrn/coreip/wrapper/utilslib/ifconfig.c,主要流程如下所示:

  1. ifconfig():調用ipnet_cmd_ifconfig(),位于vxworks-6.6/target/src/wrn/coreip/wrapper/utilslib/ifconfig.c
  2. ipnet_cmd_ifconfig():調用ipcom_socket()創建socket,然后使用IP_TRUE和IP_FALSE調用ipnet_ifconfig_if_change_state(),位于components/ip_net2-6.6/ipnet2/src/ipnet_cmd_ifconfig.c
  3. ipnet_ifconfig_if_change_state():使用IP_SIOCSIFFLAGS,并設置或清除IP_IFF_UP來調用ipcom_socketioctl(),位于
    components/ip_net2-6.6/ipnet2/src/ipnet_ioctl.c
  4. ipcom_socketioctl():調用ipnet_do_ioctl(),位于components/ip_net2-6.6/ipnet2/src/ipnet_ioctl.c
  5. ipnet_do_ioctl():調用ipnet_ioctl_if(),位于components/ip_net2-6.6/ipnet2/src/ipnet_ioctl.c
  6. ipnet_ioctl_if():使用IP_SIOCXOPEN或IP_SIOCXCLOSE調用ipnet_if_link_ioctl(),位于components/ip_net2-6.6/ipnet2/src/ipnet_netif.c
  7. ipnet_if_link_ioctl():調用netif->link_ioctl(),即通過ipnet_eth_if_init()安裝的ipnet_eth_ioctl(),位于components/ip_net2-6.6/ipnet2/src/ipnet_netif.c
  8. ipnet_eth_ioctl():調用ipnet_if_drv_ioctl(),位于components/ip_net2-6.6/ipnet2/src/ipnet_eth.c
  9. ipnet_if_drv_ioctl():調用ipnet_if_clean_snd_queue()清理并復位當前接口上的隊列,然后調用netif->ipcom.drv_ioctl(),即通過ipcom_drv_eth_init()安裝的ipcom_drv_eth_ioctl(),位于components/ip_net2-6.6/ipnet2/src/ipnet_netif.c
  10. ipcom_drv_eth_ioctl():為IP_SIOCXOPEN調用ipnet_drv_eth_sync_with_end_flags(),為IP_SIOCXCLOSE調用netif->link_ioevent即ipnet_eth_ioevent()通知協議棧網口處于IP_EIOXSTOP,位于components/ip_net2-6.6/ipnet2/src/ipnet_eth.c
  11. ipnet_drv_eth_sync_with_end_flags():調用muxIoctl獲取網口標志和狀態,若網口處于活動狀態度,則調用netif->link_ioevent即ipnet_eth_ioevent()通知協議棧網口處于IP_EIOXRUNNING狀態。

綜上所述,ifconfig up/down不會真正操作網口驅動,只是清理并復位當前網口上的隊列,然后通知協議棧網口處于IP_EIOXRUNNING或IP_EIOXSTOP狀態。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容