Skip to content

Commit 8985ecc

Browse files
Jon Maloydavem330
authored andcommitted
tipc: simplify endianness handling in topology subscriber
Because of the requirement for total distribution transparency, users send subscriptions and receive topology events in their own host format. It is up to the topology server to determine this format and do the correct conversions to and from its own host format when needed. Until now, this has been handled in a rather non-transparent way inside the topology server and subscriber code, leading to unnecessary complexity when creating subscriptions and issuing events. We now improve this situation by adding two new macros, tipc_sub_read() and tipc_evt_write(). Both those functions calculate the need for conversion internally before performing their respective operations. Hence, all handling of such conversions become transparent to the rest of the code. Acked-by: Ying Xue <[email protected]> Signed-off-by: Jon Maloy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 414574a commit 8985ecc

File tree

5 files changed

+86
-102
lines changed

5 files changed

+86
-102
lines changed

net/tipc/name_table.c

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -412,18 +412,22 @@ static struct publication *tipc_nameseq_remove_publ(struct net *net,
412412
* sequence overlapping with the requested sequence
413413
*/
414414
static void tipc_nameseq_subscribe(struct name_seq *nseq,
415-
struct tipc_subscription *s,
416-
bool status)
415+
struct tipc_subscription *sub)
417416
{
418417
struct sub_seq *sseq = nseq->sseqs;
419418
struct tipc_name_seq ns;
419+
struct tipc_subscr *s = &sub->evt.s;
420+
bool no_status;
420421

421-
tipc_subscrp_convert_seq(&s->evt.s.seq, s->swap, &ns);
422+
ns.type = tipc_sub_read(s, seq.type);
423+
ns.lower = tipc_sub_read(s, seq.lower);
424+
ns.upper = tipc_sub_read(s, seq.upper);
425+
no_status = tipc_sub_read(s, filter) & TIPC_SUB_NO_STATUS;
422426

423-
tipc_subscrp_get(s);
424-
list_add(&s->nameseq_list, &nseq->subscriptions);
427+
tipc_subscrp_get(sub);
428+
list_add(&sub->nameseq_list, &nseq->subscriptions);
425429

426-
if (!status || !sseq)
430+
if (no_status || !sseq)
427431
return;
428432

429433
while (sseq != &nseq->sseqs[nseq->first_free]) {
@@ -433,7 +437,7 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq,
433437
int must_report = 1;
434438

435439
list_for_each_entry(crs, &info->zone_list, zone_list) {
436-
tipc_subscrp_report_overlap(s, sseq->lower,
440+
tipc_subscrp_report_overlap(sub, sseq->lower,
437441
sseq->upper,
438442
TIPC_PUBLISHED,
439443
crs->ref, crs->node,
@@ -808,11 +812,12 @@ int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 ref,
808812
/**
809813
* tipc_nametbl_subscribe - add a subscription object to the name table
810814
*/
811-
void tipc_nametbl_subscribe(struct tipc_subscription *s, bool status)
815+
void tipc_nametbl_subscribe(struct tipc_subscription *sub)
812816
{
813-
struct tipc_server *srv = s->server;
817+
struct tipc_server *srv = sub->server;
814818
struct tipc_net *tn = tipc_net(srv->net);
815-
u32 type = tipc_subscrp_convert_seq_type(s->evt.s.seq.type, s->swap);
819+
struct tipc_subscr *s = &sub->evt.s;
820+
u32 type = tipc_sub_read(s, seq.type);
816821
int index = hash(type);
817822
struct name_seq *seq;
818823
struct tipc_name_seq ns;
@@ -823,10 +828,12 @@ void tipc_nametbl_subscribe(struct tipc_subscription *s, bool status)
823828
seq = tipc_nameseq_create(type, &tn->nametbl->seq_hlist[index]);
824829
if (seq) {
825830
spin_lock_bh(&seq->lock);
826-
tipc_nameseq_subscribe(seq, s, status);
831+
tipc_nameseq_subscribe(seq, sub);
827832
spin_unlock_bh(&seq->lock);
828833
} else {
829-
tipc_subscrp_convert_seq(&s->evt.s.seq, s->swap, &ns);
834+
ns.type = tipc_sub_read(s, seq.type);
835+
ns.lower = tipc_sub_read(s, seq.lower);
836+
ns.upper = tipc_sub_read(s, seq.upper);
830837
pr_warn("Failed to create subscription for {%u,%u,%u}\n",
831838
ns.type, ns.lower, ns.upper);
832839
}
@@ -836,19 +843,20 @@ void tipc_nametbl_subscribe(struct tipc_subscription *s, bool status)
836843
/**
837844
* tipc_nametbl_unsubscribe - remove a subscription object from name table
838845
*/
839-
void tipc_nametbl_unsubscribe(struct tipc_subscription *s)
846+
void tipc_nametbl_unsubscribe(struct tipc_subscription *sub)
840847
{
841-
struct tipc_server *srv = s->server;
848+
struct tipc_server *srv = sub->server;
849+
struct tipc_subscr *s = &sub->evt.s;
842850
struct tipc_net *tn = tipc_net(srv->net);
843851
struct name_seq *seq;
844-
u32 type = tipc_subscrp_convert_seq_type(s->evt.s.seq.type, s->swap);
852+
u32 type = tipc_sub_read(s, seq.type);
845853

846854
spin_lock_bh(&tn->nametbl_lock);
847855
seq = nametbl_find_seq(srv->net, type);
848856
if (seq != NULL) {
849857
spin_lock_bh(&seq->lock);
850-
list_del_init(&s->nameseq_list);
851-
tipc_subscrp_put(s);
858+
list_del_init(&sub->nameseq_list);
859+
tipc_subscrp_put(sub);
852860
if (!seq->first_free && list_empty(&seq->subscriptions)) {
853861
hlist_del_init_rcu(&seq->ns_list);
854862
kfree(seq->sseqs);

net/tipc/name_table.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ struct publication *tipc_nametbl_insert_publ(struct net *net, u32 type,
120120
struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
121121
u32 lower, u32 node, u32 ref,
122122
u32 key);
123-
void tipc_nametbl_subscribe(struct tipc_subscription *s, bool status);
123+
void tipc_nametbl_subscribe(struct tipc_subscription *s);
124124
void tipc_nametbl_unsubscribe(struct tipc_subscription *s);
125125
int tipc_nametbl_init(struct net *net);
126126
void tipc_nametbl_stop(struct net *net);

net/tipc/server.c

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -98,18 +98,6 @@ static bool connected(struct tipc_conn *con)
9898
return con && test_bit(CF_CONNECTED, &con->flags);
9999
}
100100

101-
/**
102-
* htohl - convert value to endianness used by destination
103-
* @in: value to convert
104-
* @swap: non-zero if endianness must be reversed
105-
*
106-
* Returns converted value
107-
*/
108-
static u32 htohl(u32 in, int swap)
109-
{
110-
return swap ? swab32(in) : in;
111-
}
112-
113101
static void tipc_conn_kref_release(struct kref *kref)
114102
{
115103
struct tipc_conn *con = container_of(kref, struct tipc_conn, kref);
@@ -285,21 +273,12 @@ static int tipc_con_rcv_sub(struct tipc_server *srv,
285273
struct tipc_subscr *s)
286274
{
287275
struct tipc_subscription *sub;
288-
bool status;
289-
int swap;
290-
291-
/* Determine subscriber's endianness */
292-
swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE |
293-
TIPC_SUB_CANCEL));
294276

295-
/* Detect & process a subscription cancellation request */
296-
if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) {
297-
s->filter &= ~htohl(TIPC_SUB_CANCEL, swap);
277+
if (tipc_sub_read(s, filter) & TIPC_SUB_CANCEL) {
298278
tipc_con_delete_sub(con, s);
299279
return 0;
300280
}
301-
status = !(s->filter & htohl(TIPC_SUB_NO_STATUS, swap));
302-
sub = tipc_subscrp_subscribe(srv, s, con->conid, swap, status);
281+
sub = tipc_subscrp_subscribe(srv, s, con->conid);
303282
if (!sub)
304283
return -1;
305284

net/tipc/subscr.c

Lines changed: 31 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -38,32 +38,19 @@
3838
#include "name_table.h"
3939
#include "subscr.h"
4040

41-
/**
42-
* htohl - convert value to endianness used by destination
43-
* @in: value to convert
44-
* @swap: non-zero if endianness must be reversed
45-
*
46-
* Returns converted value
47-
*/
48-
static u32 htohl(u32 in, int swap)
49-
{
50-
return swap ? swab32(in) : in;
51-
}
52-
5341
static void tipc_subscrp_send_event(struct tipc_subscription *sub,
5442
u32 found_lower, u32 found_upper,
5543
u32 event, u32 port, u32 node)
5644
{
5745
struct tipc_event *evt = &sub->evt;
58-
bool swap = sub->swap;
5946

6047
if (sub->inactive)
6148
return;
62-
evt->event = htohl(event, swap);
63-
evt->found_lower = htohl(found_lower, swap);
64-
evt->found_upper = htohl(found_upper, swap);
65-
evt->port.ref = htohl(port, swap);
66-
evt->port.node = htohl(node, swap);
49+
tipc_evt_write(evt, event, event);
50+
tipc_evt_write(evt, found_lower, found_lower);
51+
tipc_evt_write(evt, found_upper, found_upper);
52+
tipc_evt_write(evt, port.ref, port);
53+
tipc_evt_write(evt, port.node, node);
6754
tipc_conn_queue_evt(sub->server, sub->conid, event, evt);
6855
}
6956

@@ -85,29 +72,22 @@ int tipc_subscrp_check_overlap(struct tipc_name_seq *seq, u32 found_lower,
8572
return 1;
8673
}
8774

88-
u32 tipc_subscrp_convert_seq_type(u32 type, int swap)
75+
void tipc_subscrp_report_overlap(struct tipc_subscription *sub,
76+
u32 found_lower, u32 found_upper,
77+
u32 event, u32 port, u32 node,
78+
u32 scope, int must)
8979
{
90-
return htohl(type, swap);
91-
}
92-
93-
void tipc_subscrp_convert_seq(struct tipc_name_seq *in, int swap,
94-
struct tipc_name_seq *out)
95-
{
96-
out->type = htohl(in->type, swap);
97-
out->lower = htohl(in->lower, swap);
98-
out->upper = htohl(in->upper, swap);
99-
}
100-
101-
void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower,
102-
u32 found_upper, u32 event, u32 port_ref,
103-
u32 node, u32 scope, int must)
104-
{
105-
u32 filter = htohl(sub->evt.s.filter, sub->swap);
10680
struct tipc_name_seq seq;
81+
struct tipc_subscr *s = &sub->evt.s;
82+
u32 filter = tipc_sub_read(s, filter);
83+
84+
seq.type = tipc_sub_read(s, seq.type);
85+
seq.lower = tipc_sub_read(s, seq.lower);
86+
seq.upper = tipc_sub_read(s, seq.upper);
10787

108-
tipc_subscrp_convert_seq(&sub->evt.s.seq, sub->swap, &seq);
10988
if (!tipc_subscrp_check_overlap(&seq, found_lower, found_upper))
11089
return;
90+
11191
if (!must && !(filter & TIPC_SUB_PORTS))
11292
return;
11393
if (filter & TIPC_SUB_CLUSTER_SCOPE && scope == TIPC_NODE_SCOPE)
@@ -116,7 +96,7 @@ void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower,
11696
return;
11797
spin_lock(&sub->lock);
11898
tipc_subscrp_send_event(sub, found_lower, found_upper,
119-
event, port_ref, node);
99+
event, port, node);
120100
spin_unlock(&sub->lock);
121101
}
122102

@@ -156,11 +136,11 @@ void tipc_subscrp_get(struct tipc_subscription *subscription)
156136

157137
static struct tipc_subscription *tipc_subscrp_create(struct tipc_server *srv,
158138
struct tipc_subscr *s,
159-
int conid, bool swap)
139+
int conid)
160140
{
161141
struct tipc_net *tn = tipc_net(srv->net);
162142
struct tipc_subscription *sub;
163-
u32 filter = htohl(s->filter, swap);
143+
u32 filter = tipc_sub_read(s, filter);
164144

165145
/* Refuse subscription if global limit exceeded */
166146
if (atomic_read(&tn->subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) {
@@ -177,39 +157,38 @@ static struct tipc_subscription *tipc_subscrp_create(struct tipc_server *srv,
177157
}
178158

179159
/* Initialize subscription object */
160+
if (filter & TIPC_SUB_PORTS && filter & TIPC_SUB_SERVICE)
161+
goto err;
162+
if (tipc_sub_read(s, seq.lower) > tipc_sub_read(s, seq.upper))
163+
goto err;
180164
sub->server = srv;
181165
sub->conid = conid;
182166
sub->inactive = false;
183-
if (((filter & TIPC_SUB_PORTS) && (filter & TIPC_SUB_SERVICE)) ||
184-
(htohl(s->seq.lower, swap) > htohl(s->seq.upper, swap))) {
185-
pr_warn("Subscription rejected, illegal request\n");
186-
kfree(sub);
187-
return NULL;
188-
}
189-
190-
sub->swap = swap;
191167
memcpy(&sub->evt.s, s, sizeof(*s));
192168
spin_lock_init(&sub->lock);
193169
atomic_inc(&tn->subscription_count);
194170
kref_init(&sub->kref);
195171
return sub;
172+
err:
173+
pr_warn("Subscription rejected, illegal request\n");
174+
kfree(sub);
175+
return NULL;
196176
}
197177

198178
struct tipc_subscription *tipc_subscrp_subscribe(struct tipc_server *srv,
199179
struct tipc_subscr *s,
200-
int conid, bool swap,
201-
bool status)
180+
int conid)
202181
{
203182
struct tipc_subscription *sub = NULL;
204183
u32 timeout;
205184

206-
sub = tipc_subscrp_create(srv, s, conid, swap);
185+
sub = tipc_subscrp_create(srv, s, conid);
207186
if (!sub)
208187
return NULL;
209188

210-
tipc_nametbl_subscribe(sub, status);
189+
tipc_nametbl_subscribe(sub);
211190
timer_setup(&sub->timer, tipc_subscrp_timeout, 0);
212-
timeout = htohl(sub->evt.s.timeout, swap);
191+
timeout = tipc_sub_read(&sub->evt.s, timeout);
213192
if (timeout != TIPC_WAIT_FOREVER)
214193
mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout));
215194
return sub;

net/tipc/subscr.h

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ struct tipc_conn;
5252
* @timer: timer governing subscription duration (optional)
5353
* @nameseq_list: adjacent subscriptions in name sequence's subscription list
5454
* @subscrp_list: adjacent subscriptions in subscriber's subscription list
55-
* @swap: indicates if subscriber uses opposite endianness in its messages
5655
* @evt: template for events generated by subscription
5756
*/
5857
struct tipc_subscription {
@@ -63,28 +62,47 @@ struct tipc_subscription {
6362
struct list_head subscrp_list;
6463
struct tipc_event evt;
6564
int conid;
66-
bool swap;
6765
bool inactive;
6866
spinlock_t lock; /* serialize up/down and timer events */
6967
};
7068

7169
struct tipc_subscription *tipc_subscrp_subscribe(struct tipc_server *srv,
7270
struct tipc_subscr *s,
73-
int conid, bool swap,
74-
bool status);
71+
int conid);
7572
void tipc_sub_delete(struct tipc_subscription *sub);
73+
7674
int tipc_subscrp_check_overlap(struct tipc_name_seq *seq, u32 found_lower,
7775
u32 found_upper);
7876
void tipc_subscrp_report_overlap(struct tipc_subscription *sub,
79-
u32 found_lower, u32 found_upper, u32 event,
80-
u32 port_ref, u32 node, u32 scope, int must);
81-
void tipc_subscrp_convert_seq(struct tipc_name_seq *in, int swap,
82-
struct tipc_name_seq *out);
83-
u32 tipc_subscrp_convert_seq_type(u32 type, int swap);
77+
u32 found_lower, u32 found_upper,
78+
u32 event, u32 port, u32 node,
79+
u32 scope, int must);
8480
int tipc_topsrv_start(struct net *net);
8581
void tipc_topsrv_stop(struct net *net);
8682

8783
void tipc_subscrp_put(struct tipc_subscription *subscription);
8884
void tipc_subscrp_get(struct tipc_subscription *subscription);
8985

86+
#define TIPC_FILTER_MASK (TIPC_SUB_PORTS | TIPC_SUB_SERVICE | TIPC_SUB_CANCEL)
87+
88+
/* tipc_sub_read - return field_ of struct sub_ in host endian format
89+
*/
90+
#define tipc_sub_read(sub_, field_) \
91+
({ \
92+
struct tipc_subscr *sub__ = sub_; \
93+
u32 val__ = (sub__)->field_; \
94+
int swap_ = !((sub__)->filter & TIPC_FILTER_MASK); \
95+
(swap_ ? swab32(val__) : val__); \
96+
})
97+
98+
/* tipc_evt_write - write val_ to field_ of struct evt_ in user endian format
99+
*/
100+
#define tipc_evt_write(evt_, field_, val_) \
101+
({ \
102+
struct tipc_event *evt__ = evt_; \
103+
u32 val__ = val_; \
104+
int swap_ = !((evt__)->s.filter & (TIPC_FILTER_MASK)); \
105+
(evt__)->field_ = swap_ ? swab32(val__) : val__; \
106+
})
107+
90108
#endif

0 commit comments

Comments
 (0)