Add an ether_type field to struct net_device_path_ctx to reject IPv4 over IPv6 and vice-versa, this is currently not support. Otherwise, incorrect dst_entry family can be reached from datapath.
Unified · Split
| @@ -941,6 +941,7 @@ struct net_device_path_stack { · 940 unmodified lines | ||
| 941 | 941 | struct net_device_path_ctx { |
| 942 | 942 | const struct net_device *dev; |
| 943 | 943 | u8 daddr[ETH_ALEN]; |
| 944 | + __be16 ether_type; | |
| 944 | 945 | |
| 945 | 946 | int num_vlans; |
| 946 | 947 | struct { |
| @@ -360,6 +360,9 @@ static int ipip_fill_forward_path(struct net_device_path_ctx *ctx, · 359 unmodified lines | ||
| 360 | 360 | const struct iphdr *tiph = &tunnel->parms.iph; |
| 361 | 361 | struct rtable *rt; |
| 362 | 362 | |
| 363 | + if (ctx->ether_type != cpu_to_be16(ETH_P_IP)) | |
| 364 | + return -EOPNOTSUPP; | |
| 365 | + | |
| 363 | 366 | if (tunnel->collect_md) |
| 364 | 367 | return -EOPNOTSUPP; |
| 365 | 368 | |
| @@ -1852,6 +1852,9 @@ static int ip6_tnl_fill_forward_path(struct net_device_path_ctx *ctx, · 1851 unmodified lines | ||
| 1852 | 1852 | struct flowi6 fl6; |
| 1853 | 1853 | int err; |
| 1854 | 1854 | |
| 1855 | + if (ctx->ether_type != cpu_to_be16(ETH_P_IPV6)) | |
| 1856 | + return -EOPNOTSUPP; | |
| 1857 | + | |
| 1855 | 1858 | if (t->parms.flags & (IP6_TNL_F_USE_ORIG_TCLASS | |
| 1856 | 1859 | IP6_TNL_F_USE_ORIG_FLOWLABEL | |
| 1857 | 1860 | IP6_TNL_F_USE_ORIG_FWMARK)) |
| @@ -44,13 +44,15 @@ static bool nft_is_valid_ether_device(const struct net_device *dev) · 43 unmodified lines | ||
| 44 | 44 | |
| 45 | 45 | static int nft_dev_fill_forward_path(const struct dst_entry *dst_cache, |
| 46 | 46 | const struct nf_conn *ct, |
| 47 | − enum ip_conntrack_dir dir, u8 *ha, | |
| 47 | + enum ip_conntrack_dir dir, | |
| 48 | + u8 *ha, __be16 ether_type, | |
| 48 | 49 | struct net_device_path_stack *stack) |
| 49 | 50 | { |
| 50 | 51 | const void *daddr = &ct->tuplehash[!dir].tuple.src.u3; |
| 51 | 52 | struct net_device *dev = dst_cache->dev; |
| 52 | 53 | struct net_device_path_ctx ctx = { |
| 53 | 54 | .dev = dev, |
| 55 | + .ether_type = ether_type, | |
| 54 | 56 | }; |
| 55 | 57 | struct neighbour *n; |
| 56 | 58 | u8 nud_state; |
| @@ -228,7 +230,7 @@ static int nft_dev_forward_path(const struct nft_pktinfo *pkt, · 171 unmodified lines | ||
| 228 | 230 | unsigned char ha[ETH_ALEN]; |
| 229 | 231 | int i; |
| 230 | 232 | |
| 231 | − if (nft_dev_fill_forward_path(dst, ct, dir, ha, &stack) < 0 || | |
| 233 | + if (nft_dev_fill_forward_path(dst, ct, dir, ha, pkt->ethertype, &stack) < 0 || | |
| 232 | 234 | nft_dev_path_info(&stack, &info, ha, ft) < 0) |
| 233 | 235 | return -ENOENT; |
| 234 | 236 | |