を使用してTAPデバイスを開いています
p->fd = open("/dev/net/tun", O_RDWR);
// skipping error handling code
ifr.ifr_flags = IFF_TAP | IFF_ONE_QUEUE | IFF_NO_PI;
strncpy(ifr.ifr_name, p->name, IFNAMSIZ-1);
result = ioctl(p->fd, TUNSETIFF, &ifr);
// skipping error handling and setting ipv4 address & netmask code
ifr.ifr_flags = (IFF_UP | IFF_RUNNING);
result = ioctl(dummySock, SIOCSIFFLAGS, &ifr);
私が直面している問題は、アプリケーション (mozilla など) がタップ デバイスを介してパケットを送信したい場合、dst MAC アドレスを取得する必要があることです。そのため、カーネルは ARP 要求を送信します。私が書いているアプリケーションは、arp 要求を (物理 eth デバイスの raw ソケットを介して) 転送し、arp 応答を受け取ります。この arp 応答はタップ デバイスに転送されますが、カーネルはこれを受け入れることを拒否します。arp エントリを手動で追加すると、arp 要求は生成されず、双方向の IP パケット交換が行われます (mozilla は満足しています)。
Wireshark はパケットを受信でき、エラーは検出されません。ICMPv6 パケット (近隣要請と広告) の場合も同様です。デバイスでリッスンしているすべてのアプリケーションは、パケットをそのまま取得します。しかし、カーネルは ARP/ICMP のためにそれを処理しません。
私の質問は、カーネルが arp 応答/ICMPv6 メッセージを受け入れないのはなぜですか? 呼び出す必要がある ioctl 呼び出しはありますか?
編集:
タップデバイス「ethgress」でキャプチャしたパケット(tshark出力)の詳細はこちら
9 16.548328 fc00:1::2 -> ff02::1:ff00:1 ICMPv6 86 Neighbor Solicitation
10 17.243247 fc00:1::100 -> fc00:1::2 ICMPv6 86 Neighbor Advertisement
11 17.548652 fc00:1::2 -> ff02::1:ff00:1 ICMPv6 86 Neighbor Solicitation
12 17.668736 fc00:1::100 -> fc00:1::2 ICMPv6 86 Neighbor Advertisement
これは、「ethgress」の ifconfig 出力です。
ethgress Link encap:Ethernet HWaddr 00:01:02:03:04:05
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:83 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:10000
RX bytes:0 (0.0 b) TX bytes:7062 (6.8 KiB)
ご覧のとおり、カーネルは受信した ICMPv6 パケットの受け入れを拒否しています。ただし、tx パケットはインクリメントされます。
タップ デバイス「ethgress」は IPv6 アドレス fc00:1::2 で構成されており、アプリケーションは fc00:1::1 と通信しようとしています。fc00:1::1 は、適切な MAC アドレスを持つネイバー アドバタイズメント (ターゲット IP はそのパケットの fc00:1::1 です) で応答している fc00:1:100 と同じインターフェイスにあります。Tcpdump はそれをキャプチャすることができ、wireshark/tshark はそれなしでそれをデコードすることができ、適切に形成されたパケットであると言います。ただし、Rx カウンターはカーネルによってインクリメントされず、arp キャッシュも更新されません。ARP パケットの場合も同様です。
編集2:
ネットワークはこんな感じ。冗長構成の外部ボックスが 2 台あります。それらのうちの 1 つだけがアクティブになります。それらはそれぞれ物理 NIC を介して PC に接続されています。私が書いているアプリケーションはこの PC で実行され、各 NIC で raw ソケットを開きます。また、TAP デバイスも開きます。NIC に IP アドレスが設定されていません。TAP デバイスは、IPv4 と IPv6 の両方のアドレスで構成されています。mozilla などの標準アプリケーションは、タップ デバイスを介してソケットを開き、アクティブなボックスに接続しようとします。そのために、カーネルはタップ デバイスで ARP 要求/近隣要請メッセージを生成します。アプリケーションはこのメッセージを読み取り、両方の NIC に転送します。アクティブなボックスは、アプリケーションがそれを読み取り、TAP デバイスに書き込む ARP 応答で ARP 要求に応答します。この arp 応答パケットは tcpdump によってキャプチャされ、しかし、カーネルは arp キャッシュを更新しません。両方の NIC と TAP デバイスの MAC アドレスは同じです。
要求されるその他のパラメーター。
cat /proc/sys/net/ipv4/conf/all/log_martians
0
cat /proc/sys/net/ipv4/conf/all/rp_filter
1
cat /proc/sys/net/ipv4/conf/all/arp_filter
0