@@ -230,88 +230,90 @@ void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest)
230230 * tipc_enable_bearer - enable bearer with the given name
231231 */
232232static int tipc_enable_bearer (struct net * net , const char * name ,
233- u32 disc_domain , u32 priority ,
233+ u32 disc_domain , u32 prio ,
234234 struct nlattr * attr [])
235235{
236- struct tipc_net * tn = net_generic (net , tipc_net_id );
236+ struct tipc_net * tn = tipc_net (net );
237+ struct tipc_bearer_names b_names ;
238+ u32 self = tipc_own_addr (net );
239+ int with_this_prio = 1 ;
237240 struct tipc_bearer * b ;
238241 struct tipc_media * m ;
239- struct tipc_bearer_names b_names ;
240242 struct sk_buff * skb ;
241243 char addr_string [16 ];
242- u32 bearer_id ;
243- u32 with_this_prio ;
244- u32 i ;
244+ int bearer_id = 0 ;
245245 int res = - EINVAL ;
246+ char * errstr = "" ;
246247
247- if (!tn -> own_addr ) {
248- pr_warn ( "Bearer <%s> rejected, not supported in standalone mode\n" ,
249- name ) ;
250- return - ENOPROTOOPT ;
248+ if (!self ) {
249+ errstr = " not supported in standalone mode" ;
250+ res = - ENOPROTOOPT ;
251+ goto rejected ;
251252 }
253+
252254 if (!bearer_name_validate (name , & b_names )) {
253- pr_warn ( "Bearer <%s> rejected, illegal name\n" , name ) ;
254- return - EINVAL ;
255+ errstr = " illegal name" ;
256+ goto rejected ;
255257 }
256- if (tipc_addr_domain_valid (disc_domain ) &&
257- (disc_domain != tn -> own_addr )) {
258- if (tipc_in_scope (disc_domain , tn -> own_addr )) {
259- disc_domain = tn -> own_addr & TIPC_ZONE_CLUSTER_MASK ;
260- res = 0 ; /* accept any node in own cluster */
261- } else if (in_own_cluster_exact (net , disc_domain ))
262- res = 0 ; /* accept specified node in own cluster */
258+
259+ if (tipc_addr_domain_valid (disc_domain ) && disc_domain != self ) {
260+ if (tipc_in_scope (disc_domain , self )) {
261+ /* Accept any node in own cluster */
262+ disc_domain = self & TIPC_ZONE_CLUSTER_MASK ;
263+ res = 0 ;
264+ } else if (in_own_cluster_exact (net , disc_domain )) {
265+ /* Accept specified node in own cluster */
266+ res = 0 ;
267+ }
263268 }
264269 if (res ) {
265- pr_warn ("Bearer <%s> rejected, illegal discovery domain\n" ,
266- name );
267- return - EINVAL ;
270+ errstr = "illegal discovery domain" ;
271+ goto rejected ;
268272 }
269- if (( priority > TIPC_MAX_LINK_PRI ) &&
270- ( priority != TIPC_MEDIA_LINK_PRI ) ) {
271- pr_warn ( "Bearer <%s> rejected, illegal priority\n" , name ) ;
272- return - EINVAL ;
273+
274+ if ( prio > TIPC_MAX_LINK_PRI && prio != TIPC_MEDIA_LINK_PRI ) {
275+ errstr = " illegal priority" ;
276+ goto rejected ;
273277 }
274278
275279 m = tipc_media_find (b_names .media_name );
276280 if (!m ) {
277- pr_warn ("Bearer <%s> rejected, media <%s> not registered\n" ,
278- name , b_names .media_name );
279- return - EINVAL ;
281+ errstr = "media not registered" ;
282+ goto rejected ;
280283 }
281284
282- if (priority == TIPC_MEDIA_LINK_PRI )
283- priority = m -> priority ;
285+ if (prio == TIPC_MEDIA_LINK_PRI )
286+ prio = m -> priority ;
284287
285- restart :
286- bearer_id = MAX_BEARERS ;
287- with_this_prio = 1 ;
288- for (i = MAX_BEARERS ; i -- != 0 ; ) {
289- b = rtnl_dereference (tn -> bearer_list [i ]);
290- if (!b ) {
291- bearer_id = i ;
292- continue ;
293- }
288+ /* Check new bearer vs existing ones and find free bearer id if any */
289+ while (bearer_id < MAX_BEARERS ) {
290+ b = rtnl_dereference (tn -> bearer_list [bearer_id ]);
291+ if (!b )
292+ break ;
294293 if (!strcmp (name , b -> name )) {
295- pr_warn ("Bearer <%s> rejected, already enabled\n" ,
296- name );
297- return - EINVAL ;
294+ errstr = "already enabled" ;
295+ goto rejected ;
298296 }
299- if (( b -> priority == priority ) &&
300- ( ++ with_this_prio > 2 )) {
301- if ( priority -- == 0 ) {
302- pr_warn ( "Bearer <%s> rejected, duplicate priority\n" ,
303- name ) ;
304- return - EINVAL ;
305- }
306- pr_warn ( "Bearer <%s> priority adjustment required %u->%u\n" ,
307- name , priority + 1 , priority ) ;
308- goto restart ;
297+ bearer_id ++ ;
298+ if ( b -> priority != prio )
299+ continue ;
300+ if ( ++ with_this_prio <= 2 )
301+ continue ;
302+ pr_warn ( "Bearer <%s>: already 2 bearers with priority %u\n" ,
303+ name , prio );
304+ if ( prio == TIPC_MIN_LINK_PRI ) {
305+ errstr = "cannot adjust to lower" ;
306+ goto rejected ;
309307 }
308+ pr_warn ("Bearer <%s>: trying with adjusted priority\n" , name );
309+ prio -- ;
310+ bearer_id = 0 ;
311+ with_this_prio = 1 ;
310312 }
313+
311314 if (bearer_id >= MAX_BEARERS ) {
312- pr_warn ("Bearer <%s> rejected, bearer limit reached (%u)\n" ,
313- name , MAX_BEARERS );
314- return - EINVAL ;
315+ errstr = "max 3 bearers permitted" ;
316+ goto rejected ;
315317 }
316318
317319 b = kzalloc (sizeof (* b ), GFP_ATOMIC );
@@ -322,26 +324,25 @@ static int tipc_enable_bearer(struct net *net, const char *name,
322324 b -> media = m ;
323325 res = m -> enable_media (net , b , attr );
324326 if (res ) {
325- pr_warn ("Bearer <%s> rejected, enable failure (%d)\n" ,
326- name , - res );
327327 kfree (b );
328- return - EINVAL ;
328+ errstr = "failed to enable media" ;
329+ goto rejected ;
329330 }
330331
331332 b -> identity = bearer_id ;
332333 b -> tolerance = m -> tolerance ;
333334 b -> window = m -> window ;
334335 b -> domain = disc_domain ;
335336 b -> net_plane = bearer_id + 'A' ;
336- b -> priority = priority ;
337+ b -> priority = prio ;
337338 test_and_set_bit_lock (0 , & b -> up );
338339
339340 res = tipc_disc_create (net , b , & b -> bcast_addr , & skb );
340341 if (res ) {
341342 bearer_disable (net , b );
342- pr_warn ( "Bearer <%s> rejected, discovery object creation failed\n" ,
343- name ) ;
344- return - EINVAL ;
343+ kfree ( b );
344+ errstr = "failed to create discoverer" ;
345+ goto rejected ;
345346 }
346347
347348 rcu_assign_pointer (tn -> bearer_list [bearer_id ], b );
@@ -353,9 +354,12 @@ static int tipc_enable_bearer(struct net *net, const char *name,
353354 return - ENOMEM ;
354355 }
355356
356- pr_info ("Enabled bearer <%s>, discovery domain %s, priority %u\n" ,
357- name ,
358- tipc_addr_string_fill (addr_string , disc_domain ), priority );
357+ tipc_addr_string_fill (addr_string , disc_domain );
358+ pr_info ("Enabled bearer <%s>, discovery scope %s, priority %u\n" ,
359+ name , addr_string , prio );
360+ return res ;
361+ rejected :
362+ pr_warn ("Bearer <%s> rejected, %s\n" , name , errstr );
359363 return res ;
360364}
361365
0 commit comments