Skip to content

Commit 7f1c042

Browse files
dsahernAlexei Starovoitov
authored andcommitted
devmap: Formalize map value as a named struct
Add 'struct bpf_devmap_val' to formalize the expected values that can be passed in for a DEVMAP. Update devmap code to use the struct. Signed-off-by: David Ahern <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: Toke Høiland-Jørgensen <[email protected]> Link: https://lore.kernel.org/bpf/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent b36e62e commit 7f1c042

File tree

1 file changed

+28
-17
lines changed

1 file changed

+28
-17
lines changed

kernel/bpf/devmap.c

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,18 @@ struct xdp_dev_bulk_queue {
6060
unsigned int count;
6161
};
6262

63+
/* DEVMAP values */
64+
struct bpf_devmap_val {
65+
u32 ifindex; /* device index */
66+
};
67+
6368
struct bpf_dtab_netdev {
6469
struct net_device *dev; /* must be first member, due to tracepoint */
6570
struct hlist_node index_hlist;
6671
struct bpf_dtab *dtab;
6772
struct rcu_head rcu;
6873
unsigned int idx;
74+
struct bpf_devmap_val val;
6975
};
7076

7177
struct bpf_dtab {
@@ -472,18 +478,15 @@ int dev_map_generic_redirect(struct bpf_dtab_netdev *dst, struct sk_buff *skb,
472478
static void *dev_map_lookup_elem(struct bpf_map *map, void *key)
473479
{
474480
struct bpf_dtab_netdev *obj = __dev_map_lookup_elem(map, *(u32 *)key);
475-
struct net_device *dev = obj ? obj->dev : NULL;
476481

477-
return dev ? &dev->ifindex : NULL;
482+
return obj ? &obj->val : NULL;
478483
}
479484

480485
static void *dev_map_hash_lookup_elem(struct bpf_map *map, void *key)
481486
{
482487
struct bpf_dtab_netdev *obj = __dev_map_hash_lookup_elem(map,
483488
*(u32 *)key);
484-
struct net_device *dev = obj ? obj->dev : NULL;
485-
486-
return dev ? &dev->ifindex : NULL;
489+
return obj ? &obj->val : NULL;
487490
}
488491

489492
static void __dev_map_entry_free(struct rcu_head *rcu)
@@ -541,7 +544,7 @@ static int dev_map_hash_delete_elem(struct bpf_map *map, void *key)
541544

542545
static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net,
543546
struct bpf_dtab *dtab,
544-
u32 ifindex,
547+
struct bpf_devmap_val *val,
545548
unsigned int idx)
546549
{
547550
struct bpf_dtab_netdev *dev;
@@ -551,24 +554,26 @@ static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net,
551554
if (!dev)
552555
return ERR_PTR(-ENOMEM);
553556

554-
dev->dev = dev_get_by_index(net, ifindex);
555-
if (!dev->dev) {
556-
kfree(dev);
557-
return ERR_PTR(-EINVAL);
558-
}
557+
dev->dev = dev_get_by_index(net, val->ifindex);
558+
if (!dev->dev)
559+
goto err_out;
559560

560561
dev->idx = idx;
561562
dev->dtab = dtab;
563+
dev->val.ifindex = val->ifindex;
562564

563565
return dev;
566+
err_out:
567+
kfree(dev);
568+
return ERR_PTR(-EINVAL);
564569
}
565570

566571
static int __dev_map_update_elem(struct net *net, struct bpf_map *map,
567572
void *key, void *value, u64 map_flags)
568573
{
569574
struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
570575
struct bpf_dtab_netdev *dev, *old_dev;
571-
u32 ifindex = *(u32 *)value;
576+
struct bpf_devmap_val val = { };
572577
u32 i = *(u32 *)key;
573578

574579
if (unlikely(map_flags > BPF_EXIST))
@@ -578,10 +583,13 @@ static int __dev_map_update_elem(struct net *net, struct bpf_map *map,
578583
if (unlikely(map_flags == BPF_NOEXIST))
579584
return -EEXIST;
580585

581-
if (!ifindex) {
586+
/* already verified value_size <= sizeof val */
587+
memcpy(&val, value, map->value_size);
588+
589+
if (!val.ifindex) {
582590
dev = NULL;
583591
} else {
584-
dev = __dev_map_alloc_node(net, dtab, ifindex, i);
592+
dev = __dev_map_alloc_node(net, dtab, &val, i);
585593
if (IS_ERR(dev))
586594
return PTR_ERR(dev);
587595
}
@@ -609,12 +617,15 @@ static int __dev_map_hash_update_elem(struct net *net, struct bpf_map *map,
609617
{
610618
struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
611619
struct bpf_dtab_netdev *dev, *old_dev;
612-
u32 ifindex = *(u32 *)value;
620+
struct bpf_devmap_val val = { };
613621
u32 idx = *(u32 *)key;
614622
unsigned long flags;
615623
int err = -EEXIST;
616624

617-
if (unlikely(map_flags > BPF_EXIST || !ifindex))
625+
/* already verified value_size <= sizeof val */
626+
memcpy(&val, value, map->value_size);
627+
628+
if (unlikely(map_flags > BPF_EXIST || !val.ifindex))
618629
return -EINVAL;
619630

620631
spin_lock_irqsave(&dtab->index_lock, flags);
@@ -623,7 +634,7 @@ static int __dev_map_hash_update_elem(struct net *net, struct bpf_map *map,
623634
if (old_dev && (map_flags & BPF_NOEXIST))
624635
goto out_err;
625636

626-
dev = __dev_map_alloc_node(net, dtab, ifindex, idx);
637+
dev = __dev_map_alloc_node(net, dtab, &val, idx);
627638
if (IS_ERR(dev)) {
628639
err = PTR_ERR(dev);
629640
goto out_err;

0 commit comments

Comments
 (0)