在链接原始接口

时间:2018-05-25 21:52:01

标签: c select epoll dhcp

我正在尝试使用 dhclient 从LTE蜂窝调制解调器模块获取IP地址, dhclient 无法识别传入的DHCP回复。

这些模块在Linux中显示为“wwan0”接口。这类似于常规以太网接口,但由于它们是点对点接口,因此它们不会使用MAC地址并使用链接原始帧格式。

这意味着没有14字节以太网标头,并且它们具有 NOARP 标志集:

wwan0 Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
      inet6 addr: fe80::619f:fc5a:2124:a16a/64 Scope:Link
      UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
      RX packets:101 errors:0 dropped:0 overruns:0 frame:0
      TX packets:155 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1000 

dhclient 需要一个小补丁来处理NOARP接口,但它会发出有效的DHCP REQUEST并输入select()等待回复。

DHCP OFFER从LTE模块返回,但select()永远不会返回。 dhclient超时,我无法弄清楚原因。这是我到目前为止所发现的:

  • 使用select()epoll()选项编译 dhclient 并不重要,两者的行为相同。

这是典型DHCP请求/回复的tcpdump:

$ sudo /usr/sbin/tcpdump -nXXs 1600 -vv -i wwan0
tcpdump: listening on wwan0, link-type RAW (Raw IP), capture size 1600 bytes
10:49:54.532975 IP (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328)
0.0.0.0.68 > 255.255.255.255.67: [udp sum ok] BOOTP/DHCP, Request, length 300, htype 254, hlen 0, xid 0x72731a0f, Flags [none] (0x0000)
  Vendor-rfc1048 Extensions
    Magic Cookie 0x63825363
    DHCP-Message Option 53, length 1: Discover
    Parameter-Request Option 55, length 9: 
      Subnet-Mask, BR, Time-Zone, Default-Gateway
      Domain-Name, Domain-Name-Server, Hostname, Netbios-Name-Server
      Netbios-Scope
