static bool rpfilter_lookup_reverse(struct flowi4 *fl4,
				const struct net_device *dev, u8 flags)
{
	struct fib_result res;
	bool dev_match;
	struct net *net = dev_net(dev);
	int ret __maybe_unused;

	if (fib_lookup(net, fl4, &res))
		return false;

	if (res.type != RTN_UNICAST) {
		if (res.type != RTN_LOCAL || !(flags & XT_RPFILTER_ACCEPT_LOCAL))
			return false;
	}
	dev_match = false;
#ifdef CONFIG_IP_ROUTE_MULTIPATH
	for (ret = 0; ret < res.fi->fib_nhs; ret++) {
		struct fib_nh *nh = &res.fi->fib_nh[ret];

		if (nh->nh_dev == dev) {
			dev_match = true;
			break;
		}
	}
#else
	if (FIB_RES_DEV(res) == dev)
		dev_match = true;
#endif
	if (dev_match || flags & XT_RPFILTER_LOOSE)
		return FIB_RES_NH(res).nh_scope <= RT_SCOPE_HOST;
	return dev_match;
}
Exemple #2
0
void fib_select_default(struct net *net,
			const struct flowi *flp, struct fib_result *res)
{
	struct fib_table *tb;
	int table = RT_TABLE_MAIN;
#ifdef CONFIG_IP_MULTIPLE_TABLES
	if (res->r == NULL || res->r->action != FR_ACT_TO_TBL)
		return;
	table = res->r->table;
#endif
	tb = fib_get_table(net, table);
	if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
		tb->tb_select_default(tb, flp, res);
}