diff options
Diffstat (limited to 'net/tipc/subscr.c')
-rw-r--r-- | net/tipc/subscr.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 251065dfd8df..68e26470c516 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c | |||
@@ -118,15 +118,19 @@ void tipc_subscrp_convert_seq(struct tipc_name_seq *in, int swap, | |||
118 | 118 | ||
119 | void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower, | 119 | void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower, |
120 | u32 found_upper, u32 event, u32 port_ref, | 120 | u32 found_upper, u32 event, u32 port_ref, |
121 | u32 node, int must) | 121 | u32 node, u32 scope, int must) |
122 | { | 122 | { |
123 | u32 filter = htohl(sub->evt.s.filter, sub->swap); | ||
123 | struct tipc_name_seq seq; | 124 | struct tipc_name_seq seq; |
124 | 125 | ||
125 | tipc_subscrp_convert_seq(&sub->evt.s.seq, sub->swap, &seq); | 126 | tipc_subscrp_convert_seq(&sub->evt.s.seq, sub->swap, &seq); |
126 | if (!tipc_subscrp_check_overlap(&seq, found_lower, found_upper)) | 127 | if (!tipc_subscrp_check_overlap(&seq, found_lower, found_upper)) |
127 | return; | 128 | return; |
128 | if (!must && | 129 | if (!must && !(filter & TIPC_SUB_PORTS)) |
129 | !(htohl(sub->evt.s.filter, sub->swap) & TIPC_SUB_PORTS)) | 130 | return; |
131 | if (filter & TIPC_SUB_CLUSTER_SCOPE && scope == TIPC_NODE_SCOPE) | ||
132 | return; | ||
133 | if (filter & TIPC_SUB_NODE_SCOPE && scope != TIPC_NODE_SCOPE) | ||
130 | return; | 134 | return; |
131 | 135 | ||
132 | tipc_subscrp_send_event(sub, found_lower, found_upper, event, port_ref, | 136 | tipc_subscrp_send_event(sub, found_lower, found_upper, event, port_ref, |
@@ -285,21 +289,21 @@ static struct tipc_subscription *tipc_subscrp_create(struct net *net, | |||
285 | return sub; | 289 | return sub; |
286 | } | 290 | } |
287 | 291 | ||
288 | static void tipc_subscrp_subscribe(struct net *net, struct tipc_subscr *s, | 292 | static int tipc_subscrp_subscribe(struct net *net, struct tipc_subscr *s, |
289 | struct tipc_subscriber *subscriber, int swap) | 293 | struct tipc_subscriber *subscriber, int swap, |
294 | bool status) | ||
290 | { | 295 | { |
291 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
292 | struct tipc_subscription *sub = NULL; | 296 | struct tipc_subscription *sub = NULL; |
293 | u32 timeout; | 297 | u32 timeout; |
294 | 298 | ||
295 | sub = tipc_subscrp_create(net, s, swap); | 299 | sub = tipc_subscrp_create(net, s, swap); |
296 | if (!sub) | 300 | if (!sub) |
297 | return tipc_conn_terminate(tn->topsrv, subscriber->conid); | 301 | return -1; |
298 | 302 | ||
299 | spin_lock_bh(&subscriber->lock); | 303 | spin_lock_bh(&subscriber->lock); |
300 | list_add(&sub->subscrp_list, &subscriber->subscrp_list); | 304 | list_add(&sub->subscrp_list, &subscriber->subscrp_list); |
301 | sub->subscriber = subscriber; | 305 | sub->subscriber = subscriber; |
302 | tipc_nametbl_subscribe(sub); | 306 | tipc_nametbl_subscribe(sub, status); |
303 | tipc_subscrb_get(subscriber); | 307 | tipc_subscrb_get(subscriber); |
304 | spin_unlock_bh(&subscriber->lock); | 308 | spin_unlock_bh(&subscriber->lock); |
305 | 309 | ||
@@ -308,6 +312,7 @@ static void tipc_subscrp_subscribe(struct net *net, struct tipc_subscr *s, | |||
308 | 312 | ||
309 | if (timeout != TIPC_WAIT_FOREVER) | 313 | if (timeout != TIPC_WAIT_FOREVER) |
310 | mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout)); | 314 | mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout)); |
315 | return 0; | ||
311 | } | 316 | } |
312 | 317 | ||
313 | /* Handle one termination request for the subscriber */ | 318 | /* Handle one termination request for the subscriber */ |
@@ -317,12 +322,13 @@ static void tipc_subscrb_release_cb(int conid, void *usr_data) | |||
317 | } | 322 | } |
318 | 323 | ||
319 | /* Handle one request to create a new subscription for the subscriber */ | 324 | /* Handle one request to create a new subscription for the subscriber */ |
320 | static void tipc_subscrb_rcv_cb(struct net *net, int conid, | 325 | static int tipc_subscrb_rcv_cb(struct net *net, int conid, |
321 | struct sockaddr_tipc *addr, void *usr_data, | 326 | struct sockaddr_tipc *addr, void *usr_data, |
322 | void *buf, size_t len) | 327 | void *buf, size_t len) |
323 | { | 328 | { |
324 | struct tipc_subscriber *subscriber = usr_data; | 329 | struct tipc_subscriber *subscriber = usr_data; |
325 | struct tipc_subscr *s = (struct tipc_subscr *)buf; | 330 | struct tipc_subscr *s = (struct tipc_subscr *)buf; |
331 | bool status; | ||
326 | int swap; | 332 | int swap; |
327 | 333 | ||
328 | /* Determine subscriber's endianness */ | 334 | /* Determine subscriber's endianness */ |
@@ -332,10 +338,11 @@ static void tipc_subscrb_rcv_cb(struct net *net, int conid, | |||
332 | /* Detect & process a subscription cancellation request */ | 338 | /* Detect & process a subscription cancellation request */ |
333 | if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) { | 339 | if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) { |
334 | s->filter &= ~htohl(TIPC_SUB_CANCEL, swap); | 340 | s->filter &= ~htohl(TIPC_SUB_CANCEL, swap); |
335 | return tipc_subscrp_cancel(s, subscriber); | 341 | tipc_subscrp_cancel(s, subscriber); |
342 | return 0; | ||
336 | } | 343 | } |
337 | 344 | status = !(s->filter & htohl(TIPC_SUB_NO_STATUS, swap)); | |
338 | tipc_subscrp_subscribe(net, s, subscriber, swap); | 345 | return tipc_subscrp_subscribe(net, s, subscriber, swap, status); |
339 | } | 346 | } |
340 | 347 | ||
341 | /* Handle one request to establish a new subscriber */ | 348 | /* Handle one request to establish a new subscriber */ |