Chap14-NetworkDevice

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

14.3.2.1 界面資訊欄位(5/5)
• • • • • • • • • • IFF_PROMISC 啟動混雜模式. IFF_MULTICAST 介面是否具備群播能力. IFF_ALLMULTI 要求介面收下所有群播封包. IFF_MASTER 負載平衡. 驅程不需理會. IFF_SLAVE 負載平衡. 驅程不需理會. IFF_PORTSEL 支援具備切換傳媒能力的網卡. IFF_AUTOMEDIA 同上,多了自動. IFF_DYNAMIC 介面的硬體位址可以被改變.撥接裝置. IFF_RUNNING 與IFF_UP相同,只為了保持BSD相容性. IFF_NOTRAILERS Linux並未使用.為了BSD相容性
14.3.2.3 工具欄位(2/2)
• spinlock_t xmit_lock; 保護驅程的hard_start_xmit,避免它被同時多次重複 呼叫. • int xmit_lock_owner; 代表目前有多少個CPU取得了xmit_lock的擁有權. • struct module *owner; 擁有本網路裝置結構的模組.用來維護模組的用量計次.
開啟與關閉
• 驅動程式可以在模組的載入期或核心的啟動 期探測硬體介面是否存在。 • 在介面傳輸封包之前,核心必須先開啟介面, 並賦予它一個軟體位址(IP 位址) • uesr-space提供IP位址核心開啟、關閉、 設定網路介面的user-space程式為ifconfig • Ifconfig設定軟體位址給介面時:
14.3.2.1 界面資訊欄位(2/5)
• unsigned short hard_header_len; 硬體標頭長度,計算單位是octet. 對於Ethernet值為14 • unsigned mtu; 傳輸單位上限.對於Ethernet值為1500 octets • unsigned long tx_queue_len; 傳輸佇列可容納的訊框長度上限. ether_setup()設為100 • unsigned short type; 介面硬體型態. 提供ARP判斷介面支援何種硬體位址
14.3 詳解net_device結構
•初次研究網路驅動程式的讀者可以略過本節, 因為就算不了解它,也不會妨礙你的入門學習. •逐一描述每個欄位的意義與用途,參考性質,不 需強記. •此結構可分為兩大部分:開放與隱藏. •開放-此結構宣告為靜態結構,可以預先設定初 值的欄位. •隱藏-剩餘欄位,主要提供核心內部的網路層使 用.
– ioctl(SIOCSIFADDR)=>設定軟體位址給介面 – Ioctl(SIOCSIFILAGS)=>要求驅動程式開啟、關 閉介面=>觸動open及stop作業方法…
傳送
• 網路介面最重要的任務資料的”傳送” 與“接收”。 • 當核心需要送出資料封包時:
– 將資料排入出境封包佇列(outgoing queue) – 呼叫網路介面的hard_star_transmit()作業方法
14.3.2 隱藏欄位
• 這些欄位大致可分成三大類: 第一類 提供網路介面資訊(ifconfig). 第二類 輔助驅動程式(核心用不到). 第三類 裝置作業方法,是kernel-driver介面的一部分. • 其後說明上述欄位,並非表示在此結構的實際排列順序.
14.3.2.1 界面資訊欄位(1/5)
14.3.2.1 界面資訊欄位(3/5)
• unsigned char addr_len; 硬體位址(MAC)長度. • unsigned char broadcast[MAX_ADDR_LEN]; 廣播位址. • unsigned char dev_addr[MAX_ADDR_LEN]; 硬體位址. • 以Ethernet而言,硬體位址長度為6 octets,廣播位址 是6個連續0xff, ether_setup()能正確地填寫這兩值, 但MAC位址則須靠驅動程式自己填寫.
• 核心經手的每一封包,都是包裝成一個 struct sk_buff結構(socket buffer) • 指向sk_buff的指標,通常取名為skb
– skb->data指向即將被送出的封包 – Skb->len是該封包的長度,單位是octet
傳送
• 避免同時傳輸
– 為了避免hard_start_xmit()函式同時被呼叫, 核心在net_device結構裡設置了一個 xmit_lock空轉鎖來保護它…
14.3.1 開放欄位(1/2)
• • • • • char name[IFNAMESIZ] 裝置名稱 unsigned long rmem_end; unsigned long rmem_start; unsigned long mem_end; unsigned long mem_start; 裝置的公共記憶體範圍,rmem是接收區的範 圍,mem是傳送區的範圍. • unsigned long base_addr; 網路卡I/O基底位址 • unsigned char irq; 裝置使用的中 斷編號
14.3.2.2 網路介面的作業方法(4/4)
• int (*change_mtu)(struct net_device *dev, int new_mtu); 當介面MTU有所變更時,由此作業方法負責相關動作. • int (*header_cache) (struct neighbour *neigh, struct hh_cache *hh); 將ARP查詢的結果填寫到hh_cache結構. • int (*header_cache_update) (struct hh_cache *hh, struct net_device *dev, unsigned char *haddr); MAC位址備改變時,修正hh_cache結構裡的目標位址. • int (*hard_header_parse) (struct sk_buff *skb, unsigned char *haddr); 從skb取出來源位址,然後複製到haddr所指的緩衝區.
• 設定網路介面的資訊性欄位 (driver/net/net_init.c) void ether_setup(struct net_device *dev); void fddi_setup(struct net_device *dev); void hippi_setup(struct net_device *dev); void ltalk_setup(struct net_device *dev); void tr_setup(struct net_device *dev); void fc_setup(struct net_device *dev); • 這六類已經涵括所有能夠找到的網路技術,若有更新奇 的玩意兒,就只好老老實實自己填寫下面的欄位了.
14.3.2.1 界面資訊欄位(4/5)
• unsigned short flags; 介面旗標.flags是一個位元遮罩,<linux/if.h>定義了 一系列代表各種位元值的IFF_符號(InterFace Flags), 有效的旗標包括: • IFF_UP 介面運作狀態.對驅程唯讀,只有核心能變更. • IFF_BROADCAST 介面是否具備廣播能力. • IFF_DEBUG 除錯模式.驅程用此控制printk的囉唆程度 • IFF_LOOPBACK 只有loopback介面才能設立此旗標. • IFF_POINTOPOINT 點對點介面. • IFF_NOARP 是否支援ARP.
14.3.2.3 工具欄位(1/2)
• unsigned long trans_start; 開始傳輸的系統時刻. • unsigned long last_rx; 最近一次收到完整封包的系統時刻. • int watchdog_timeo; 網路子系統斷定傳輸逾期的最短時間間隔. • void *priv; 地位相當於filp->private_data. • struct dev_mc_list *mc_list; • int mc_count; 這兩個欄位用來處理群播傳輸. mc_count是mc_list的節點 個數.
14.3.1 開放欄位(2/2)
• unsigned char if_port; 若網卡有多個連接埠,此欄代表正在使用的的那個連接 埠. • unsigned char dma; 分配給網路裝置的DMA通道. • unsigned long state; 裝置的狀態,驅程不直接操作這些旗標,而是透過一組 工具函式來改變或取得. • struct net_device *next; 指向全域鏈結串列裡的下一個裝置,驅程不應該接觸到. • int (*init)(struct net_device *dev); 指向初始函式的指標.
14.3.2.2 網路介面的作業方法(3/4)
• 以下為額外作業方法: • int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd); 執行特殊的ioctl命令. • void (*set_multicast_list)(struct net_device *dev); 每當裝置的群播名單或flags位元遮罩有任何變動時, 就會觸發此作業方法. • int (*set_mac_address)(struct net_device *dev, void *addr); 若你的網卡提供改變硬體位址的能力,則可以實作此作 業方法.
14.3.2.2 網路介面的作業方法(2/4)
• int (*rebuild_header)(struct sk_buff *skb); 負責在傳輸封包之前重建硬體標頭. 2.4改用hard_header • void (*tx_timeout)(struct net_device *dev); 若無法在一段合理時間內完成封包傳輸,則會呼叫此作 業方法. • struct net_device_stats *(*get_stats)(struct net_device *dev); 每當應用程式需介面統計資訊時,就會觸動此作業方法. • int (*set_config)(struct net_device *dev, struct ifmap *map); 更改介面的硬體組態.
14.3.2.2 網路介面的作業方法(1/4)
• 大致可分成基本與額外兩組,你的驅程必須提供基本作 業方法,網路介面才有用.額外作業方法是屬於比較高 階的功能,並不嚴格要求一定要具備. • 以下為基本作業方法: • int (*open)(struct net_device *dev); 開啟介面 • int (*stop)(struct net_device *dev); 停用介面 • int (*hard_start_xmit) (struct sk_buff *skb, struct net_device *dev); 要求硬體開始送出一個封包 • int (*hard_header) (struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); 負責建構硬體標頭
• 傳輸逾期
– 就驅動程式觀點來看,硬體超過一段不合理 的時間沒回應。因此,發覺問題的方法就是 設置一些計時器……
接收方式
• 處理封包接收方式: 1.interrupt handler 2.polling (消率差) • 網路硬體中斷觸發中斷,並配置sk_buff給 handler.
wk.baidu.com
snull
void snull_rx(struct net_device *dev, int len, unsigned char *buf) { struct sk_buff *skb; struct snull_priv *priv = (struct snull_priv *) dev->priv; /* * The packet has been retrieved from the transmission * medium. Build an skb around it, so upper layers can handle it */ skb = dev_alloc_skb(len+2); if (!skb) { printk("snull rx: low on mem - packet dropped\n"); priv->stats.rx_dropped++; return; }
相关文档
最新文档