Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add periodictimer to net/MRP to enable retries #48

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/net/mrp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
45 changes: 45 additions & 0 deletions net/802/mrp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand All @@ -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);
Expand Down