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
60 unsigned int count;60 unsigned int count;
61};61};
62 62
63/* DEVMAP values */
64struct bpf_devmap_val {
65 u32 ifindex; /* device index */
66};
67
63struct bpf_dtab_netdev {68struct bpf_dtab_netdev {
64 struct net_device *dev; /* must be first member, due to tracepoint */69 struct net_device *dev; /* must be first member, due to tracepoint */
65 struct hlist_node index_hlist;70 struct hlist_node index_hlist;
66 struct bpf_dtab *dtab;71 struct bpf_dtab *dtab;
67 struct rcu_head rcu;72 struct rcu_head rcu;
68 unsigned int idx;73 unsigned int idx;
74 struct bpf_devmap_val val;
69};75};
70 76
71struct bpf_dtab {77struct bpf_dtab {
@@ -472,18 +478,15 @@ int dev_map_generic_redirect(struct bpf_dtab_netdev *dst, struct sk_buff *skb, · 400 unmodified lines
472static void *dev_map_lookup_elem(struct bpf_map *map, void *key)478static void *dev_map_lookup_elem(struct bpf_map *map, void *key)
473{479{
474 struct bpf_dtab_netdev *obj = __dev_map_lookup_elem(map, *(u32 *)key);480 struct bpf_dtab_netdev *obj = __dev_map_lookup_elem(map, *(u32 *)key);
475 struct net_device *dev = obj ? obj->dev : NULL;
476 481
477 return dev ? &dev->ifindex : NULL;482 return obj ? &obj->val : NULL;
478}483}
479 484
480static void *dev_map_hash_lookup_elem(struct bpf_map *map, void *key)485static void *dev_map_hash_lookup_elem(struct bpf_map *map, void *key)
481{486{
482 struct bpf_dtab_netdev *obj = __dev_map_hash_lookup_elem(map,487 struct bpf_dtab_netdev *obj = __dev_map_hash_lookup_elem(map,
483 *(u32 *)key);488 *(u32 *)key);
484 struct net_device *dev = obj ? obj->dev : NULL;489 return obj ? &obj->val : NULL;
485
486 return dev ? &dev->ifindex : NULL;
487}490}
488 491
489static void __dev_map_entry_free(struct rcu_head *rcu)492static 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
541 544
542static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net,545static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net,
543 struct bpf_dtab *dtab,546 struct bpf_dtab *dtab,
544 u32 ifindex,547 struct bpf_devmap_val *val,
545 unsigned int idx)548 unsigned int idx)
546{549{
547 struct bpf_dtab_netdev *dev;550 struct bpf_dtab_netdev *dev;
@@ -551,16 +554,18 @@ static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net, · 3 unmodified lines
551 if (!dev)554 if (!dev)
552 return ERR_PTR(-ENOMEM);555 return ERR_PTR(-ENOMEM);
553 556
554 dev->dev = dev_get_by_index(net, ifindex);557 dev->dev = dev_get_by_index(net, val->ifindex);
555 if (!dev->dev) {558 if (!dev->dev)
556 kfree(dev);559 goto err_out;
557 return ERR_PTR(-EINVAL);
558 }
559 560
560 dev->idx = idx;561 dev->idx = idx;
561 dev->dtab = dtab;562 dev->dtab = dtab;
563 dev->val.ifindex = val->ifindex;
562 564
563 return dev;565 return dev;
566err_out:
567 kfree(dev);
568 return ERR_PTR(-EINVAL);
564}569}
565 570
566static int __dev_map_update_elem(struct net *net, struct bpf_map *map,571static 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
568{573{
569 struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);574 struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
570 struct bpf_dtab_netdev *dev, *old_dev;575 struct bpf_dtab_netdev *dev, *old_dev;
571 u32 ifindex = *(u32 *)value;576 struct bpf_devmap_val val = { };
572 u32 i = *(u32 *)key;577 u32 i = *(u32 *)key;
573 578
574 if (unlikely(map_flags > BPF_EXIST))579 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
578 if (unlikely(map_flags == BPF_NOEXIST))583 if (unlikely(map_flags == BPF_NOEXIST))
579 return -EEXIST;584 return -EEXIST;
580 585
581 if (!ifindex) {586 /* already verified value_size <= sizeof val */
587 memcpy(&val, value, map->value_size);
588
589 if (!val.ifindex) {
582 dev = NULL;590 dev = NULL;
583 } else {591 } else {
584 dev = __dev_map_alloc_node(net, dtab, ifindex, i);592 dev = __dev_map_alloc_node(net, dtab, &val, i);
585 if (IS_ERR(dev))593 if (IS_ERR(dev))
586 return PTR_ERR(dev);594 return PTR_ERR(dev);
587 }595 }
@@ -609,12 +617,15 @@ static int __dev_map_hash_update_elem(struct net *net, struct bpf_map *map, · 21 unmodified lines
609{617{
610 struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);618 struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
611 struct bpf_dtab_netdev *dev, *old_dev;619 struct bpf_dtab_netdev *dev, *old_dev;
612 u32 ifindex = *(u32 *)value;620 struct bpf_devmap_val val = { };
613 u32 idx = *(u32 *)key;621 u32 idx = *(u32 *)key;
614 unsigned long flags;622 unsigned long flags;
615 int err = -EEXIST;623 int err = -EEXIST;
616 624
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))
618 return -EINVAL;629 return -EINVAL;
619 630
620 spin_lock_irqsave(&dtab->index_lock, flags);631 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
623 if (old_dev && (map_flags & BPF_NOEXIST))634 if (old_dev && (map_flags & BPF_NOEXIST))
624 goto out_err;635 goto out_err;
625 636
626 dev = __dev_map_alloc_node(net, dtab, ifindex, idx);637 dev = __dev_map_alloc_node(net, dtab, &val, idx);
627 if (IS_ERR(dev)) {638 if (IS_ERR(dev)) {
628 err = PTR_ERR(dev);639 err = PTR_ERR(dev);
629 goto out_err;640 goto out_err;