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

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

ภาพรวมของ APF

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

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

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

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

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

การแก้ไข 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 คือ 1024 ไบต์ ส่วน APFv6 ต้องใช้ 2048 ไบต์ อย่างไรก็ตาม เราขอแนะนำอย่างยิ่งให้คุณจัดสรร 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 แต่ละรายการทำงานอย่างไร หากต้องการศึกษาโปรแกรมที่สร้างขึ้นจริง ให้แก้ไขกรณีทดสอบเพื่อพิมพ์โปรแกรมเป็นสตริงเลขฐานสิบหก

โฟลเดอร์ 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 ที่ติดตั้งล่าสุดในรูปแบบสตริงเลขฐานสิบหก
  • 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.

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

หากต้องการแสดงสตริงไบนารีเลขฐานสิบหกของแพ็กเก็ตดิบ ให้ใช้ตัวเลือก --packet หากต้องการแสดงสตริงไบนารีเลขฐานสิบหกของภูมิภาคข้อมูล ซึ่ง ใช้เพื่อจัดเก็บ ตัวนับ APF ให้ใช้ตัวเลือก --data เนื่องจากตัวนับแต่ละรายการมีความยาว 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 ที่ถูกต้อง

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

นอกจากนี้ เราขอแนะนำอย่างยิ่งให้คุณรวมการทดสอบ APF ไว้ในชุดทดสอบการผสานรวม Wi-Fi ของเฟิร์มแวร์

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

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

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

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

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

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

โปรแกรม APF 1

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

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

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

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

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
โปรแกรม APF 2

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

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

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

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

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]

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

Pseudocode ต่อไปนี้อธิบายตรรกะของโปรแกรม 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