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