diff options
| -rw-r--r-- | net/tipc/discover.c | 19 | ||||
| -rw-r--r-- | net/tipc/net.c | 45 | ||||
| -rw-r--r-- | net/tipc/net.h | 2 |
3 files changed, 48 insertions, 18 deletions
diff --git a/net/tipc/discover.c b/net/tipc/discover.c index 2830709957bd..c138d68e8a69 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c | |||
| @@ -166,7 +166,8 @@ static bool tipc_disc_addr_trial_msg(struct tipc_discoverer *d, | |||
| 166 | 166 | ||
| 167 | /* Apply trial address if we just left trial period */ | 167 | /* Apply trial address if we just left trial period */ |
| 168 | if (!trial && !self) { | 168 | if (!trial && !self) { |
| 169 | tipc_net_finalize(net, tn->trial_addr); | 169 | tipc_sched_net_finalize(net, tn->trial_addr); |
| 170 | msg_set_prevnode(buf_msg(d->skb), tn->trial_addr); | ||
| 170 | msg_set_type(buf_msg(d->skb), DSC_REQ_MSG); | 171 | msg_set_type(buf_msg(d->skb), DSC_REQ_MSG); |
| 171 | } | 172 | } |
| 172 | 173 | ||
| @@ -300,14 +301,12 @@ static void tipc_disc_timeout(struct timer_list *t) | |||
| 300 | goto exit; | 301 | goto exit; |
| 301 | } | 302 | } |
| 302 | 303 | ||
| 303 | /* Trial period over ? */ | 304 | /* Did we just leave trial period ? */ |
| 304 | if (!time_before(jiffies, tn->addr_trial_end)) { | 305 | if (!time_before(jiffies, tn->addr_trial_end) && !tipc_own_addr(net)) { |
| 305 | /* Did we just leave it ? */ | 306 | mod_timer(&d->timer, jiffies + TIPC_DISC_INIT); |
| 306 | if (!tipc_own_addr(net)) | 307 | spin_unlock_bh(&d->lock); |
| 307 | tipc_net_finalize(net, tn->trial_addr); | 308 | tipc_sched_net_finalize(net, tn->trial_addr); |
| 308 | 309 | return; | |
| 309 | msg_set_type(buf_msg(d->skb), DSC_REQ_MSG); | ||
| 310 | msg_set_prevnode(buf_msg(d->skb), tipc_own_addr(net)); | ||
| 311 | } | 310 | } |
| 312 | 311 | ||
| 313 | /* Adjust timeout interval according to discovery phase */ | 312 | /* Adjust timeout interval according to discovery phase */ |
| @@ -319,6 +318,8 @@ static void tipc_disc_timeout(struct timer_list *t) | |||
| 319 | d->timer_intv = TIPC_DISC_SLOW; | 318 | d->timer_intv = TIPC_DISC_SLOW; |
| 320 | else if (!d->num_nodes && d->timer_intv > TIPC_DISC_FAST) | 319 | else if (!d->num_nodes && d->timer_intv > TIPC_DISC_FAST) |
| 321 | d->timer_intv = TIPC_DISC_FAST; | 320 | d->timer_intv = TIPC_DISC_FAST; |
| 321 | msg_set_type(buf_msg(d->skb), DSC_REQ_MSG); | ||
| 322 | msg_set_prevnode(buf_msg(d->skb), tn->trial_addr); | ||
| 322 | } | 323 | } |
| 323 | 324 | ||
| 324 | mod_timer(&d->timer, jiffies + d->timer_intv); | 325 | mod_timer(&d->timer, jiffies + d->timer_intv); |
diff --git a/net/tipc/net.c b/net/tipc/net.c index 62199cf5a56c..f076edb74338 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c | |||
| @@ -104,6 +104,14 @@ | |||
| 104 | * - A local spin_lock protecting the queue of subscriber events. | 104 | * - A local spin_lock protecting the queue of subscriber events. |
| 105 | */ | 105 | */ |
| 106 | 106 | ||
| 107 | struct tipc_net_work { | ||
| 108 | struct work_struct work; | ||
| 109 | struct net *net; | ||
| 110 | u32 addr; | ||
| 111 | }; | ||
| 112 | |||
| 113 | static void tipc_net_finalize(struct net *net, u32 addr); | ||
| 114 | |||
| 107 | int tipc_net_init(struct net *net, u8 *node_id, u32 addr) | 115 | int tipc_net_init(struct net *net, u8 *node_id, u32 addr) |
| 108 | { | 116 | { |
| 109 | if (tipc_own_id(net)) { | 117 | if (tipc_own_id(net)) { |
| @@ -119,17 +127,38 @@ int tipc_net_init(struct net *net, u8 *node_id, u32 addr) | |||
| 119 | return 0; | 127 | return 0; |
| 120 | } | 128 | } |
| 121 | 129 | ||
| 122 | void tipc_net_finalize(struct net *net, u32 addr) | 130 | static void tipc_net_finalize(struct net *net, u32 addr) |
| 123 | { | 131 | { |
| 124 | struct tipc_net *tn = tipc_net(net); | 132 | struct tipc_net *tn = tipc_net(net); |
| 125 | 133 | ||
| 126 | if (!cmpxchg(&tn->node_addr, 0, addr)) { | 134 | if (cmpxchg(&tn->node_addr, 0, addr)) |
| 127 | tipc_set_node_addr(net, addr); | 135 | return; |
| 128 | tipc_named_reinit(net); | 136 | tipc_set_node_addr(net, addr); |
| 129 | tipc_sk_reinit(net); | 137 | tipc_named_reinit(net); |
| 130 | tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr, | 138 | tipc_sk_reinit(net); |
| 131 | TIPC_CLUSTER_SCOPE, 0, addr); | 139 | tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr, |
| 132 | } | 140 | TIPC_CLUSTER_SCOPE, 0, addr); |
| 141 | } | ||
| 142 | |||
| 143 | static void tipc_net_finalize_work(struct work_struct *work) | ||
| 144 | { | ||
| 145 | struct tipc_net_work *fwork; | ||
| 146 | |||
| 147 | fwork = container_of(work, struct tipc_net_work, work); | ||
| 148 | tipc_net_finalize(fwork->net, fwork->addr); | ||
| 149 | kfree(fwork); | ||
| 150 | } | ||
| 151 | |||
| 152 | void tipc_sched_net_finalize(struct net *net, u32 addr) | ||
| 153 | { | ||
| 154 | struct tipc_net_work *fwork = kzalloc(sizeof(*fwork), GFP_ATOMIC); | ||
| 155 | |||
| 156 | if (!fwork) | ||
| 157 | return; | ||
| 158 | INIT_WORK(&fwork->work, tipc_net_finalize_work); | ||
| 159 | fwork->net = net; | ||
| 160 | fwork->addr = addr; | ||
| 161 | schedule_work(&fwork->work); | ||
| 133 | } | 162 | } |
| 134 | 163 | ||
| 135 | void tipc_net_stop(struct net *net) | 164 | void tipc_net_stop(struct net *net) |
diff --git a/net/tipc/net.h b/net/tipc/net.h index 09ad02b50bb1..b7f2e364eb99 100644 --- a/net/tipc/net.h +++ b/net/tipc/net.h | |||
| @@ -42,7 +42,7 @@ | |||
| 42 | extern const struct nla_policy tipc_nl_net_policy[]; | 42 | extern const struct nla_policy tipc_nl_net_policy[]; |
| 43 | 43 | ||
| 44 | int tipc_net_init(struct net *net, u8 *node_id, u32 addr); | 44 | int tipc_net_init(struct net *net, u8 *node_id, u32 addr); |
| 45 | void tipc_net_finalize(struct net *net, u32 addr); | 45 | void tipc_sched_net_finalize(struct net *net, u32 addr); |
| 46 | void tipc_net_stop(struct net *net); | 46 | void tipc_net_stop(struct net *net); |
| 47 | int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb); | 47 | int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb); |
| 48 | int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info); | 48 | int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info); |
