mirror of
https://github.com/torvalds/linux.git
synced 2026-09-14 16:10:02 +02:00
netfilter pull request 26-07-31
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEjF9xRqF1emXiQiqU1w0aZmrPKyEFAmpsvPAACgkQ1w0aZmrP KyFK9Q/+IhNDdeTfwLhAemxCtgCVyqsuKYprtnNU6eH4s+5RMF9uKiWQIzdjfOfP G5f9TvPfJbhqPAr6L3t1MpVu+wNSLlABdCJIEhTR1rMZaEEHZPuXH0TGlml+u8yC /izI0s7YP0ijGfGZgNznYXToGEzHRiMQ800LE/U8G5+QQE1pIp+ihpMTWz+4lNzS XmHqFmc1UoWCmkvMR5OkwqV3m1Q8PsNkeNwt85G6Uq4D4ILeoSo6oiphMTkuN6ZU kcWwBC0ko2yvBWMLtygFroa7ZQbM3CIkqjvBhORNyQ1X0/uK1JXvTVWiwxPgnWOM 1wfKTAxgaqxOH0tVAi6CD6oOjEoCKnEYrnlIJ5vV0bJDTbCg/bofDpqODO7CvaOs LahTQB/3MTemCKHWrXgOo7Wf/LR4fs01pO4dLdezb1rPhLG34ACuDbLEMwzKxD3V Wl1py7l0CUVAbg/o02la5x/2Gng0JYENPOJCUAesDkHKXTebgSUMI4CSUK47AcrY e6skGbkVO86gzwiPWuUrtF8jcxmQl9jrtqsaUfpXM78uRwzSWIIOBpfmF2oovM6z my+yN+uLfIdzde1P2so6tyjdCNAwkGGsavycdFYqXU7w7/dGO45hicGy2ZQvxFzF qy2EphdePWNJ8FXSvYnsmLfqG0LZLT7biIhvxLWRNjVf10nTd7w= =T2rO -----END PGP SIGNATURE----- Merge tag 'nf-next-26-07-31' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next Pablo Neira Ayuso says: ==================== Netfilter updates for net-next The following patchset contains Netfilter updates for net-next: 1) Update conncount to use the original tuple after ct lookup to ensure consistent counting, from Fernando F. Mancera. 2) Remove redundant net_device field in info structure that helps parse the flowtable path discovery. 3) Move net_device to flowtable check to the flowtable discovery path parser. This is preparation work to pass the tunnel dst_entry via .fill_forward_path. 4) Update DSA .fill_forward_path to break at the user DSA, since the conduit DSA is not used in the datapath. This slighly simplifies the flowtable path discovery parser. 5) Do not advance index in the path stack prematurely, otherwise it points to uninitialized slots on error. Not an issue currently but it could be once tunnel dst_entry is passed via .fill_forward_path. 6) Pass the tunnel dst_entry via dev_fill_forward_path(). 7) Update ipip and ip6ip6 tunnels to pass the dst_entry through dev_fill_forward_path(). 8) Call skb_valid_dst() before accessing skb_dst() to ensure dst_entry is not a template. 9) Use UNACK timeout when RST packet does not match the expected window while in ESTABLISHED state, the existing approach the CLOSE state timeout which is only 10 seconds. Adopt a more conservative timeout by default for this case. * tag 'nf-next-26-07-31' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next: netfilter: conntrack: tcp: use UNACK timeout for non-closing RST packets netfilter: nf_tables: call skb_valid_dst() before skb_dst() netfilter: flowtable: release tunnel route on error when building forward path net: pass dst via net_device_path in dev_fill_forward_path() net: do not advance stack index from dev_fwd_path() net: dsa: stop at the user device in .fill_forward_path netfilter: flowtable: consolidate flowtable device check netfilter: flowtable: consolidate net_device field in nft_forward_info struct netfilter: conncount: normalize tuple and zone on successful ct lookup ==================== Link: https://patch.msgid.link/20260731153402.851224-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
419ce0a308
|
|
@ -296,14 +296,18 @@ static int airoha_ppe_get_wdma_info(struct net_device *dev, const u8 *addr,
|
|||
return err;
|
||||
|
||||
path = &stack.path[stack.num_paths - 1];
|
||||
if (path->type != DEV_PATH_MTK_WDMA)
|
||||
return -EINVAL;
|
||||
if (path->type != DEV_PATH_MTK_WDMA) {
|
||||
err = -EINVAL;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
info->idx = path->mtk_wdma.wdma_idx;
|
||||
info->bss = path->mtk_wdma.bss;
|
||||
info->wcid = path->mtk_wdma.wcid;
|
||||
err_out:
|
||||
dev_fill_forward_path_release(&stack);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int airoha_get_dsa_port(struct net_device **dev)
|
||||
|
|
|
|||
|
|
@ -108,16 +108,20 @@ mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_i
|
|||
return err;
|
||||
|
||||
path = &stack.path[stack.num_paths - 1];
|
||||
if (path->type != DEV_PATH_MTK_WDMA)
|
||||
return -1;
|
||||
if (path->type != DEV_PATH_MTK_WDMA) {
|
||||
err = -EINVAL;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
info->wdma_idx = path->mtk_wdma.wdma_idx;
|
||||
info->queue = path->mtk_wdma.queue;
|
||||
info->bss = path->mtk_wdma.bss;
|
||||
info->wcid = path->mtk_wdma.wcid;
|
||||
info->amsdu = path->mtk_wdma.amsdu;
|
||||
err_out:
|
||||
dev_fill_forward_path_release(&stack);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -892,6 +892,7 @@ struct net_device_path {
|
|||
u8 h_dest[ETH_ALEN];
|
||||
} encap;
|
||||
struct {
|
||||
struct dst_entry *dst;
|
||||
union {
|
||||
struct in_addr src_v4;
|
||||
struct in6_addr src_v6;
|
||||
|
|
@ -3427,6 +3428,7 @@ int dev_get_iflink(const struct net_device *dev);
|
|||
int dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb);
|
||||
int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
|
||||
struct net_device_path_stack *stack);
|
||||
void dev_fill_forward_path_release(struct net_device_path_stack *stack);
|
||||
struct net_device *dev_get_by_name(struct net *net, const char *name);
|
||||
struct net_device *dev_get_by_name_rcu(struct net *net, const char *name);
|
||||
struct net_device *__dev_get_by_name(struct net *net, const char *name);
|
||||
|
|
|
|||
|
|
@ -742,14 +742,33 @@ EXPORT_SYMBOL_GPL(dev_fill_metadata_dst);
|
|||
|
||||
static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack)
|
||||
{
|
||||
int k = stack->num_paths++;
|
||||
|
||||
if (k >= NET_DEVICE_PATH_STACK_MAX)
|
||||
if (stack->num_paths + 1 > NET_DEVICE_PATH_STACK_MAX)
|
||||
return NULL;
|
||||
|
||||
return &stack->path[k];
|
||||
return &stack->path[stack->num_paths];
|
||||
}
|
||||
|
||||
void dev_fill_forward_path_release(struct net_device_path_stack *stack)
|
||||
{
|
||||
struct net_device_path *path;
|
||||
int k;
|
||||
|
||||
if (stack->num_paths == 0)
|
||||
return;
|
||||
|
||||
for (k = stack->num_paths - 1; k >= 0; k--) {
|
||||
path = &stack->path[k];
|
||||
switch (path->type) {
|
||||
case DEV_PATH_TUN:
|
||||
dst_release(path->tun.dst);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dev_fill_forward_path_release);
|
||||
|
||||
int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
|
||||
struct net_device_path_stack *stack)
|
||||
{
|
||||
|
|
@ -766,15 +785,16 @@ int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
|
|||
last_dev = ctx.dev;
|
||||
path = dev_fwd_path(stack);
|
||||
if (!path)
|
||||
return -1;
|
||||
goto err_out;
|
||||
|
||||
memset(path, 0, sizeof(struct net_device_path));
|
||||
ret = ctx.dev->netdev_ops->ndo_fill_forward_path(&ctx, path);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
goto err_out;
|
||||
|
||||
stack->num_paths++;
|
||||
if (WARN_ON_ONCE(last_dev == ctx.dev))
|
||||
return -1;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (!ctx.dev)
|
||||
|
|
@ -782,11 +802,17 @@ int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
|
|||
|
||||
path = dev_fwd_path(stack);
|
||||
if (!path)
|
||||
return -1;
|
||||
goto err_out;
|
||||
|
||||
path->type = DEV_PATH_ETHERNET;
|
||||
path->dev = ctx.dev;
|
||||
stack->num_paths++;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
err_out:
|
||||
dev_fill_forward_path_release(stack);
|
||||
|
||||
return -1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dev_fill_forward_path);
|
||||
|
||||
|
|
|
|||
|
|
@ -2547,14 +2547,13 @@ static int dsa_user_fill_forward_path(struct net_device_path_ctx *ctx,
|
|||
struct net_device_path *path)
|
||||
{
|
||||
struct dsa_port *dp = dsa_user_to_port(ctx->dev);
|
||||
struct net_device *conduit = dsa_port_to_conduit(dp);
|
||||
struct dsa_port *cpu_dp = dp->cpu_dp;
|
||||
|
||||
path->dev = ctx->dev;
|
||||
path->type = DEV_PATH_DSA;
|
||||
path->dsa.proto = cpu_dp->tag_ops->proto;
|
||||
path->dsa.port = dp->index;
|
||||
ctx->dev = conduit;
|
||||
ctx->dev = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -376,10 +376,10 @@ static int ipip_fill_forward_path(struct net_device_path_ctx *ctx,
|
|||
path->tun.src_v4.s_addr = tiph->saddr;
|
||||
path->tun.dst_v4.s_addr = tiph->daddr;
|
||||
path->tun.l3_proto = IPPROTO_IPIP;
|
||||
path->tun.dst = &rt->dst;
|
||||
path->dev = ctx->dev;
|
||||
|
||||
ctx->dev = rt->dst.dev;
|
||||
ip_rt_put(rt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <net/tcp.h>
|
||||
#include <net/route.h>
|
||||
#include <net/dst.h>
|
||||
#include <net/dst_metadata.h>
|
||||
#include <net/netfilter/ipv4/nf_reject.h>
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/netfilter_bridge.h>
|
||||
|
|
@ -263,6 +264,7 @@ static int nf_reject_fill_skb_dst(struct sk_buff *skb_in)
|
|||
if (!dst)
|
||||
return -1;
|
||||
|
||||
skb_dst_drop(skb_in);
|
||||
skb_dst_set(skb_in, dst);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -279,7 +281,7 @@ void nf_send_reset(struct net *net, struct sock *sk, struct sk_buff *oldskb,
|
|||
if (!oth)
|
||||
return;
|
||||
|
||||
if (!skb_dst(oldskb) && nf_reject_fill_skb_dst(oldskb) < 0)
|
||||
if (!skb_valid_dst(oldskb) && nf_reject_fill_skb_dst(oldskb) < 0)
|
||||
return;
|
||||
|
||||
if (skb_rtable(oldskb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
|
||||
|
|
@ -352,7 +354,7 @@ void nf_send_unreach(struct sk_buff *skb_in, int code, int hook)
|
|||
if (iph->frag_off & htons(IP_OFFSET))
|
||||
return;
|
||||
|
||||
if (!skb_dst(skb_in) && nf_reject_fill_skb_dst(skb_in) < 0)
|
||||
if (!skb_valid_dst(skb_in) && nf_reject_fill_skb_dst(skb_in) < 0)
|
||||
return;
|
||||
|
||||
if (skb_csum_unnecessary(skb_in) ||
|
||||
|
|
|
|||
|
|
@ -1870,12 +1870,14 @@ static int ip6_tnl_fill_forward_path(struct net_device_path_ctx *ctx,
|
|||
path->tun.src_v6 = fl6.saddr;
|
||||
path->tun.dst_v6 = fl6.daddr;
|
||||
path->tun.l3_proto = IPPROTO_IPV6;
|
||||
path->tun.dst = dst;
|
||||
path->dev = ctx->dev;
|
||||
ctx->dev = dst->dev;
|
||||
}
|
||||
|
||||
err = dst->error;
|
||||
dst_release(dst);
|
||||
if (err)
|
||||
dst_release(dst);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <net/ip6_route.h>
|
||||
#include <net/ip6_fib.h>
|
||||
#include <net/ip6_checksum.h>
|
||||
#include <net/dst_metadata.h>
|
||||
#include <net/netfilter/ipv6/nf_reject.h>
|
||||
#include <linux/netfilter_ipv6.h>
|
||||
#include <linux/netfilter_bridge.h>
|
||||
|
|
@ -304,6 +305,7 @@ static int nf_reject6_fill_skb_dst(struct sk_buff *skb_in)
|
|||
if (!dst)
|
||||
return -1;
|
||||
|
||||
skb_dst_drop(skb_in);
|
||||
skb_dst_set(skb_in, dst);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -336,10 +338,12 @@ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
|
|||
fl6.fl6_sport = otcph->dest;
|
||||
fl6.fl6_dport = otcph->source;
|
||||
|
||||
if (!skb_dst(oldskb)) {
|
||||
if (!skb_valid_dst(oldskb)) {
|
||||
nf_ip6_route(net, &dst, flowi6_to_flowi(&fl6), false);
|
||||
if (!dst)
|
||||
return;
|
||||
|
||||
skb_dst_drop(oldskb);
|
||||
skb_dst_set(oldskb, dst);
|
||||
}
|
||||
|
||||
|
|
@ -440,7 +444,7 @@ void nf_send_unreach6(struct net *net, struct sk_buff *skb_in,
|
|||
if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL)
|
||||
skb_in->dev = net->loopback_dev;
|
||||
|
||||
if (!skb_dst(skb_in) && nf_reject6_fill_skb_dst(skb_in) < 0)
|
||||
if (!skb_valid_dst(skb_in) && nf_reject6_fill_skb_dst(skb_in) < 0)
|
||||
return;
|
||||
|
||||
icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0);
|
||||
|
|
|
|||
|
|
@ -158,6 +158,8 @@ static bool get_ct_or_tuple_from_skb(struct net *net,
|
|||
return true;
|
||||
|
||||
found_ct = nf_ct_tuplehash_to_ctrack(h);
|
||||
*tuple = found_ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
|
||||
*zone = nf_ct_zone(found_ct);
|
||||
*refcounted = true;
|
||||
*ct = found_ct;
|
||||
|
||||
|
|
|
|||
|
|
@ -1281,8 +1281,9 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct,
|
|||
if (ct->proto.tcp.retrans >= tn->tcp_max_retrans &&
|
||||
timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS])
|
||||
timeout = timeouts[TCP_CONNTRACK_RETRANS];
|
||||
else if (unlikely(index == TCP_RST_SET))
|
||||
timeout = timeouts[TCP_CONNTRACK_CLOSE];
|
||||
else if (unlikely(index == TCP_RST_SET &&
|
||||
new_state == TCP_CONNTRACK_ESTABLISHED))
|
||||
timeout = timeouts[TCP_CONNTRACK_UNACK];
|
||||
else if ((ct->proto.tcp.seen[0].flags | ct->proto.tcp.seen[1].flags) &
|
||||
IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED &&
|
||||
timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK])
|
||||
|
|
|
|||
|
|
@ -42,8 +42,7 @@ static bool nft_is_valid_ether_device(const struct net_device *dev)
|
|||
return true;
|
||||
}
|
||||
|
||||
static int nft_dev_fill_forward_path(const struct nf_flow_route *route,
|
||||
const struct dst_entry *dst_cache,
|
||||
static int nft_dev_fill_forward_path(const struct dst_entry *dst_cache,
|
||||
const struct nf_conn *ct,
|
||||
enum ip_conntrack_dir dir, u8 *ha,
|
||||
struct net_device_path_stack *stack)
|
||||
|
|
@ -76,14 +75,14 @@ static int nft_dev_fill_forward_path(const struct nf_flow_route *route,
|
|||
}
|
||||
|
||||
struct nft_forward_info {
|
||||
const struct net_device *indev;
|
||||
const struct net_device *outdev;
|
||||
const struct net_device *dev;
|
||||
struct id {
|
||||
__u16 id;
|
||||
__be16 proto;
|
||||
} encap[NF_FLOW_TABLE_ENCAP_MAX];
|
||||
u8 num_encaps;
|
||||
struct flow_offload_tunnel tun;
|
||||
struct dst_entry *tun_dst;
|
||||
u8 num_tuns;
|
||||
u8 ingress_vlans;
|
||||
u8 h_source[ETH_ALEN];
|
||||
|
|
@ -92,9 +91,12 @@ struct nft_forward_info {
|
|||
enum flow_offload_xmit_type xmit_type;
|
||||
};
|
||||
|
||||
static int nft_dev_path_info(const struct net_device_path_stack *stack,
|
||||
static bool nft_flowtable_find_dev(const struct net_device *dev,
|
||||
struct nft_flowtable *ft);
|
||||
|
||||
static int nft_dev_path_info(struct net_device_path_stack *stack,
|
||||
struct nft_forward_info *info,
|
||||
unsigned char *ha, struct nf_flowtable *flowtable)
|
||||
unsigned char *ha, struct nft_flowtable *ft)
|
||||
{
|
||||
const struct net_device_path *path;
|
||||
int i;
|
||||
|
|
@ -109,29 +111,27 @@ static int nft_dev_path_info(const struct net_device_path_stack *stack,
|
|||
case DEV_PATH_VLAN:
|
||||
case DEV_PATH_PPPOE:
|
||||
case DEV_PATH_TUN:
|
||||
info->indev = path->dev;
|
||||
info->dev = path->dev;
|
||||
if (is_zero_ether_addr(info->h_source))
|
||||
memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
|
||||
|
||||
if (path->type == DEV_PATH_ETHERNET)
|
||||
if (path->type == DEV_PATH_ETHERNET ||
|
||||
path->type == DEV_PATH_DSA)
|
||||
break;
|
||||
if (path->type == DEV_PATH_DSA) {
|
||||
i = stack->num_paths;
|
||||
break;
|
||||
}
|
||||
|
||||
/* DEV_PATH_VLAN, DEV_PATH_PPPOE and DEV_PATH_TUN */
|
||||
if (path->type == DEV_PATH_TUN) {
|
||||
if (info->num_tuns)
|
||||
return -1;
|
||||
goto err_out;
|
||||
|
||||
info->tun.src_v6 = path->tun.src_v6;
|
||||
info->tun.dst_v6 = path->tun.dst_v6;
|
||||
info->tun.l3_proto = path->tun.l3_proto;
|
||||
info->tun_dst = path->tun.dst;
|
||||
info->num_tuns++;
|
||||
} else {
|
||||
if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX)
|
||||
return -1;
|
||||
goto err_out;
|
||||
|
||||
info->encap[info->num_encaps].id =
|
||||
path->encap.id;
|
||||
|
|
@ -152,13 +152,13 @@ static int nft_dev_path_info(const struct net_device_path_stack *stack,
|
|||
switch (path->bridge.vlan_mode) {
|
||||
case DEV_PATH_BR_VLAN_UNTAG_HW:
|
||||
if (info->num_encaps == 0)
|
||||
return -1;
|
||||
goto err_out;
|
||||
|
||||
info->ingress_vlans |= BIT(info->num_encaps - 1);
|
||||
break;
|
||||
case DEV_PATH_BR_VLAN_TAG:
|
||||
if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX)
|
||||
return -1;
|
||||
goto err_out;
|
||||
|
||||
info->encap[info->num_encaps].id = path->bridge.vlan_id;
|
||||
info->encap[info->num_encaps].proto = path->bridge.vlan_proto;
|
||||
|
|
@ -166,7 +166,7 @@ static int nft_dev_path_info(const struct net_device_path_stack *stack,
|
|||
break;
|
||||
case DEV_PATH_BR_VLAN_UNTAG:
|
||||
if (info->num_encaps == 0)
|
||||
return -1;
|
||||
goto err_out;
|
||||
|
||||
info->num_encaps--;
|
||||
break;
|
||||
|
|
@ -176,16 +176,22 @@ static int nft_dev_path_info(const struct net_device_path_stack *stack,
|
|||
info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
info->outdev = info->indev;
|
||||
|
||||
if (nf_flowtable_hw_offload(flowtable) &&
|
||||
nft_is_valid_ether_device(info->indev))
|
||||
if (nf_flowtable_hw_offload(&ft->data) &&
|
||||
nft_is_valid_ether_device(info->dev))
|
||||
info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
|
||||
|
||||
if (!nft_flowtable_find_dev(info->dev, ft))
|
||||
goto err_out;
|
||||
|
||||
return 0;
|
||||
err_out:
|
||||
dev_fill_forward_path_release(stack);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool nft_flowtable_find_dev(const struct net_device *dev,
|
||||
|
|
@ -205,44 +211,6 @@ static bool nft_flowtable_find_dev(const struct net_device *dev,
|
|||
return found;
|
||||
}
|
||||
|
||||
static int nft_flow_tunnel_update_route(const struct nft_pktinfo *pkt,
|
||||
struct flow_offload_tunnel *tun,
|
||||
struct nf_flow_route *route,
|
||||
enum ip_conntrack_dir dir)
|
||||
{
|
||||
struct dst_entry *cur_dst = route->tuple[dir].dst;
|
||||
struct dst_entry *tun_dst = NULL;
|
||||
struct flowi fl = {};
|
||||
|
||||
switch (nft_pf(pkt)) {
|
||||
case NFPROTO_IPV4:
|
||||
fl.u.ip4.daddr = tun->dst_v4.s_addr;
|
||||
fl.u.ip4.saddr = tun->src_v4.s_addr;
|
||||
fl.u.ip4.flowi4_iif = nft_in(pkt)->ifindex;
|
||||
fl.u.ip4.flowi4_dscp = ip4h_dscp(ip_hdr(pkt->skb));
|
||||
fl.u.ip4.flowi4_mark = pkt->skb->mark;
|
||||
fl.u.ip4.flowi4_flags = FLOWI_FLAG_ANYSRC;
|
||||
break;
|
||||
case NFPROTO_IPV6:
|
||||
fl.u.ip6.daddr = tun->dst_v6;
|
||||
fl.u.ip6.saddr = tun->src_v6;
|
||||
fl.u.ip6.flowi6_iif = nft_in(pkt)->ifindex;
|
||||
fl.u.ip6.flowlabel = ip6_flowinfo(ipv6_hdr(pkt->skb));
|
||||
fl.u.ip6.flowi6_mark = pkt->skb->mark;
|
||||
fl.u.ip6.flowi6_flags = FLOWI_FLAG_ANYSRC;
|
||||
break;
|
||||
}
|
||||
|
||||
nf_route(nft_net(pkt), &tun_dst, &fl, false, nft_pf(pkt));
|
||||
if (!tun_dst)
|
||||
return -ENOENT;
|
||||
|
||||
route->tuple[dir].dst = tun_dst;
|
||||
dst_release(cur_dst);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nft_dev_forward_path(const struct nft_pktinfo *pkt,
|
||||
struct nf_flow_route *route,
|
||||
const struct nf_conn *ct,
|
||||
|
|
@ -255,28 +223,25 @@ static int nft_dev_forward_path(const struct nft_pktinfo *pkt,
|
|||
unsigned char ha[ETH_ALEN];
|
||||
int i;
|
||||
|
||||
if (nft_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) < 0 ||
|
||||
nft_dev_path_info(&stack, &info, ha, &ft->data) < 0)
|
||||
if (nft_dev_fill_forward_path(dst, ct, dir, ha, &stack) < 0 ||
|
||||
nft_dev_path_info(&stack, &info, ha, ft) < 0)
|
||||
return -ENOENT;
|
||||
|
||||
if (!nft_flowtable_find_dev(info.indev, ft))
|
||||
return -ENOENT;
|
||||
route->tuple[!dir].in.ifindex = info.dev->ifindex;
|
||||
route->tuple[dir].out.ifindex = info.dev->ifindex;
|
||||
|
||||
if (info.outdev)
|
||||
route->tuple[dir].out.ifindex = info.outdev->ifindex;
|
||||
|
||||
route->tuple[!dir].in.ifindex = info.indev->ifindex;
|
||||
for (i = 0; i < info.num_encaps; i++) {
|
||||
route->tuple[!dir].in.encap[i].id = info.encap[i].id;
|
||||
route->tuple[!dir].in.encap[i].proto = info.encap[i].proto;
|
||||
}
|
||||
|
||||
if (info.num_tuns &&
|
||||
!nft_flow_tunnel_update_route(pkt, &info.tun, route, dir)) {
|
||||
if (info.num_tuns) {
|
||||
route->tuple[!dir].in.tun.src_v6 = info.tun.dst_v6;
|
||||
route->tuple[!dir].in.tun.dst_v6 = info.tun.src_v6;
|
||||
route->tuple[!dir].in.tun.l3_proto = info.tun.l3_proto;
|
||||
route->tuple[!dir].in.num_tuns = info.num_tuns;
|
||||
dst_release(route->tuple[dir].dst);
|
||||
route->tuple[dir].dst = info.tun_dst;
|
||||
}
|
||||
|
||||
route->tuple[!dir].in.num_encaps = info.num_encaps;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <net/dst.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/dst_metadata.h>
|
||||
#include <net/tcp_states.h> /* for TCP_TIME_WAIT */
|
||||
#include <net/netfilter/nf_tables.h>
|
||||
#include <net/netfilter/nf_tables_core.h>
|
||||
|
|
@ -279,11 +280,12 @@ static bool nft_meta_get_eval_ifname(enum nft_meta_keys key, u32 *dest,
|
|||
static noinline bool
|
||||
nft_meta_get_eval_rtclassid(const struct sk_buff *skb, u32 *dest)
|
||||
{
|
||||
const struct dst_entry *dst = skb_dst(skb);
|
||||
const struct dst_entry *dst;
|
||||
|
||||
if (!dst)
|
||||
if (!skb_valid_dst(skb))
|
||||
return false;
|
||||
|
||||
dst = skb_dst(skb);
|
||||
*dest = dst->tclassid;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/netfilter.h>
|
||||
#include <linux/netfilter/nf_tables.h>
|
||||
#include <net/dst.h>
|
||||
#include <net/dst_metadata.h>
|
||||
#include <net/ip6_route.h>
|
||||
#include <net/route.h>
|
||||
#include <net/netfilter/nf_tables.h>
|
||||
|
|
@ -59,10 +60,11 @@ void nft_rt_get_eval(const struct nft_expr *expr,
|
|||
u32 *dest = ®s->data[priv->dreg];
|
||||
const struct dst_entry *dst;
|
||||
|
||||
dst = skb_dst(skb);
|
||||
if (!dst)
|
||||
if (!skb_valid_dst(skb))
|
||||
goto err;
|
||||
|
||||
dst = skb_dst(skb);
|
||||
|
||||
switch (priv->key) {
|
||||
#ifdef CONFIG_IP_ROUTE_CLASSID
|
||||
case NFT_RT_CLASSID:
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/netfilter/nf_tables.h>
|
||||
#include <net/netfilter/nf_tables_core.h>
|
||||
#include <net/netfilter/nf_tables.h>
|
||||
#include <net/dst_metadata.h>
|
||||
#include <linux/in.h>
|
||||
#include <net/xfrm.h>
|
||||
|
||||
|
|
@ -177,9 +178,15 @@ static void nft_xfrm_get_eval_out(const struct nft_xfrm *priv,
|
|||
struct nft_regs *regs,
|
||||
const struct nft_pktinfo *pkt)
|
||||
{
|
||||
const struct dst_entry *dst = skb_dst(pkt->skb);
|
||||
const struct dst_entry *dst;
|
||||
int i;
|
||||
|
||||
if (!skb_valid_dst(pkt->skb)) {
|
||||
regs->verdict.code = NFT_BREAK;
|
||||
return;
|
||||
}
|
||||
|
||||
dst = skb_dst(pkt->skb);
|
||||
for (i = 0; dst && dst->xfrm;
|
||||
dst = ((const struct xfrm_dst *)dst)->child, i++) {
|
||||
if (i < priv->spnum)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user