.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * IEEE 802.1Q Multiple Registration Protocol (MRP) |
---|
3 | 4 | * |
---|
.. | .. |
---|
5 | 6 | * |
---|
6 | 7 | * Adapted from code in net/802/garp.c |
---|
7 | 8 | * Copyright (c) 2008 Patrick McHardy <kaber@trash.net> |
---|
8 | | - * |
---|
9 | | - * This program is free software; you can redistribute it and/or |
---|
10 | | - * modify it under the terms of the GNU General Public License |
---|
11 | | - * version 2 as published by the Free Software Foundation. |
---|
12 | 9 | */ |
---|
13 | 10 | #include <linux/kernel.h> |
---|
14 | 11 | #include <linux/timer.h> |
---|
.. | .. |
---|
539 | 536 | struct mrp_attr *attr; |
---|
540 | 537 | |
---|
541 | 538 | if (sizeof(struct mrp_skb_cb) + len > |
---|
542 | | - FIELD_SIZEOF(struct sk_buff, cb)) |
---|
| 539 | + sizeof_field(struct sk_buff, cb)) |
---|
543 | 540 | return -ENOMEM; |
---|
544 | 541 | |
---|
545 | 542 | spin_lock_bh(&app->lock); |
---|
.. | .. |
---|
564 | 561 | struct mrp_attr *attr; |
---|
565 | 562 | |
---|
566 | 563 | if (sizeof(struct mrp_skb_cb) + len > |
---|
567 | | - FIELD_SIZEOF(struct sk_buff, cb)) |
---|
| 564 | + sizeof_field(struct sk_buff, cb)) |
---|
568 | 565 | return; |
---|
569 | 566 | |
---|
570 | 567 | spin_lock_bh(&app->lock); |
---|
.. | .. |
---|
609 | 606 | spin_unlock(&app->lock); |
---|
610 | 607 | |
---|
611 | 608 | mrp_queue_xmit(app); |
---|
612 | | - mrp_join_timer_arm(app); |
---|
| 609 | + spin_lock(&app->lock); |
---|
| 610 | + if (likely(app->active)) |
---|
| 611 | + mrp_join_timer_arm(app); |
---|
| 612 | + spin_unlock(&app->lock); |
---|
613 | 613 | } |
---|
614 | 614 | |
---|
615 | 615 | static void mrp_periodic_timer_arm(struct mrp_applicant *app) |
---|
.. | .. |
---|
623 | 623 | struct mrp_applicant *app = from_timer(app, t, periodic_timer); |
---|
624 | 624 | |
---|
625 | 625 | spin_lock(&app->lock); |
---|
626 | | - mrp_mad_event(app, MRP_EVENT_PERIODIC); |
---|
627 | | - mrp_pdu_queue(app); |
---|
| 626 | + if (likely(app->active)) { |
---|
| 627 | + mrp_mad_event(app, MRP_EVENT_PERIODIC); |
---|
| 628 | + mrp_pdu_queue(app); |
---|
| 629 | + mrp_periodic_timer_arm(app); |
---|
| 630 | + } |
---|
628 | 631 | spin_unlock(&app->lock); |
---|
629 | | - |
---|
630 | | - mrp_periodic_timer_arm(app); |
---|
631 | 632 | } |
---|
632 | 633 | |
---|
633 | 634 | static int mrp_pdu_parse_end_mark(struct sk_buff *skb, int *offset) |
---|
.. | .. |
---|
708 | 709 | * advance to the next event in its Vector. |
---|
709 | 710 | */ |
---|
710 | 711 | if (sizeof(struct mrp_skb_cb) + mrp_cb(skb)->mh->attrlen > |
---|
711 | | - FIELD_SIZEOF(struct sk_buff, cb)) |
---|
| 712 | + sizeof_field(struct sk_buff, cb)) |
---|
712 | 713 | return -1; |
---|
713 | 714 | if (skb_copy_bits(skb, *offset, mrp_cb(skb)->attrvalue, |
---|
714 | 715 | mrp_cb(skb)->mh->attrlen) < 0) |
---|
.. | .. |
---|
875 | 876 | app->dev = dev; |
---|
876 | 877 | app->app = appl; |
---|
877 | 878 | app->mad = RB_ROOT; |
---|
| 879 | + app->active = true; |
---|
878 | 880 | spin_lock_init(&app->lock); |
---|
879 | 881 | skb_queue_head_init(&app->queue); |
---|
880 | 882 | rcu_assign_pointer(dev->mrp_port->applicants[appl->type], app); |
---|
.. | .. |
---|
903 | 905 | |
---|
904 | 906 | RCU_INIT_POINTER(port->applicants[appl->type], NULL); |
---|
905 | 907 | |
---|
| 908 | + spin_lock_bh(&app->lock); |
---|
| 909 | + app->active = false; |
---|
| 910 | + spin_unlock_bh(&app->lock); |
---|
906 | 911 | /* Delete timer and generate a final TX event to flush out |
---|
907 | 912 | * all pending messages before the applicant is gone. |
---|
908 | 913 | */ |
---|