版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、Good is good, but better carries it.精益求精,善益求善。skbuff詳解及功能分析sk_buffstructsk_buff可能是linux網(wǎng)絡(luò)代碼中最重要的數(shù)據(jù)結(jié)構(gòu),它表示接收或發(fā)送數(shù)據(jù)包的包頭信息,并包含很多成員變量供網(wǎng)絡(luò)代碼中的各子系統(tǒng)使用。這個(gè)結(jié)構(gòu)被網(wǎng)絡(luò)的不同層(MAC或者其他二層鏈路協(xié)議,三層的IP,四層的TCP或UDP等)使用,并且其中的成員變量在結(jié)構(gòu)從一層向另一層傳遞時(shí)改變。L4向L3傳遞前會(huì)添加一個(gè)L4的頭部,同樣,L3向L2傳遞前,會(huì)添加一個(gè)L3的頭部。添加頭部比在不同層之間拷貝數(shù)據(jù)的效率更高。由于在緩沖區(qū)的頭部添加數(shù)據(jù)意味著要修改指向緩沖區(qū)
2、的指針,這是個(gè)復(fù)雜的操作,所以內(nèi)核提供了一個(gè)函數(shù)skb_reserve來完成這個(gè)功能。協(xié)議棧中的每一層在往下一層傳遞緩沖區(qū)前,第一件事就是調(diào)用skb_reserve在緩沖區(qū)的頭部給協(xié)議頭預(yù)留一定的空間。skb_reserve同樣被設(shè)備驅(qū)動(dòng)使用來對(duì)齊接收到包的包頭。如果緩沖區(qū)向上層協(xié)議傳遞,舊的協(xié)議層的頭部信息就沒什么用了。例如,L2的頭部只有在網(wǎng)絡(luò)驅(qū)動(dòng)處理L2的協(xié)議時(shí)有用,L3是不會(huì)關(guān)心它的信息的。但是,內(nèi)核并沒有把L2的頭部從緩沖區(qū)中刪除,而是把有效荷載的指針指向L3的頭部,這樣做,可以節(jié)省CPU時(shí)間。有些sk_buff成員變量的作用是方便查找或者是連接數(shù)據(jù)結(jié)構(gòu)本身。內(nèi)核可以把sk_buff
3、組織成一個(gè)雙向鏈表。當(dāng)然,這個(gè)鏈表的結(jié)構(gòu)要比常見的雙向鏈表的結(jié)構(gòu)復(fù)雜一點(diǎn)。就像任何一個(gè)雙向鏈表一樣,sk_buff中有兩個(gè)指針next和prev,其中,next指向下一個(gè)節(jié)點(diǎn),而prev指向上一個(gè)節(jié)點(diǎn)。在第一個(gè)節(jié)點(diǎn)前面會(huì)插入另一個(gè)結(jié)構(gòu)sk_buff_head,這是一個(gè)輔助節(jié)點(diǎn)(作為sk_buff雙向鏈表的頭),它的定義如下:structsk_buff_headstructsk_buff-*next;structsk_buff-*prev;_u32qlen;spinlock_tlock;qlen代表鏈表元素的個(gè)數(shù)lock用于防止對(duì)鏈表的并發(fā)訪問sk_buff和sk_buff_head的前兩個(gè)元素
4、是一樣的:next和prev指針。這使得它們可以放到同一個(gè)鏈表中,盡管sk_buff_head要比sk_buff小得多。另外,相同的函數(shù)可以同樣應(yīng)用于sk_buff和sk_buff_head。sk_buff-sk這是一個(gè)指向擁有這個(gè)sk_buff的sock結(jié)構(gòu)的指針。這個(gè)指針在網(wǎng)絡(luò)包由本機(jī)發(fā)出或者由本機(jī)進(jìn)程接收時(shí)有效,因?yàn)椴蹇谙嚓P(guān)的信息被L4(TCP或UDP)或者用戶空間程序使用。如果sk_buff只在轉(zhuǎn)發(fā)中使用(這意味著,源地址和目的地址都不是本機(jī)地址),這個(gè)指針是NULLsk_buff-len表示當(dāng)前協(xié)議數(shù)據(jù)包的長度。它包括主緩沖區(qū)中的數(shù)據(jù)長度(data指針指向它)和分片中的數(shù)據(jù)長度。sk
5、_buff-data_len和len不同,data_len只計(jì)算分片中數(shù)據(jù)的長度sk_buff-mac_len這是mac頭的長度sk_buff-users這是一個(gè)引用計(jì)數(shù),用于計(jì)算有多少實(shí)體引用了這個(gè)sk_buff緩沖區(qū)。它的主要用途是防止釋放sk_buff后,還有其他實(shí)體引用這個(gè)sk_buff。因此,每個(gè)引用這個(gè)緩沖區(qū)的實(shí)體都必須在適當(dāng)?shù)臅r(shí)候增加或減小這個(gè)變量。這個(gè)計(jì)數(shù)器只保護(hù)sk_buff結(jié)構(gòu)本身,而緩沖區(qū)的數(shù)據(jù)部分由類似的計(jì)數(shù)器(dataref)來保護(hù).有時(shí)可以用atomic_inc和atomic_dec函數(shù)來直接增加或減小users,但是,通常還是使用函數(shù)skb_get和kfree_s
6、kb來操作這個(gè)變量。sk_buff-truesize這是緩沖區(qū)的總長度,包括sk_buff結(jié)構(gòu)和數(shù)據(jù)部分。如果申請(qǐng)一個(gè)len字節(jié)的緩沖區(qū),alloc_skb函數(shù)會(huì)把它初始化成len+sizeof(sk_buff)。當(dāng)skb-len變化時(shí),這個(gè)變量也會(huì)變化。sk_buff-headsk_buff-datask_buff-tailsk_buff-end它們表示緩沖區(qū)和數(shù)據(jù)部分的邊界。在每一層申請(qǐng)緩沖區(qū)時(shí),它會(huì)分配比協(xié)議頭或協(xié)議數(shù)據(jù)大的空間。head和end指向緩沖區(qū)的頭部和尾部,而data和tail指向?qū)嶋H數(shù)據(jù)的頭部和尾部。每一層會(huì)在head和data之間填充協(xié)議頭,或者在tail和end之間添加
7、新的協(xié)議數(shù)據(jù)。數(shù)據(jù)部分會(huì)在尾部包含一個(gè)附加的頭部。void(*destructor)(structsk_buff*skb)這個(gè)函數(shù)指針可以初始化成一個(gè)在緩沖區(qū)釋放時(shí)完成某些動(dòng)作的函數(shù)。如果緩沖區(qū)不屬于一個(gè)socket,這個(gè)函數(shù)指針通常是不會(huì)被賦值的。如果緩沖區(qū)屬于一個(gè)socket,這個(gè)函數(shù)指針會(huì)被賦值為sock_rfree或sock_wfree(分別由skb_set_owner_r或skb_set_owner_w函數(shù)初始化)。這兩個(gè)sock_xxx函數(shù)用于更新socket的隊(duì)列中的內(nèi)存容量。sk_buff-tstamp這個(gè)變量只對(duì)接收到的包有意義。它代表包接收時(shí)的時(shí)間戳,或者有時(shí)代表包準(zhǔn)備發(fā)出
8、時(shí)的時(shí)間戳。它在netif_rx里面由函數(shù)net_timestamp設(shè)置,而netif_rx是設(shè)備驅(qū)動(dòng)收到一個(gè)包后調(diào)用的函數(shù)。sk_buff-dev這個(gè)變量的類型是net_device,net_device它代表一個(gè)網(wǎng)絡(luò)設(shè)備。dev的作用與這個(gè)包是準(zhǔn)備發(fā)出的包還是剛接收的包有關(guān)。當(dāng)收到一個(gè)包時(shí),設(shè)備驅(qū)動(dòng)會(huì)把sk_buff的dev指針指向收到這個(gè)包的網(wǎng)絡(luò)設(shè)備;當(dāng)一個(gè)包被發(fā)送時(shí),這個(gè)變量代表將要發(fā)送這個(gè)包的設(shè)備。在發(fā)送網(wǎng)絡(luò)包時(shí)設(shè)置這個(gè)值的代碼要比接收網(wǎng)絡(luò)包時(shí)設(shè)置這個(gè)值的代碼復(fù)雜。有些網(wǎng)絡(luò)功能可以把多個(gè)網(wǎng)絡(luò)設(shè)備組成一個(gè)虛擬的網(wǎng)絡(luò)設(shè)備(也就是說,這些設(shè)備沒有和物理設(shè)備直接關(guān)聯(lián)),并由一個(gè)虛擬網(wǎng)絡(luò)設(shè)備驅(qū)
9、動(dòng)管理。當(dāng)虛擬設(shè)備被使用時(shí),dev指針指向虛擬設(shè)備的net_device結(jié)構(gòu)。而虛擬設(shè)備驅(qū)動(dòng)會(huì)在一組設(shè)備中選擇一個(gè)設(shè)備并把dev指針修改為這個(gè)設(shè)備的net_device結(jié)構(gòu)。因此,在某些情況下,指向傳輸設(shè)備的指針會(huì)在包處理過程中被改變。sk_buff-input_dev這是收到包的網(wǎng)絡(luò)設(shè)備的指針。如果包是本地生成的,這個(gè)值為NULL。對(duì)以太網(wǎng)設(shè)備來說,這個(gè)值由eth_type_trans初始化,它主要被流量控制代碼使用。sk_buff-hsk_buff-nhsk_buff-mac這些是指向TCP/IP各層協(xié)議頭的指針:h指向L4(傳輸層),nh指向L3(網(wǎng)絡(luò)層),mac指向L2(數(shù)據(jù)鏈路層)。
10、每個(gè)指針的類型都是一個(gè)聯(lián)合,包含多個(gè)數(shù)據(jù)結(jié)構(gòu),每一個(gè)數(shù)據(jù)結(jié)構(gòu)都表示內(nèi)核在這一層可以解析的協(xié)議。例如,h是一個(gè)包含內(nèi)核所能解析的L4協(xié)議的數(shù)據(jù)結(jié)構(gòu)的聯(lián)合。每一個(gè)聯(lián)合都有一個(gè)raw變量用于初始化,后續(xù)的訪問都是通過協(xié)議相關(guān)的變量進(jìn)行的。當(dāng)接收一個(gè)包時(shí),處理n層協(xié)議頭的函數(shù)從其下層(n-1層)收到一個(gè)緩沖區(qū),它的skb-data指向n層協(xié)議的頭。處理n層協(xié)議的函數(shù)把本層的指針(例如,L3對(duì)應(yīng)的是skb-nh指針)初始化為skb-data,因?yàn)檫@個(gè)指針(data指針)的值會(huì)在處理下一層協(xié)議時(shí)改變(skb-data將被初始化成緩沖區(qū)里的其他地址)。在處理n層協(xié)議的函數(shù)結(jié)束時(shí),在把包傳遞給n+1層的處理函
11、數(shù)前,它會(huì)把skb-data指針指向n層協(xié)議頭的末尾,這正好是n+1層協(xié)議的協(xié)議頭。當(dāng)網(wǎng)卡驅(qū)動(dòng)程序收到一個(gè)UDP數(shù)據(jù)報(bào)后,它創(chuàng)建一個(gè)結(jié)構(gòu)體structsk_buff,確保sk_buff-data成員指向的空間足夠存放收到的數(shù)據(jù)(對(duì)于數(shù)據(jù)報(bào)分片的情況,因?yàn)楸容^復(fù)雜,我們暫時(shí)忽略,我們假設(shè)一次收到的是一個(gè)完整的UDP數(shù)據(jù)報(bào))。把收到的數(shù)據(jù)全部拷貝到sk_buff-data指向的空間,然后,把skb-mac.raw指向data,此時(shí),數(shù)據(jù)報(bào)的開始位置是一個(gè)以太網(wǎng)頭,所以skb-mac.raw指向鏈路層的以太網(wǎng)頭。然后通過調(diào)用skb_pull剝掉以太網(wǎng)頭,所謂剝掉以太網(wǎng)頭,只是把data加上sizeo
12、f(structethhdr),同時(shí)len減去這個(gè)值,這樣,在邏輯上,skb已經(jīng)不包含以太網(wǎng)頭了,但通過skb-mac.raw還能找到它。這就是我們通常所說的,IP數(shù)據(jù)報(bào)被收到后,在鏈路層被剝?nèi)ヒ蕴W(wǎng)頭。sk_buff-dst這個(gè)變量在路由子系統(tǒng)中使用sk_buff-sp這個(gè)變量被IPSec協(xié)議用于跟蹤傳輸?shù)男畔k_buff-cb48這是一個(gè)“controlbuffer”,或者說是一個(gè)私有信息的存儲(chǔ)空間,由每一層自己維護(hù)并使用。它在分配sk_buff結(jié)構(gòu)時(shí)分配(它目前的大小是48字節(jié),已經(jīng)足夠?yàn)槊恳粚哟鎯?chǔ)必要的私有信息了)。在每一層中,訪問這個(gè)變量的代碼通常用宏實(shí)現(xiàn)以增強(qiáng)代碼的可讀性。例如,
13、TCP用這個(gè)變量存儲(chǔ)tcp_skb_cb結(jié)構(gòu)。下面這個(gè)宏被TCP代碼用來訪問cb變量。在這個(gè)宏里面,有一個(gè)簡(jiǎn)單的類型轉(zhuǎn)換:#defineTCP_SKB_CB(_skb)(structtcp_skb_cb*)&(_skb)-cb0)下面的例子是TCP子系統(tǒng)在收到一個(gè)分段時(shí)填充相關(guān)數(shù)據(jù)結(jié)構(gòu)的代碼:inttcp_v4_rcv(structsk_buff*skb).th=skb-h.th;TCP_SKB_CB(skb)-seq=ntohl(th-seq);TCP_SKB_CB(skb)-end_seq=(TCP_SKB_CB(skb)-seq+th-syn+th-fin+skb-len-th-doff
14、*4);TCP_SKB_CB(skb)-ack_seq=ntohl(th-ack_seq);TCP_SKB_CB(skb)-when=0;TCP_SKB_CB(skb)-flags=skb-nh.iph-tos;TCP_SKB_CB(skb)-sacked=0;.如果想要了解cb中的參數(shù)是如何被取出的,可以查看net/ipv4/tcp_output.c中的tcp_transmit_skb函數(shù)。這個(gè)函數(shù)被TCP用于向IP層發(fā)送一個(gè)分段。sk_buff-csumsk_buff-ip_summed表示校驗(yàn)和以及相關(guān)狀態(tài)標(biāo)記sk_buff-cloned一個(gè)布爾標(biāo)記,當(dāng)被設(shè)置時(shí),表示這個(gè)結(jié)構(gòu)是另一個(gè)sk
15、_buff的克隆sk_buff-pkt_type這個(gè)變量表示幀的類型,分類是由L2的目的地址來決定的。這個(gè)值在網(wǎng)卡驅(qū)動(dòng)程序中由函數(shù)eth_type_trans通過判斷目的以太網(wǎng)地址來確定。如果目的地址是FF:FF:FF:FF:FF:FF,則為廣播地址,pkt_type=PACKET_BROADCAST;如果最高位為1,則為組播地址,pkt_type=PACKET_MULTICAST;如果目的mac地址跟本機(jī)mac地址不相等,則不是發(fā)給本機(jī)的數(shù)據(jù)報(bào),pkt_type=PACKET_OTHERHOST;否則就是缺省值PACKET_HOST。/*Packettypes*/#definePACKET_
16、HOST0/*Tous*/#definePACKET_BROADCAST1/*Toall*/#definePACKET_MULTICAST2/*Togroup*/#definePACKET_OTHERHOST3/*Tosomeoneelse*/#definePACKET_OUTGOING4/*Outgoingofanytype*/sk_buff-priority這個(gè)變量描述發(fā)送或轉(zhuǎn)發(fā)包的QoS類別。如果包是本地生成的,socket層會(huì)設(shè)置priority變量。如果包是將要被轉(zhuǎn)發(fā)的,rt_tos2priority函數(shù)會(huì)根據(jù)ip頭中的Tos域來計(jì)算賦給這個(gè)變量的值。這個(gè)變量的值與DSCP(Diff
17、ServCodePoint)沒有任何關(guān)系。sk_buff-protocol這個(gè)變量是高層協(xié)議從二層設(shè)備的角度所看到的協(xié)議。典型的協(xié)議包括IP,IPV6和ARP。完整的列表在include/linux/if_ether.h中。由于每個(gè)協(xié)議都有自己的協(xié)議處理函數(shù)來處理接收到的包,因此,這個(gè)域被設(shè)備驅(qū)動(dòng)用于通知上層調(diào)用哪個(gè)協(xié)議處理函數(shù)。每個(gè)網(wǎng)絡(luò)驅(qū)動(dòng)都調(diào)用netif_rx來通知上層網(wǎng)絡(luò)協(xié)議的協(xié)議處理函數(shù),因此protocol變量必須在這些協(xié)議處理函數(shù)調(diào)用之前初始化。linux內(nèi)核是模塊化的,你可以選擇包含或者刪除某些功能。因此,sk_buff結(jié)構(gòu)里面的一些成員變量只有在內(nèi)核選擇支持某些功能時(shí)才有效,比
18、如防火墻(netfilter)或者qos:_u32nfctinfo.#ifdefCONFIG_NETFILTERstructnf_conntrack*nfct;#ifdefined(CONFIG_NF_CONNTRACK)|defined(CONFIG_NF_CONNTRACK_MODULE)structsk_buff*nfct_reasm;#endif#ifdefCONFIG_BRIDGE_NETFILTERstructnf_bridge_info*nf_bridge;#endif_u32nfmark;#endif/*CONFIG_NETFILTER*/這些變量被netfilter使用(防火
19、墻代碼),內(nèi)核編譯選項(xiàng)是“DeviceDrivers-Networkingsupport-Networkingoptions-Networkpacketfiltering”和兩個(gè)子選項(xiàng)“Networkpacketfilteringdebugging”和“BridgedIP/ARPpacketsfiltering”#ifdefCONFIG_NET_SCHED_u16tc_index;#ifdefCONFIG_NET_CLS_ACT_u16tc_verd;#endif#endif這兩個(gè)變量被流量控制代碼使用。tc_index只有在編譯時(shí)定義了CONFIG_NET_SCHED符號(hào)才有效;tc_ver
20、d只有在編譯時(shí)定義了CONFIG_NET_CLS_ACT符號(hào)才有效。這兩個(gè)符號(hào)可以通過選擇特定的編譯選項(xiàng)來定義:NetworkingNetworkingoptionsQoSand/orfairqueueing*QoSand/orfairqueueing*ActionsQoS選項(xiàng)不能被編譯成內(nèi)核模塊。原因就是,內(nèi)核編譯之后,由某個(gè)選項(xiàng)所控制的數(shù)據(jù)結(jié)構(gòu)是不能動(dòng)態(tài)變化的。一般來說,如果某個(gè)選項(xiàng)會(huì)修改內(nèi)核數(shù)據(jù)結(jié)構(gòu)(比如說,在sk_buff里面增加一個(gè)項(xiàng)tc_index),那么,包含這個(gè)選項(xiàng)的組件就不能被編譯成內(nèi)核模塊。你可能經(jīng)常需要查找是哪個(gè)makemenuconfig編譯選項(xiàng)或者變種定義了某個(gè)#if
21、def標(biāo)記,以便理解內(nèi)核中包含的某段代碼。在2.6內(nèi)核中,最快的,查找它們之間關(guān)聯(lián)關(guān)系的方法,就是查找分布在內(nèi)核源代碼樹中的kconfig文件中是否定義了相應(yīng)的符號(hào)(每個(gè)目錄都有一個(gè)這樣的文件)。在2.4內(nèi)核中,你需要查看Documentation/Configure.help文件。QualityofService(QoS)服務(wù)質(zhì)量Skb分配和釋放流程Skb的分配釋放流程涉及到的主要內(nèi)容有:網(wǎng)卡環(huán)的實(shí)現(xiàn),skb在協(xié)議棧的傳送流程,slab的實(shí)現(xiàn)。每個(gè)部分的內(nèi)容都很多,本文檔忽略實(shí)現(xiàn)的細(xì)節(jié),目的是給出一個(gè)基本的流程。首先從網(wǎng)卡驅(qū)動(dòng)層開始分析,以e1000e驅(qū)動(dòng)為例,如圖1所示:圖1網(wǎng)卡對(duì)skb分配和釋放R1:內(nèi)核分配skb,并將其加入rx_ring,用于接收數(shù)據(jù)包;R2:網(wǎng)卡接收網(wǎng)絡(luò)數(shù)據(jù),并將數(shù)據(jù)寫入R1中分配的skb;R3:內(nèi)核接收R2中的skb,此時(shí)R2中的skb已經(jīng)脫離rx_ring,最后內(nèi)核會(huì)執(zhí)行R1操作,以補(bǔ)充skb。T1:內(nèi)核將要發(fā)送的skb寫入環(huán)tx_ring;T2:網(wǎng)卡發(fā)送T1中寫入的skb;T3:內(nèi)核釋放已經(jīng)發(fā)送的skb。補(bǔ)充說明:1)其中_alloc_skb(),e1000_receive_skb
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度毛竹砍伐與生態(tài)補(bǔ)償基金管理合同4篇
- 2025年物流概述合同:國際物流Ⅱ全程服務(wù)及風(fēng)險(xiǎn)管理2篇
- 二零二五年度城市綠化帶植被恢復(fù)與景觀提升合同4篇
- 2025年消防給水系統(tǒng)施工安全協(xié)議范本下載大全3篇
- 2025年物流企業(yè)對(duì)司機(jī)全面服務(wù)合同范本3篇
- 2025版張偉與李芳離婚協(xié)議書附帶房產(chǎn)及車輛分割條款4篇
- 2025年教育貸款委托借款合同范本3篇
- 二零二五年度旅行社旅游目的地投資合作合同4篇
- 2025年度輪胎銷售團(tuán)隊(duì)激勵(lì)與績效考核合同4篇
- 二零二五年度文化創(chuàng)意產(chǎn)業(yè)抵押擔(dān)保合同3篇
- 申根簽證申請(qǐng)表模板
- 企業(yè)會(huì)計(jì)準(zhǔn)則、應(yīng)用指南及附錄2023年8月
- 諒解書(標(biāo)準(zhǔn)樣本)
- 2022年浙江省事業(yè)編制招聘考試《計(jì)算機(jī)專業(yè)基礎(chǔ)知識(shí)》真題試卷【1000題】
- 認(rèn)養(yǎng)一頭牛IPO上市招股書
- GB/T 3767-2016聲學(xué)聲壓法測(cè)定噪聲源聲功率級(jí)和聲能量級(jí)反射面上方近似自由場(chǎng)的工程法
- GB/T 23574-2009金屬切削機(jī)床油霧濃度的測(cè)量方法
- 西班牙語構(gòu)詞.前后綴
- 動(dòng)物生理學(xué)-全套課件(上)
- 河北省衡水市各縣區(qū)鄉(xiāng)鎮(zhèn)行政村村莊村名居民村民委員會(huì)明細(xì)
- DB32-T 2665-2014機(jī)動(dòng)車維修費(fèi)用結(jié)算規(guī)范-(高清現(xiàn)行)
評(píng)論
0/150
提交評(píng)論