Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mrp: add periodictimer to allow retries when packets get lost

MRP doesn't implement the periodictimer in 802.1Q, so it never retries
if packets get lost. I ran into this problem when MRP sent a MVRP
JoinIn before the interface was fully up. The JoinIn was lost, MRP
didn't retry, and MVRP registration failed.

Tested against Juniper QFabric switches

Signed-off-by: Noel Burton-Krahn <noel@burton-krahn.com>
Acked-by: David Ward <david.ward@ll.mit.edu>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Noel Burton-Krahn and committed by
David S. Miller
9fe34f5d a224bd36

+28
+1
include/net/mrp.h
··· 112 112 struct mrp_application *app; 113 113 struct net_device *dev; 114 114 struct timer_list join_timer; 115 + struct timer_list periodic_timer; 115 116 116 117 spinlock_t lock; 117 118 struct sk_buff_head queue;
+27
net/802/mrp.c
··· 24 24 static unsigned int mrp_join_time __read_mostly = 200; 25 25 module_param(mrp_join_time, uint, 0644); 26 26 MODULE_PARM_DESC(mrp_join_time, "Join time in ms (default 200ms)"); 27 + 28 + static unsigned int mrp_periodic_time __read_mostly = 1000; 29 + module_param(mrp_periodic_time, uint, 0644); 30 + MODULE_PARM_DESC(mrp_periodic_time, "Periodic time in ms (default 1s)"); 31 + 27 32 MODULE_LICENSE("GPL"); 28 33 29 34 static const u8 ··· 600 595 mrp_join_timer_arm(app); 601 596 } 602 597 598 + static void mrp_periodic_timer_arm(struct mrp_applicant *app) 599 + { 600 + mod_timer(&app->periodic_timer, 601 + jiffies + msecs_to_jiffies(mrp_periodic_time)); 602 + } 603 + 604 + static void mrp_periodic_timer(unsigned long data) 605 + { 606 + struct mrp_applicant *app = (struct mrp_applicant *)data; 607 + 608 + spin_lock(&app->lock); 609 + mrp_mad_event(app, MRP_EVENT_PERIODIC); 610 + mrp_pdu_queue(app); 611 + spin_unlock(&app->lock); 612 + 613 + mrp_periodic_timer_arm(app); 614 + } 615 + 603 616 static int mrp_pdu_parse_end_mark(struct sk_buff *skb, int *offset) 604 617 { 605 618 __be16 endmark; ··· 868 845 rcu_assign_pointer(dev->mrp_port->applicants[appl->type], app); 869 846 setup_timer(&app->join_timer, mrp_join_timer, (unsigned long)app); 870 847 mrp_join_timer_arm(app); 848 + setup_timer(&app->periodic_timer, mrp_periodic_timer, 849 + (unsigned long)app); 850 + mrp_periodic_timer_arm(app); 871 851 return 0; 872 852 873 853 err3: ··· 896 870 * all pending messages before the applicant is gone. 897 871 */ 898 872 del_timer_sync(&app->join_timer); 873 + del_timer_sync(&app->periodic_timer); 899 874 900 875 spin_lock_bh(&app->lock); 901 876 mrp_mad_event(app, MRP_EVENT_TX);