0x0000:  4510 0148 0000 0000 8011 3996 0000 0000  E..H......9.....
0x0010:  ffff ffff 0044 0043 0134 2813 01fe 0000  .....D.C.4(.....
0x0020:  7273 1a0f 0000 0000 0000 0000 0000 0000  rs..............
0x0030:  0000 0000 0000 0000 0000 0000 0000 0000  ................
[... all zeros ...]
0x00f0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0100:  0000 0000 0000 0000 6382 5363 3501 0137  ........c.Sc5..7
0x0110:  0901 1c02 030f 060c 2c2f ff00 0000 0000  ........,/......
0x0120:  0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0130:  0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0140:  0000 0000 0000 0000                      ........


10:49:54.540519 IP (tos 0x0, ttl 255, id 178, offset 0, flags [none], proto UDP (17), length 306)
10.176.3.160.67 > 10.176.3.159.68: [udp sum ok] BOOTP/DHCP, Reply, length 278, htype 254, hlen 0, xid 0x72731a0f, Flags [none] (0x0000)
  Your-IP 10.176.3.159
  Server-IP 10.176.3.160
  Vendor-rfc1048 Extensions
    Magic Cookie 0x63825363
    DHCP-Message Option 53, length 1: Offer
    Subnet-Mask Option 1, length 4: 255.255.255.192
    Default-Gateway Option 3, length 4: 10.176.3.160
    Domain-Name-Server Option 6, length 8: 199.7.156.169,199.7.156.168
    Lease-Time Option 51, length 4: 7200
    Server-ID Option 54, length 4: 10.176.3.160
0x0000:  4500 0132 00b2 0000 ff11 9d6a 0ab0 03a0  E..2.......j....
0x0010:  0ab0 039f 0043 0044 011e 4a14 02fe 0000  .....C.D..J.....
0x0020:  7273 1a0f 0000 0000 0000 0000 0ab0 039f  rs..............
0x0030:  0ab0 03a0 0000 0000 0000 0000 0000 0000  ................
0x0040:  0000 0000 0000 0000 0000 0000 0000 0000  ................
[... all zeros ...]
0x00f0:  0000 0000 0000 0000 0000 0000 0000 0000  ................
0x0100:  0000 0000 0000 0000 6382 5363 3501 0201  ........c.Sc5...
0x0110:  04ff ffff c003 040a b003 a006 08c7 079c  ................
0x0120:  a9c7 079c a833 0400 001c 2036 040a b003  .....3.....6....
0x0130:  a0ff                                     ..

有没有人知道为什么select() / epoll()无法接收DHCP回复?是因为它既没有MAC地址也没有IP地址可以用来匹配传入的帧?鉴于套接字绑定到IP 0.0.0.0,恕我直言并不是一个令人满意的解释。

如果重要,这些LTE模块是USB设备。他们使用usbnet框架和qmi-wwan驱动程序。

下面是一个ftrace代码段,显示传入的数据包由qmi_wwan_rx_fixup()处理,但随后在ip_route_input_rcu()中出错。有什么想法吗?

0)                |          irq_exit() {
0)                |            __do_softirq() {
0)                |              tasklet_action() {
0)                |                usbnet_bh() {
0)                |                  skb_dequeue() {
0)   0.539 us     |                    _raw_spin_lock_irqsave();
0)   0.461 us     |                    _raw_spin_unlock_irqrestore();
0)   7.077 us     |                  }
0)   1.000 us     |                  qmi_wwan_rx_fixup();
0)                |                  usbnet_skb_return() {
0)   0.615 us     |                    skb_defer_rx_timestamp();
0)                |                    netif_rx() {
0)                |                      netif_rx_internal() {
0)                |                        enqueue_to_backlog() {
0)   0.615 us     |                          _raw_spin_lock();
0)   0.539 us     |                          __raise_softirq_irqoff();
0)   8.615 us     |                        }
0) + 12.077 us    |                      }
0) + 15.307 us    |                    }
0) + 22.923 us    |                  }
0)                |                  skb_dequeue() {
0)   0.462 us     |                    _raw_spin_lock_irqsave();
0)   0.538 us     |                    _raw_spin_unlock_irqrestore();
0)   7.154 us     |                  }
0)   0.846 us     |                  netif_tx_wake_queue();
0) + 55.847 us    |                }
0) + 60.231 us    |              }
0)   0.770 us     |              rcu_bh_qs();
0)                |              net_rx_action() {
0)   0.616 us     |                __usecs_to_jiffies();
0)                |                process_backlog() {
0)   0.462 us     |                  _raw_spin_lock();
0)                |                  __netif_receive_skb() {
0)                |                    __netif_receive_skb_core() {
0)                |                      packet_rcv() {
0)                |                        run_filter() {
0)                |                          __bpf_prog_run32() {
0)   3.000 us     |                            ___bpf_prog_run();
0)   6.308 us     |                          }
0) + 10.616 us    |                        }
0)   1.077 us     |                        consume_skb();
0) + 19.000 us    |                      }
0)                |                      ip_rcv() {
0)                |                        nf_hook_slow() {
0)   0.846 us     |                          ipv4_conntrack_defrag();
0)                |                          iptable_raw_hook() {
0)                |                            ipt_do_table() {
0)   1.308 us     |                              udp_mt();
0)   0.538 us     |                              __local_bh_enable_ip();
0) + 19.692 us    |                            }
0) + 23.307 us    |                          }
0)                |                          ipv4_conntrack_in() {

                        [...]

0) ! 126.384 us   |                          }
0)                |                          iptable_mangle_hook() {
0)                |                            ipt_do_table() {
0)   0.384 us     |                              __local_bh_enable_ip();
0)   5.385 us     |                            }
0)   8.769 us     |                          }
0)                |                          iptable_nat_ipv4_in() {

                        [...]

0) + 80.539 us    |                          }
0) ! 255.923 us   |                        }
0)                |                        ip_rcv_finish() {
0)                |                          udp_v4_early_demux() {
0)   0.615 us     |                            udp4_portaddr_hash();
0)   4.693 us     |                          }
0)                |                          ip_route_input_noref() {
0)                |                            ip_route_input_rcu() {
0)   0.615 us     |                              make_kuid();
0)                |                              __fib_lookup() {
0)                |                                l3mdev_update_flow() {
0)   0.615 us     |                                  dev_get_by_index_rcu();
0)   0.462 us     |                                  l3mdev_master_ifindex_rcu();
0)   7.077 us     |                                }
0)                |                                fib_rules_lookup() {

                        [...]

0) + 51.769 us    |                                }
0) + 64.769 us    |                              }
0)                |                              rt_dst_alloc() {
0)                |                                dst_alloc() {
0)   0.615 us     |                                  kmem_cache_alloc();
0)   1.462 us     |                                  dst_init();
0)   8.461 us     |                                }
0) + 12.384 us    |                              }
0) + 89.153 us    |                            }
0) + 92.538 us    |                          }
0)                |                          ip_error() {
0)   0.615 us     |                            __local_bh_enable_ip();
0)   0.462 us     |                            l3mdev_master_ifindex_rcu();
0)                |                            inet_getpeer() {
0)   2.384 us     |                              lookup();
0)   6.230 us     |                            }
0)   0.615 us     |                            inet_putpeer();
0)                |                            icmp_send() {

                        [...]

0) ! 457.462 us   |                            }
0)                |                            kfree_skb() {

0 个答案:

没有答案