@@ -498,95 +498,76 @@ static int genl_lock_done(struct netlink_callback *cb)
498
498
return rc ;
499
499
}
500
500
501
- static int genl_family_rcv_msg (const struct genl_family * family ,
502
- struct sk_buff * skb ,
503
- struct nlmsghdr * nlh ,
504
- struct netlink_ext_ack * extack )
501
+ static int genl_family_rcv_msg_dumpit (const struct genl_family * family ,
502
+ struct sk_buff * skb ,
503
+ struct nlmsghdr * nlh ,
504
+ struct netlink_ext_ack * extack ,
505
+ const struct genl_ops * ops ,
506
+ int hdrlen , struct net * net )
505
507
{
506
- const struct genl_ops * ops ;
507
- struct net * net = sock_net (skb -> sk );
508
- struct genl_info info ;
509
- struct genlmsghdr * hdr = nlmsg_data (nlh );
510
- struct nlattr * * attrbuf ;
511
- int hdrlen , err ;
512
-
513
- /* this family doesn't exist in this netns */
514
- if (!family -> netnsok && !net_eq (net , & init_net ))
515
- return - ENOENT ;
516
-
517
- hdrlen = GENL_HDRLEN + family -> hdrsize ;
518
- if (nlh -> nlmsg_len < nlmsg_msg_size (hdrlen ))
519
- return - EINVAL ;
508
+ int err ;
520
509
521
- ops = genl_get_cmd (hdr -> cmd , family );
522
- if (ops == NULL )
510
+ if (!ops -> dumpit )
523
511
return - EOPNOTSUPP ;
524
512
525
- if ((ops -> flags & GENL_ADMIN_PERM ) &&
526
- !netlink_capable (skb , CAP_NET_ADMIN ))
527
- return - EPERM ;
528
-
529
- if ((ops -> flags & GENL_UNS_ADMIN_PERM ) &&
530
- !netlink_ns_capable (skb , net -> user_ns , CAP_NET_ADMIN ))
531
- return - EPERM ;
532
-
533
- if ((nlh -> nlmsg_flags & NLM_F_DUMP ) == NLM_F_DUMP ) {
534
- int rc ;
535
-
536
- if (ops -> dumpit == NULL )
537
- return - EOPNOTSUPP ;
538
-
539
- if (!(ops -> validate & GENL_DONT_VALIDATE_DUMP )) {
540
- int hdrlen = GENL_HDRLEN + family -> hdrsize ;
541
-
542
- if (nlh -> nlmsg_len < nlmsg_msg_size (hdrlen ))
543
- return - EINVAL ;
513
+ if (!(ops -> validate & GENL_DONT_VALIDATE_DUMP )) {
514
+ if (nlh -> nlmsg_len < nlmsg_msg_size (hdrlen ))
515
+ return - EINVAL ;
544
516
545
- if (family -> maxattr ) {
546
- unsigned int validate = NL_VALIDATE_STRICT ;
547
-
548
- if (ops -> validate &
549
- GENL_DONT_VALIDATE_DUMP_STRICT )
550
- validate = NL_VALIDATE_LIBERAL ;
551
- rc = __nla_validate (nlmsg_attrdata (nlh , hdrlen ),
552
- nlmsg_attrlen (nlh , hdrlen ),
553
- family -> maxattr ,
554
- family -> policy ,
555
- validate , extack );
556
- if (rc )
557
- return rc ;
558
- }
517
+ if (family -> maxattr ) {
518
+ unsigned int validate = NL_VALIDATE_STRICT ;
519
+
520
+ if (ops -> validate & GENL_DONT_VALIDATE_DUMP_STRICT )
521
+ validate = NL_VALIDATE_LIBERAL ;
522
+ err = __nla_validate (nlmsg_attrdata (nlh , hdrlen ),
523
+ nlmsg_attrlen (nlh , hdrlen ),
524
+ family -> maxattr , family -> policy ,
525
+ validate , extack );
526
+ if (err )
527
+ return err ;
559
528
}
529
+ }
560
530
561
- if (!family -> parallel_ops ) {
562
- struct netlink_dump_control c = {
563
- .module = family -> module ,
564
- /* we have const, but the netlink API doesn't */
565
- .data = (void * )ops ,
566
- .start = genl_lock_start ,
567
- .dump = genl_lock_dumpit ,
568
- .done = genl_lock_done ,
569
- };
531
+ if (!family -> parallel_ops ) {
532
+ struct netlink_dump_control c = {
533
+ .module = family -> module ,
534
+ /* we have const, but the netlink API doesn't */
535
+ .data = (void * )ops ,
536
+ .start = genl_lock_start ,
537
+ .dump = genl_lock_dumpit ,
538
+ .done = genl_lock_done ,
539
+ };
570
540
571
- genl_unlock ();
572
- rc = __netlink_dump_start (net -> genl_sock , skb , nlh , & c );
573
- genl_lock ();
541
+ genl_unlock ();
542
+ err = __netlink_dump_start (net -> genl_sock , skb , nlh , & c );
543
+ genl_lock ();
574
544
575
- } else {
576
- struct netlink_dump_control c = {
577
- .module = family -> module ,
578
- .start = ops -> start ,
579
- .dump = ops -> dumpit ,
580
- .done = ops -> done ,
581
- };
545
+ } else {
546
+ struct netlink_dump_control c = {
547
+ .module = family -> module ,
548
+ .start = ops -> start ,
549
+ .dump = ops -> dumpit ,
550
+ .done = ops -> done ,
551
+ };
552
+
553
+ err = __netlink_dump_start (net -> genl_sock , skb , nlh , & c );
554
+ }
582
555
583
- rc = __netlink_dump_start ( net -> genl_sock , skb , nlh , & c ) ;
584
- }
556
+ return err ;
557
+ }
585
558
586
- return rc ;
587
- }
559
+ static int genl_family_rcv_msg_doit (const struct genl_family * family ,
560
+ struct sk_buff * skb ,
561
+ struct nlmsghdr * nlh ,
562
+ struct netlink_ext_ack * extack ,
563
+ const struct genl_ops * ops ,
564
+ int hdrlen , struct net * net )
565
+ {
566
+ struct nlattr * * attrbuf ;
567
+ struct genl_info info ;
568
+ int err ;
588
569
589
- if (ops -> doit == NULL )
570
+ if (! ops -> doit )
590
571
return - EOPNOTSUPP ;
591
572
592
573
if (family -> maxattr && family -> parallel_ops ) {
@@ -638,6 +619,44 @@ static int genl_family_rcv_msg(const struct genl_family *family,
638
619
return err ;
639
620
}
640
621
622
+ static int genl_family_rcv_msg (const struct genl_family * family ,
623
+ struct sk_buff * skb ,
624
+ struct nlmsghdr * nlh ,
625
+ struct netlink_ext_ack * extack )
626
+ {
627
+ const struct genl_ops * ops ;
628
+ struct net * net = sock_net (skb -> sk );
629
+ struct genlmsghdr * hdr = nlmsg_data (nlh );
630
+ int hdrlen ;
631
+
632
+ /* this family doesn't exist in this netns */
633
+ if (!family -> netnsok && !net_eq (net , & init_net ))
634
+ return - ENOENT ;
635
+
636
+ hdrlen = GENL_HDRLEN + family -> hdrsize ;
637
+ if (nlh -> nlmsg_len < nlmsg_msg_size (hdrlen ))
638
+ return - EINVAL ;
639
+
640
+ ops = genl_get_cmd (hdr -> cmd , family );
641
+ if (ops == NULL )
642
+ return - EOPNOTSUPP ;
643
+
644
+ if ((ops -> flags & GENL_ADMIN_PERM ) &&
645
+ !netlink_capable (skb , CAP_NET_ADMIN ))
646
+ return - EPERM ;
647
+
648
+ if ((ops -> flags & GENL_UNS_ADMIN_PERM ) &&
649
+ !netlink_ns_capable (skb , net -> user_ns , CAP_NET_ADMIN ))
650
+ return - EPERM ;
651
+
652
+ if ((nlh -> nlmsg_flags & NLM_F_DUMP ) == NLM_F_DUMP )
653
+ return genl_family_rcv_msg_dumpit (family , skb , nlh , extack ,
654
+ ops , hdrlen , net );
655
+ else
656
+ return genl_family_rcv_msg_doit (family , skb , nlh , extack ,
657
+ ops , hdrlen , net );
658
+ }
659
+
641
660
static int genl_rcv_msg (struct sk_buff * skb , struct nlmsghdr * nlh ,
642
661
struct netlink_ext_ack * extack )
643
662
{
0 commit comments