1 điểm bởi GN⁺ 2025-06-09 | 1 bình luận | Chia sẻ qua WhatsApp
  • Dịch vụ EthernetTracker của Android chỉ nhận diện các giao diện mạng có tên là ethX
  • Trình điều khiển CDC Ethernet của Linux tạo tên giao diện là usbX
  • Vì vậy, các thiết bị CDC Ethernet tiêu chuẩn không tự động được kích hoạt trên Android
  • Để khắc phục, người dùng phải tự root điện thoại và thay đổi giá trị config_ethernet_iface_regex
  • Cách thực tế là chỉ dùng các sản phẩm chipset nhất định có trình điều khiển đặc thù của nhà cung cấp, thay vì bộ chuyển đổi USB Ethernet tuân theo chuẩn

Giới thiệu và tổng quan vấn đề

  • Nguyên nhân cốt lõi khiến CDC Ethernet không hoạt động trên thiết bị Android là do quy tắc đặt tên giao diện
  • Về mặt hệ thống, Android có hỗ trợ bộ chuyển đổi USB Ethernet, nhưng điều kiện để menu Ethernet được kích hoạt lại bị ràng buộc
  • Rất khó để có được thông tin về các chipset tương thích, và trên thực tế cấu trúc này khiến người dùng phải dựa vào những "lời đồn" truyền miệng
  • Android cũng dựa trên nhân Linux, nhưng không phải mọi thứ đều được quyết định chỉ bằng cấu hình nhân

Gỡ lỗi USB và thiết lập ADB

  • Cần bật gỡ lỗi USB và cài ADB trên thiết bị Android
  • Để kiểm thử bộ chuyển đổi mạng, cần chuyển ADB sang chế độ mạng qua Wi‑Fi
  • Có thể dùng lệnh để kiểm tra phiên bản nhân và kiến trúc hiện tại

Cách kiểm tra phiên bản và cấu hình nhân

  • Điện thoại mới (Android 11 trở lên) dùng cấu trúc nhân GKI (Generic Kernel Image)
    • Google xây dựng nhân cơ bản, còn nhà sản xuất chỉ bổ sung các mô-đun
    • Có thể xác định các tính năng được hỗ trợ từ tệp cấu hình nhân tương ứng (gki_defconfig)
  • Với điện thoại cũ, cần tìm tệp defconfig trong mã nguồn nhân do từng nhà sản xuất cung cấp để kiểm tra
  • Nếu may mắn, bạn cũng có thể kiểm tra trực tiếp cấu hình nhân hiện tại tại đường dẫn /proc/config.gz

Cách xác định bộ chuyển đổi USB Ethernet được hỗ trợ

  • Phần lớn các giá trị cấu hình nhân liên quan có dạng CONFIG_USB_NET_XXX
    • y nghĩa là tích hợp sẵn, m nghĩa là biên dịch dưới dạng mô-đun (có thể dùng được), is not set nghĩa là không được hỗ trợ
  • Có thể tham khảo mô tả của từng giá trị cấu hình trong tệp drivers/net/usb/Kconfig
  • Tuy vậy, thông tin về chipset của bộ chuyển đổi vẫn hiếm khi được hiển thị rõ ràng

CDC Ethernet (Communications Device Class) và trường hợp áp dụng trên Android

  • CDC là chuẩn mạng USB, cung cấp nhiều giao thức như EEM/ECM/NCM
  • Trên Linux, Windows và macOS, thiết bị CDC Ethernet tiêu chuẩn được tự động nhận diện mà không cần trình điều khiển riêng
  • Ở cấp độ nhân, Android cũng đã biên dịch sẵn các trình điều khiển liên quan
    • Ví dụ: thiết bị Samsung có CONFIG_USB_NET_CDCETHER, EEM, NCM đều được đặt là y
  • Tuy nhiên, menu Ethernet vẫn không được kích hoạt

Logic theo dõi giao diện mạng của Android

  • Android dùng lớp EthernetTracker.java để phát hiện giao diện mạng
  • Khi có giao diện mới xuất hiện, EthernetTracker sẽ so khớp theo mẫu tên (biểu thức chính quy)
  • Tiêu chí khớp được lấy từ tài nguyên config_ethernet_iface_regex
    • Giá trị mặc định là eth\\d (chỉ các giao diện mạng bắt đầu bằng eth và theo sau là chữ số mới hợp lệ)
  • Tên do nhân tạo ra (usb0) không khớp với mẫu này nên bị bỏ qua trong quá trình theo dõi và kích hoạt

