netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [nf-next PATCH] net: netfilter: Support iif matches in POSTROUTING
@ 2019-11-12 16:14 Phil Sutter
  2019-11-13 23:08 ` Pablo Neira Ayuso
  2019-11-15 22:36 ` Pablo Neira Ayuso
  0 siblings, 2 replies; 4+ messages in thread
From: Phil Sutter @ 2019-11-12 16:14 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, Eric Garver

Instead of generally passing NULL to NF_HOOK_COND() for input device,
pass skb->dev which contains input device for routed skbs.

Note that iptables (both legacy and nft) reject rules with input
interface match from being added to POSTROUTING chains, but nftables
allows this.

Cc: Eric Garver <eric@garver.life>
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 net/ipv4/ip_output.c    | 4 ++--
 net/ipv4/xfrm4_output.c | 2 +-
 net/ipv6/ip6_output.c   | 4 ++--
 net/ipv6/xfrm6_output.c | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 3d8baaaf7086d..9d83cb320dcb7 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -422,7 +422,7 @@ int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 
 int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
-	struct net_device *dev = skb_dst(skb)->dev;
+	struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
 
 	IP_UPD_PO_STATS(net, IPSTATS_MIB_OUT, skb->len);
 
@@ -430,7 +430,7 @@ int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 	skb->protocol = htons(ETH_P_IP);
 
 	return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING,
-			    net, sk, skb, NULL, dev,
+			    net, sk, skb, indev, dev,
 			    ip_finish_output,
 			    !(IPCB(skb)->flags & IPSKB_REROUTED));
 }
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index ecff3fce98073..89ba7c87de5df 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -92,7 +92,7 @@ static int __xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
 	return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING,
-			    net, sk, skb, NULL, skb_dst(skb)->dev,
+			    net, sk, skb, skb->dev, skb_dst(skb)->dev,
 			    __xfrm4_output,
 			    !(IPCB(skb)->flags & IPSKB_REROUTED));
 }
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 71827b56c0063..945508a7cb0f1 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -160,7 +160,7 @@ static int ip6_finish_output(struct net *net, struct sock *sk, struct sk_buff *s
 
 int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
-	struct net_device *dev = skb_dst(skb)->dev;
+	struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
 	struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
 
 	skb->protocol = htons(ETH_P_IPV6);
@@ -173,7 +173,7 @@ int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 	}
 
 	return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING,
-			    net, sk, skb, NULL, dev,
+			    net, sk, skb, indev, dev,
 			    ip6_finish_output,
 			    !(IP6CB(skb)->flags & IP6SKB_REROUTED));
 }
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index eecac1b7148e5..fbe51d40bd7e9 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -187,7 +187,7 @@ static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
 	return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING,
-			    net, sk, skb,  NULL, skb_dst(skb)->dev,
+			    net, sk, skb,  skb->dev, skb_dst(skb)->dev,
 			    __xfrm6_output,
 			    !(IP6CB(skb)->flags & IP6SKB_REROUTED));
 }
-- 
2.24.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [nf-next PATCH] net: netfilter: Support iif matches in POSTROUTING
  2019-11-12 16:14 [nf-next PATCH] net: netfilter: Support iif matches in POSTROUTING Phil Sutter
