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 | struct net_device_path_ctx { | 941 | struct net_device_path_ctx { |
| 942 | const struct net_device *dev; | 942 | const struct net_device *dev; |
| 943 | u8 daddr[ETH_ALEN]; | 943 | u8 daddr[ETH_ALEN]; |
| 944 | __be16 ether_type; | ||
| 944 | 945 | ||
| 945 | int num_vlans; | 946 | int num_vlans; |
| 946 | struct { | 947 | struct { |
| @@ -360,6 +360,9 @@ static int ipip_fill_forward_path(struct net_device_path_ctx *ctx, · 359 unmodified lines | |||
| 360 | const struct iphdr *tiph = &tunnel->parms.iph; | 360 | const struct iphdr *tiph = &tunnel->parms.iph; |
| 361 | struct rtable *rt; | 361 | struct rtable *rt; |
| 362 | 362 | ||
| 363 | if (ctx->ether_type != cpu_to_be16(ETH_P_IP)) | ||
| 364 | return -EOPNOTSUPP; | ||
| 365 | |||
| 363 | if (tunnel->collect_md) | 366 | if (tunnel->collect_md) |
| 364 | return -EOPNOTSUPP; | 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 | struct flowi6 fl6; | 1852 | struct flowi6 fl6; |
| 1853 | int err; | 1853 | int err; |
| 1854 | 1854 | ||
| 1855 | if (ctx->ether_type != cpu_to_be16(ETH_P_IPV6)) | ||
| 1856 | return -EOPNOTSUPP; | ||
| 1857 | |||
| 1855 | if (t->parms.flags & (IP6_TNL_F_USE_ORIG_TCLASS | | 1858 | if (t->parms.flags & (IP6_TNL_F_USE_ORIG_TCLASS | |
| 1856 | IP6_TNL_F_USE_ORIG_FLOWLABEL | | 1859 | IP6_TNL_F_USE_ORIG_FLOWLABEL | |
| 1857 | IP6_TNL_F_USE_ORIG_FWMARK)) | 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 | static int nft_dev_fill_forward_path(const struct dst_entry *dst_cache, | 45 | static int nft_dev_fill_forward_path(const struct dst_entry *dst_cache, |
| 46 | const struct nf_conn *ct, | 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 | struct net_device_path_stack *stack) | 49 | struct net_device_path_stack *stack) |
| 49 | { | 50 | { |
| 50 | const void *daddr = &ct->tuplehash[!dir].tuple.src.u3; | 51 | const void *daddr = &ct->tuplehash[!dir].tuple.src.u3; |
| 51 | struct net_device *dev = dst_cache->dev; | 52 | struct net_device *dev = dst_cache->dev; |
| 52 | struct net_device_path_ctx ctx = { | 53 | struct net_device_path_ctx ctx = { |
| 53 | .dev = dev, | 54 | .dev = dev, |
| 55 | .ether_type = ether_type, | ||
| 54 | }; | 56 | }; |
| 55 | struct neighbour *n; | 57 | struct neighbour *n; |
| 56 | u8 nud_state; | 58 | u8 nud_state; |
| @@ -228,7 +230,7 @@ static int nft_dev_forward_path(const struct nft_pktinfo *pkt, · 171 unmodified lines | |||
| 228 | unsigned char ha[ETH_ALEN]; | 230 | unsigned char ha[ETH_ALEN]; |
| 229 | int i; | 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 | nft_dev_path_info(&stack, &info, ha, ft) < 0) | 234 | nft_dev_path_info(&stack, &info, ha, ft) < 0) |
| 233 | return -ENOENT; | 235 | return -ENOENT; |
| 234 | 236 | ||