アウトライン
ARP要求を送信するために使用arp_solicit、最初のソースアドレスARP_ANNOUNCEパラメータに応じて選択し、次いで送信カーネルの時間上限の数は、カーネルがarp_send_dst送信機能に達していないか否かを判断するが呼び出された最大値に達した場合、アプリケーション要求の最大数か否かを判定し続けます、アプリケーションに到達していない通知は、ARP要求を送信します。
ソースコード解析
1 / * 2 のARP要求を送信する 。3 のARPリクエストオブジェクトネイバー 4 SKB元IPアドレスを取得する隣接エントリにパケットを送信するバッファ 。5 * / 6 静的 ボイド arp_solicit(構造体いななきネイバー*、構造体 sk_buff * SKB) 。7 { 8 __be32 SADDR = 0 ; 9 U8のdst_ha [MAX_ADDR_LEN]、* dst_hw = NULL; 10 構造体 net_deviceは* DEV = neigh-> DEV; 11 __be32ターゲットは= *(__ * BE32)はneigh-> PRIMARY_KEY; 12である INTはプローブ= atomic_read(&neigh->プローブ)。 13 構造体 in_device * in_dev。 14 構造体 dst_entry * DST = NULL; 15 16 rcu_read_lock()。 17 18 / * 获取IP配置块* / 19 in_dev = __in_dev_get_rcu(DEV)。 20 であれば(!{in_dev) 21 rcu_read_unlock()。 22 リターン; 23 } 24 25 / * 选取源地址* / 26 スイッチ(IN_DEV_ARP_ANNOUNCE(in_dev)){ 27 デフォルト: 28 ケース 0: / * デフォルトでは、任意のローカルアナウンスIP * / 29 / * 使用するローカルアドレス* / 30 IF(SKB && inet_addr_type_dev_table(dev_net(DEV)、DEV、 31は ip_hdrは(SKB) - > SADDR)== RTN_LOCAL) 32 にsaddr ip_hdr =(SKB) - > SADDR; 33である BREAK ; 34である ケース 1: / * 中にsaddrの同じサブネットアナウンスを制限する* / 35 / * 同じサブネット上* / 36 IF(!SKB) 37 [ BREAK 。 38 / * SKBソースIP取得* / 39を SADDR = ip_hdr(SKB) - > SADDR; 40 / * ソースアドレスがローカルインタフェースのアドレスである* / 41である IF (inet_addr_type_dev_table(dev_net(DEV)、DEV、 42は SADDR)== RTN_LOCAL ){ 43れる / * SADDRターゲットに知られているべきである* / 44である * / 同じサブネットか否かを判断する* / 45 IF (inet_addr_onlink(in_dev、ターゲット、SADDR)) 46で BREAK ; 47 } 48 = SADDR 0 ; 49 BREAK 。 50 ケース 2: / * セカンダリIPを避けるには、プライマリ/好ましいものGET * / 51である * / IPマスターを得、IP禁止* / 52である BREAK ; 53である } 54は rcu_read_unlock(); 55 56である * / 送信元アドレスが空である、選択アドレス* / 57である 場合(!SADDR) 58 をsaddr = inet_select_addr(DEV、ターゲット、RT_SCOPE_LINK); 59 60 / * ユニキャスト送信端の数かどうかを計算する* / 61である プローブ- (neigh-> = NEIGH_VAR UCAST_PROBES、PARMS)。 62 63 / *使用されていません* / 64 IF(プローブ< 0 ){ 65 IF(いななき&NUD_STATE( - !> NUD_VALID)) 66 pr_debug(" NUD_INVALID \ N-でウカストプローブしようとしている" ); 67 / * 送信先ハードウェアアドレス* / 68 neigh_ha_snapshot(dst_ha、いななき、DEV); 69 dst_hw = dst_ha; 70 } 71れる / * 使い切っ* / 72を 他{ 73である * / アプリケーションを使用して、送信の数かどうかを計算完全ARPD * / 74 - = NEIGH_VAR(neigh->プローブPARMS、APP_PROBES); 75 76 / * 未使用の終了* / 77 IF(プローブ< 0 ){ 78 / * アプリケーションARPD要求* / 79 )(いななきneigh_app_ns; 80 リターン; 81 } 82 } 83 84 / * オブジェクトを取得しますルートキャッシュ* / 85 IF(SKB &&(DEV-> priv_flags&!IFF_XMIT_DST_RELEASE)) 86 DST = skb_dst(SKB); 87 88 / * 送信要求パケットのARP * / 89 arp_send_dst(ARPOP_REQUEST、ETH_P_ARP、ターゲット、DEV、SADDR、 90 dst_hw、DEV-> dev_addr、NULL、DST)。 91 }