Giới hạn của cách khắc phục và kết luận

  • Biểu thức chính quy đặt tên này người dùng không thể tự thay đổi (nếu không root)
  • Kết quả là sản phẩm CDC Ethernet tiêu chuẩn dù có kết nối cũng không thể dùng trong menu mạng
  • Ngược lại, chỉ một số bộ chuyển đổi được đăng ký trực tiếp bằng trình điều khiển của nhà cung cấp hoặc chipset mới có thể dùng được
  • Dù Google có đưa mã hỗ trợ chuẩn như mô-đun EEM vào nhân, trên thực tế nó vẫn không hoạt động
  • Đây là một vấn đề rất đơn giản, chỉ cần đổi biểu thức chính quy thành tối thiểu (eth|usb)\\d là có thể giải quyết, nhưng hiện vẫn chưa được sửa

Tóm tắt

  • Nguyên nhân cốt lõi: Android không phải là cố tình bỏ qua chuẩn CDC Ethernet, mà là giao diện mạng không được kích hoạt vì tên của nó không khớp với biểu thức chính quy (eth\\d)
  • Cách lách qua: Phải root điện thoại rồi thay đổi giá trị config_ethernet_iface_regex thành dạng như (eth|usb)\\d
  • Lựa chọn thực tế: Thay vì bộ chuyển đổi hỗ trợ USB CDC tiêu chuẩn, giải pháp thực tế hơn là chọn sản phẩm có tích hợp trình điều khiển rõ ràng theo từng chipset
  • Vấn đề mang tính cấu trúc: Đây là ví dụ cho thấy chính sách đặt tên ở tầng phần mềm phía trên còn thiếu sót đã trở thành giới hạn mang tính hệ thống về khả năng hiển thị với người dùng và tương thích tiêu chuẩn

