···125125 spin_unlock(&inet_addr_hash_lock);126126}127127128128+/**129129+ * __ip_dev_find - find the first device with a given source address.130130+ * @net: the net namespace131131+ * @addr: the source address132132+ * @devref: if true, take a reference on the found device133133+ *134134+ * If a caller uses devref=false, it should be protected by RCU, or RTNL135135+ */136136+struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref)137137+{138138+ unsigned int hash = inet_addr_hash(net, addr);139139+ struct net_device *result = NULL;140140+ struct in_ifaddr *ifa;141141+ struct hlist_node *node;142142+143143+ rcu_read_lock();144144+ hlist_for_each_entry_rcu(ifa, node, &inet_addr_lst[hash], hash) {145145+ struct net_device *dev = ifa->ifa_dev->dev;146146+147147+ if (!net_eq(dev_net(dev), net))148148+ continue;149149+ if (ifa->ifa_address == addr) {150150+ result = dev;151151+ break;152152+ }153153+ }154154+ if (result && devref)155155+ dev_hold(result);156156+ rcu_read_unlock();157157+ return result;158158+}159159+EXPORT_SYMBOL(__ip_dev_find);160160+128161static void rtmsg_ifa(int event, struct in_ifaddr *, struct nlmsghdr *, u32);129162130163static BLOCKING_NOTIFIER_HEAD(inetaddr_chain);
-40
net/ipv4/fib_frontend.c
···132132 rt_cache_flush(net, -1);133133}134134135135-/**136136- * __ip_dev_find - find the first device with a given source address.137137- * @net: the net namespace138138- * @addr: the source address139139- * @devref: if true, take a reference on the found device140140- *141141- * If a caller uses devref=false, it should be protected by RCU, or RTNL142142- */143143-struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref)144144-{145145- struct flowi fl = {146146- .fl4_dst = addr,147147- };148148- struct fib_result res = { 0 };149149- struct net_device *dev = NULL;150150- struct fib_table *local_table;151151-152152-#ifdef CONFIG_IP_MULTIPLE_TABLES153153- res.r = NULL;154154-#endif155155-156156- rcu_read_lock();157157- local_table = fib_get_table(net, RT_TABLE_LOCAL);158158- if (!local_table ||159159- fib_table_lookup(local_table, &fl, &res, FIB_LOOKUP_NOREF)) {160160- rcu_read_unlock();161161- return NULL;162162- }163163- if (res.type != RTN_LOCAL)164164- goto out;165165- dev = FIB_RES_DEV(res);166166-167167- if (dev && devref)168168- dev_hold(dev);169169-out:170170- rcu_read_unlock();171171- return dev;172172-}173173-EXPORT_SYMBOL(__ip_dev_find);174174-175135/*176136 * Find address type as if only "dev" was present in the system. If177137 * on_dev is NULL then all interfaces are taken into consideration.