diff options
author | Noel Burton-Krahn <noel@burton-krahn.com> | 2013-09-18 15:24:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-09-23 16:53:52 -0400 |
commit | 9fe34f5d920b183ec063550e0f4ec854aa373316 (patch) | |
tree | ece6e10648809dc2aa87e434b3c7b0f3b0dea0d0 /net/802/mrp.c | |
parent | a224bd36bf5ccc72d0f12ab11216706762133177 (diff) |
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>
Diffstat (limited to 'net/802/mrp.c')
-rw-r--r-- | net/802/mrp.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/net/802/mrp.c b/net/802/mrp.c index 1eb05d80b07b..3ed616215870 100644 --- a/net/802/mrp.c +++ b/net/802/mrp.c | |||
@@ -24,6 +24,11 @@ | |||
24 | static unsigned int mrp_join_time __read_mostly = 200; | 24 | static unsigned int mrp_join_time __read_mostly = 200; |
25 | module_param(mrp_join_time, uint, 0644); | 25 | module_param(mrp_join_time, uint, 0644); |
26 | MODULE_PARM_DESC(mrp_join_time, "Join time in ms (default 200ms)"); | 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 | MODULE_LICENSE("GPL"); | 32 | MODULE_LICENSE("GPL"); |
28 | 33 | ||
29 | static const u8 | 34 | static const u8 |
@@ -595,6 +600,24 @@ static void mrp_join_timer(unsigned long data) | |||
595 | mrp_join_timer_arm(app); | 600 | mrp_join_timer_arm(app); |
596 | } | 601 | } |
597 | 602 | ||
603 | static void mrp_periodic_timer_arm(struct mrp_applicant *app) | ||
604 | { | ||
605 | mod_timer(&app->periodic_timer, | ||
606 | jiffies + msecs_to_jiffies(mrp_periodic_time)); | ||
607 | } | ||
608 | |||
609 | static void mrp_periodic_timer(unsigned long data) | ||
610 | { | ||
611 | struct mrp_applicant *app = (struct mrp_applicant *)data; | ||
612 | |||
613 | spin_lock(&app->lock); | ||
614 | mrp_mad_event(app, MRP_EVENT_PERIODIC); | ||
615 | mrp_pdu_queue(app); | ||
616 | spin_unlock(&app->lock); | ||
617 | |||
618 | mrp_periodic_timer_arm(app); | ||
619 | } | ||
620 | |||
598 | static int mrp_pdu_parse_end_mark(struct sk_buff *skb, int *offset) | 621 | static int mrp_pdu_parse_end_mark(struct sk_buff *skb, int *offset) |
599 | { | 622 | { |
600 | __be16 endmark; | 623 | __be16 endmark; |
@@ -845,6 +868,9 @@ int mrp_init_applicant(struct net_device *dev, struct mrp_application *appl) | |||
845 | rcu_assign_pointer(dev->mrp_port->applicants[appl->type], app); | 868 | rcu_assign_pointer(dev->mrp_port->applicants[appl->type], app); |
846 | setup_timer(&app->join_timer, mrp_join_timer, (unsigned long)app); | 869 | setup_timer(&app->join_timer, mrp_join_timer, (unsigned long)app); |
847 | mrp_join_timer_arm(app); | 870 | mrp_join_timer_arm(app); |
871 | setup_timer(&app->periodic_timer, mrp_periodic_timer, | ||
872 | (unsigned long)app); | ||
873 | mrp_periodic_timer_arm(app); | ||
848 | return 0; | 874 | return 0; |
849 | 875 | ||
850 | err3: | 876 | err3: |
@@ -870,6 +896,7 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl) | |||
870 | * all pending messages before the applicant is gone. | 896 | * all pending messages before the applicant is gone. |
871 | */ | 897 | */ |
872 | del_timer_sync(&app->join_timer); | 898 | del_timer_sync(&app->join_timer); |
899 | del_timer_sync(&app->periodic_timer); | ||
873 | 900 | ||
874 | spin_lock_bh(&app->lock); | 901 | spin_lock_bh(&app->lock); |
875 | mrp_mad_event(app, MRP_EVENT_TX); | 902 | mrp_mad_event(app, MRP_EVENT_TX); |