ตัวกรองแพ็กเก็ต Android

ตัวกรองแพ็กเก็ต Android (APF) ช่วยให้เฟรมเวิร์กควบคุมตรรกะการกรองแพ็กเก็ตฮาร์ดแวร์ขณะรันไทม์ได้ ซึ่งช่วยให้ระบบประหยัดพลังงานด้วยการทิ้งแพ็กเก็ตในฮาร์ดแวร์ และช่วยให้เฟรมเวิร์ก Android เปลี่ยนกฎการกรองขณะรันไทม์ตามสภาพเครือข่ายได้

ภาพรวมของ APF

APF ประกอบด้วยองค์ประกอบหลัก 2 ส่วน ได้แก่

  • โปรแกรมแปลภาษา APF ทำงานบนฮาร์ดแวร์เครือข่าย (โดยทั่วไปคือชิปเซ็ต Wi-Fi) โปรแกรมแปลภาษา APF จะเรียกใช้ไบต์โค้ด APF ในแพ็กเก็ตที่ได้รับจากฮาร์ดแวร์และตัดสินใจว่าจะยอมรับ ทิ้ง หรือตอบกลับแพ็กเก็ตเหล่านั้น
  • โค้ดการสร้างโปรแกรม APF จะทำงานบน CPU หลัก โค้ดจะสร้างและอัปเดตโปรแกรม APF ตามสถานะเครือข่ายและอุปกรณ์

เมธอด Wi-Fi HAL ช่วยให้เฟรมเวิร์ก Android ติดตั้งโปรแกรม APF ไปป์ไลน์ และอ่านตัวนับปัจจุบันได้ โมดูล Mainline สแต็กเครือข่ายสามารถอัปเดตไบต์โค้ดของโปรแกรม APF ได้ทุกเมื่อขณะที่ APF ทำงานอยู่

มีการใช้ตัวกรอง APF หลายรายการ ตัวอย่างเช่น APF มีตัวกรองเพื่อทิ้งอีเทอร์ประเภทที่ไม่อนุญาต กรองแพ็กเก็ตการโฆษณาเราเตอร์ IPv6 (RA) กรองการรับส่งข้อมูลมัลติแคสต์และบรอดแคสต์หากไม่ได้ล็อกมัลติแคสต์ไว้ ทิ้งแพ็กเก็ต DHCP สำหรับโฮสต์อื่นๆ และทิ้งแพ็กเก็ตโปรโตคอลการแก้ไขที่อยู่ (ARP) และแพ็กเก็ตการค้นหาเพื่อนบ้าน (ND) ที่ไม่ได้รับอนุญาต หากเฟิร์มแวร์รองรับ APFv6 ApfFilter จะสร้างกฎเพื่อตอบกลับประเภทแพ็กเก็ตทั่วไปด้วย ซึ่งปกติแล้วจะต้องทำให้ CPU ตื่นขึ้นเพื่อตอบกลับ เช่น การค้นหา ARP และการค้นหา NS รายการตัวกรองทั้งหมดจะระบุไว้ใน ApfFilter

