netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* PATCH: periodictimer for mrp.c
@ 2013-09-16 20:32 Noel Burton-Krahn
  0 siblings, 0 replies; only message in thread
From: Noel Burton-Krahn @ 2013-09-16 20:32 UTC (permalink / raw)
  To: netdev

[-- Attachment #1: Type: text/plain, Size: 1025 bytes --]

(originally to "David S. Miller" <davem@davemloft.net>, CC'ed to
netdev.  Resent in text/plain)


I ran into a problem when testing MVRP support in net/mrp.c:  MRP
would transmit JoinIn messages before the network interface was fully
up, the packets would be lost, and MRP would never retry.  It looks
like the MRP implementation was missing the periodictimer defined in
[802.1Q-2011] to retry if packets get lost.  The attached patch patch
adds the periodictimer.

Note: As far as I can tell in [802.1Q-2011], the periodic timer never
turns off.  It fires every second, causing MRP to bounce from state QA
to AA and back.  You might think that would stop when the registrar
responds with an JoinIn, but there's no state in the MRP state table
to ignore the periodic timer after getting a reply.  The result is MRP
sends a JoinIn message every second.  This may not be desirable, but
it's what the spec requires.

[802.1Q-2011]
http://standards.ieee.org/findstds/standard/802.1Q-2011.html

Does this look OK to you?

--
Noel

[-- Attachment #2: mrp-periodictimer.patch --]
[-- Type: application/octet-stream, Size: 2955 bytes --]

diff --git a/include/net/mrp.h b/include/net/mrp.h
index 4fbf02a..0f7558b 100644
--- a/include/net/mrp.h
+++ b/include/net/mrp.h
@@ -112,6 +112,7 @@ struct mrp_applicant {
 	struct mrp_application	*app;
 	struct net_device	*dev;
 	struct timer_list	join_timer;
+	struct timer_list	periodic_timer;
 
 	spinlock_t		lock;
 	struct sk_buff_head	queue;
diff --git a/net/802/mrp.c b/net/802/mrp.c
index 1eb05d8..97566ec 100644
--- a/net/802/mrp.c
+++ b/net/802/mrp.c
@@ -24,6 +24,11 @@
 static unsigned int mrp_join_time __read_mostly = 200;
 module_param(mrp_join_time, uint, 0644);
 MODULE_PARM_DESC(mrp_join_time, "Join time in ms (default 200ms)");
+
+static unsigned int mrp_periodic_time __read_mostly = 1000;
+module_param(mrp_periodic_time, uint, 0644);
+MODULE_PARM_DESC(mrp_periodic_time, "Periodic time in ms (default 1s)");
+
 MODULE_LICENSE("GPL");
 
 static const u8
@@ -595,6 +600,43 @@ static void mrp_join_timer(unsigned long data)
 	mrp_join_timer_arm(app);
 }
 
+static void mrp_periodic_timer_arm(struct mrp_applicant *app)
+{
+	unsigned long delay;
+
+	delay = (u64)msecs_to_jiffies(mrp_periodic_time);
+	mod_timer(&app->periodic_timer, jiffies + delay);
+}
+
+
+/*
+  Added periodic timer from [802.1Q-2011] to retry if MRP loses
+  messages.  MRP used to lose JoinIn messages and never retry if it
+  sent messages before the interface becomes ready.
+
+  The periodic timer from the 802.1Q spec never turns off.  It fires
+  every second, causing MRP to bounce from state QA to AA and back.
+  You might think that would stop when the registrar responds with an
+  JoinIn, but there's no state in the MRP state table to ignore the
+  periodic timer after getting a reply.  The result is MRP sends a
+  JoinIn message every second.  This may not be desirable, but it's
+  what the spec requires.
+  
+  [802.1Q-2011]
+  http://standards.ieee.org/findstds/standard/802.1Q-2011.html
+*/
+static void mrp_periodic_timer(unsigned long data)
+{
+	struct mrp_applicant *app = (struct mrp_applicant *)data;
+
+	spin_lock(&app->lock);
+	mrp_mad_event(app, MRP_EVENT_PERIODIC);
+	mrp_pdu_queue(app);
+	spin_unlock(&app->lock);
+
+	mrp_periodic_timer_arm(app);
+}
+
 static int mrp_pdu_parse_end_mark(struct sk_buff *skb, int *offset)
 {
 	__be16 endmark;
@@ -845,6 +887,8 @@ int mrp_init_applicant(struct net_device *dev, struct mrp_application *appl)
 	rcu_assign_pointer(dev->mrp_port->applicants[appl->type], app);
 	setup_timer(&app->join_timer, mrp_join_timer, (unsigned long)app);
 	mrp_join_timer_arm(app);
+	setup_timer(&app->periodic_timer, mrp_periodic_timer, (unsigned long)app);
+	mrp_periodic_timer_arm(app);
 	return 0;
 
 err3:
@@ -870,6 +914,7 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl)
 	 * all pending messages before the applicant is gone.
 	 */
 	del_timer_sync(&app->join_timer);
+	del_timer_sync(&app->periodic_timer);
 
 	spin_lock_bh(&app->lock);
 	mrp_mad_event(app, MRP_EVENT_TX);

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2013-09-16 20:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-16 20:32 PATCH: periodictimer for mrp.c Noel Burton-Krahn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).