提交 9fe34f5d 编写于 作者: N Noel Burton-Krahn 提交者: David S. Miller

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: NNoel Burton-Krahn <noel@burton-krahn.com>
Acked-by: NDavid Ward <david.ward@ll.mit.edu>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 a224bd36
...@@ -112,6 +112,7 @@ struct mrp_applicant { ...@@ -112,6 +112,7 @@ struct mrp_applicant {
struct mrp_application *app; struct mrp_application *app;
struct net_device *dev; struct net_device *dev;
struct timer_list join_timer; struct timer_list join_timer;
struct timer_list periodic_timer;
spinlock_t lock; spinlock_t lock;
struct sk_buff_head queue; struct sk_buff_head queue;
......
...@@ -24,6 +24,11 @@ ...@@ -24,6 +24,11 @@
static unsigned int mrp_join_time __read_mostly = 200; static unsigned int mrp_join_time __read_mostly = 200;
module_param(mrp_join_time, uint, 0644); module_param(mrp_join_time, uint, 0644);
MODULE_PARM_DESC(mrp_join_time, "Join time in ms (default 200ms)"); 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"); MODULE_LICENSE("GPL");
static const u8 static const u8
...@@ -595,6 +600,24 @@ static void mrp_join_timer(unsigned long data) ...@@ -595,6 +600,24 @@ static void mrp_join_timer(unsigned long data)
mrp_join_timer_arm(app); mrp_join_timer_arm(app);
} }
static void mrp_periodic_timer_arm(struct mrp_applicant *app)
{
mod_timer(&app->periodic_timer,
jiffies + msecs_to_jiffies(mrp_periodic_time));
}
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) static int mrp_pdu_parse_end_mark(struct sk_buff *skb, int *offset)
{ {
__be16 endmark; __be16 endmark;
...@@ -845,6 +868,9 @@ int mrp_init_applicant(struct net_device *dev, struct mrp_application *appl) ...@@ -845,6 +868,9 @@ int mrp_init_applicant(struct net_device *dev, struct mrp_application *appl)
rcu_assign_pointer(dev->mrp_port->applicants[appl->type], app); rcu_assign_pointer(dev->mrp_port->applicants[appl->type], app);
setup_timer(&app->join_timer, mrp_join_timer, (unsigned long)app); setup_timer(&app->join_timer, mrp_join_timer, (unsigned long)app);
mrp_join_timer_arm(app); mrp_join_timer_arm(app);
setup_timer(&app->periodic_timer, mrp_periodic_timer,
(unsigned long)app);
mrp_periodic_timer_arm(app);
return 0; return 0;
err3: err3:
...@@ -870,6 +896,7 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl) ...@@ -870,6 +896,7 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl)
* all pending messages before the applicant is gone. * all pending messages before the applicant is gone.
*/ */
del_timer_sync(&app->join_timer); del_timer_sync(&app->join_timer);
del_timer_sync(&app->periodic_timer);
spin_lock_bh(&app->lock); spin_lock_bh(&app->lock);
mrp_mad_event(app, MRP_EVENT_TX); mrp_mad_event(app, MRP_EVENT_TX);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册