เนื่องจากโค้ดการสร้างโปรแกรม APF เป็นส่วนหนึ่งของโมดูลสแต็กเครือข่าย คุณจึงใช้ [การอัปเดตหลักรายเดือนเพื่อเพิ่มตัวกรองใหม่และอัปเดตตรรกะการกรองได้

การแก้ไข APF

รายการต่อไปนี้อธิบายประวัติการแก้ไขของ APF

  • APFv6: เวอร์ชันนี้เปิดตัวใน Android 15 โดยรองรับการกรองแพ็กเก็ต มีตัวนับสำหรับการแก้ไขข้อบกพร่องและเมตริก ตลอดจนรองรับการส่งแพ็กเก็ต
  • APFv4: เวอร์ชันนี้เปิดตัวใน Android 10 โดยรองรับการกรองแพ็กเก็ตและมีตัวนับสำหรับการแก้ไขข้อบกพร่องและเมตริก
  • APFv2: เปิดตัวใน Android 7 เวอร์ชันนี้รองรับการกรองแพ็กเก็ต

การผสานรวม APF

API ของ APF ระหว่างโปรแกรมแปลภาษา APF กับฮาร์ดแวร์จะกำหนดไว้ใน apf_interpreter.h (APFv4, APFv6) โค้ดเฟิร์มแวร์ Wi-Fi จะเรียกใช้ accept_packet() ใน APFv4 หรือ apf_run() ใน APFv6 เพื่อพิจารณาว่าควรทิ้งแพ็กเก็ตหรือไม่ (ค่าที่แสดงผลเป็น 0) หรือส่งไปยังตัวประมวลผลแอป (ค่าที่แสดงผลไม่ใช่ 0) หากต้องส่งแพ็กเก็ต apf_run() จะแสดงผลเป็น 0 ด้วยเนื่องจากไม่จำเป็นต้องส่งแพ็กเก็ตไปยังโปรแกรมประมวลผลแอป หากเฟิร์มแวร์รองรับ APFv6 จะต้องติดตั้งใช้งาน API ของ apf_allocate_buffer() และ apf_transmit_buffer() โปรแกรมแปลภาษา APF จะเรียกใช้ API 2 รายการนี้ในระหว่างตรรกะการส่งแพ็กเก็ต คำสั่ง APF มีความยาวแบบไม่ตายตัว คำสั่งแต่ละรายการมีความยาวอย่างน้อย 1 ไบต์ รหัสคำสั่ง APF ได้รับการกำหนดไว้ใน apf.h สำหรับ APFv4 และแทรกอยู่ภายใน apf_interpreter.c สำหรับ APFv6

APF ต้องใช้หน่วยความจําเฉพาะ หน่วยความจํานี้ใช้ทั้งสําหรับโปรแกรม APF เองและการจัดเก็บข้อมูล และชิปเซ็ตต้องไม่ล้างหรือเขียนหน่วยความจํา ยกเว้นผ่านเมธอด APF HAL บิตโค้ด APF ใช้พื้นที่เก็บข้อมูลเพื่อจัดเก็บตัวนับสำหรับแพ็กเก็ตที่ยอมรับและทิ้ง คุณสามารถอ่านภูมิภาคข้อมูลได้จากเฟรมเวิร์ก Android คำสั่ง APF ใช้หน่วยความจำอย่างมีประสิทธิภาพ แต่การประหยัดพลังงานและการเพิ่มประสิทธิภาพการทำงานให้สูงสุดต้องใช้กฎการกรองแบบไดนามิกที่ซับซ้อน ความซับซ้อนนี้ทำให้ต้องมีการจัดสรรหน่วยความจำส่วนหนึ่งในชิปเซ็ต ข้อกำหนดหน่วยความจำขั้นต่ำสำหรับ APFv4 คือ 1,024 ไบต์ ส่วน APFv6 ต้องใช้ 2,048 ไบต์ อย่างไรก็ตาม เราขอแนะนําอย่างยิ่งให้จัดสรร 4096 ไบต์สําหรับ APFv6 เพื่อให้ได้ประสิทธิภาพสูงสุด ต้องคอมไพล์โปรแกรมตีความ APF เป็นเฟิร์มแวร์ ทั้งโปรแกรมตีความ APFv4 และ APFv6 ได้รับการเพิ่มประสิทธิภาพสำหรับขนาดโค้ด ภายใต้สถาปัตยกรรม arm32 โปรแกรมตีความ APFv4 ที่คอมไพล์แล้วมีขนาดประมาณ 1.8 KB ส่วนโปรแกรมตีความ APFv6 ที่ซับซ้อนกว่าซึ่งมีฟีเจอร์เพิ่มเติม (เช่น การรองรับการตรวจสอบผลรวมในตัวและโค้ดการขยายรหัส DNS ในตัว) จะมีขนาดประมาณ 4 KB

ตัวกรอง APF สามารถทำงานร่วมกับตัวกรองอื่นๆ ของผู้ให้บริการชิปเซ็ตภายในเฟิร์มแวร์ได้ ผู้ให้บริการชิปเซ็ตสามารถเลือกที่จะเรียกใช้ตรรกะการกรองก่อนหรือหลังกระบวนการกรอง APF หากมีการทิ้งแพ็กเก็ตก่อนที่จะถึงตัวกรอง APF ตัวกรอง APF จะไม่ประมวลผลแพ็กเก็ต

เมื่อเปิด APF เฟิร์มแวร์ต้องให้สิทธิ์เข้าถึงทั้งแพ็กเก็ตแก่ตัวกรอง APF ไม่ใช่แค่ส่วนหัว เพื่อให้ตัวกรอง APF ทำงานได้อย่างถูกต้อง

ตัวอย่างโปรแกรม APF

ApfTest และ ApfFilterTest มีโปรแกรมทดสอบตัวอย่างที่แสดงวิธีการทำงานของตัวกรอง APF แต่ละรายการ หากต้องการศึกษาโปรแกรมที่สร้างขึ้นจริง ให้แก้ไขเคสทดสอบเพื่อพิมพ์โปรแกรมเป็นสตริงฐาน 16

โฟลเดอร์ testdata มีโปรแกรม APFv4 ตัวอย่างสำหรับตัวกรอง APF RA โฟลเดอร์ samples มียูทิลิตี Python ที่สร้างโปรแกรมการโอน APFv6 โปรดดูรายละเอียดเพิ่มเติมในเอกสารประกอบในไฟล์ยูทิลิตี Python

แก้ไขข้อบกพร่อง APF

หากต้องการตรวจสอบว่าเปิดใช้ APF ในอุปกรณ์หรือไม่ ให้แสดงโปรแกรมปัจจุบัน แสดงตัวนับปัจจุบัน และเรียกใช้คำสั่ง adb shell dumpsys network_stack ต่อไปนี้เป็นตัวอย่างของคำสั่งนี้

adb shell dumpsys network_stack
......
IpClient.wlan0 APF dump:
    Capabilities: ApfCapabilities{version: 4, maxSize: 4096, format: 1}
......
    Last program:
      6bfcb03a01b8120c6b9494026506006b907c025e88a27c025988a47c025488b87c024f88cd7c024a88e17c024588e384004408066a0e6bdca4022b000600010800060412147a1e016bd884021f00021a1c6b8c7c021c0000686bd4a402080006ffffffffffff6a266bbca402010004c0a801eb6bf87401f6120c84005f08000a17821f1112149c00181fffab0d2a108211446a3239a20506c2fc393057dd6bf47401cb0a1e52f06bac7c01c600e06bb41a1e7e000001b9ffffffff6bb07e000001aec0a801ff6be868a4019a0006ffffffffffff6bb874019b6bf07401907c001386dd686bd0a4017d0006ffffffffffff6bc874017e0a147a0e3a6b980a267c017000ff6be07401650a366ba87c016200858219886a26a2050fff02000000000000000000000000006ba4740146aa0e84013700e6aa0f8c0130006068a4011b000f33330000000184c9b26aed4c86dd606a12a2f02600b03afffe8000000000000086c9b2fffe6aed4cff02000000000000000000000000000186006a3aa2e9024000123c92e4606a3ea2d70800000000000000006a56a2ce04030440c01a5a92c9601a5e92c4606a62a2bb04000000006a66a2a6102401fa00049c048400000000000000006a76a29d04030440c01a7a9298601a7e9293606c0082a28904000000006c0086a27310fdfd9ed67950000400000000000000006c0096a2690418033c001a9a9264606c009ea24e102401fa00049c048000000000000000006c00aea24404180330001ab2923f606c00b6a22910fdfd9ed67950000000000000000000006c00c6a21f04190300001aca921a606c00cea20410fdfd9ed67950000400000000000000016bc472086be4b03a01b87206b03a01b87201
    APF packet counters:
      TOTAL_PACKETS: 469
      PASSED_DHCP: 4
      PASSED_IPV4: 65
      PASSED_IPV6_NON_ICMP: 64
      PASSED_IPV4_UNICAST: 64
      PASSED_IPV6_ICMP: 223
      PASSED_IPV6_UNICAST_NON_ICMP: 6
      PASSED_ARP_UNICAST_REPLY: 4
      PASSED_NON_IP_UNICAST: 1
      DROPPED_RA: 4
      DROPPED_IPV4_BROADCAST_ADDR: 7
      DROPPED_IPV4_BROADCAST_NET: 27

ผลลัพธ์ของคำสั่ง adb shell dumpsys network_stack ตัวอย่างนี้ประกอบด้วยข้อมูลต่อไปนี้

  • ApfCapabilities{version: 4, maxSize: 4096, format: 1}: หมายความว่าชิป Wi-Fi รองรับ APF (เวอร์ชัน 4)
  • Last program: ส่วนนี้เป็นไบนารีของโปรแกรม APF ที่ติดตั้งล่าสุดในรูปแบบสตริงฐาน 16
  • APF packet counters: ส่วนนี้แสดงจำนวนแพ็กเก็ตที่ APF ส่งหรือทิ้ง และเหตุผลที่เฉพาะเจาะจง

หากต้องการถอดรหัสและถอดประกอบโค้ดเป็นภาษาแอสเซมเบลที่มนุษย์อ่านได้ ให้ใช้เครื่องมือ apf_disassembler หากต้องการคอมไพล์ไบนารีที่เรียกใช้งานได้ ให้เรียกใช้คำสั่ง m apf_disassembler ต่อไปนี้เป็นตัวอย่างวิธีใช้เครื่องมือ apf_disassembler

echo "6bfcb03a01b8120c6b949401e906006b907c01e288a27c01dd88a47c01d888b87c01d388cd7c01ce88e17c01c988e384004008066a0e6bdca401af000600010800060412147a1e016bd88401a300021a1c6b8c7c01a00000686bd4a4018c0006ffffffffffff1a266bc07c018900006bf874017e120c84005408000a17821f1112149c00181fffab0d2a108211446a3239a205065a56483ac3146bf47401530a1e52f06bac7c014e00e06bb41a1e7e00000141ffffffff6be868a4012d0006ffffffffffff6bb874012e6bf07401237c001386dd686bd0a401100006ffffffffffff6bc87401110a147a0d3a6b980a267c010300ff6be072f90a366ba87af8858218886a26a2040fff02000000000000000000000000006ba472ddaa0e82d0aeaa0f8c00c9025868a2b60f5a56483ac3140c8126f3895186dd606a12a28b2600783afffe8000000000000002005efffe00026fff02000000000000000000000000000186006a3aa284024000123c94007d02586a3ea2700800000000000000006a56a26704190500001a5a94006002586a5ea23b2020014860486000000000000000006464200148604860000000000000000000646a7ea23204030440c01a8294002b02581a8694002402586c008aa21a04000000006c008ea204102a0079e10abcf60500000000000000006bc472086be4b03a01b87206b03a01b87201" | out/host/linux-x86/bin/apf_disassembler
       0: li    r1, -4
       2: lddw  r0, [r1+0]
       3: add   r0, 1
       5: stdw  r0, [r1+0]
       6: ldh   r0, [12]
       8: li    r1, -108
      10: jlt   r0, 0x600, 504
      15: li    r1, -112
      17: jeq   r0, 0x88a2, 504
      22: jeq   r0, 0x88a4, 504
      27: jeq   r0, 0x88b8, 504
      32: jeq   r0, 0x88cd, 504
      37: jeq   r0, 0x88e1, 504
      42: jeq   r0, 0x88e3, 504
      47: jne   r0, 0x806, 116
......

หากต้องการตรวจสอบผลลัพธ์ APF ออฟไลน์ ให้ใช้เครื่องมือ apf_run หากต้องการคอมไพล์ไบนารีที่เรียกใช้งานได้ ให้เรียกใช้คำสั่ง m apf_run เครื่องมือ apf_runรองรับทั้งโปรแกรมตีความ APFv4 และ APFv6

ต่อไปนี้เป็นคู่มือสําหรับคําสั่ง apf_run โดยค่าเริ่มต้น คำสั่ง apf_run จะทำงานในอินเทอร์พรีเตอร์ APFv4 การส่งอาร์กิวเมนต์ --v6 ไปยัง apf_run จะช่วยให้โปรแกรมทำงานกับโปรแกรมล่าม APFv6 ได้ ส่วนอาร์กิวเมนต์อื่นๆ ทั้งหมดจะใช้ได้กับทั้ง APFv4 และ APFv6

apf_run --help
Usage: apf_run --program <program> --pcap <file>|--packet <packet> [--data <content>] [--age <number>] [--trace]
  --program    APF program, in hex.
  --pcap       Pcap file to run through program.
  --packet     Packet to run through program.
  --data       Data memory contents, in hex.
  --age        Age of program in seconds (default: 0).
  --trace      Enable APF interpreter debug tracing
  --v6         Use APF v6
  -c, --cnt    Print the APF counters
  -h, --help   Show this message.

ต่อไปนี้คือตัวอย่างการส่งแพ็กเก็ต 1 รายการไปยัง APF เพื่อตรวจสอบว่าระบบจะทิ้งหรือส่งแพ็กเก็ตได้หรือไม่

หากต้องการแสดงแพ็กเก็ตดิบในรูปแบบสตริงไบนารีฐานสิบหก ให้ใช้ตัวเลือก --packet หากต้องการระบุสตริงไบนารีฐาน 16 ของเขตข้อมูล ซึ่งใช้เพื่อจัดเก็บตัวนับ APF ให้ใช้ --data option เนื่องจากตัวนับแต่ละรายการมีความยาว 4 ไบต์ พื้นที่ข้อมูลจึงต้องยาวพอที่จะไม่เกิดบัฟเฟอร์ที่ล้น

out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b9494010c06006b907c010588a27c010088a47c00fb88b87c00f688cd7c00f188e17c00ec88e384003908066a0e6bdca2d40600010800060412147a18016bd882ca021a1c6b8c7ac900686bd4a2b706ffffffffffff6a266bbca2b204c0a814656bf872a8120c84005808000a17821e1112149c00171fffab0d2a108210446a3239a204064651dbcc88ff6bf4727e0a1e52f06bac7a7be06bb41a1e7e0000006effffffff6bb07e00000063c0a814ff6be868a25106ffffffffffff6bb872536bf072497c001086dd686bd0a23806ffffffffffff6bc8723a0a147a0b3a6b980a267a2eff6be072240a366ba87a23858218886a26a2040fff02000000000000000000000000006ba472086be4b03a01b87206b03a01b87201 --packet 5ebcd79a8f0dc244efaab81408060001080006040002c244efaab814c0a8ca1e5ebcd79a8f0d --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Packet passed
Data: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000001

หากต้องการตรวจสอบผลลัพธ์ APF กับไฟล์ pcap ที่ถ่ายโดย tcpdump ให้ใช้apf_runคำสั่งต่อไปนี้

out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b989401df06006b947c01d888a27c01d388a47c01ce88b87c01c988cd7c01c488e17c01bf88e384004408066a0e6bdca401a5000600010800060412147a1e016bd884019900021a1c6b907c01960000686bd4a401820006ffffffffffff6a266bc0a4017b0004c0a82b056bf874017084005f08000a17821f1112149c00181fffab0d2a108211446a3239a20506fabe589435936bf47401470a1e52f06bb07c014200e06bb81a1e7e00000135ffffffff6bb47e0000012ac0a82bff6be868a401160006ffffffffffff6bbc7401176bf074010c7c001086dd686bd0a2fb06ffffffffffff6bcc72fd0a147a0b3a6b9c0a267af1ff6be072e70a366bac7ae6858218886a26a2040fff02000000000000000000000000006ba872cbaa0e82be8eaa0f8c00b7025868a2a40ffabe5894359352a9874d08aa86dd606a12a2792600583afffe80000000000000f7d4e8ccd81ddb43fe80000000000000f8be58fffe94359386006a3aa272024108123c94006b02586a3ea25e0800000000000000006a56a25504030440c01a5a94004e02581a5e94004702586a62a23e04000000006a66a229102409891f9a26ae6d00000000000000006a76a22004190300001a7a94001902586a7ea204102409891f9a26ae6dba98e781ca9ef9ba6bc872086be4b03a01b87206b03a01b87201 --pcap apf.pcap --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
37 packets dropped
1733 packets passed
Data: 00000000000000000000000000000000000000000200000005000000000000000000000002000000000000001b000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000689000000000000003c00000000000000000000000000000000000006ea

หากต้องการทดสอบความสามารถในการส่ง APFv6 ให้ใช้คำสั่ง apf_run ดังนี้

$ apf_run --program 75001001020304050608060001080006040002AA300E3CAA0FBA06AA09BA07AA08BA086A01BA09120C84006F08066A0EA30206000108000604032B12147A27017A020203301A1C820200032D68A30206FFFFFFFFFFFF020E1A267E000000020A000001032C020B1A267E000000020A000001032CAB24003CCA0606CB0306CB090ACB0306C60A000001CA0606CA1C04AA
0A3A12AA1AAA25FFFF032F020D120C84001708000A1782100612149C00091FFFAB0D2A10820207032A02117C000E86DD68A30206FFFFFFFFFFFF021603190A1482020002187A023A02120A36820285031F8216886A26A2020FFF020000000000000000000000000003200214 --packet FFFFFFFFFFFF112233445566080600010800060400011122334455660A0000020000000000000A0000
01 --data 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 --age 0 --v6 --trace
      R0       R1       PC  Instruction
-------------------------------------------------
       0        0        0: data        16, 01020304050608060001080006040002
       0        0       19: debugbuf    size=3644
       0        0       23: ldm         r0, m[15]
       0        0       25: stdw        counter=6, r0
       0        0       27: ldm         r0, m[9]
       0        0       29: stdw        counter=7, r0
       0        0       31: ldm         r0, m[8]
 134d811        0       33: stdw        counter=8, r0
 134d811        0       35: li          r0, 1
       1        0       37: stdw        counter=9, r0
       1        0       39: ldh         r0, [12]
     806        0       41: jne         r0, 0x806, 157
     806        0       46: li          r0, 14
       e        0       48: jbseq       r0, 0x6, 59, 000108000604
       e        0       59: ldh         r0, [20]
       1        0       61: jeq         r0, 0x1, 103
       1        0      103: ldw         r0, [38]
 a000001        0      105: jeq         r0, 0xa000001, 116
 a000001        0      116: allocate    60
 a000001        0      120: pktcopy     src=6, len=6
 a000001        0      123: datacopy    src=3, len=6
 a000001        0      126: datacopy    src=9, len=10
 a000001        0      129: datacopy    src=3, len=6
 a000001        0      132: write       0x0a000001
 a000001        0      137: pktcopy     src=6, len=6
 a000001        0      140: pktcopy     src=28, len=4
 a000001        0      143: ldm         r0, m[10]
      2a        0      145: add         r0, 18
      3c        0      147: stm         r0, m[10]
      3c        0      149: transmit    ip_ofs=255
      3c        0      153: drop        counter=47
Packet dropped
Data: 00000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000100000011d8340100000000000000000000000000000000000000000100000078563412
transmitted packet: 112233445566010203040506080600010800060400020102030405060a0000011122334455660a000002000000000000000000000000000000000000

เมื่อคุณใช้พารามิเตอร์ --trace เครื่องมือ apf_run จะแสดงผลลัพธ์โดยละเอียดของแต่ละขั้นตอนในการดำเนินการของโปรแกรมล่าม ซึ่งเป็นประโยชน์สำหรับการแก้ไขข้อบกพร่อง ในตัวอย่างนี้ เราจะป้อนแพ็กเก็ตการค้นหา ARP ลงในโปรแกรม APF เอาต์พุตแสดงให้เห็นว่าระบบทิ้งการค้นหา ARP แต่สร้างแพ็กเก็ตตอบกลับ รายละเอียดของแพ็กเก็ตที่สร้างขึ้นนี้จะแสดงในส่วน transmitted packet

ปัญหาการผสานรวมที่พบได้ทั่วไป

ส่วนนี้จะไฮไลต์ปัญหาที่พบบ่อยหลายประการระหว่างการผสานรวม APF ดังนี้

  • การล้างพื้นที่ข้อมูลโดยไม่คาดคิด: หน่วยความจำ APF ต้องสงวนไว้สำหรับ APF ทั้งหมด โดยมีเพียงรหัสอินเทอร์พรีเตอร์หรือรหัสเฟรมเวิร์ก (ผ่าน HAL API) เท่านั้นที่ได้รับอนุญาตให้แก้ไขพื้นที่หน่วยความจำ APF
  • ปัญหาการติดตั้งโปรแกรม APF ขนาด X ไบต์ (X <= maxLen): เฟิร์มแวร์ต้องรองรับการอ่านหรือเขียนโปรแกรมที่มีความยาวสูงสุด maxLen โดยไม่เกิดข้อผิดพลาด ขัดข้อง หรือตัดตอน การเขียนต้องไม่เปลี่ยนแปลงไบต์ใดๆ ระหว่าง X ถึง maxLen
  • การติดตั้งใช้งาน APF ในโค้ดไดรเวอร์: คุณควรติดตั้งใช้งาน APF ในเฟิร์มแวร์เท่านั้น ไม่ใช่ในโค้ดไดรเวอร์ มิเช่นนั้นจะไม่มีประโยชน์ในการประหยัดพลังงานเนื่องจาก CPU ต้องตื่นขึ้นเพื่อประมวลผลแพ็กเก็ต
  • ค่า filter_age หรือ filter_age_16384th ไม่ถูกต้อง: ต้องส่งค่า filter_age (APFv4) และ filter_age_16384th (APFv6) ไปยังฟังก์ชัน accept_packet() และ apf_run() อย่างถูกต้อง ดูรายละเอียดเกี่ยวกับการคำนวณ filter_age_16384th ได้ในเอกสารประกอบใน apf_interpreter.h
  • ไม่ได้เปิดใช้ APF เมื่อจำเป็น: คุณต้องเปิดใช้ APF เมื่อหน้าจอปิดอยู่และลิงก์ Wi-Fi ไม่มีการใช้งานหรือมีการรับส่งข้อมูลต่ำกว่า 10 Mbps
  • แพ็กเก็ตที่ถูกตัดให้สั้นลงซึ่งส่งไปยัง accept_packet() หรือ apf_run(): แพ็กเก็ตแบบยูนิแคสต์ บรอดแคสต์ และมัลติแคสต์ทั้งหมดที่ส่งไปยัง accept_packet() หรือ apf_run() ต้องสมบูรณ์ การส่งแพ็กเก็ตที่ตัดให้สั้นลงใน APF ไม่ถูกต้อง

การทดสอบ APF

ตั้งแต่ Android 15 เป็นต้นไป Android จะมีทั้งกรณีทดสอบ CTS สำหรับอุปกรณ์เครื่องเดียวและหลายเครื่องสำหรับการผสานรวมตัวกรอง APF และโปรแกรมแปลภาษา APF เพื่อให้มั่นใจว่า APF ทำงานได้อย่างถูกต้อง รายละเอียดวัตถุประสงค์ของข้อเท็จจริงการทดสอบแต่ละรายการมีดังนี้

  • ApfFilter และ apf_interpreter การทดสอบการผสานรวม: ยืนยันว่า ApfFilter สร้างไบต์โค้ดที่ถูกต้อง และ apf_interpreter ดำเนินการกับโค้ดอย่างถูกต้องเพื่อให้ได้ผลลัพธ์ตามที่คาดไว้
  • CTS อุปกรณ์เดียวของ APF: ใช้อุปกรณ์เครื่องเดียวเพื่อทดสอบฟังก์ชันการทำงานของ APF ในชิปเซ็ต Wi-Fi ยืนยันว่า
    • APF จะเปิดขึ้นเมื่อหน้าจอปิดอยู่และการรับส่งข้อมูล Wi-Fi ต่ำกว่า 10 Mbps
    • มีการประกาศความสามารถของ APF อย่างถูกต้อง
    • การดำเนินการอ่านและเขียนในภูมิภาคหน่วยความจำ APF สำเร็จ และไม่มีการแก้ไขภูมิภาคหน่วยความจำโดยไม่คาดคิด
    • ระบบส่งอาร์กิวเมนต์ไปยัง accept_packet() หรือ apf_run() อย่างถูกต้อง
    • เฟิร์มแวร์ที่ผสานรวมกับ APFv4/APFv6 อาจทิ้งแพ็กเก็ต
    • เฟิร์มแวร์ที่ผสานรวมกับ APFv6 จะตอบกลับแพ็กเก็ตได้
  • CTS หลายอุปกรณ์ของ APF: ใช้อุปกรณ์ 2 เครื่อง (เครื่องส่ง 1 เครื่อง เครื่องรับ 1 เครื่อง) เพื่อทดสอบลักษณะการกรองของ APF ระบบจะสร้างแพ็กเก็ตประเภทต่างๆ ฝั่งผู้ส่ง และทดสอบว่าระบบทิ้ง ผ่าน หรือตอบกลับแพ็กเก็ตอย่างถูกต้องหรือไม่ตามกฎที่กำหนดค่าไว้ใน ApfFilter

วิธีการทดสอบการผสานรวมเพิ่มเติม

นอกจากนี้ เราขอแนะนําอย่างยิ่งให้ผู้ให้บริการชิปเซ็ตรวมการทดสอบ APF ไว้ในชุดทดสอบการผสานรวม Wi-Fi ของเฟิร์มแวร์

การผสานรวมการทดสอบ APF เข้ากับชุดทดสอบการผสานรวม Wi-Fi ของเฟิร์มแวร์มีความสําคัญต่อการยืนยันฟังก์ชันการทํางานของ APF ที่ถูกต้องในสถานการณ์การเชื่อมต่อ Wi-Fi ที่ซับซ้อน เช่น สถานการณ์การเชื่อมต่อ Wi-Fi แบบพักก่อนหรือโรมมิง ดูวิธีการโดยละเอียดเกี่ยวกับการทดสอบการผสานรวมได้ที่ส่วนต่อไปนี้

สิ่งที่ต้องมีก่อน

เมื่อทำการทดสอบการผสานรวม ให้ทำดังนี้

  • ต้องเปิดใช้ APF ในทุกกรณีทดสอบการผสานรวม (เช่น การโรมมิง การทำก่อนหยุดพัก)
  • ล้างหน่วยความจํา APF เมื่อเริ่มการทดสอบแต่ละครั้ง
  • ติดตั้งหรือติดตั้งโปรแกรม APF อีกครั้งทุก 5 นาทีในระหว่างการทดสอบ

สถานการณ์การทดสอบ

APF ต้องทำงานอยู่ตลอดการทดสอบการผสานรวม เอกสารนี้มีโปรแกรม APF 2 รายการที่ติดตั้งได้ในระหว่างการทดสอบ โปรแกรมอยู่ในรูปแบบสตริงฐานสิบหก และผู้ทดสอบต้องแปลงสตริงฐานสิบหกเป็นไบนารีและติดตั้งลงในเฟิร์มแวร์เพื่อให้apf_interpreterเรียกใช้โปรแกรมได้ ในระหว่างการทดสอบการผสานรวม ผู้ทดสอบควรส่งแพ็กเก็ตที่คาดว่าจะทริกเกอร์ตรรกะการกรองในโปรแกรม 1 และโปรแกรม 2

โปรแกรม APF 1

เมื่อหน้าจออุปกรณ์เปิดอยู่ ให้ติดตั้ง APF program 1 โปรแกรมนี้จะทิ้งแพ็กเก็ตที่ไม่เป็นอันตรายซึ่งไม่ส่งผลต่อฟังก์ชันการทำงานของอุปกรณ์ ระบบจะใช้แพ็กเก็ตเหล่านี้เพื่อทดสอบว่า APF กรองการเข้าชมเครือข่ายอย่างถูกต้องหรือไม่

ตรรกะโปรแกรม APF 1 มีดังนี้

  1. ตัวนับการลดลงและเพิ่มขึ้น
    1. ค่า EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. แพ็กเก็ตการค้นพบหรือคำขอ DHCP ของ IPv4
    3. แพ็กเกต RS
  2. ผ่านและเพิ่มตัวนับ: แพ็กเก็ตอื่นๆ ทั้งหมด

โค้ด 1 ไบต์ของโปรแกรม APF มีดังนี้

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
โปรแกรม APF 2

เมื่อหน้าจออุปกรณ์ปิดอยู่ ให้ติดตั้ง APF program 2 โปรแกรมนี้จะกรองแพ็กเก็ตทั้งหมดที่โปรแกรม APF 1 กรองออก รวมถึงแพ็กเก็ตคำขอ ping หากต้องการยืนยันว่าติดตั้ง APF program 2 อย่างถูกต้อง ให้ส่งแพ็กเก็ต ping ไปยังอุปกรณ์ทดสอบ

ตรรกะโปรแกรม APF 2 มีดังนี้

  1. ตัวนับการลดลงและเพิ่มขึ้น
    1. ค่า EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. แพ็กเก็ตการค้นพบหรือคำขอ DHCP ของ IPv4
    3. แพ็กเกต RS
  2. ลดลงและเพิ่มตัวนับ: แพ็กเก็ตคำขอ ping ICMP
  3. ส่งและเพิ่มตัวนับ: แพ็กเก็ตอื่นๆ ทั้งหมด

โค้ด 2 ไบต์ของโปรแกรม APF มีดังนี้

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C007488A27C006F88A47C006A88B87C006588CD7C006088E17C005B88E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE87234120C84000E86DD0A1482093A0A368204856BE0721F120C84001008000A17820B01AB0D220E8204086BE472086BDCB03A01B87206B03A01B87201
การยืนยันข้อมูล

หากต้องการตรวจสอบว่าโปรแกรม APF ทำงานอยู่และมีการผ่านหรือทิ้งแพ็กเก็ตอย่างถูกต้อง ให้ทำดังนี้

  • ดึงข้อมูลและยืนยันภูมิภาคข้อมูล APF ทุก 5 นาที
  • อย่าล้างตัวนับ
  • สร้างแพ็กเก็ตทดสอบเพื่อทริกเกอร์กฎตัวกรองแต่ละรายการ
  • ยืนยันการเพิ่มขึ้นของตัวนับโดยใช้ตำแหน่งหน่วยความจำต่อไปนี้

    ชื่อตัวนับ ตำแหน่งหน่วยความจำ
    DROPPED_ETHERTYPE_DENYLISTED [ApfRamSize - 20, ApfRamSize - 16]
    DROPPED_DHCP_REQUEST_DISCOVERY [ApfRamSize - 24, ApfRamSize - 20]
    DROPPED_ICMP4_ECHO_REQUEST [ApfRamSize - 28, ApfRamSize - 24]
    DROPPED_RS [ApfRamSize - 32, ApfRamSize - 28]
    PASSED_PACKET [ApfRamSize - 36, ApfRamSize - 32]

รหัสจำลองสำหรับโปรแกรม APF 1 และโปรแกรม APF 2

รหัสจำลองต่อไปนี้อธิบายตรรกะของโปรแกรม APF 1 และโปรแกรม APF 2 โดยละเอียด

// ethertype filter
If the ethertype in [0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3]:
    drop packet and increase counter: DROPPED_ETHERTYPE_DENYLISTED

// dhcp discover/request filter
if ethertype != ETH_P_IP:
    skip the filter
if ipv4_src_addr != 0.0.0.0:
    skip the filter
if ipv4_dst_addr != 255.255.255.255
    skip the filter
if not UDP packet:
    skip the filter
if UDP src port is not dhcp request port:
    skip the filter
else:
    drop the packet and increase the counter: DROPPED_DHCP_REQUEST_DISCOVERY

// Router Solicitation filter:
if ethertype != ETH_P_IPV6:
    skip the filter
if not ICMP6 packet:
    skip the filter
if ICMP6 type is not a Router Solicitation:
    skip the filter
else:
    drop the packet and increase the counter: DROPPED_RS

// IPv4 ping filter (only included in Program 2)
if ethertype != ETH_P_IP:
    skip the filter
if it ipv4 protocol is not ICMP:
    skip the filter
if port is not a ping request port
    skip the filter
else:
    drop the packet and increase the counter: DROPPED_ICMP4_ECHO_REQUEST

pass the packet and increase: PASSED_PACKET