1 bình luận

 
GN⁺ 2025-06-09
Ý kiến Hacker News
  • Chia sẻ trải nghiệm từng rất vất vả khi cố kết nối thiết bị Android với bộ chuyển đổi CDC Ethernet ở công ty cũ nên đã viết bài này; sau đó có người nói rằng nếu đổi một bit nhất định trong địa chỉ MAC thì kernel sẽ gán tên ethX; tác giả chưa tự kiểm thử hay cập nhật nội dung đó vào bài, hiện nay cũng hầu như không còn dùng thiết bị Android nữa; đồng thời bổ sung rằng cách này chỉ dùng được khi bạn có thể kiểm soát địa chỉ MAC
    • Thông tin này có vẻ sẽ hữu ích với tôi; tôi đã tìm ra đó là bit nào và chia sẻ liên kết liên quan
    • Bày tỏ phản hồi tích cực với bài viết đó
  • Đánh giá đây là một bài phân tích rất sâu; kiểm tra mã nguồn thì có vẻ vào tháng 10/2023, regex gây ra vấn đề đã được đổi từ eth\d thành *, nên nhiều khả năng lỗi đã được khắc phục; đưa ra liên kết thay đổi mã liên quan; giải thích rằng từ Android U+ (có lẽ là phiên bản 14) mặc định đã bao gồm cả usb\d+eth%d
    • Giải thích rằng thay đổi này về sau đã bị rollback vì "có những thiết bị tethering qua giao diện usbX", rồi sau đó lại được áp dụng trở lại nhưng chỉ hỗ trợ từ Android V+ (phiên bản mới) trở lên; kèm liên kết rollbackliên kết áp dụng cuối cùng
  • Chỉ trích mạnh việc dịch vụ EthernetTracker của Android chỉ chấp nhận các interface được đặt tên theo ethX; giải thích rằng trên các bản phân phối Linux, vấn đề này đã được giải quyết từ những năm 2000; hồi tưởng việc mỗi driver thường dùng tiền tố tên riêng khiến phải rà soát toàn bộ hệ thống rất bất tiện; ngày nay các bản phân phối Linux tự động đổi tên interface mạng bằng các công cụ như udev, và quá trình này hoạt động qua lời gọi ioctl SIOCSIFNAME của kernel; đồng thời bổ sung rằng kernel hiện đại còn hỗ trợ tiện lợi là tự gán số cho các tên kiểu wlan* hoặc wlan%d
  • Nhìn vào lịch sử commit của LineageOS thì có vẻ vấn đề này đã được sửa rồi lại bị hoàn tác do vấn đề tương thích, và ở các phiên bản Android mới nhất thì đã được áp dụng trở lại; xét nội dung commit thì có vẻ cả phía Google cũng tham gia nên có thể các bản build chính thức của Google cũng đã nhận thay đổi này
  • Đồng cảm với câu trong bài rằng "<i>không có cách nào để thay đổi giá trị config_ethernet_iface_regex ngoài việc root điện thoại</i>", và cho rằng đây là thêm một lý do nữa khiến quyền root quan trọng trên thiết bị tôi sở hữu
    • Tôi nghĩ chính việc có thể tùy ý chuyển hướng lưu lượng mạng là lý do lớn nhất khiến không nên cấp quyền superuser cho user space; tôi ủng hộ việc gây áp lực để OEM cho phép mở khóa bootloader, nhưng trên Android tôi không nghĩ ra được mấy trường hợp sử dụng đủ chính đáng so với phạm vi đe dọa lớn mà quyền root trao cho kẻ tấn công
  • Hỏi "không dùng được" ở đây nghĩa là gì; khi cắm một hub USB dongle dành cho MacBook vào điện thoại Android thì cổng Ethernet vẫn hoạt động bình thường, và cũng từng có trải nghiệm modem di động được nhận diện như thiết bị Ethernet rồi chạy tốt trên Android
    • Thông báo rằng vấn đề này đã được sửa, và bài gốc là bài từ 2 năm trước
  • Phàn nàn rằng Android rất khó chịu ở chỗ không cho kết nối đồng thời nhiều mạng; ví dụ muốn vừa nối vào WiFi không có Internet (cũng không có router mặc định) vừa giữ mạng di động thì không được; trên Linux hay Windows điều này là bình thường nhưng Android lại cưỡng ép chặn, thậm chí ở nhiều bản biến thể nếu cố bám vào WiFi không có Internet thì kết nối còn bị ngắt theo cách khó hiểu; ngoài ra chỉ có vài API tạm tạm để ứng dụng dùng được phần nào, còn bản thân người dùng thì bị chặn không có quyền kiểm soát này
    • iOS cũng tương tự; khi kết nối WiFi để lấy video từ camera hành trình thì sẽ hiện popup kiểu "không có Internet, chuyển sang di động?", nhưng kể cả khi chọn tiếp tục ở lại WiFi thì cuối cùng iOS vẫn tự động ép chuyển sang mạng CarPlay; đồng thời nói thêm rằng thậm chí còn không có cách tắt thủ công
    • Windows thực ra cũng không thể đồng thời kết nối hai mạng WiFi bằng hai bộ điều hợp không dây, ít nhất là trên GUI thì không làm được, còn qua terminal thì chưa thử
    • Cho rằng giới hạn này thực sự rất bực; khi Internet gặp sự cố mà muốn dùng điện thoại để chẩn đoán thì máy lại không chịu ở yên trên WiFi nên rất khó làm; cũng phàn nàn thêm rằng thiết lập DNS trên Android còn có những vấn đề rắc rối khác như không nhận từ DHCP
    • Kể lại trải nghiệm còn khó chịu hơn khi mang điện thoại Android bản phương Tây vào Trung Quốc đại lục; vì Android kiểm tra kết nối Internet qua dịch vụ của Google nên WiFi nội bộ lúc nào cũng bị cảnh báo không có Internet; mỗi lần như vậy người dùng lại phải thủ công trả lời có muốn tiếp tục giữ kết nối hay không
  • Khuyên rằng cũng nhất định phải kiểm tra yêu cầu firmware; có những thiết bị nhìn như được nhận diện bình thường nhưng nếu thiếu firmware thì ifup sẽ thất bại, giao diện Android hoàn toàn không cho thấy tình trạng này mà chỉ xem dmesg mới biết vấn đề; không chắc CDC có bị như vậy không, nhưng kinh nghiệm là nhiều USB Ethernet dongle dùng chipset Realtek, Kawasaki và có trường hợp cần firmware; thay đổi phía Android này có vẻ là chuyện gần đây, nhưng trên thiết bị debug AOSP thuần thì vẫn dùng USB network dongle tốt nên đoán rằng có thể là do quy ước đặt tên ở phía kernel hoặc driver CDC; nói chung vẫn nên để ý chipset của dongle và việc nó có cần firmware hay không
  • Chia sẻ kinh nghiệm đang sở hữu hơn 15 bộ chuyển đổi USB Ethernet, dùng các chipset khác nhau như Realtek, AXIS mà tất cả đều hoạt động rất tốt; tin rằng chỉ cần chọn đúng các mẫu không cần driver trên Linux thì hầu như sẽ dùng ổn trên mọi OS và cả BIOS
    • Cung cấp thông tin rằng vấn đề đã được sửa trong năm 2023 và đưa liên kết Hacker News liên quan
    • Chia sẻ thêm rằng bộ chuyển đổi Ethernet gắn trên dock Thunderbolt/USB hoạt động tốt trên cả hai điện thoại Pixel 5 và Pixel 9
  • Khen đây là một hành trình debug hoàn hảo; thấy rất thú vị khi chỉ vì một regex mà cả một nhóm thiết bị trở nên không hoạt động; hồi tưởng gần đây cũng từng gặp một giới hạn cấu trúc tương tự trong hệ thống alignment/escalation của GPT-4 và OpenAI; đã cố kích hoạt logic nội bộ bằng cả tài liệu chính thức lẫn log, nhưng cuối cùng có vẻ vẫn bị chặn chỉ vì nhìn thì hợp lý với con người nhưng lại không khớp regex của giao diện nội bộ; chia sẻ ghi chép liên quan ở liên kết riêng, và đề nghị nếu ai quan tâm đến cấu trúc hệ thống hay những ranh giới giao diện vô hình thì rất muốn nghe ý kiến