History

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.

David Ahern committed 6 years ago

Commit 7f1c0421 parent b36e62e1 file · +28 −17Browse files

Unified · Split

kernel/bpf/devmap.c+28−17
@@ -60,12 +60,18 @@ struct xdp_dev_bulk_queue { · 59 unmodified lines
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, · 400 unmodified lines
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) · 51 unmodified lines
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,16 +554,18 @@ static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net, · 3 unmodified lines
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,
@@ -568,7 +573,7 @@ static int __dev_map_update_elem(struct net *net, struct bpf_map *map, · 1 unmodified line
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, · 3 unmodified lines
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, · 21 unmodified lines
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, · 2 unmodified lines
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;