@ 2019-11-13 23:08 ` Pablo Neira Ayuso
  2019-11-14 10:47   ` Phil Sutter
  2019-11-15 22:36 ` Pablo Neira Ayuso
  1 sibling, 1 reply; 4+ messages in thread
From: Pablo Neira Ayuso @ 2019-11-13 23:08 UTC (permalink / raw)
  To: Phil Sutter; +Cc: netfilter-devel, netdev, Eric Garver

On Tue, Nov 12, 2019 at 05:14:37PM +0100, Phil Sutter wrote:
> Instead of generally passing NULL to NF_HOOK_COND() for input device,
> pass skb->dev which contains input device for routed skbs.
> 
> Note that iptables (both legacy and nft) reject rules with input
> interface match from being added to POSTROUTING chains, but nftables
> allows this.

Yes, it allows this but it will not ever match, right? So even if the
rule is loaded, it will be useless.

Do you have a usecase in mind that would benefit from this specifically?

> Cc: Eric Garver <eric@garver.life>
> Signed-off-by: Phil Sutter <phil@nwl.cc>
> ---
>  net/ipv4/ip_output.c    | 4 ++--
>  net/ipv4/xfrm4_output.c | 2 +-
>  net/ipv6/ip6_output.c   | 4 ++--
>  net/ipv6/xfrm6_output.c | 2 +-
>  4 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
> index 3d8baaaf7086d..9d83cb320dcb7 100644
> --- a/net/ipv4/ip_output.c
> +++ b/net/ipv4/ip_output.c
> @@ -422,7 +422,7 @@ int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb)
>  
>  int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
>  {
> -	struct net_device *dev = skb_dst(skb)->dev;
> +	struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
>  
>  	IP_UPD_PO_STATS(net, IPSTATS_MIB_OUT, skb->len);
>  
> @@ -430,7 +430,7 @@ int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb)
>  	skb->protocol = htons(ETH_P_IP);
>  
>  	return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING,
> -			    net, sk, skb, NULL, dev,
> +			    net, sk, skb, indev, dev,
>  			    ip_finish_output,
>  			    !(IPCB(skb)->flags & IPSKB_REROUTED));
>  }
> diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
> index ecff3fce98073..89ba7c87de5df 100644
> --- a/net/ipv4/xfrm4_output.c
> +++ b/net/ipv4/xfrm4_output.c
> @@ -92,7 +92,7 @@ static int __xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb)
>  int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb)
>  {
>  	return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING,
> -			    net, sk, skb, NULL, skb_dst(skb)->dev,
> +			    net, sk, skb, skb->dev, skb_dst(skb)->dev,
>  			    __xfrm4_output,
>  			    !(IPCB(skb)->flags & IPSKB_REROUTED));
>  }
> diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
> index 71827b56c0063..945508a7cb0f1 100644
> --- a/net/ipv6/ip6_output.c
> +++ b/net/ipv6/ip6_output.c
> @@ -160,7 +160,7 @@ static int ip6_finish_output(struct net *net, struct sock *sk, struct sk_buff *s
>  
>  int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
>  {
> -	struct net_device *dev = skb_dst(skb)->dev;
> +	struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
>  	struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
>  
>  	skb->protocol = htons(ETH_P_IPV6);
> @@ -173,7 +173,7 @@ int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
>  	}
>  
>  	return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING,
> -			    net, sk, skb, NULL, dev,
> +			    net, sk, skb, indev, dev,
>  			    ip6_finish_output,
>  			    !(IP6CB(skb)->flags & IP6SKB_REROUTED));
>  }
> diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
> index eecac1b7148e5..fbe51d40bd7e9 100644
> --- a/net/ipv6/xfrm6_output.c
> +++ b/net/ipv6/xfrm6_output.c
> @@ -187,7 +187,7 @@ static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
>  int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
>  {
>  	return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING,
> -			    net, sk, skb,  NULL, skb_dst(skb)->dev,
> +			    net, sk, skb,  skb->dev, skb_dst(skb)->dev,
>  			    __xfrm6_output,
>  			    !(IP6CB(skb)->flags & IP6SKB_REROUTED));
>  }
> -- 
> 2.24.0
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [nf-next PATCH] net: netfilter: Support iif matches in POSTROUTING
  2019-11-13 23:08 ` Pablo Neira Ayuso
@ 2019-11-14 10:47   ` Phil Sutter
  0 siblings, 0 replies; 4+ messages in thread
From: Phil Sutter @ 2019-11-14 10:47 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev, Eric Garver

On Thu, Nov 14, 2019 at 12:08:42AM +0100, Pablo Neira Ayuso wrote:
> On Tue, Nov 12, 2019 at 05:14:37PM +0100, Phil Sutter wrote:
> > Instead of generally passing NULL to NF_HOOK_COND() for input device,
> > pass skb->dev which contains input device for routed skbs.
> > 
> > Note that iptables (both legacy and nft) reject rules with input
> > interface match from being added to POSTROUTING chains, but nftables
> > allows this.
> 
> Yes, it allows this but it will not ever match, right? So even if the
> rule is loaded, it will be useless.

This patch changes that. What you're referring to is the NFWS discussion
about nft_meta: In the past, iif* matches would enter error path if
input interface was NULL, thereby aborting rule traversal (NFT_BREAK).
That was changed in commit cb81572e8cb50 ("netfilter: nf_tables: Make
nft_meta expression more robust") to instead just set dreg to something
that usually doesn't match.

> Do you have a usecase in mind that would benefit from this specifically?

I would like to masquerade traffic coming from a local private
interface, like so:

| nft add rule ip filter POSTROUTING iifname 'vnetbr0' masquerade

A typical idiom commonly used to avoid this disallowed match is to
masquerade anything that's not routed to the private interface:

| iptables -t nat -A POSTROUTING ! -o vnetbr0 -j MASQUERADE

But this rule will match more traffic than necessary, also things get a
bit complicated when using multiple private interfaces between which
traffic shouldn't be masqueraded.

Firewalld has a special workaround, it marks packets for later:

| iptables -t nat -A PREROUTING -i vnetbr0 -j MARK --set-mark 0xbeef
| iptables -t nat -A POSTROUTING -m mark --mark 0xbeef -j MASQUERADE

Cheers, Phil

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [nf-next PATCH] net: netfilter: Support iif matches in POSTROUTING
  2019-11-12 16:14 [nf-next PATCH] net: netfilter: Support iif matches in POSTROUTING Phil Sutter
  2019-11-13 23:08 ` Pablo Neira Ayuso
@ 2019-11-15 22:36 ` Pablo Neira Ayuso
  1 sibling, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2019-11-15 22:36 UTC (permalink / raw)
  To: Phil Sutter; +Cc: netfilter-devel, netdev, Eric Garver

On Tue, Nov 12, 2019 at 05:14:37PM +0100, Phil Sutter wrote:
> Instead of generally passing NULL to NF_HOOK_COND() for input device,
> pass skb->dev which contains input device for routed skbs.
> 
> Note that iptables (both legacy and nft) reject rules with input
> interface match from being added to POSTROUTING chains, but nftables
> allows this.

Applied, thanks.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-11-15 22:36 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-12 16:14 [nf-next PATCH] net: netfilter: Support iif matches in POSTROUTING Phil Sutter
2019-11-13 23:08 ` Pablo Neira Ayuso
2019-11-14 10:47   ` Phil Sutter
2019-11-15 22:36 ` Pablo Neira Ayuso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).