mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	netfilter: nft_fib: Support existence check
Instead of the actual interface index or name, set destination register to just 1 or 0 depending on whether the lookup succeeded or not if NFTA_FIB_F_PRESENT was set in userspace. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
		
							parent
							
								
									1a64edf54f
								
							
						
					
					
						commit
						055c4b34b9
					
				
					 5 changed files with 14 additions and 9 deletions
				
			
		| 
						 | 
					@ -32,6 +32,6 @@ void nft_fib6_eval_type(const struct nft_expr *expr, struct nft_regs *regs,
 | 
				
			||||||
void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
 | 
					void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
 | 
				
			||||||
		   const struct nft_pktinfo *pkt);
 | 
							   const struct nft_pktinfo *pkt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void nft_fib_store_result(void *reg, enum nft_fib_result r,
 | 
					void nft_fib_store_result(void *reg, const struct nft_fib *priv,
 | 
				
			||||||
			  const struct nft_pktinfo *pkt, int index);
 | 
								  const struct nft_pktinfo *pkt, int index);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1257,6 +1257,7 @@ enum nft_fib_flags {
 | 
				
			||||||
	NFTA_FIB_F_MARK		= 1 << 2,	/* use skb->mark */
 | 
						NFTA_FIB_F_MARK		= 1 << 2,	/* use skb->mark */
 | 
				
			||||||
	NFTA_FIB_F_IIF		= 1 << 3,	/* restrict to iif */
 | 
						NFTA_FIB_F_IIF		= 1 << 3,	/* restrict to iif */
 | 
				
			||||||
	NFTA_FIB_F_OIF		= 1 << 4,	/* restrict to oif */
 | 
						NFTA_FIB_F_OIF		= 1 << 4,	/* restrict to oif */
 | 
				
			||||||
 | 
						NFTA_FIB_F_PRESENT	= 1 << 5,	/* check existence only */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum nft_ct_helper_attributes {
 | 
					enum nft_ct_helper_attributes {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -90,7 +90,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nft_hook(pkt) == NF_INET_PRE_ROUTING &&
 | 
						if (nft_hook(pkt) == NF_INET_PRE_ROUTING &&
 | 
				
			||||||
	    nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
 | 
						    nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
 | 
				
			||||||
		nft_fib_store_result(dest, priv->result, pkt,
 | 
							nft_fib_store_result(dest, priv, pkt,
 | 
				
			||||||
				     nft_in(pkt)->ifindex);
 | 
									     nft_in(pkt)->ifindex);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -99,7 +99,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
 | 
				
			||||||
	if (ipv4_is_zeronet(iph->saddr)) {
 | 
						if (ipv4_is_zeronet(iph->saddr)) {
 | 
				
			||||||
		if (ipv4_is_lbcast(iph->daddr) ||
 | 
							if (ipv4_is_lbcast(iph->daddr) ||
 | 
				
			||||||
		    ipv4_is_local_multicast(iph->daddr)) {
 | 
							    ipv4_is_local_multicast(iph->daddr)) {
 | 
				
			||||||
			nft_fib_store_result(dest, priv->result, pkt,
 | 
								nft_fib_store_result(dest, priv, pkt,
 | 
				
			||||||
					     get_ifindex(pkt->skb->dev));
 | 
										     get_ifindex(pkt->skb->dev));
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -159,7 +159,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nft_hook(pkt) == NF_INET_PRE_ROUTING &&
 | 
						if (nft_hook(pkt) == NF_INET_PRE_ROUTING &&
 | 
				
			||||||
	    nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
 | 
						    nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
 | 
				
			||||||
		nft_fib_store_result(dest, priv->result, pkt,
 | 
							nft_fib_store_result(dest, priv, pkt,
 | 
				
			||||||
				     nft_in(pkt)->ifindex);
 | 
									     nft_in(pkt)->ifindex);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,8 @@ const struct nla_policy nft_fib_policy[NFTA_FIB_MAX + 1] = {
 | 
				
			||||||
EXPORT_SYMBOL(nft_fib_policy);
 | 
					EXPORT_SYMBOL(nft_fib_policy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NFTA_FIB_F_ALL (NFTA_FIB_F_SADDR | NFTA_FIB_F_DADDR | \
 | 
					#define NFTA_FIB_F_ALL (NFTA_FIB_F_SADDR | NFTA_FIB_F_DADDR | \
 | 
				
			||||||
			NFTA_FIB_F_MARK | NFTA_FIB_F_IIF | NFTA_FIB_F_OIF)
 | 
								NFTA_FIB_F_MARK | NFTA_FIB_F_IIF | NFTA_FIB_F_OIF | \
 | 
				
			||||||
 | 
								NFTA_FIB_F_PRESENT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr,
 | 
					int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr,
 | 
				
			||||||
		     const struct nft_data **data)
 | 
							     const struct nft_data **data)
 | 
				
			||||||
| 
						 | 
					@ -133,18 +134,21 @@ int nft_fib_dump(struct sk_buff *skb, const struct nft_expr *expr)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(nft_fib_dump);
 | 
					EXPORT_SYMBOL_GPL(nft_fib_dump);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void nft_fib_store_result(void *reg, enum nft_fib_result r,
 | 
					void nft_fib_store_result(void *reg, const struct nft_fib *priv,
 | 
				
			||||||
			  const struct nft_pktinfo *pkt, int index)
 | 
								  const struct nft_pktinfo *pkt, int index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net_device *dev;
 | 
						struct net_device *dev;
 | 
				
			||||||
	u32 *dreg = reg;
 | 
						u32 *dreg = reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (r) {
 | 
						switch (priv->result) {
 | 
				
			||||||
	case NFT_FIB_RESULT_OIF:
 | 
						case NFT_FIB_RESULT_OIF:
 | 
				
			||||||
		*dreg = index;
 | 
							*dreg = (priv->flags & NFTA_FIB_F_PRESENT) ? !!index : index;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case NFT_FIB_RESULT_OIFNAME:
 | 
						case NFT_FIB_RESULT_OIFNAME:
 | 
				
			||||||
		dev = dev_get_by_index_rcu(nft_net(pkt), index);
 | 
							dev = dev_get_by_index_rcu(nft_net(pkt), index);
 | 
				
			||||||
 | 
							if (priv->flags & NFTA_FIB_F_PRESENT)
 | 
				
			||||||
 | 
								*dreg = !!dev;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
			strncpy(reg, dev ? dev->name : "", IFNAMSIZ);
 | 
								strncpy(reg, dev ? dev->name : "", IFNAMSIZ);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue