Blame view
net/tipc/subscr.c
5.4 KB
b97bf3fd8
|
1 |
/* |
5b06c85c3
|
2 |
* net/tipc/subscr.c: TIPC network topology service |
c43072852
|
3 |
* |
df79d040d
|
4 |
* Copyright (c) 2000-2017, Ericsson AB |
13a2e8987
|
5 |
* Copyright (c) 2005-2007, 2010-2013, Wind River Systems |
b97bf3fd8
|
6 7 |
* All rights reserved. * |
9ea1fd3c1
|
8 |
* Redistribution and use in source and binary forms, with or without |
b97bf3fd8
|
9 10 |
* modification, are permitted provided that the following conditions are met: * |
9ea1fd3c1
|
11 12 13 14 15 16 17 18 |
* 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the names of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. |
b97bf3fd8
|
19 |
* |
9ea1fd3c1
|
20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
* Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
b97bf3fd8
|
34 35 36 37 |
* POSSIBILITY OF SUCH DAMAGE. */ #include "core.h" |
b97bf3fd8
|
38 |
#include "name_table.h" |
5b06c85c3
|
39 |
#include "subscr.h" |
b97bf3fd8
|
40 |
|
da0a75e86
|
41 42 43 |
static void tipc_sub_send_event(struct tipc_subscription *sub, u32 found_lower, u32 found_upper, u32 event, u32 port, u32 node) |
b97bf3fd8
|
44 |
{ |
414574a0a
|
45 |
struct tipc_event *evt = &sub->evt; |
b97bf3fd8
|
46 |
|
df79d040d
|
47 48 |
if (sub->inactive) return; |
8985ecc7c
|
49 50 51 52 53 |
tipc_evt_write(evt, event, event); tipc_evt_write(evt, found_lower, found_lower); tipc_evt_write(evt, found_upper, found_upper); tipc_evt_write(evt, port.ref, port); tipc_evt_write(evt, port.node, node); |
026321c6d
|
54 |
tipc_topsrv_queue_evt(sub->net, sub->conid, event, evt); |
b97bf3fd8
|
55 56 57 |
} /** |
da0a75e86
|
58 |
* tipc_sub_check_overlap - test for subscription overlap with the |
57f1d1868
|
59 |
* given values |
b97bf3fd8
|
60 61 62 |
* * Returns 1 if there is overlap, otherwise 0. */ |
da0a75e86
|
63 64 |
int tipc_sub_check_overlap(struct tipc_name_seq *seq, u32 found_lower, u32 found_upper) |
b97bf3fd8
|
65 |
{ |
a4273c73e
|
66 67 68 69 |
if (found_lower < seq->lower) found_lower = seq->lower; if (found_upper > seq->upper) found_upper = seq->upper; |
b97bf3fd8
|
70 71 72 73 |
if (found_lower > found_upper) return 0; return 1; } |
da0a75e86
|
74 75 76 77 |
void tipc_sub_report_overlap(struct tipc_subscription *sub, u32 found_lower, u32 found_upper, u32 event, u32 port, u32 node, u32 scope, int must) |
a4273c73e
|
78 |
{ |
8985ecc7c
|
79 80 |
struct tipc_subscr *s = &sub->evt.s; u32 filter = tipc_sub_read(s, filter); |
da0a75e86
|
81 |
struct tipc_name_seq seq; |
8985ecc7c
|
82 83 84 85 |
seq.type = tipc_sub_read(s, seq.type); seq.lower = tipc_sub_read(s, seq.lower); seq.upper = tipc_sub_read(s, seq.upper); |
a4273c73e
|
86 |
|
da0a75e86
|
87 |
if (!tipc_sub_check_overlap(&seq, found_lower, found_upper)) |
b97bf3fd8
|
88 |
return; |
8985ecc7c
|
89 |
|
232d07b74
|
90 91 92 93 94 |
if (!must && !(filter & TIPC_SUB_PORTS)) return; if (filter & TIPC_SUB_CLUSTER_SCOPE && scope == TIPC_NODE_SCOPE) return; if (filter & TIPC_SUB_NODE_SCOPE && scope != TIPC_NODE_SCOPE) |
b97bf3fd8
|
95 |
return; |
df79d040d
|
96 |
spin_lock(&sub->lock); |
da0a75e86
|
97 98 |
tipc_sub_send_event(sub, found_lower, found_upper, event, port, node); |
df79d040d
|
99 |
spin_unlock(&sub->lock); |
b97bf3fd8
|
100 |
} |
da0a75e86
|
101 |
static void tipc_sub_timeout(struct timer_list *t) |
b97bf3fd8
|
102 |
{ |
31b102bb5
|
103 |
struct tipc_subscription *sub = from_timer(sub, t, timer); |
df79d040d
|
104 |
struct tipc_subscr *s = &sub->evt.s; |
28353e7fa
|
105 |
|
df79d040d
|
106 |
spin_lock(&sub->lock); |
da0a75e86
|
107 108 |
tipc_sub_send_event(sub, s->seq.lower, s->seq.upper, TIPC_SUBSCR_TIMEOUT, 0, 0); |
df79d040d
|
109 110 |
sub->inactive = true; spin_unlock(&sub->lock); |
eb409460b
|
111 |
} |
da0a75e86
|
112 |
static void tipc_sub_kref_release(struct kref *kref) |
d094c4d5f
|
113 |
{ |
5c45ab24a
|
114 |
kfree(container_of(kref, struct tipc_subscription, kref)); |
d094c4d5f
|
115 |
} |
da0a75e86
|
116 |
void tipc_sub_put(struct tipc_subscription *subscription) |
d094c4d5f
|
117 |
{ |
da0a75e86
|
118 |
kref_put(&subscription->kref, tipc_sub_kref_release); |
d094c4d5f
|
119 |
} |
da0a75e86
|
120 |
void tipc_sub_get(struct tipc_subscription *subscription) |
d094c4d5f
|
121 122 123 |
{ kref_get(&subscription->kref); } |
5c45ab24a
|
124 |
struct tipc_subscription *tipc_sub_subscribe(struct net *net, |
242e82cc9
|
125 126 |
struct tipc_subscr *s, int conid) |
a62fbccec
|
127 |
{ |
8985ecc7c
|
128 |
u32 filter = tipc_sub_read(s, filter); |
da0a75e86
|
129 |
struct tipc_subscription *sub; |
242e82cc9
|
130 |
u32 timeout; |
eb409460b
|
131 |
|
242e82cc9
|
132 133 134 135 |
if ((filter & TIPC_SUB_PORTS && filter & TIPC_SUB_SERVICE) || (tipc_sub_read(s, seq.lower) > tipc_sub_read(s, seq.upper))) { pr_warn("Subscription rejected, illegal request "); |
7c13c6224
|
136 |
return NULL; |
b97bf3fd8
|
137 |
} |
28353e7fa
|
138 |
sub = kmalloc(sizeof(*sub), GFP_ATOMIC); |
a10bd924a
|
139 |
if (!sub) { |
2cf8aa19f
|
140 141 |
pr_warn("Subscription rejected, no memory "); |
7c13c6224
|
142 |
return NULL; |
b97bf3fd8
|
143 |
} |
b714295ab
|
144 145 |
INIT_LIST_HEAD(&sub->service_list); INIT_LIST_HEAD(&sub->sub_list); |
5c45ab24a
|
146 |
sub->net = net; |
df79d040d
|
147 148 |
sub->conid = conid; sub->inactive = false; |
57f1d1868
|
149 |
memcpy(&sub->evt.s, s, sizeof(*s)); |
df79d040d
|
150 |
spin_lock_init(&sub->lock); |
d094c4d5f
|
151 |
kref_init(&sub->kref); |
c3317f4db
|
152 153 154 155 |
if (!tipc_nametbl_subscribe(sub)) { kfree(sub); return NULL; } |
da0a75e86
|
156 |
timer_setup(&sub->timer, tipc_sub_timeout, 0); |
8985ecc7c
|
157 |
timeout = tipc_sub_read(&sub->evt.s, timeout); |
d094c4d5f
|
158 159 |
if (timeout != TIPC_WAIT_FOREVER) mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout)); |
df79d040d
|
160 |
return sub; |
b97bf3fd8
|
161 |
} |
242e82cc9
|
162 |
void tipc_sub_unsubscribe(struct tipc_subscription *sub) |
b97bf3fd8
|
163 |
{ |
df79d040d
|
164 165 166 |
tipc_nametbl_unsubscribe(sub); if (sub->evt.s.timeout != TIPC_WAIT_FOREVER) del_timer_sync(&sub->timer); |
da0a75e86
|
167 168 |
list_del(&sub->sub_list); tipc_sub_put(sub); |
b97bf3fd8
|
169 |
} |