^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * AARP: An implementation of the AppleTalk AARP protocol for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Ethernet 'ELAP'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Alan Cox <Alan.Cox@linux.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This doesn't fit cleanly with the IP arp. Potentially we can use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * the generic neighbour discovery code to clean this up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * FIXME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * We ought to handle the retransmits with a single list and a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * separate fast timer for when it is needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Use neighbour discovery code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Token Ring Support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * References:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Inside AppleTalk (2nd Ed).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Fixes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Jaume Grau - flush caches on AARP_PROBE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Rob Newberry - Added proxy AARP and AARP proc fs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * moved probing from DDP module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Arnaldo C. Melo - don't mangle rx packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <net/datalink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <net/psnap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/atalk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int sysctl_aarp_tick_time = AARP_TICK_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int sysctl_aarp_retransmit_limit = AARP_RETRANSMIT_LIMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* Lists of aarp entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * struct aarp_entry - AARP entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * @last_sent - Last time we xmitted the aarp request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * @packet_queue - Queue of frames wait for resolution
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * @status - Used for proxy AARP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * expires_at - Entry expiry time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * target_addr - DDP Address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * dev - Device to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * hwaddr - Physical i/f address of target/router
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * xmit_count - When this hits 10 we give up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * next - Next entry in chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct aarp_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* These first two are only used for unresolved entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned long last_sent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct sk_buff_head packet_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned long expires_at;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct atalk_addr target_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) char hwaddr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned short xmit_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct aarp_entry *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* Hashed list of resolved, unresolved and proxy entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static struct aarp_entry *resolved[AARP_HASH_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static struct aarp_entry *unresolved[AARP_HASH_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static struct aarp_entry *proxies[AARP_HASH_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static int unresolved_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* One lock protects it all. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static DEFINE_RWLOCK(aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Used to walk the list and purge/kick entries. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static struct timer_list aarp_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * Delete an aarp queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * Must run under aarp_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static void __aarp_expire(struct aarp_entry *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) skb_queue_purge(&a->packet_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) kfree(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * Send an aarp queue entry request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * Must run under aarp_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static void __aarp_send_query(struct aarp_entry *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static unsigned char aarp_eth_multicast[ETH_ALEN] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct net_device *dev = a->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct elapaarp *eah;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct atalk_addr *sat = atalk_find_dev_addr(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (!sat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /* Set up the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) skb_reset_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) skb_put(skb, sizeof(*eah));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) skb->protocol = htons(ETH_P_ATALK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) skb->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) eah = aarp_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* Set up the ARP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) eah->hw_type = htons(AARP_HW_TYPE_ETHERNET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) eah->pa_type = htons(ETH_P_ATALK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) eah->hw_len = ETH_ALEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) eah->pa_len = AARP_PA_ALEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) eah->function = htons(AARP_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ether_addr_copy(eah->hw_src, dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) eah->pa_src_zero = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) eah->pa_src_net = sat->s_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) eah->pa_src_node = sat->s_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) eth_zero_addr(eah->hw_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) eah->pa_dst_zero = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) eah->pa_dst_net = a->target_addr.s_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) eah->pa_dst_node = a->target_addr.s_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* Send it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) aarp_dl->request(aarp_dl, skb, aarp_eth_multicast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* Update the sending count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) a->xmit_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) a->last_sent = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* This runs under aarp_lock and in softint context, so only atomic memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * allocations can be used. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static void aarp_send_reply(struct net_device *dev, struct atalk_addr *us,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct atalk_addr *them, unsigned char *sha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct elapaarp *eah;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* Set up the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) skb_reset_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) skb_put(skb, sizeof(*eah));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) skb->protocol = htons(ETH_P_ATALK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) skb->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) eah = aarp_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /* Set up the ARP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) eah->hw_type = htons(AARP_HW_TYPE_ETHERNET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) eah->pa_type = htons(ETH_P_ATALK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) eah->hw_len = ETH_ALEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) eah->pa_len = AARP_PA_ALEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) eah->function = htons(AARP_REPLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ether_addr_copy(eah->hw_src, dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) eah->pa_src_zero = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) eah->pa_src_net = us->s_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) eah->pa_src_node = us->s_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (!sha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) eth_zero_addr(eah->hw_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ether_addr_copy(eah->hw_dst, sha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) eah->pa_dst_zero = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) eah->pa_dst_net = them->s_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) eah->pa_dst_node = them->s_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* Send it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) aarp_dl->request(aarp_dl, skb, sha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * Send probe frames. Called from aarp_probe_network and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * aarp_proxy_probe_network.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static void aarp_send_probe(struct net_device *dev, struct atalk_addr *us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct elapaarp *eah;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static unsigned char aarp_eth_multicast[ETH_ALEN] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* Set up the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) skb_reset_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) skb_put(skb, sizeof(*eah));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) skb->protocol = htons(ETH_P_ATALK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) skb->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) eah = aarp_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* Set up the ARP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) eah->hw_type = htons(AARP_HW_TYPE_ETHERNET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) eah->pa_type = htons(ETH_P_ATALK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) eah->hw_len = ETH_ALEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) eah->pa_len = AARP_PA_ALEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) eah->function = htons(AARP_PROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ether_addr_copy(eah->hw_src, dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) eah->pa_src_zero = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) eah->pa_src_net = us->s_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) eah->pa_src_node = us->s_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) eth_zero_addr(eah->hw_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) eah->pa_dst_zero = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) eah->pa_dst_net = us->s_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) eah->pa_dst_node = us->s_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* Send it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) aarp_dl->request(aarp_dl, skb, aarp_eth_multicast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * Handle an aarp timer expire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * Must run under the aarp_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static void __aarp_expire_timer(struct aarp_entry **n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct aarp_entry *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) while (*n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* Expired ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (time_after(jiffies, (*n)->expires_at)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) t = *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) *n = (*n)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) __aarp_expire(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) n = &((*n)->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * Kick all pending requests 5 times a second.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * Must run under the aarp_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static void __aarp_kick(struct aarp_entry **n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct aarp_entry *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) while (*n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* Expired: if this will be the 11th tx, we delete instead. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if ((*n)->xmit_count >= sysctl_aarp_retransmit_limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) t = *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) *n = (*n)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) __aarp_expire(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) __aarp_send_query(*n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) n = &((*n)->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * A device has gone down. Take all entries referring to the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * and remove them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * Must run under the aarp_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static void __aarp_expire_device(struct aarp_entry **n, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct aarp_entry *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) while (*n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if ((*n)->dev == dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) t = *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) *n = (*n)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) __aarp_expire(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) n = &((*n)->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* Handle the timer event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static void aarp_expire_timeout(struct timer_list *unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) int ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) write_lock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) __aarp_expire_timer(&resolved[ct]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) __aarp_kick(&unresolved[ct]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) __aarp_expire_timer(&unresolved[ct]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) __aarp_expire_timer(&proxies[ct]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) write_unlock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) mod_timer(&aarp_timer, jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) (unresolved_count ? sysctl_aarp_tick_time :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) sysctl_aarp_expiry_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* Network device notifier chain handler. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int aarp_device_event(struct notifier_block *this, unsigned long event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct net_device *dev = netdev_notifier_info_to_dev(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) int ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (!net_eq(dev_net(dev), &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (event == NETDEV_DOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) write_lock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) __aarp_expire_device(&resolved[ct], dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) __aarp_expire_device(&unresolved[ct], dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) __aarp_expire_device(&proxies[ct], dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) write_unlock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /* Expire all entries in a hash chain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static void __aarp_expire_all(struct aarp_entry **n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct aarp_entry *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) while (*n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) t = *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) *n = (*n)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) __aarp_expire(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* Cleanup all hash chains -- module unloading */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static void aarp_purge(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) int ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) write_lock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) __aarp_expire_all(&resolved[ct]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) __aarp_expire_all(&unresolved[ct]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) __aarp_expire_all(&proxies[ct]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) write_unlock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * Create a new aarp entry. This must use GFP_ATOMIC because it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * runs while holding spinlocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static struct aarp_entry *aarp_alloc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct aarp_entry *a = kmalloc(sizeof(*a), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) skb_queue_head_init(&a->packet_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * Find an entry. We might return an expired but not yet purged entry. We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * don't care as it will do no harm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * This must run under the aarp_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static struct aarp_entry *__aarp_find_entry(struct aarp_entry *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct atalk_addr *sat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) while (list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (list->target_addr.s_net == sat->s_net &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) list->target_addr.s_node == sat->s_node &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) list->dev == dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) list = list->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /* Called from the DDP code, and thus must be exported. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) void aarp_proxy_remove(struct net_device *dev, struct atalk_addr *sa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) int hash = sa->s_node % (AARP_HASH_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct aarp_entry *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) write_lock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) a = __aarp_find_entry(proxies[hash], dev, sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) a->expires_at = jiffies - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) write_unlock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* This must run under aarp_lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static struct atalk_addr *__aarp_proxy_find(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct atalk_addr *sa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) int hash = sa->s_node % (AARP_HASH_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct aarp_entry *a = __aarp_find_entry(proxies[hash], dev, sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return a ? sa : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * Probe a Phase 1 device or a device that requires its Net:Node to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * be set via an ioctl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static void aarp_send_probe_phase1(struct atalk_iface *iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct ifreq atreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct sockaddr_at *sa = (struct sockaddr_at *)&atreq.ifr_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) const struct net_device_ops *ops = iface->dev->netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) sa->sat_addr.s_node = iface->address.s_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) sa->sat_addr.s_net = ntohs(iface->address.s_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /* We pass the Net:Node to the drivers/cards by a Device ioctl. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (!(ops->ndo_do_ioctl(iface->dev, &atreq, SIOCSIFADDR))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ops->ndo_do_ioctl(iface->dev, &atreq, SIOCGIFADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (iface->address.s_net != htons(sa->sat_addr.s_net) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) iface->address.s_node != sa->sat_addr.s_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) iface->status |= ATIF_PROBE_FAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) iface->address.s_net = htons(sa->sat_addr.s_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) iface->address.s_node = sa->sat_addr.s_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) void aarp_probe_network(struct atalk_iface *atif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (atif->dev->type == ARPHRD_LOCALTLK ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) atif->dev->type == ARPHRD_PPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) aarp_send_probe_phase1(atif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) aarp_send_probe(atif->dev, &atif->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /* Defer 1/10th */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (atif->status & ATIF_PROBE_FAIL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) int hash, retval = -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct aarp_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * we don't currently support LocalTalk or PPP for proxy AARP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * if someone wants to try and add it, have fun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (atif->dev->type == ARPHRD_LOCALTLK ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) atif->dev->type == ARPHRD_PPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * create a new AARP entry with the flags set to be published --
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * we need this one to hang around even if it's in use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) entry = aarp_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (!entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) entry->expires_at = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) entry->status = ATIF_PROBE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) entry->target_addr.s_node = sa->s_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) entry->target_addr.s_net = sa->s_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) entry->dev = atif->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) write_lock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) hash = sa->s_node % (AARP_HASH_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) entry->next = proxies[hash];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) proxies[hash] = entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) aarp_send_probe(atif->dev, sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /* Defer 1/10th */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) write_unlock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) write_lock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (entry->status & ATIF_PROBE_FAIL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (entry->status & ATIF_PROBE_FAIL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) entry->expires_at = jiffies - 1; /* free the entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) retval = -EADDRINUSE; /* return network full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) } else { /* clear the probing flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) entry->status &= ~ATIF_PROBE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) retval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) write_unlock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* Send a DDP frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) int aarp_send_ddp(struct net_device *dev, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct atalk_addr *sa, void *hwaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) static char ddp_eth_multicast[ETH_ALEN] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) int hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct aarp_entry *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /* Check for LocalTalk first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (dev->type == ARPHRD_LOCALTLK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) struct atalk_addr *at = atalk_find_dev_addr(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) struct ddpehdr *ddp = (struct ddpehdr *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) int ft = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * Compressible ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * IFF: src_net == dest_net == device_net
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * (zero matches anything)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if ((!ddp->deh_snet || at->s_net == ddp->deh_snet) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) (!ddp->deh_dnet || at->s_net == ddp->deh_dnet)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) skb_pull(skb, sizeof(*ddp) - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * The upper two remaining bytes are the port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * numbers we just happen to need. Now put the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * length in the lower two.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) *((__be16 *)skb->data) = htons(skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) ft = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * Nice and easy. No AARP type protocols occur here so we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * just shovel it out with a 3 byte LLAP header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) skb_push(skb, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) skb->data[0] = sa->s_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) skb->data[1] = at->s_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) skb->data[2] = ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) skb->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) goto sendit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) /* On a PPP link we neither compress nor aarp. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (dev->type == ARPHRD_PPP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) skb->protocol = htons(ETH_P_PPPTALK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) skb->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) goto sendit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* Non ELAP we cannot do. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (dev->type != ARPHRD_ETHER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) goto free_it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) skb->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) skb->protocol = htons(ETH_P_ATALK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) hash = sa->s_node % (AARP_HASH_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /* Do we have a resolved entry? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (sa->s_node == ATADDR_BCAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* Send it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ddp_dl->request(ddp_dl, skb, ddp_eth_multicast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) goto sent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) write_lock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) a = __aarp_find_entry(resolved[hash], dev, sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (a) { /* Return 1 and fill in the address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) a->expires_at = jiffies + (sysctl_aarp_expiry_time * 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) ddp_dl->request(ddp_dl, skb, a->hwaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) write_unlock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) goto sent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /* Do we have an unresolved entry: This is the less common path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) a = __aarp_find_entry(unresolved[hash], dev, sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (a) { /* Queue onto the unresolved queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) skb_queue_tail(&a->packet_queue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /* Allocate a new entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) a = aarp_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (!a) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /* Whoops slipped... good job it's an unreliable protocol 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) write_unlock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) goto free_it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* Set up the queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) skb_queue_tail(&a->packet_queue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) a->expires_at = jiffies + sysctl_aarp_resolve_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) a->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) a->next = unresolved[hash];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) a->target_addr = *sa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) a->xmit_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) unresolved[hash] = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) unresolved_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) /* Send an initial request for the address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) __aarp_send_query(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * Switch to fast timer if needed (That is if this is the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * unresolved entry to get added)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (unresolved_count == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) mod_timer(&aarp_timer, jiffies + sysctl_aarp_tick_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /* Now finally, it is safe to drop the lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) write_unlock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /* Tell the ddp layer we have taken over for this frame. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) goto sent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) sendit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (skb->sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) skb->priority = skb->sk->sk_priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (dev_queue_xmit(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) sent:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return NET_XMIT_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) free_it:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return NET_XMIT_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) EXPORT_SYMBOL(aarp_send_ddp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * An entry in the aarp unresolved queue has become resolved. Send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * all the frames queued under it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * Must run under aarp_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static void __aarp_resolved(struct aarp_entry **list, struct aarp_entry *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) int hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) while (*list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (*list == a) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) unresolved_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) *list = a->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) /* Move into the resolved list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) a->next = resolved[hash];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) resolved[hash] = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) /* Kick frames off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) while ((skb = skb_dequeue(&a->packet_queue)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) a->expires_at = jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) sysctl_aarp_expiry_time * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) ddp_dl->request(ddp_dl, skb, a->hwaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) list = &((*list)->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * This is called by the SNAP driver whenever we see an AARP SNAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * frame. We currently only support Ethernet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static int aarp_rcv(struct sk_buff *skb, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct packet_type *pt, struct net_device *orig_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct elapaarp *ea = aarp_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) int hash, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) __u16 function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) struct aarp_entry *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) struct atalk_addr sa, *ma, da;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) struct atalk_iface *ifa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (!net_eq(dev_net(dev), &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* We only do Ethernet SNAP AARP. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (dev->type != ARPHRD_ETHER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) /* Frame size ok? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (!skb_pull(skb, sizeof(*ea)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) function = ntohs(ea->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) /* Sanity check fields. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (function < AARP_REQUEST || function > AARP_PROBE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) ea->pa_src_zero || ea->pa_dst_zero)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) /* Looks good. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) hash = ea->pa_src_node % (AARP_HASH_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) /* Build an address. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) sa.s_node = ea->pa_src_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) sa.s_net = ea->pa_src_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) /* Process the packet. Check for replies of me. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) ifa = atalk_find_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (!ifa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (ifa->status & ATIF_PROBE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) ifa->address.s_node == ea->pa_dst_node &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) ifa->address.s_net == ea->pa_dst_net) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) ifa->status |= ATIF_PROBE_FAIL; /* Fail the probe (in use) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /* Check for replies of proxy AARP entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) da.s_node = ea->pa_dst_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) da.s_net = ea->pa_dst_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) write_lock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) a = __aarp_find_entry(proxies[hash], dev, &da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (a && a->status & ATIF_PROBE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) a->status |= ATIF_PROBE_FAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * we do not respond to probe or request packets for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * this address while we are probing this address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) switch (function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) case AARP_REPLY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (!unresolved_count) /* Speed up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) /* Find the entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) a = __aarp_find_entry(unresolved[hash], dev, &sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (!a || dev != a->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) /* We can fill one in - this is good. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) ether_addr_copy(a->hwaddr, ea->hw_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) __aarp_resolved(&unresolved[hash], a, hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (!unresolved_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) mod_timer(&aarp_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) jiffies + sysctl_aarp_expiry_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) case AARP_REQUEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) case AARP_PROBE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * If it is my address set ma to my address and reply.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * We can treat probe and request the same. Probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) * simply means we shouldn't cache the querying host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * as in a probe they are proposing an address not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * using one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * Support for proxy-AARP added. We check if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) * address is one of our proxies before we toss the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * packet out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) sa.s_node = ea->pa_dst_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) sa.s_net = ea->pa_dst_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) /* See if we have a matching proxy. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) ma = __aarp_proxy_find(dev, &sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (!ma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) ma = &ifa->address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) else { /* We need to make a copy of the entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) da.s_node = sa.s_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) da.s_net = sa.s_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) ma = &da;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (function == AARP_PROBE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) * A probe implies someone trying to get an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) * address. So as a precaution flush any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) * entries we have for this address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) a = __aarp_find_entry(resolved[sa.s_node %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) (AARP_HASH_SIZE - 1)],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) skb->dev, &sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * Make it expire next tick - that avoids us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * getting into a probe/flush/learn/probe/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * flush/learn cycle during probing of a slow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * to respond host addr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (a) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) a->expires_at = jiffies - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) mod_timer(&aarp_timer, jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) sysctl_aarp_tick_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) if (sa.s_node != ma->s_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (sa.s_net && ma->s_net && sa.s_net != ma->s_net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) sa.s_node = ea->pa_src_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) sa.s_net = ea->pa_src_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) /* aarp_my_address has found the address to use for us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) aarp_send_reply(dev, ma, &sa, ea->hw_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) write_unlock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) out0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) static struct notifier_block aarp_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) .notifier_call = aarp_device_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) static unsigned char aarp_snap_id[] = { 0x00, 0x00, 0x00, 0x80, 0xF3 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) int __init aarp_proto_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) aarp_dl = register_snap_client(aarp_snap_id, aarp_rcv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (!aarp_dl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) printk(KERN_CRIT "Unable to register AARP with SNAP.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) timer_setup(&aarp_timer, aarp_expire_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) aarp_timer.expires = jiffies + sysctl_aarp_expiry_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) add_timer(&aarp_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) rc = register_netdevice_notifier(&aarp_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) del_timer_sync(&aarp_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) unregister_snap_client(aarp_dl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) /* Remove the AARP entries associated with a device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) void aarp_device_down(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) int ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) write_lock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) __aarp_expire_device(&resolved[ct], dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) __aarp_expire_device(&unresolved[ct], dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) __aarp_expire_device(&proxies[ct], dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) write_unlock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) * Get the aarp entry that is in the chain described
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * by the iterator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) * If pos is set then skip till that index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * pos = 1 is the first entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) static struct aarp_entry *iter_next(struct aarp_iter_state *iter, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) int ct = iter->bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) struct aarp_entry **table = iter->table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) loff_t off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) struct aarp_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) rescan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) while (ct < AARP_HASH_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) for (entry = table[ct]; entry; entry = entry->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (!pos || ++off == *pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) iter->table = table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) iter->bucket = ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) ++ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (table == resolved) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) ct = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) table = unresolved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) goto rescan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (table == unresolved) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ct = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) table = proxies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) goto rescan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) static void *aarp_seq_start(struct seq_file *seq, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) __acquires(aarp_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) struct aarp_iter_state *iter = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) read_lock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) iter->table = resolved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) iter->bucket = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return *pos ? iter_next(iter, pos) : SEQ_START_TOKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static void *aarp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) struct aarp_entry *entry = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) struct aarp_iter_state *iter = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) ++*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) /* first line after header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (v == SEQ_START_TOKEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) entry = iter_next(iter, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) /* next entry in current bucket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) else if (entry->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) /* next bucket or table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) ++iter->bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) entry = iter_next(iter, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) static void aarp_seq_stop(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) __releases(aarp_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) read_unlock_bh(&aarp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) static const char *dt2str(unsigned long ticks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) static char buf[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) sprintf(buf, "%ld.%02ld", ticks / HZ, ((ticks % HZ) * 100) / HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) static int aarp_seq_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) struct aarp_iter_state *iter = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) struct aarp_entry *entry = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) unsigned long now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (v == SEQ_START_TOKEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) seq_puts(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) "Address Interface Hardware Address"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) " Expires LastSend Retry Status\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) seq_printf(seq, "%04X:%02X %-12s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) ntohs(entry->target_addr.s_net),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) (unsigned int) entry->target_addr.s_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) entry->dev ? entry->dev->name : "????");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) seq_printf(seq, "%pM", entry->hwaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) seq_printf(seq, " %8s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) dt2str((long)entry->expires_at - (long)now));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (iter->table == unresolved)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) seq_printf(seq, " %8s %6hu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) dt2str(now - entry->last_sent),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) entry->xmit_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) seq_puts(seq, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) seq_printf(seq, " %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) (iter->table == resolved) ? "resolved"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) : (iter->table == unresolved) ? "unresolved"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) : (iter->table == proxies) ? "proxies"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) : "unknown");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) const struct seq_operations aarp_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) .start = aarp_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .next = aarp_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) .stop = aarp_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) .show = aarp_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) /* General module cleanup. Called from cleanup_module() in ddp.c. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) void aarp_cleanup_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) del_timer_sync(&aarp_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) unregister_netdevice_notifier(&aarp_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) unregister_snap_client(aarp_dl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) aarp_purge();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }