Loading net/ipv4/devinet.c +33 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,39 @@ static void inet_hash_remove(struct in_ifaddr *ifa) spin_unlock(&inet_addr_hash_lock); } /** * __ip_dev_find - find the first device with a given source address. * @net: the net namespace * @addr: the source address * @devref: if true, take a reference on the found device * * If a caller uses devref=false, it should be protected by RCU, or RTNL */ struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) { unsigned int hash = inet_addr_hash(net, addr); struct net_device *result = NULL; struct in_ifaddr *ifa; struct hlist_node *node; rcu_read_lock(); hlist_for_each_entry_rcu(ifa, node, &inet_addr_lst[hash], hash) { struct net_device *dev = ifa->ifa_dev->dev; if (!net_eq(dev_net(dev), net)) continue; if (ifa->ifa_address == addr) { result = dev; break; } } if (result && devref) dev_hold(result); rcu_read_unlock(); return result; } EXPORT_SYMBOL(__ip_dev_find); static void rtmsg_ifa(int event, struct in_ifaddr *, struct nlmsghdr *, u32); static BLOCKING_NOTIFIER_HEAD(inetaddr_chain); Loading net/ipv4/fib_frontend.c +0 −40 Original line number Diff line number Diff line Loading @@ -132,46 +132,6 @@ static void fib_flush(struct net *net) rt_cache_flush(net, -1); } /** * __ip_dev_find - find the first device with a given source address. * @net: the net namespace * @addr: the source address * @devref: if true, take a reference on the found device * * If a caller uses devref=false, it should be protected by RCU, or RTNL */ struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) { struct flowi fl = { .fl4_dst = addr, }; struct fib_result res = { 0 }; struct net_device *dev = NULL; struct fib_table *local_table; #ifdef CONFIG_IP_MULTIPLE_TABLES res.r = NULL; #endif rcu_read_lock(); local_table = fib_get_table(net, RT_TABLE_LOCAL); if (!local_table || fib_table_lookup(local_table, &fl, &res, FIB_LOOKUP_NOREF)) { rcu_read_unlock(); return NULL; } if (res.type != RTN_LOCAL) goto out; dev = FIB_RES_DEV(res); if (dev && devref) dev_hold(dev); out: rcu_read_unlock(); return dev; } EXPORT_SYMBOL(__ip_dev_find); /* * Find address type as if only "dev" was present in the system. If * on_dev is NULL then all interfaces are taken into consideration. Loading Loading
net/ipv4/devinet.c +33 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,39 @@ static void inet_hash_remove(struct in_ifaddr *ifa) spin_unlock(&inet_addr_hash_lock); } /** * __ip_dev_find - find the first device with a given source address. * @net: the net namespace * @addr: the source address * @devref: if true, take a reference on the found device * * If a caller uses devref=false, it should be protected by RCU, or RTNL */ struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) { unsigned int hash = inet_addr_hash(net, addr); struct net_device *result = NULL; struct in_ifaddr *ifa; struct hlist_node *node; rcu_read_lock(); hlist_for_each_entry_rcu(ifa, node, &inet_addr_lst[hash], hash) { struct net_device *dev = ifa->ifa_dev->dev; if (!net_eq(dev_net(dev), net)) continue; if (ifa->ifa_address == addr) { result = dev; break; } } if (result && devref) dev_hold(result); rcu_read_unlock(); return result; } EXPORT_SYMBOL(__ip_dev_find); static void rtmsg_ifa(int event, struct in_ifaddr *, struct nlmsghdr *, u32); static BLOCKING_NOTIFIER_HEAD(inetaddr_chain); Loading
net/ipv4/fib_frontend.c +0 −40 Original line number Diff line number Diff line Loading @@ -132,46 +132,6 @@ static void fib_flush(struct net *net) rt_cache_flush(net, -1); } /** * __ip_dev_find - find the first device with a given source address. * @net: the net namespace * @addr: the source address * @devref: if true, take a reference on the found device * * If a caller uses devref=false, it should be protected by RCU, or RTNL */ struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) { struct flowi fl = { .fl4_dst = addr, }; struct fib_result res = { 0 }; struct net_device *dev = NULL; struct fib_table *local_table; #ifdef CONFIG_IP_MULTIPLE_TABLES res.r = NULL; #endif rcu_read_lock(); local_table = fib_get_table(net, RT_TABLE_LOCAL); if (!local_table || fib_table_lookup(local_table, &fl, &res, FIB_LOOKUP_NOREF)) { rcu_read_unlock(); return NULL; } if (res.type != RTN_LOCAL) goto out; dev = FIB_RES_DEV(res); if (dev && devref) dev_hold(dev); out: rcu_read_unlock(); return dev; } EXPORT_SYMBOL(__ip_dev_find); /* * Find address type as if only "dev" was present in the system. If * on_dev is NULL then all interfaces are taken into consideration. Loading