aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bcast.c5
-rw-r--r--net/tipc/bcast.h1
-rw-r--r--net/tipc/bearer.c18
-rw-r--r--net/tipc/link.c167
-rw-r--r--net/tipc/link.h7
-rw-r--r--net/tipc/name_table.c20
-rw-r--r--net/tipc/net.c7
-rw-r--r--net/tipc/netlink.c69
-rw-r--r--net/tipc/netlink.h11
-rw-r--r--net/tipc/netlink_compat.c2
-rw-r--r--net/tipc/node.c130
-rw-r--r--net/tipc/server.c4
-rw-r--r--net/tipc/socket.c9
-rw-r--r--net/tipc/subscr.c132
-rw-r--r--net/tipc/subscr.h11
-rw-r--r--net/tipc/udp_media.c44
16 files changed, 331 insertions, 306 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index e401108360a2..ae469b37d852 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -412,11 +412,6 @@ enomem:
412 return -ENOMEM; 412 return -ENOMEM;
413} 413}
414 414
415void tipc_bcast_reinit(struct net *net)
416{
417 tipc_link_reinit(tipc_bc_sndlink(net), tipc_own_addr(net));
418}
419
420void tipc_bcast_stop(struct net *net) 415void tipc_bcast_stop(struct net *net)
421{ 416{
422 struct tipc_net *tn = net_generic(net, tipc_net_id); 417 struct tipc_net *tn = net_generic(net, tipc_net_id);
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 1944c6c00bb9..d5e79b3767fd 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -46,7 +46,6 @@ struct tipc_node_map;
46extern const char tipc_bclink_name[]; 46extern const char tipc_bclink_name[];
47 47
48int tipc_bcast_init(struct net *net); 48int tipc_bcast_init(struct net *net);
49void tipc_bcast_reinit(struct net *net);
50void tipc_bcast_stop(struct net *net); 49void tipc_bcast_stop(struct net *net);
51void tipc_bcast_add_peer(struct net *net, struct tipc_link *l, 50void tipc_bcast_add_peer(struct net *net, struct tipc_link *l,
52 struct sk_buff_head *xmitq); 51 struct sk_buff_head *xmitq);
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 802ffad3200d..27a5406213c6 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -40,6 +40,7 @@
40#include "link.h" 40#include "link.h"
41#include "discover.h" 41#include "discover.h"
42#include "bcast.h" 42#include "bcast.h"
43#include "netlink.h"
43 44
44#define MAX_ADDR_STR 60 45#define MAX_ADDR_STR 60
45 46
@@ -54,23 +55,6 @@ static struct tipc_media * const media_info_array[] = {
54 NULL 55 NULL
55}; 56};
56 57
57static const struct nla_policy
58tipc_nl_bearer_policy[TIPC_NLA_BEARER_MAX + 1] = {
59 [TIPC_NLA_BEARER_UNSPEC] = { .type = NLA_UNSPEC },
60 [TIPC_NLA_BEARER_NAME] = {
61 .type = NLA_STRING,
62 .len = TIPC_MAX_BEARER_NAME
63 },
64 [TIPC_NLA_BEARER_PROP] = { .type = NLA_NESTED },
65 [TIPC_NLA_BEARER_DOMAIN] = { .type = NLA_U32 }
66};
67
68static const struct nla_policy tipc_nl_media_policy[TIPC_NLA_MEDIA_MAX + 1] = {
69 [TIPC_NLA_MEDIA_UNSPEC] = { .type = NLA_UNSPEC },
70 [TIPC_NLA_MEDIA_NAME] = { .type = NLA_STRING },
71 [TIPC_NLA_MEDIA_PROP] = { .type = NLA_NESTED }
72};
73
74static void bearer_disable(struct net *net, struct tipc_bearer *b); 58static void bearer_disable(struct net *net, struct tipc_bearer *b);
75 59
76/** 60/**
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 347cdc99ed09..7d2bb3e70baa 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/link.c: TIPC link code 2 * net/tipc/link.c: TIPC link code
3 * 3 *
4 * Copyright (c) 1996-2007, 2012-2015, Ericsson AB 4 * Copyright (c) 1996-2007, 2012-2016, Ericsson AB
5 * Copyright (c) 2004-2007, 2010-2013, Wind River Systems 5 * Copyright (c) 2004-2007, 2010-2013, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -123,11 +123,11 @@ struct tipc_stats {
123struct tipc_link { 123struct tipc_link {
124 u32 addr; 124 u32 addr;
125 char name[TIPC_MAX_LINK_NAME]; 125 char name[TIPC_MAX_LINK_NAME];
126 struct tipc_media_addr *media_addr;
127 struct net *net; 126 struct net *net;
128 127
129 /* Management and link supervision data */ 128 /* Management and link supervision data */
130 u32 peer_session; 129 u32 peer_session;
130 u32 session;
131 u32 peer_bearer_id; 131 u32 peer_bearer_id;
132 u32 bearer_id; 132 u32 bearer_id;
133 u32 tolerance; 133 u32 tolerance;
@@ -137,11 +137,7 @@ struct tipc_link {
137 u16 peer_caps; 137 u16 peer_caps;
138 bool active; 138 bool active;
139 u32 silent_intv_cnt; 139 u32 silent_intv_cnt;
140 struct { 140 char if_name[TIPC_MAX_IF_NAME];
141 unchar hdr[INT_H_SIZE];
142 unchar body[TIPC_MAX_IF_NAME];
143 } proto_msg;
144 struct tipc_msg *pmsg;
145 u32 priority; 141 u32 priority;
146 char net_plane; 142 char net_plane;
147 143
@@ -196,14 +192,6 @@ struct tipc_link {
196static const char *link_co_err = "Link tunneling error, "; 192static const char *link_co_err = "Link tunneling error, ";
197static const char *link_rst_msg = "Resetting link "; 193static const char *link_rst_msg = "Resetting link ";
198 194
199/* Properties valid for media, bearar and link */
200static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
201 [TIPC_NLA_PROP_UNSPEC] = { .type = NLA_UNSPEC },
202 [TIPC_NLA_PROP_PRIO] = { .type = NLA_U32 },
203 [TIPC_NLA_PROP_TOL] = { .type = NLA_U32 },
204 [TIPC_NLA_PROP_WIN] = { .type = NLA_U32 }
205};
206
207/* Send states for broadcast NACKs 195/* Send states for broadcast NACKs
208 */ 196 */
209enum { 197enum {
@@ -216,10 +204,11 @@ enum {
216 * Interval between NACKs when packets arrive out of order 204 * Interval between NACKs when packets arrive out of order
217 */ 205 */
218#define TIPC_NACK_INTV (TIPC_MIN_LINK_WIN * 2) 206#define TIPC_NACK_INTV (TIPC_MIN_LINK_WIN * 2)
219/* 207
220 * Out-of-range value for link session numbers 208/* Wildcard value for link session numbers. When it is known that
209 * peer endpoint is down, any session number must be accepted.
221 */ 210 */
222#define WILDCARD_SESSION 0x10000 211#define ANY_SESSION 0x10000
223 212
224/* Link FSM states: 213/* Link FSM states:
225 */ 214 */
@@ -399,16 +388,6 @@ char *tipc_link_name(struct tipc_link *l)
399 return l->name; 388 return l->name;
400} 389}
401 390
402static u32 link_own_addr(struct tipc_link *l)
403{
404 return msg_prevnode(l->pmsg);
405}
406
407void tipc_link_reinit(struct tipc_link *l, u32 addr)
408{
409 msg_set_prevnode(l->pmsg, addr);
410}
411
412/** 391/**
413 * tipc_link_create - create a new link 392 * tipc_link_create - create a new link
414 * @n: pointer to associated node 393 * @n: pointer to associated node
@@ -442,29 +421,22 @@ bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
442 struct tipc_link **link) 421 struct tipc_link **link)
443{ 422{
444 struct tipc_link *l; 423 struct tipc_link *l;
445 struct tipc_msg *hdr;
446 424
447 l = kzalloc(sizeof(*l), GFP_ATOMIC); 425 l = kzalloc(sizeof(*l), GFP_ATOMIC);
448 if (!l) 426 if (!l)
449 return false; 427 return false;
450 *link = l; 428 *link = l;
451 l->pmsg = (struct tipc_msg *)&l->proto_msg; 429 l->session = session;
452 hdr = l->pmsg;
453 tipc_msg_init(ownnode, hdr, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE, peer);
454 msg_set_size(hdr, sizeof(l->proto_msg));
455 msg_set_session(hdr, session);
456 msg_set_bearer_id(hdr, l->bearer_id);
457 430
458 /* Note: peer i/f name is completed by reset/activate message */ 431 /* Note: peer i/f name is completed by reset/activate message */
459 sprintf(l->name, "%u.%u.%u:%s-%u.%u.%u:unknown", 432 sprintf(l->name, "%u.%u.%u:%s-%u.%u.%u:unknown",
460 tipc_zone(ownnode), tipc_cluster(ownnode), tipc_node(ownnode), 433 tipc_zone(ownnode), tipc_cluster(ownnode), tipc_node(ownnode),
461 if_name, tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); 434 if_name, tipc_zone(peer), tipc_cluster(peer), tipc_node(peer));
462 strcpy((char *)msg_data(hdr), if_name); 435 strcpy(l->if_name, if_name);
463
464 l->addr = peer; 436 l->addr = peer;
465 l->peer_caps = peer_caps; 437 l->peer_caps = peer_caps;
466 l->net = net; 438 l->net = net;
467 l->peer_session = WILDCARD_SESSION; 439 l->peer_session = ANY_SESSION;
468 l->bearer_id = bearer_id; 440 l->bearer_id = bearer_id;
469 l->tolerance = tolerance; 441 l->tolerance = tolerance;
470 l->net_plane = net_plane; 442 l->net_plane = net_plane;
@@ -791,7 +763,7 @@ static int link_schedule_user(struct tipc_link *link, struct sk_buff_head *list)
791 struct tipc_msg *msg = buf_msg(skb_peek(list)); 763 struct tipc_msg *msg = buf_msg(skb_peek(list));
792 int imp = msg_importance(msg); 764 int imp = msg_importance(msg);
793 u32 oport = msg_origport(msg); 765 u32 oport = msg_origport(msg);
794 u32 addr = link_own_addr(link); 766 u32 addr = tipc_own_addr(link->net);
795 struct sk_buff *skb; 767 struct sk_buff *skb;
796 768
797 /* This really cannot happen... */ 769 /* This really cannot happen... */
@@ -840,16 +812,9 @@ void link_prepare_wakeup(struct tipc_link *l)
840 812
841void tipc_link_reset(struct tipc_link *l) 813void tipc_link_reset(struct tipc_link *l)
842{ 814{
843 /* Link is down, accept any session */ 815 l->peer_session = ANY_SESSION;
844 l->peer_session = WILDCARD_SESSION; 816 l->session++;
845
846 /* If peer is up, it only accepts an incremented session number */
847 msg_set_session(l->pmsg, msg_session(l->pmsg) + 1);
848
849 /* Prepare for renewed mtu size negotiation */
850 l->mtu = l->advertised_mtu; 817 l->mtu = l->advertised_mtu;
851
852 /* Clean up all queues and counters: */
853 __skb_queue_purge(&l->transmq); 818 __skb_queue_purge(&l->transmq);
854 __skb_queue_purge(&l->deferdq); 819 __skb_queue_purge(&l->deferdq);
855 skb_queue_splice_init(&l->wakeupq, l->inputq); 820 skb_queue_splice_init(&l->wakeupq, l->inputq);
@@ -904,8 +869,10 @@ int tipc_link_xmit(struct tipc_link *l, struct sk_buff_head *list,
904 if (unlikely(l->backlog[i].len >= l->backlog[i].limit)) 869 if (unlikely(l->backlog[i].len >= l->backlog[i].limit))
905 return link_schedule_user(l, list); 870 return link_schedule_user(l, list);
906 } 871 }
907 if (unlikely(msg_size(hdr) > mtu)) 872 if (unlikely(msg_size(hdr) > mtu)) {
873 skb_queue_purge(list);
908 return -EMSGSIZE; 874 return -EMSGSIZE;
875 }
909 876
910 /* Prepare each packet for sending, and add to relevant queue: */ 877 /* Prepare each packet for sending, and add to relevant queue: */
911 while (skb_queue_len(list)) { 878 while (skb_queue_len(list)) {
@@ -917,8 +884,10 @@ int tipc_link_xmit(struct tipc_link *l, struct sk_buff_head *list,
917 884
918 if (likely(skb_queue_len(transmq) < maxwin)) { 885 if (likely(skb_queue_len(transmq) < maxwin)) {
919 _skb = skb_clone(skb, GFP_ATOMIC); 886 _skb = skb_clone(skb, GFP_ATOMIC);
920 if (!_skb) 887 if (!_skb) {
888 skb_queue_purge(list);
921 return -ENOBUFS; 889 return -ENOBUFS;
890 }
922 __skb_dequeue(list); 891 __skb_dequeue(list);
923 __skb_queue_tail(transmq, skb); 892 __skb_queue_tail(transmq, skb);
924 __skb_queue_tail(xmitq, _skb); 893 __skb_queue_tail(xmitq, _skb);
@@ -1153,7 +1122,7 @@ int tipc_link_build_ack_msg(struct tipc_link *l, struct sk_buff_head *xmitq)
1153 1122
1154 /* Broadcast ACK must be sent via a unicast link => defer to caller */ 1123 /* Broadcast ACK must be sent via a unicast link => defer to caller */
1155 if (link_is_bc_rcvlink(l)) { 1124 if (link_is_bc_rcvlink(l)) {
1156 if (((l->rcv_nxt ^ link_own_addr(l)) & 0xf) != 0xf) 1125 if (((l->rcv_nxt ^ tipc_own_addr(l->net)) & 0xf) != 0xf)
1157 return 0; 1126 return 0;
1158 l->rcv_unacked = 0; 1127 l->rcv_unacked = 0;
1159 return TIPC_LINK_SND_BC_ACK; 1128 return TIPC_LINK_SND_BC_ACK;
@@ -1261,39 +1230,34 @@ drop:
1261 return rc; 1230 return rc;
1262} 1231}
1263 1232
1264/*
1265 * Send protocol message to the other endpoint.
1266 */
1267static void tipc_link_proto_xmit(struct tipc_link *l, u32 msg_typ,
1268 int probe_msg, u32 gap, u32 tolerance,
1269 u32 priority)
1270{
1271 struct sk_buff *skb = NULL;
1272 struct sk_buff_head xmitq;
1273
1274 __skb_queue_head_init(&xmitq);
1275 tipc_link_build_proto_msg(l, msg_typ, probe_msg, gap,
1276 tolerance, priority, &xmitq);
1277 skb = __skb_dequeue(&xmitq);
1278 if (!skb)
1279 return;
1280 tipc_bearer_xmit_skb(l->net, l->bearer_id, skb, l->media_addr);
1281 l->rcv_unacked = 0;
1282}
1283
1284static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe, 1233static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
1285 u16 rcvgap, int tolerance, int priority, 1234 u16 rcvgap, int tolerance, int priority,
1286 struct sk_buff_head *xmitq) 1235 struct sk_buff_head *xmitq)
1287{ 1236{
1288 struct sk_buff *skb = NULL; 1237 struct sk_buff *skb;
1289 struct tipc_msg *hdr = l->pmsg; 1238 struct tipc_msg *hdr;
1239 struct sk_buff_head *dfq = &l->deferdq;
1290 bool node_up = link_is_up(l->bc_rcvlink); 1240 bool node_up = link_is_up(l->bc_rcvlink);
1291 1241
1292 /* Don't send protocol message during reset or link failover */ 1242 /* Don't send protocol message during reset or link failover */
1293 if (tipc_link_is_blocked(l)) 1243 if (tipc_link_is_blocked(l))
1294 return; 1244 return;
1295 1245
1296 msg_set_type(hdr, mtyp); 1246 if (!tipc_link_is_up(l) && (mtyp == STATE_MSG))
1247 return;
1248
1249 if (!skb_queue_empty(dfq))
1250 rcvgap = buf_seqno(skb_peek(dfq)) - l->rcv_nxt;
1251
1252 skb = tipc_msg_create(LINK_PROTOCOL, mtyp, INT_H_SIZE,
1253 TIPC_MAX_IF_NAME, l->addr,
1254 tipc_own_addr(l->net), 0, 0, 0);
1255 if (!skb)
1256 return;
1257
1258 hdr = buf_msg(skb);
1259 msg_set_session(hdr, l->session);
1260 msg_set_bearer_id(hdr, l->bearer_id);
1297 msg_set_net_plane(hdr, l->net_plane); 1261 msg_set_net_plane(hdr, l->net_plane);
1298 msg_set_next_sent(hdr, l->snd_nxt); 1262 msg_set_next_sent(hdr, l->snd_nxt);
1299 msg_set_ack(hdr, l->rcv_nxt - 1); 1263 msg_set_ack(hdr, l->rcv_nxt - 1);
@@ -1303,36 +1267,23 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
1303 msg_set_linkprio(hdr, priority); 1267 msg_set_linkprio(hdr, priority);
1304 msg_set_redundant_link(hdr, node_up); 1268 msg_set_redundant_link(hdr, node_up);
1305 msg_set_seq_gap(hdr, 0); 1269 msg_set_seq_gap(hdr, 0);
1306
1307 /* Compatibility: created msg must not be in sequence with pkt flow */
1308 msg_set_seqno(hdr, l->snd_nxt + U16_MAX / 2); 1270 msg_set_seqno(hdr, l->snd_nxt + U16_MAX / 2);
1309 1271
1310 if (mtyp == STATE_MSG) { 1272 if (mtyp == STATE_MSG) {
1311 if (!tipc_link_is_up(l)) 1273 msg_set_seq_gap(hdr, rcvgap);
1312 return; 1274 msg_set_size(hdr, INT_H_SIZE);
1313
1314 /* Override rcvgap if there are packets in deferred queue */
1315 if (!skb_queue_empty(&l->deferdq))
1316 rcvgap = buf_seqno(skb_peek(&l->deferdq)) - l->rcv_nxt;
1317 if (rcvgap) {
1318 msg_set_seq_gap(hdr, rcvgap);
1319 l->stats.sent_nacks++;
1320 }
1321 msg_set_probe(hdr, probe); 1275 msg_set_probe(hdr, probe);
1322 if (probe)
1323 l->stats.sent_probes++;
1324 l->stats.sent_states++; 1276 l->stats.sent_states++;
1325 l->rcv_unacked = 0; 1277 l->rcv_unacked = 0;
1326 } else { 1278 } else {
1327 /* RESET_MSG or ACTIVATE_MSG */ 1279 /* RESET_MSG or ACTIVATE_MSG */
1328 msg_set_max_pkt(hdr, l->advertised_mtu); 1280 msg_set_max_pkt(hdr, l->advertised_mtu);
1329 msg_set_ack(hdr, l->rcv_nxt - 1); 1281 strcpy(msg_data(hdr), l->if_name);
1330 msg_set_next_sent(hdr, 1);
1331 } 1282 }
1332 skb = tipc_buf_acquire(msg_size(hdr)); 1283 if (probe)
1333 if (!skb) 1284 l->stats.sent_probes++;
1334 return; 1285 if (rcvgap)
1335 skb_copy_to_linear_data(skb, hdr, msg_size(hdr)); 1286 l->stats.sent_nacks++;
1336 skb->priority = TC_PRIO_CONTROL; 1287 skb->priority = TC_PRIO_CONTROL;
1337 __skb_queue_tail(xmitq, skb); 1288 __skb_queue_tail(xmitq, skb);
1338} 1289}
@@ -1357,7 +1308,7 @@ void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl,
1357 1308
1358 /* At least one packet required for safe algorithm => add dummy */ 1309 /* At least one packet required for safe algorithm => add dummy */
1359 skb = tipc_msg_create(TIPC_LOW_IMPORTANCE, TIPC_DIRECT_MSG, 1310 skb = tipc_msg_create(TIPC_LOW_IMPORTANCE, TIPC_DIRECT_MSG,
1360 BASIC_H_SIZE, 0, l->addr, link_own_addr(l), 1311 BASIC_H_SIZE, 0, l->addr, tipc_own_addr(l->net),
1361 0, 0, TIPC_ERR_NO_PORT); 1312 0, 0, TIPC_ERR_NO_PORT);
1362 if (!skb) { 1313 if (!skb) {
1363 pr_warn("%sunable to create tunnel packet\n", link_co_err); 1314 pr_warn("%sunable to create tunnel packet\n", link_co_err);
@@ -1368,7 +1319,7 @@ void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl,
1368 __skb_queue_purge(&tmpxq); 1319 __skb_queue_purge(&tmpxq);
1369 1320
1370 /* Initialize reusable tunnel packet header */ 1321 /* Initialize reusable tunnel packet header */
1371 tipc_msg_init(link_own_addr(l), &tnlhdr, TUNNEL_PROTOCOL, 1322 tipc_msg_init(tipc_own_addr(l->net), &tnlhdr, TUNNEL_PROTOCOL,
1372 mtyp, INT_H_SIZE, l->addr); 1323 mtyp, INT_H_SIZE, l->addr);
1373 pktcnt = skb_queue_len(&l->transmq) + skb_queue_len(&l->backlogq); 1324 pktcnt = skb_queue_len(&l->transmq) + skb_queue_len(&l->backlogq);
1374 msg_set_msgcnt(&tnlhdr, pktcnt); 1325 msg_set_msgcnt(&tnlhdr, pktcnt);
@@ -1427,7 +1378,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1427 if (tipc_link_is_blocked(l) || !xmitq) 1378 if (tipc_link_is_blocked(l) || !xmitq)
1428 goto exit; 1379 goto exit;
1429 1380
1430 if (link_own_addr(l) > msg_prevnode(hdr)) 1381 if (tipc_own_addr(l->net) > msg_prevnode(hdr))
1431 l->net_plane = msg_net_plane(hdr); 1382 l->net_plane = msg_net_plane(hdr);
1432 1383
1433 switch (mtyp) { 1384 switch (mtyp) {
@@ -1435,7 +1386,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1435 1386
1436 /* Ignore duplicate RESET with old session number */ 1387 /* Ignore duplicate RESET with old session number */
1437 if ((less_eq(msg_session(hdr), l->peer_session)) && 1388 if ((less_eq(msg_session(hdr), l->peer_session)) &&
1438 (l->peer_session != WILDCARD_SESSION)) 1389 (l->peer_session != ANY_SESSION))
1439 break; 1390 break;
1440 /* fall thru' */ 1391 /* fall thru' */
1441 1392
@@ -1479,6 +1430,12 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1479 if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL)) 1430 if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL))
1480 l->tolerance = peers_tol; 1431 l->tolerance = peers_tol;
1481 1432
1433 if (peers_prio && in_range(peers_prio, TIPC_MIN_LINK_PRI,
1434 TIPC_MAX_LINK_PRI)) {
1435 l->priority = peers_prio;
1436 rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
1437 }
1438
1482 l->silent_intv_cnt = 0; 1439 l->silent_intv_cnt = 0;
1483 l->stats.recv_states++; 1440 l->stats.recv_states++;
1484 if (msg_probe(hdr)) 1441 if (msg_probe(hdr))
@@ -1526,7 +1483,7 @@ static bool tipc_link_build_bc_proto_msg(struct tipc_link *l, bool bcast,
1526 u16 gap_to = peers_snd_nxt - 1; 1483 u16 gap_to = peers_snd_nxt - 1;
1527 1484
1528 skb = tipc_msg_create(BCAST_PROTOCOL, STATE_MSG, INT_H_SIZE, 1485 skb = tipc_msg_create(BCAST_PROTOCOL, STATE_MSG, INT_H_SIZE,
1529 0, l->addr, link_own_addr(l), 0, 0, 0); 1486 0, l->addr, tipc_own_addr(l->net), 0, 0, 0);
1530 if (!skb) 1487 if (!skb)
1531 return false; 1488 return false;
1532 hdr = buf_msg(skb); 1489 hdr = buf_msg(skb);
@@ -1681,7 +1638,7 @@ int tipc_link_bc_nack_rcv(struct tipc_link *l, struct sk_buff *skb,
1681 if (mtyp != STATE_MSG) 1638 if (mtyp != STATE_MSG)
1682 return 0; 1639 return 0;
1683 1640
1684 if (dnode == link_own_addr(l)) { 1641 if (dnode == tipc_own_addr(l->net)) {
1685 tipc_link_bc_ack_rcv(l, acked, xmitq); 1642 tipc_link_bc_ack_rcv(l, acked, xmitq);
1686 rc = tipc_link_retrans(l->bc_sndlink, from, to, xmitq); 1643 rc = tipc_link_retrans(l->bc_sndlink, from, to, xmitq);
1687 l->stats.recv_nacks++; 1644 l->stats.recv_nacks++;
@@ -2023,16 +1980,18 @@ msg_full:
2023 return -EMSGSIZE; 1980 return -EMSGSIZE;
2024} 1981}
2025 1982
2026void tipc_link_set_tolerance(struct tipc_link *l, u32 tol) 1983void tipc_link_set_tolerance(struct tipc_link *l, u32 tol,
1984 struct sk_buff_head *xmitq)
2027{ 1985{
2028 l->tolerance = tol; 1986 l->tolerance = tol;
2029 tipc_link_proto_xmit(l, STATE_MSG, 0, 0, tol, 0); 1987 tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, tol, 0, xmitq);
2030} 1988}
2031 1989
2032void tipc_link_set_prio(struct tipc_link *l, u32 prio) 1990void tipc_link_set_prio(struct tipc_link *l, u32 prio,
1991 struct sk_buff_head *xmitq)
2033{ 1992{
2034 l->priority = prio; 1993 l->priority = prio;
2035 tipc_link_proto_xmit(l, STATE_MSG, 0, 0, 0, prio); 1994 tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, 0, prio, xmitq);
2036} 1995}
2037 1996
2038void tipc_link_set_abort_limit(struct tipc_link *l, u32 limit) 1997void tipc_link_set_abort_limit(struct tipc_link *l, u32 limit)
diff --git a/net/tipc/link.h b/net/tipc/link.h
index b2ae0f4276af..6a94175ee20a 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -86,7 +86,6 @@ bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer,
86 struct sk_buff_head *namedq, 86 struct sk_buff_head *namedq,
87 struct tipc_link *bc_sndlink, 87 struct tipc_link *bc_sndlink,
88 struct tipc_link **link); 88 struct tipc_link **link);
89void tipc_link_reinit(struct tipc_link *l, u32 addr);
90void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl, 89void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl,
91 int mtyp, struct sk_buff_head *xmitq); 90 int mtyp, struct sk_buff_head *xmitq);
92void tipc_link_build_reset_msg(struct tipc_link *l, struct sk_buff_head *xmitq); 91void tipc_link_build_reset_msg(struct tipc_link *l, struct sk_buff_head *xmitq);
@@ -112,8 +111,10 @@ char tipc_link_plane(struct tipc_link *l);
112int tipc_link_prio(struct tipc_link *l); 111int tipc_link_prio(struct tipc_link *l);
113int tipc_link_window(struct tipc_link *l); 112int tipc_link_window(struct tipc_link *l);
114unsigned long tipc_link_tolerance(struct tipc_link *l); 113unsigned long tipc_link_tolerance(struct tipc_link *l);
115void tipc_link_set_tolerance(struct tipc_link *l, u32 tol); 114void tipc_link_set_tolerance(struct tipc_link *l, u32 tol,
116void tipc_link_set_prio(struct tipc_link *l, u32 prio); 115 struct sk_buff_head *xmitq);
116void tipc_link_set_prio(struct tipc_link *l, u32 prio,
117 struct sk_buff_head *xmitq);
117void tipc_link_set_abort_limit(struct tipc_link *l, u32 limit); 118void tipc_link_set_abort_limit(struct tipc_link *l, u32 limit);
118void tipc_link_set_queue_limits(struct tipc_link *l, u32 window); 119void tipc_link_set_queue_limits(struct tipc_link *l, u32 window);
119int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg, 120int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg,
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 91fce70291a8..e190460fe0d3 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -47,12 +47,6 @@
47 47
48#define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */ 48#define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */
49 49
50static const struct nla_policy
51tipc_nl_name_table_policy[TIPC_NLA_NAME_TABLE_MAX + 1] = {
52 [TIPC_NLA_NAME_TABLE_UNSPEC] = { .type = NLA_UNSPEC },
53 [TIPC_NLA_NAME_TABLE_PUBL] = { .type = NLA_NESTED }
54};
55
56/** 50/**
57 * struct name_info - name sequence publication info 51 * struct name_info - name sequence publication info
58 * @node_list: circular list of publications made by own node 52 * @node_list: circular list of publications made by own node
@@ -418,6 +412,9 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq,
418 struct tipc_subscription *s) 412 struct tipc_subscription *s)
419{ 413{
420 struct sub_seq *sseq = nseq->sseqs; 414 struct sub_seq *sseq = nseq->sseqs;
415 struct tipc_name_seq ns;
416
417 tipc_subscrp_convert_seq(&s->evt.s.seq, s->swap, &ns);
421 418
422 list_add(&s->nameseq_list, &nseq->subscriptions); 419 list_add(&s->nameseq_list, &nseq->subscriptions);
423 420
@@ -425,7 +422,7 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq,
425 return; 422 return;
426 423
427 while (sseq != &nseq->sseqs[nseq->first_free]) { 424 while (sseq != &nseq->sseqs[nseq->first_free]) {
428 if (tipc_subscrp_check_overlap(s, sseq->lower, sseq->upper)) { 425 if (tipc_subscrp_check_overlap(&ns, sseq->lower, sseq->upper)) {
429 struct publication *crs; 426 struct publication *crs;
430 struct name_info *info = sseq->info; 427 struct name_info *info = sseq->info;
431 int must_report = 1; 428 int must_report = 1;
@@ -722,9 +719,10 @@ int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 ref,
722void tipc_nametbl_subscribe(struct tipc_subscription *s) 719void tipc_nametbl_subscribe(struct tipc_subscription *s)
723{ 720{
724 struct tipc_net *tn = net_generic(s->net, tipc_net_id); 721 struct tipc_net *tn = net_generic(s->net, tipc_net_id);
725 u32 type = s->seq.type; 722 u32 type = tipc_subscrp_convert_seq_type(s->evt.s.seq.type, s->swap);
726 int index = hash(type); 723 int index = hash(type);
727 struct name_seq *seq; 724 struct name_seq *seq;
725 struct tipc_name_seq ns;
728 726
729 spin_lock_bh(&tn->nametbl_lock); 727 spin_lock_bh(&tn->nametbl_lock);
730 seq = nametbl_find_seq(s->net, type); 728 seq = nametbl_find_seq(s->net, type);
@@ -735,8 +733,9 @@ void tipc_nametbl_subscribe(struct tipc_subscription *s)
735 tipc_nameseq_subscribe(seq, s); 733 tipc_nameseq_subscribe(seq, s);
736 spin_unlock_bh(&seq->lock); 734 spin_unlock_bh(&seq->lock);
737 } else { 735 } else {
736 tipc_subscrp_convert_seq(&s->evt.s.seq, s->swap, &ns);
738 pr_warn("Failed to create subscription for {%u,%u,%u}\n", 737 pr_warn("Failed to create subscription for {%u,%u,%u}\n",
739 s->seq.type, s->seq.lower, s->seq.upper); 738 ns.type, ns.lower, ns.upper);
740 } 739 }
741 spin_unlock_bh(&tn->nametbl_lock); 740 spin_unlock_bh(&tn->nametbl_lock);
742} 741}
@@ -748,9 +747,10 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription *s)
748{ 747{
749 struct tipc_net *tn = net_generic(s->net, tipc_net_id); 748 struct tipc_net *tn = net_generic(s->net, tipc_net_id);
750 struct name_seq *seq; 749 struct name_seq *seq;
750 u32 type = tipc_subscrp_convert_seq_type(s->evt.s.seq.type, s->swap);
751 751
752 spin_lock_bh(&tn->nametbl_lock); 752 spin_lock_bh(&tn->nametbl_lock);
753 seq = nametbl_find_seq(s->net, s->seq.type); 753 seq = nametbl_find_seq(s->net, type);
754 if (seq != NULL) { 754 if (seq != NULL) {
755 spin_lock_bh(&seq->lock); 755 spin_lock_bh(&seq->lock);
756 list_del_init(&s->nameseq_list); 756 list_del_init(&s->nameseq_list);
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 77bf9113c7a7..28bf4feeb81c 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -41,11 +41,7 @@
41#include "socket.h" 41#include "socket.h"
42#include "node.h" 42#include "node.h"
43#include "bcast.h" 43#include "bcast.h"
44 44#include "netlink.h"
45static const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
46 [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC },
47 [TIPC_NLA_NET_ID] = { .type = NLA_U32 }
48};
49 45
50/* 46/*
51 * The TIPC locking policy is designed to ensure a very fine locking 47 * The TIPC locking policy is designed to ensure a very fine locking
@@ -116,7 +112,6 @@ int tipc_net_start(struct net *net, u32 addr)
116 tn->own_addr = addr; 112 tn->own_addr = addr;
117 tipc_named_reinit(net); 113 tipc_named_reinit(net);
118 tipc_sk_reinit(net); 114 tipc_sk_reinit(net);
119 tipc_bcast_reinit(net);
120 115
121 tipc_nametbl_publish(net, TIPC_CFG_SRV, tn->own_addr, tn->own_addr, 116 tipc_nametbl_publish(net, TIPC_CFG_SRV, tn->own_addr, tn->own_addr,
122 TIPC_ZONE_SCOPE, 0, tn->own_addr); 117 TIPC_ZONE_SCOPE, 0, tn->own_addr);
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 8975b0135b76..56935df2167a 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -55,6 +55,75 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = {
55 [TIPC_NLA_NAME_TABLE] = { .type = NLA_NESTED, } 55 [TIPC_NLA_NAME_TABLE] = { .type = NLA_NESTED, }
56}; 56};
57 57
58const struct nla_policy
59tipc_nl_name_table_policy[TIPC_NLA_NAME_TABLE_MAX + 1] = {
60 [TIPC_NLA_NAME_TABLE_UNSPEC] = { .type = NLA_UNSPEC },
61 [TIPC_NLA_NAME_TABLE_PUBL] = { .type = NLA_NESTED }
62};
63
64const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = {
65 [TIPC_NLA_SOCK_UNSPEC] = { .type = NLA_UNSPEC },
66 [TIPC_NLA_SOCK_ADDR] = { .type = NLA_U32 },
67 [TIPC_NLA_SOCK_REF] = { .type = NLA_U32 },
68 [TIPC_NLA_SOCK_CON] = { .type = NLA_NESTED },
69 [TIPC_NLA_SOCK_HAS_PUBL] = { .type = NLA_FLAG }
70};
71
72const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
73 [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC },
74 [TIPC_NLA_NET_ID] = { .type = NLA_U32 }
75};
76
77const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = {
78 [TIPC_NLA_LINK_UNSPEC] = { .type = NLA_UNSPEC },
79 [TIPC_NLA_LINK_NAME] = { .type = NLA_STRING,
80 .len = TIPC_MAX_LINK_NAME },
81 [TIPC_NLA_LINK_MTU] = { .type = NLA_U32 },
82 [TIPC_NLA_LINK_BROADCAST] = { .type = NLA_FLAG },
83 [TIPC_NLA_LINK_UP] = { .type = NLA_FLAG },
84 [TIPC_NLA_LINK_ACTIVE] = { .type = NLA_FLAG },
85 [TIPC_NLA_LINK_PROP] = { .type = NLA_NESTED },
86 [TIPC_NLA_LINK_STATS] = { .type = NLA_NESTED },
87 [TIPC_NLA_LINK_RX] = { .type = NLA_U32 },
88 [TIPC_NLA_LINK_TX] = { .type = NLA_U32 }
89};
90
91const struct nla_policy tipc_nl_node_policy[TIPC_NLA_NODE_MAX + 1] = {
92 [TIPC_NLA_NODE_UNSPEC] = { .type = NLA_UNSPEC },
93 [TIPC_NLA_NODE_ADDR] = { .type = NLA_U32 },
94 [TIPC_NLA_NODE_UP] = { .type = NLA_FLAG }
95};
96
97/* Properties valid for media, bearer and link */
98const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
99 [TIPC_NLA_PROP_UNSPEC] = { .type = NLA_UNSPEC },
100 [TIPC_NLA_PROP_PRIO] = { .type = NLA_U32 },
101 [TIPC_NLA_PROP_TOL] = { .type = NLA_U32 },
102 [TIPC_NLA_PROP_WIN] = { .type = NLA_U32 }
103};
104
105const struct nla_policy tipc_nl_bearer_policy[TIPC_NLA_BEARER_MAX + 1] = {
106 [TIPC_NLA_BEARER_UNSPEC] = { .type = NLA_UNSPEC },
107 [TIPC_NLA_BEARER_NAME] = { .type = NLA_STRING,
108 .len = TIPC_MAX_BEARER_NAME },
109 [TIPC_NLA_BEARER_PROP] = { .type = NLA_NESTED },
110 [TIPC_NLA_BEARER_DOMAIN] = { .type = NLA_U32 }
111};
112
113const struct nla_policy tipc_nl_media_policy[TIPC_NLA_MEDIA_MAX + 1] = {
114 [TIPC_NLA_MEDIA_UNSPEC] = { .type = NLA_UNSPEC },
115 [TIPC_NLA_MEDIA_NAME] = { .type = NLA_STRING },
116 [TIPC_NLA_MEDIA_PROP] = { .type = NLA_NESTED }
117};
118
119const struct nla_policy tipc_nl_udp_policy[TIPC_NLA_UDP_MAX + 1] = {
120 [TIPC_NLA_UDP_UNSPEC] = {.type = NLA_UNSPEC},
121 [TIPC_NLA_UDP_LOCAL] = {.type = NLA_BINARY,
122 .len = sizeof(struct sockaddr_storage)},
123 [TIPC_NLA_UDP_REMOTE] = {.type = NLA_BINARY,
124 .len = sizeof(struct sockaddr_storage)},
125};
126
58/* Users of the legacy API (tipc-config) can't handle that we add operations, 127/* Users of the legacy API (tipc-config) can't handle that we add operations,
59 * so we have a separate genl handling for the new API. 128 * so we have a separate genl handling for the new API.
60 */ 129 */
diff --git a/net/tipc/netlink.h b/net/tipc/netlink.h
index 08a1db67b927..ed1dbcb4afbd 100644
--- a/net/tipc/netlink.h
+++ b/net/tipc/netlink.h
@@ -35,6 +35,7 @@
35 35
36#ifndef _TIPC_NETLINK_H 36#ifndef _TIPC_NETLINK_H
37#define _TIPC_NETLINK_H 37#define _TIPC_NETLINK_H
38#include <net/netlink.h>
38 39
39extern struct genl_family tipc_genl_family; 40extern struct genl_family tipc_genl_family;
40int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***buf); 41int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***buf);
@@ -45,6 +46,16 @@ struct tipc_nl_msg {
45 u32 seq; 46 u32 seq;
46}; 47};
47 48
49extern const struct nla_policy tipc_nl_name_table_policy[];
50extern const struct nla_policy tipc_nl_sock_policy[];
51extern const struct nla_policy tipc_nl_net_policy[];
52extern const struct nla_policy tipc_nl_link_policy[];
53extern const struct nla_policy tipc_nl_node_policy[];
54extern const struct nla_policy tipc_nl_prop_policy[];
55extern const struct nla_policy tipc_nl_bearer_policy[];
56extern const struct nla_policy tipc_nl_media_policy[];
57extern const struct nla_policy tipc_nl_udp_policy[];
58
48int tipc_netlink_start(void); 59int tipc_netlink_start(void);
49int tipc_netlink_compat_start(void); 60int tipc_netlink_compat_start(void);
50void tipc_netlink_stop(void); 61void tipc_netlink_stop(void);
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
index 2c016fdefe97..d7d050f44fc1 100644
--- a/net/tipc/netlink_compat.c
+++ b/net/tipc/netlink_compat.c
@@ -1104,8 +1104,8 @@ static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info)
1104 req_nlh = (struct nlmsghdr *)skb->data; 1104 req_nlh = (struct nlmsghdr *)skb->data;
1105 msg.req = nlmsg_data(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN; 1105 msg.req = nlmsg_data(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN;
1106 msg.cmd = req_userhdr->cmd; 1106 msg.cmd = req_userhdr->cmd;
1107 msg.dst_sk = info->dst_sk;
1108 msg.net = genl_info_net(info); 1107 msg.net = genl_info_net(info);
1108 msg.dst_sk = skb->sk;
1109 1109
1110 if ((msg.cmd & 0xC000) && (!netlink_net_capable(skb, CAP_NET_ADMIN))) { 1110 if ((msg.cmd & 0xC000) && (!netlink_net_capable(skb, CAP_NET_ADMIN))) {
1111 msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_NET_ADMIN); 1111 msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_NET_ADMIN);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 9d7a16fc5ca4..ace178fd3850 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -41,6 +41,7 @@
41#include "socket.h" 41#include "socket.h"
42#include "bcast.h" 42#include "bcast.h"
43#include "discover.h" 43#include "discover.h"
44#include "netlink.h"
44 45
45#define INVALID_NODE_SIG 0x10000 46#define INVALID_NODE_SIG 0x10000
46 47
@@ -164,28 +165,6 @@ struct tipc_sock_conn {
164 struct list_head list; 165 struct list_head list;
165}; 166};
166 167
167static const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = {
168 [TIPC_NLA_LINK_UNSPEC] = { .type = NLA_UNSPEC },
169 [TIPC_NLA_LINK_NAME] = {
170 .type = NLA_STRING,
171 .len = TIPC_MAX_LINK_NAME
172 },
173 [TIPC_NLA_LINK_MTU] = { .type = NLA_U32 },
174 [TIPC_NLA_LINK_BROADCAST] = { .type = NLA_FLAG },
175 [TIPC_NLA_LINK_UP] = { .type = NLA_FLAG },
176 [TIPC_NLA_LINK_ACTIVE] = { .type = NLA_FLAG },
177 [TIPC_NLA_LINK_PROP] = { .type = NLA_NESTED },
178 [TIPC_NLA_LINK_STATS] = { .type = NLA_NESTED },
179 [TIPC_NLA_LINK_RX] = { .type = NLA_U32 },
180 [TIPC_NLA_LINK_TX] = { .type = NLA_U32 }
181};
182
183static const struct nla_policy tipc_nl_node_policy[TIPC_NLA_NODE_MAX + 1] = {
184 [TIPC_NLA_NODE_UNSPEC] = { .type = NLA_UNSPEC },
185 [TIPC_NLA_NODE_ADDR] = { .type = NLA_U32 },
186 [TIPC_NLA_NODE_UP] = { .type = NLA_FLAG }
187};
188
189static struct tipc_link *node_active_link(struct tipc_node *n, int sel) 168static struct tipc_link *node_active_link(struct tipc_node *n, int sel)
190{ 169{
191 int bearer_id = n->active_links[sel & 1]; 170 int bearer_id = n->active_links[sel & 1];
@@ -225,9 +204,10 @@ static unsigned int tipc_hashfn(u32 addr)
225 204
226static void tipc_node_kref_release(struct kref *kref) 205static void tipc_node_kref_release(struct kref *kref)
227{ 206{
228 struct tipc_node *node = container_of(kref, struct tipc_node, kref); 207 struct tipc_node *n = container_of(kref, struct tipc_node, kref);
229 208
230 tipc_node_delete(node); 209 kfree(n->bc_entry.link);
210 kfree_rcu(n, rcu);
231} 211}
232 212
233static void tipc_node_put(struct tipc_node *node) 213static void tipc_node_put(struct tipc_node *node)
@@ -245,23 +225,23 @@ static void tipc_node_get(struct tipc_node *node)
245 */ 225 */
246static struct tipc_node *tipc_node_find(struct net *net, u32 addr) 226static struct tipc_node *tipc_node_find(struct net *net, u32 addr)
247{ 227{
248 struct tipc_net *tn = net_generic(net, tipc_net_id); 228 struct tipc_net *tn = tipc_net(net);
249 struct tipc_node *node; 229 struct tipc_node *node;
230 unsigned int thash = tipc_hashfn(addr);
250 231
251 if (unlikely(!in_own_cluster_exact(net, addr))) 232 if (unlikely(!in_own_cluster_exact(net, addr)))
252 return NULL; 233 return NULL;
253 234
254 rcu_read_lock(); 235 rcu_read_lock();
255 hlist_for_each_entry_rcu(node, &tn->node_htable[tipc_hashfn(addr)], 236 hlist_for_each_entry_rcu(node, &tn->node_htable[thash], hash) {
256 hash) { 237 if (node->addr != addr)
257 if (node->addr == addr) { 238 continue;
258 tipc_node_get(node); 239 if (!kref_get_unless_zero(&node->kref))
259 rcu_read_unlock(); 240 node = NULL;
260 return node; 241 break;
261 }
262 } 242 }
263 rcu_read_unlock(); 243 rcu_read_unlock();
264 return NULL; 244 return node;
265} 245}
266 246
267static void tipc_node_read_lock(struct tipc_node *n) 247static void tipc_node_read_lock(struct tipc_node *n)
@@ -395,21 +375,20 @@ static void tipc_node_delete(struct tipc_node *node)
395{ 375{
396 list_del_rcu(&node->list); 376 list_del_rcu(&node->list);
397 hlist_del_rcu(&node->hash); 377 hlist_del_rcu(&node->hash);
398 kfree(node->bc_entry.link); 378 tipc_node_put(node);
399 kfree_rcu(node, rcu); 379
380 del_timer_sync(&node->timer);
381 tipc_node_put(node);
400} 382}
401 383
402void tipc_node_stop(struct net *net) 384void tipc_node_stop(struct net *net)
403{ 385{
404 struct tipc_net *tn = net_generic(net, tipc_net_id); 386 struct tipc_net *tn = tipc_net(net);
405 struct tipc_node *node, *t_node; 387 struct tipc_node *node, *t_node;
406 388
407 spin_lock_bh(&tn->node_list_lock); 389 spin_lock_bh(&tn->node_list_lock);
408 list_for_each_entry_safe(node, t_node, &tn->node_list, list) { 390 list_for_each_entry_safe(node, t_node, &tn->node_list, list)
409 if (del_timer(&node->timer)) 391 tipc_node_delete(node);
410 tipc_node_put(node);
411 tipc_node_put(node);
412 }
413 spin_unlock_bh(&tn->node_list_lock); 392 spin_unlock_bh(&tn->node_list_lock);
414} 393}
415 394
@@ -530,9 +509,7 @@ static void tipc_node_timeout(unsigned long data)
530 if (rc & TIPC_LINK_DOWN_EVT) 509 if (rc & TIPC_LINK_DOWN_EVT)
531 tipc_node_link_down(n, bearer_id, false); 510 tipc_node_link_down(n, bearer_id, false);
532 } 511 }
533 if (!mod_timer(&n->timer, jiffies + n->keepalive_intv)) 512 mod_timer(&n->timer, jiffies + n->keepalive_intv);
534 tipc_node_get(n);
535 tipc_node_put(n);
536} 513}
537 514
538/** 515/**
@@ -845,7 +822,7 @@ void tipc_node_check_dest(struct net *net, u32 onode,
845 memcpy(&le->maddr, maddr, sizeof(*maddr)); 822 memcpy(&le->maddr, maddr, sizeof(*maddr));
846exit: 823exit:
847 tipc_node_write_unlock(n); 824 tipc_node_write_unlock(n);
848 if (reset && !tipc_link_is_reset(l)) 825 if (reset && l && !tipc_link_is_reset(l))
849 tipc_node_link_down(n, b->identity, false); 826 tipc_node_link_down(n, b->identity, false);
850 tipc_node_put(n); 827 tipc_node_put(n);
851} 828}
@@ -1166,7 +1143,7 @@ msg_full:
1166 * @dnode: address of destination node 1143 * @dnode: address of destination node
1167 * @selector: a number used for deterministic link selection 1144 * @selector: a number used for deterministic link selection
1168 * Consumes the buffer chain, except when returning -ELINKCONG 1145 * Consumes the buffer chain, except when returning -ELINKCONG
1169 * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE 1146 * Returns 0 if success, otherwise: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE,-ENOBUF
1170 */ 1147 */
1171int tipc_node_xmit(struct net *net, struct sk_buff_head *list, 1148int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
1172 u32 dnode, int selector) 1149 u32 dnode, int selector)
@@ -1174,33 +1151,43 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
1174 struct tipc_link_entry *le = NULL; 1151 struct tipc_link_entry *le = NULL;
1175 struct tipc_node *n; 1152 struct tipc_node *n;
1176 struct sk_buff_head xmitq; 1153 struct sk_buff_head xmitq;
1177 int bearer_id = -1; 1154 int bearer_id;
1178 int rc = -EHOSTUNREACH; 1155 int rc;
1156
1157 if (in_own_node(net, dnode)) {
1158 tipc_sk_rcv(net, list);
1159 return 0;
1160 }
1179 1161
1180 __skb_queue_head_init(&xmitq);
1181 n = tipc_node_find(net, dnode); 1162 n = tipc_node_find(net, dnode);
1182 if (likely(n)) { 1163 if (unlikely(!n)) {
1183 tipc_node_read_lock(n); 1164 skb_queue_purge(list);
1184 bearer_id = n->active_links[selector & 1]; 1165 return -EHOSTUNREACH;
1185 if (bearer_id >= 0) { 1166 }
1186 le = &n->links[bearer_id]; 1167
1187 spin_lock_bh(&le->lock); 1168 tipc_node_read_lock(n);
1188 rc = tipc_link_xmit(le->link, list, &xmitq); 1169 bearer_id = n->active_links[selector & 1];
1189 spin_unlock_bh(&le->lock); 1170 if (unlikely(bearer_id == INVALID_BEARER_ID)) {
1190 }
1191 tipc_node_read_unlock(n); 1171 tipc_node_read_unlock(n);
1192 if (likely(!rc))
1193 tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr);
1194 else if (rc == -ENOBUFS)
1195 tipc_node_link_down(n, bearer_id, false);
1196 tipc_node_put(n); 1172 tipc_node_put(n);
1197 return rc; 1173 skb_queue_purge(list);
1174 return -EHOSTUNREACH;
1198 } 1175 }
1199 1176
1200 if (likely(in_own_node(net, dnode))) { 1177 __skb_queue_head_init(&xmitq);
1201 tipc_sk_rcv(net, list); 1178 le = &n->links[bearer_id];
1202 return 0; 1179 spin_lock_bh(&le->lock);
1203 } 1180 rc = tipc_link_xmit(le->link, list, &xmitq);
1181 spin_unlock_bh(&le->lock);
1182 tipc_node_read_unlock(n);
1183
1184 if (likely(rc == 0))
1185 tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr);
1186 else if (rc == -ENOBUFS)
1187 tipc_node_link_down(n, bearer_id, false);
1188
1189 tipc_node_put(n);
1190
1204 return rc; 1191 return rc;
1205} 1192}
1206 1193
@@ -1637,9 +1624,12 @@ int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info)
1637 char *name; 1624 char *name;
1638 struct tipc_link *link; 1625 struct tipc_link *link;
1639 struct tipc_node *node; 1626 struct tipc_node *node;
1627 struct sk_buff_head xmitq;
1640 struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1]; 1628 struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
1641 struct net *net = sock_net(skb->sk); 1629 struct net *net = sock_net(skb->sk);
1642 1630
1631 __skb_queue_head_init(&xmitq);
1632
1643 if (!info->attrs[TIPC_NLA_LINK]) 1633 if (!info->attrs[TIPC_NLA_LINK])
1644 return -EINVAL; 1634 return -EINVAL;
1645 1635
@@ -1683,13 +1673,13 @@ int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info)
1683 u32 tol; 1673 u32 tol;
1684 1674
1685 tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]); 1675 tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
1686 tipc_link_set_tolerance(link, tol); 1676 tipc_link_set_tolerance(link, tol, &xmitq);
1687 } 1677 }
1688 if (props[TIPC_NLA_PROP_PRIO]) { 1678 if (props[TIPC_NLA_PROP_PRIO]) {
1689 u32 prio; 1679 u32 prio;
1690 1680
1691 prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); 1681 prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
1692 tipc_link_set_prio(link, prio); 1682 tipc_link_set_prio(link, prio, &xmitq);
1693 } 1683 }
1694 if (props[TIPC_NLA_PROP_WIN]) { 1684 if (props[TIPC_NLA_PROP_WIN]) {
1695 u32 win; 1685 u32 win;
@@ -1701,7 +1691,7 @@ int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info)
1701 1691
1702out: 1692out:
1703 tipc_node_read_unlock(node); 1693 tipc_node_read_unlock(node);
1704 1694 tipc_bearer_xmit(net, bearer_id, &xmitq, &node->links[bearer_id].maddr);
1705 return res; 1695 return res;
1706} 1696}
1707 1697
diff --git a/net/tipc/server.c b/net/tipc/server.c
index 922e04a43396..2446bfbaa309 100644
--- a/net/tipc/server.c
+++ b/net/tipc/server.c
@@ -571,13 +571,13 @@ static void tipc_work_stop(struct tipc_server *s)
571 571
572static int tipc_work_start(struct tipc_server *s) 572static int tipc_work_start(struct tipc_server *s)
573{ 573{
574 s->rcv_wq = alloc_workqueue("tipc_rcv", WQ_UNBOUND, 1); 574 s->rcv_wq = alloc_ordered_workqueue("tipc_rcv", 0);
575 if (!s->rcv_wq) { 575 if (!s->rcv_wq) {
576 pr_err("can't start tipc receive workqueue\n"); 576 pr_err("can't start tipc receive workqueue\n");
577 return -ENOMEM; 577 return -ENOMEM;
578 } 578 }
579 579
580 s->send_wq = alloc_workqueue("tipc_send", WQ_UNBOUND, 1); 580 s->send_wq = alloc_ordered_workqueue("tipc_send", 0);
581 if (!s->send_wq) { 581 if (!s->send_wq) {
582 pr_err("can't start tipc send workqueue\n"); 582 pr_err("can't start tipc send workqueue\n");
583 destroy_workqueue(s->rcv_wq); 583 destroy_workqueue(s->rcv_wq);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 4d420bb27396..3eeb50a27b89 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -42,6 +42,7 @@
42#include "name_distr.h" 42#include "name_distr.h"
43#include "socket.h" 43#include "socket.h"
44#include "bcast.h" 44#include "bcast.h"
45#include "netlink.h"
45 46
46#define SS_LISTENING -1 /* socket is listening */ 47#define SS_LISTENING -1 /* socket is listening */
47#define SS_READY -2 /* socket is connectionless */ 48#define SS_READY -2 /* socket is connectionless */
@@ -126,14 +127,6 @@ static const struct proto_ops stream_ops;
126static const struct proto_ops msg_ops; 127static const struct proto_ops msg_ops;
127static struct proto tipc_proto; 128static struct proto tipc_proto;
128 129
129static const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = {
130 [TIPC_NLA_SOCK_UNSPEC] = { .type = NLA_UNSPEC },
131 [TIPC_NLA_SOCK_ADDR] = { .type = NLA_U32 },
132 [TIPC_NLA_SOCK_REF] = { .type = NLA_U32 },
133 [TIPC_NLA_SOCK_CON] = { .type = NLA_NESTED },
134 [TIPC_NLA_SOCK_HAS_PUBL] = { .type = NLA_FLAG }
135};
136
137static const struct rhashtable_params tsk_rht_params; 130static const struct rhashtable_params tsk_rht_params;
138 131
139/* 132/*
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index f9ff73a8d815..e6cb386fbf34 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -92,25 +92,42 @@ static void tipc_subscrp_send_event(struct tipc_subscription *sub,
92 * 92 *
93 * Returns 1 if there is overlap, otherwise 0. 93 * Returns 1 if there is overlap, otherwise 0.
94 */ 94 */
95int tipc_subscrp_check_overlap(struct tipc_subscription *sub, u32 found_lower, 95int tipc_subscrp_check_overlap(struct tipc_name_seq *seq, u32 found_lower,
96 u32 found_upper) 96 u32 found_upper)
97{ 97{
98 if (found_lower < sub->seq.lower) 98 if (found_lower < seq->lower)
99 found_lower = sub->seq.lower; 99 found_lower = seq->lower;
100 if (found_upper > sub->seq.upper) 100 if (found_upper > seq->upper)
101 found_upper = sub->seq.upper; 101 found_upper = seq->upper;
102 if (found_lower > found_upper) 102 if (found_lower > found_upper)
103 return 0; 103 return 0;
104 return 1; 104 return 1;
105} 105}
106 106
107u32 tipc_subscrp_convert_seq_type(u32 type, int swap)
108{
109 return htohl(type, swap);
110}
111
112void tipc_subscrp_convert_seq(struct tipc_name_seq *in, int swap,
113 struct tipc_name_seq *out)
114{
115 out->type = htohl(in->type, swap);
116 out->lower = htohl(in->lower, swap);
117 out->upper = htohl(in->upper, swap);
118}
119
107void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower, 120void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower,
108 u32 found_upper, u32 event, u32 port_ref, 121 u32 found_upper, u32 event, u32 port_ref,
109 u32 node, int must) 122 u32 node, int must)
110{ 123{
111 if (!tipc_subscrp_check_overlap(sub, found_lower, found_upper)) 124 struct tipc_name_seq seq;
125
126 tipc_subscrp_convert_seq(&sub->evt.s.seq, sub->swap, &seq);
127 if (!tipc_subscrp_check_overlap(&seq, found_lower, found_upper))
112 return; 128 return;
113 if (!must && !(sub->filter & TIPC_SUB_PORTS)) 129 if (!must &&
130 !(htohl(sub->evt.s.filter, sub->swap) & TIPC_SUB_PORTS))
114 return; 131 return;
115 132
116 tipc_subscrp_send_event(sub, found_lower, found_upper, event, port_ref, 133 tipc_subscrp_send_event(sub, found_lower, found_upper, event, port_ref,
@@ -171,12 +188,14 @@ static struct tipc_subscriber *tipc_subscrb_create(int conid)
171static void tipc_subscrb_delete(struct tipc_subscriber *subscriber) 188static void tipc_subscrb_delete(struct tipc_subscriber *subscriber)
172{ 189{
173 struct tipc_subscription *sub, *temp; 190 struct tipc_subscription *sub, *temp;
191 u32 timeout;
174 192
175 spin_lock_bh(&subscriber->lock); 193 spin_lock_bh(&subscriber->lock);
176 /* Destroy any existing subscriptions for subscriber */ 194 /* Destroy any existing subscriptions for subscriber */
177 list_for_each_entry_safe(sub, temp, &subscriber->subscrp_list, 195 list_for_each_entry_safe(sub, temp, &subscriber->subscrp_list,
178 subscrp_list) { 196 subscrp_list) {
179 if (del_timer(&sub->timer)) { 197 timeout = htohl(sub->evt.s.timeout, sub->swap);
198 if ((timeout == TIPC_WAIT_FOREVER) || del_timer(&sub->timer)) {
180 tipc_subscrp_delete(sub); 199 tipc_subscrp_delete(sub);
181 tipc_subscrb_put(subscriber); 200 tipc_subscrb_put(subscriber);
182 } 201 }
@@ -200,13 +219,16 @@ static void tipc_subscrp_cancel(struct tipc_subscr *s,
200 struct tipc_subscriber *subscriber) 219 struct tipc_subscriber *subscriber)
201{ 220{
202 struct tipc_subscription *sub, *temp; 221 struct tipc_subscription *sub, *temp;
222 u32 timeout;
203 223
204 spin_lock_bh(&subscriber->lock); 224 spin_lock_bh(&subscriber->lock);
205 /* Find first matching subscription, exit if not found */ 225 /* Find first matching subscription, exit if not found */
206 list_for_each_entry_safe(sub, temp, &subscriber->subscrp_list, 226 list_for_each_entry_safe(sub, temp, &subscriber->subscrp_list,
207 subscrp_list) { 227 subscrp_list) {
208 if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) { 228 if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) {
209 if (del_timer(&sub->timer)) { 229 timeout = htohl(sub->evt.s.timeout, sub->swap);
230 if ((timeout == TIPC_WAIT_FOREVER) ||
231 del_timer(&sub->timer)) {
210 tipc_subscrp_delete(sub); 232 tipc_subscrp_delete(sub);
211 tipc_subscrb_put(subscriber); 233 tipc_subscrb_put(subscriber);
212 } 234 }
@@ -216,66 +238,67 @@ static void tipc_subscrp_cancel(struct tipc_subscr *s,
216 spin_unlock_bh(&subscriber->lock); 238 spin_unlock_bh(&subscriber->lock);
217} 239}
218 240
219static int tipc_subscrp_create(struct net *net, struct tipc_subscr *s, 241static struct tipc_subscription *tipc_subscrp_create(struct net *net,
220 struct tipc_subscriber *subscriber, 242 struct tipc_subscr *s,
221 struct tipc_subscription **sub_p) 243 int swap)
222{ 244{
223 struct tipc_net *tn = net_generic(net, tipc_net_id); 245 struct tipc_net *tn = net_generic(net, tipc_net_id);
224 struct tipc_subscription *sub; 246 struct tipc_subscription *sub;
225 int swap; 247 u32 filter = htohl(s->filter, swap);
226
227 /* Determine subscriber's endianness */
228 swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE));
229
230 /* Detect & process a subscription cancellation request */
231 if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) {
232 s->filter &= ~htohl(TIPC_SUB_CANCEL, swap);
233 tipc_subscrp_cancel(s, subscriber);
234 return 0;
235 }
236 248
237 /* Refuse subscription if global limit exceeded */ 249 /* Refuse subscription if global limit exceeded */
238 if (atomic_read(&tn->subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) { 250 if (atomic_read(&tn->subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) {
239 pr_warn("Subscription rejected, limit reached (%u)\n", 251 pr_warn("Subscription rejected, limit reached (%u)\n",
240 TIPC_MAX_SUBSCRIPTIONS); 252 TIPC_MAX_SUBSCRIPTIONS);
241 return -EINVAL; 253 return NULL;
242 } 254 }
243 255
244 /* Allocate subscription object */ 256 /* Allocate subscription object */
245 sub = kmalloc(sizeof(*sub), GFP_ATOMIC); 257 sub = kmalloc(sizeof(*sub), GFP_ATOMIC);
246 if (!sub) { 258 if (!sub) {
247 pr_warn("Subscription rejected, no memory\n"); 259 pr_warn("Subscription rejected, no memory\n");
248 return -ENOMEM; 260 return NULL;
249 } 261 }
250 262
251 /* Initialize subscription object */ 263 /* Initialize subscription object */
252 sub->net = net; 264 sub->net = net;
253 sub->seq.type = htohl(s->seq.type, swap); 265 if (((filter & TIPC_SUB_PORTS) && (filter & TIPC_SUB_SERVICE)) ||
254 sub->seq.lower = htohl(s->seq.lower, swap); 266 (htohl(s->seq.lower, swap) > htohl(s->seq.upper, swap))) {
255 sub->seq.upper = htohl(s->seq.upper, swap);
256 sub->timeout = msecs_to_jiffies(htohl(s->timeout, swap));
257 sub->filter = htohl(s->filter, swap);
258 if ((!(sub->filter & TIPC_SUB_PORTS) ==
259 !(sub->filter & TIPC_SUB_SERVICE)) ||
260 (sub->seq.lower > sub->seq.upper)) {
261 pr_warn("Subscription rejected, illegal request\n"); 267 pr_warn("Subscription rejected, illegal request\n");
262 kfree(sub); 268 kfree(sub);
263 return -EINVAL; 269 return NULL;
264 } 270 }
265 spin_lock_bh(&subscriber->lock); 271
266 list_add(&sub->subscrp_list, &subscriber->subscrp_list);
267 spin_unlock_bh(&subscriber->lock);
268 sub->subscriber = subscriber;
269 sub->swap = swap; 272 sub->swap = swap;
270 memcpy(&sub->evt.s, s, sizeof(*s)); 273 memcpy(&sub->evt.s, s, sizeof(*s));
271 atomic_inc(&tn->subscription_count); 274 atomic_inc(&tn->subscription_count);
275 return sub;
276}
277
278static void tipc_subscrp_subscribe(struct net *net, struct tipc_subscr *s,
279 struct tipc_subscriber *subscriber, int swap)
280{
281 struct tipc_net *tn = net_generic(net, tipc_net_id);
282 struct tipc_subscription *sub = NULL;
283 u32 timeout;
284
285 sub = tipc_subscrp_create(net, s, swap);
286 if (!sub)
287 return tipc_conn_terminate(tn->topsrv, subscriber->conid);
288
289 spin_lock_bh(&subscriber->lock);
290 list_add(&sub->subscrp_list, &subscriber->subscrp_list);
291 tipc_subscrb_get(subscriber);
292 sub->subscriber = subscriber;
293 tipc_nametbl_subscribe(sub);
294 spin_unlock_bh(&subscriber->lock);
295
296 timeout = htohl(sub->evt.s.timeout, swap);
297 if (timeout == TIPC_WAIT_FOREVER)
298 return;
299
272 setup_timer(&sub->timer, tipc_subscrp_timeout, (unsigned long)sub); 300 setup_timer(&sub->timer, tipc_subscrp_timeout, (unsigned long)sub);
273 if (sub->timeout != TIPC_WAIT_FOREVER) 301 mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout));
274 sub->timeout += jiffies;
275 if (!mod_timer(&sub->timer, sub->timeout))
276 tipc_subscrb_get(subscriber);
277 *sub_p = sub;
278 return 0;
279} 302}
280 303
281/* Handle one termination request for the subscriber */ 304/* Handle one termination request for the subscriber */
@@ -289,15 +312,22 @@ static void tipc_subscrb_rcv_cb(struct net *net, int conid,
289 struct sockaddr_tipc *addr, void *usr_data, 312 struct sockaddr_tipc *addr, void *usr_data,
290 void *buf, size_t len) 313 void *buf, size_t len)
291{ 314{
292 struct tipc_subscriber *subscrb = usr_data; 315 struct tipc_subscriber *subscriber = usr_data;
293 struct tipc_subscription *sub = NULL; 316 struct tipc_subscr *s = (struct tipc_subscr *)buf;
294 struct tipc_net *tn = net_generic(net, tipc_net_id); 317 int swap;
295 318
296 if (tipc_subscrp_create(net, (struct tipc_subscr *)buf, subscrb, &sub)) 319 /* Determine subscriber's endianness */
297 return tipc_conn_terminate(tn->topsrv, subscrb->conid); 320 swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE |
321 TIPC_SUB_CANCEL));
322
323 /* Detect & process a subscription cancellation request */
324 if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) {
325 s->filter &= ~htohl(TIPC_SUB_CANCEL, swap);
326 return tipc_subscrp_cancel(s, subscriber);
327 }
298 328
299 if (sub) 329 if (s)
300 tipc_nametbl_subscribe(sub); 330 tipc_subscrp_subscribe(net, s, subscriber, swap);
301} 331}
302 332
303/* Handle one request to establish a new subscriber */ 333/* Handle one request to establish a new subscriber */
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h
index 92ee18cc5fe6..be60103082c9 100644
--- a/net/tipc/subscr.h
+++ b/net/tipc/subscr.h
@@ -50,21 +50,15 @@ struct tipc_subscriber;
50 * @subscriber: pointer to its subscriber 50 * @subscriber: pointer to its subscriber
51 * @seq: name sequence associated with subscription 51 * @seq: name sequence associated with subscription
52 * @net: point to network namespace 52 * @net: point to network namespace
53 * @timeout: duration of subscription (in ms)
54 * @filter: event filtering to be done for subscription
55 * @timer: timer governing subscription duration (optional) 53 * @timer: timer governing subscription duration (optional)
56 * @nameseq_list: adjacent subscriptions in name sequence's subscription list 54 * @nameseq_list: adjacent subscriptions in name sequence's subscription list
57 * @subscrp_list: adjacent subscriptions in subscriber's subscription list 55 * @subscrp_list: adjacent subscriptions in subscriber's subscription list
58 * @server_ref: object reference of server port associated with subscription
59 * @swap: indicates if subscriber uses opposite endianness in its messages 56 * @swap: indicates if subscriber uses opposite endianness in its messages
60 * @evt: template for events generated by subscription 57 * @evt: template for events generated by subscription
61 */ 58 */
62struct tipc_subscription { 59struct tipc_subscription {
63 struct tipc_subscriber *subscriber; 60 struct tipc_subscriber *subscriber;
64 struct tipc_name_seq seq;
65 struct net *net; 61 struct net *net;
66 unsigned long timeout;
67 u32 filter;
68 struct timer_list timer; 62 struct timer_list timer;
69 struct list_head nameseq_list; 63 struct list_head nameseq_list;
70 struct list_head subscrp_list; 64 struct list_head subscrp_list;
@@ -72,11 +66,14 @@ struct tipc_subscription {
72 struct tipc_event evt; 66 struct tipc_event evt;
73}; 67};
74 68
75int tipc_subscrp_check_overlap(struct tipc_subscription *sub, u32 found_lower, 69int tipc_subscrp_check_overlap(struct tipc_name_seq *seq, u32 found_lower,
76 u32 found_upper); 70 u32 found_upper);
77void tipc_subscrp_report_overlap(struct tipc_subscription *sub, 71void tipc_subscrp_report_overlap(struct tipc_subscription *sub,
78 u32 found_lower, u32 found_upper, u32 event, 72 u32 found_lower, u32 found_upper, u32 event,
79 u32 port_ref, u32 node, int must); 73 u32 port_ref, u32 node, int must);
74void tipc_subscrp_convert_seq(struct tipc_name_seq *in, int swap,
75 struct tipc_name_seq *out);
76u32 tipc_subscrp_convert_seq_type(u32 type, int swap);
80int tipc_topsrv_start(struct net *net); 77int tipc_topsrv_start(struct net *net);
81void tipc_topsrv_stop(struct net *net); 78void tipc_topsrv_stop(struct net *net);
82 79
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index d63a911e7fe2..c9cf2be3674a 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -48,19 +48,12 @@
48#include <linux/tipc_netlink.h> 48#include <linux/tipc_netlink.h>
49#include "core.h" 49#include "core.h"
50#include "bearer.h" 50#include "bearer.h"
51#include "netlink.h"
51 52
52/* IANA assigned UDP port */ 53/* IANA assigned UDP port */
53#define UDP_PORT_DEFAULT 6118 54#define UDP_PORT_DEFAULT 6118
54 55
55#define UDP_MIN_HEADROOM 28 56#define UDP_MIN_HEADROOM 48
56
57static const struct nla_policy tipc_nl_udp_policy[TIPC_NLA_UDP_MAX + 1] = {
58 [TIPC_NLA_UDP_UNSPEC] = {.type = NLA_UNSPEC},
59 [TIPC_NLA_UDP_LOCAL] = {.type = NLA_BINARY,
60 .len = sizeof(struct sockaddr_storage)},
61 [TIPC_NLA_UDP_REMOTE] = {.type = NLA_BINARY,
62 .len = sizeof(struct sockaddr_storage)},
63};
64 57
65/** 58/**
66 * struct udp_media_addr - IP/UDP addressing information 59 * struct udp_media_addr - IP/UDP addressing information
@@ -181,6 +174,8 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
181 err = PTR_ERR(rt); 174 err = PTR_ERR(rt);
182 goto tx_error; 175 goto tx_error;
183 } 176 }
177
178 skb->dev = rt->dst.dev;
184 ttl = ip4_dst_hoplimit(&rt->dst); 179 ttl = ip4_dst_hoplimit(&rt->dst);
185 udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb, src->ipv4.s_addr, 180 udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb, src->ipv4.s_addr,
186 dst->ipv4.s_addr, 0, ttl, 0, src->udp_port, 181 dst->ipv4.s_addr, 0, ttl, 0, src->udp_port,
@@ -201,7 +196,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
201 ttl = ip6_dst_hoplimit(ndst); 196 ttl = ip6_dst_hoplimit(ndst);
202 err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb, 197 err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb,
203 ndst->dev, &src->ipv6, 198 ndst->dev, &src->ipv6,
204 &dst->ipv6, 0, ttl, src->udp_port, 199 &dst->ipv6, 0, ttl, 0, src->udp_port,
205 dst->udp_port, false); 200 dst->udp_port, false);
206#endif 201#endif
207 } 202 }
@@ -274,7 +269,7 @@ static int parse_options(struct nlattr *attrs[], struct udp_bearer *ub,
274 struct udp_media_addr *remote) 269 struct udp_media_addr *remote)
275{ 270{
276 struct nlattr *opts[TIPC_NLA_UDP_MAX + 1]; 271 struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
277 struct sockaddr_storage *sa_local, *sa_remote; 272 struct sockaddr_storage sa_local, sa_remote;
278 273
279 if (!attrs[TIPC_NLA_BEARER_UDP_OPTS]) 274 if (!attrs[TIPC_NLA_BEARER_UDP_OPTS])
280 goto err; 275 goto err;
@@ -283,41 +278,48 @@ static int parse_options(struct nlattr *attrs[], struct udp_bearer *ub,
283 tipc_nl_udp_policy)) 278 tipc_nl_udp_policy))
284 goto err; 279 goto err;
285 if (opts[TIPC_NLA_UDP_LOCAL] && opts[TIPC_NLA_UDP_REMOTE]) { 280 if (opts[TIPC_NLA_UDP_LOCAL] && opts[TIPC_NLA_UDP_REMOTE]) {
286 sa_local = nla_data(opts[TIPC_NLA_UDP_LOCAL]); 281 nla_memcpy(&sa_local, opts[TIPC_NLA_UDP_LOCAL],
287 sa_remote = nla_data(opts[TIPC_NLA_UDP_REMOTE]); 282 sizeof(sa_local));
283 nla_memcpy(&sa_remote, opts[TIPC_NLA_UDP_REMOTE],
284 sizeof(sa_remote));
288 } else { 285 } else {
289err: 286err:
290 pr_err("Invalid UDP bearer configuration"); 287 pr_err("Invalid UDP bearer configuration");
291 return -EINVAL; 288 return -EINVAL;
292 } 289 }
293 if ((sa_local->ss_family & sa_remote->ss_family) == AF_INET) { 290 if ((sa_local.ss_family & sa_remote.ss_family) == AF_INET) {
294 struct sockaddr_in *ip4; 291 struct sockaddr_in *ip4;
295 292
296 ip4 = (struct sockaddr_in *)sa_local; 293 ip4 = (struct sockaddr_in *)&sa_local;
297 local->proto = htons(ETH_P_IP); 294 local->proto = htons(ETH_P_IP);
298 local->udp_port = ip4->sin_port; 295 local->udp_port = ip4->sin_port;
299 local->ipv4.s_addr = ip4->sin_addr.s_addr; 296 local->ipv4.s_addr = ip4->sin_addr.s_addr;
300 297
301 ip4 = (struct sockaddr_in *)sa_remote; 298 ip4 = (struct sockaddr_in *)&sa_remote;
302 remote->proto = htons(ETH_P_IP); 299 remote->proto = htons(ETH_P_IP);
303 remote->udp_port = ip4->sin_port; 300 remote->udp_port = ip4->sin_port;
304 remote->ipv4.s_addr = ip4->sin_addr.s_addr; 301 remote->ipv4.s_addr = ip4->sin_addr.s_addr;
305 return 0; 302 return 0;
306 303
307#if IS_ENABLED(CONFIG_IPV6) 304#if IS_ENABLED(CONFIG_IPV6)
308 } else if ((sa_local->ss_family & sa_remote->ss_family) == AF_INET6) { 305 } else if ((sa_local.ss_family & sa_remote.ss_family) == AF_INET6) {
306 int atype;
309 struct sockaddr_in6 *ip6; 307 struct sockaddr_in6 *ip6;
310 308
311 ip6 = (struct sockaddr_in6 *)sa_local; 309 ip6 = (struct sockaddr_in6 *)&sa_local;
310 atype = ipv6_addr_type(&ip6->sin6_addr);
311 if (__ipv6_addr_needs_scope_id(atype) && !ip6->sin6_scope_id)
312 return -EINVAL;
313
312 local->proto = htons(ETH_P_IPV6); 314 local->proto = htons(ETH_P_IPV6);
313 local->udp_port = ip6->sin6_port; 315 local->udp_port = ip6->sin6_port;
314 local->ipv6 = ip6->sin6_addr; 316 memcpy(&local->ipv6, &ip6->sin6_addr, sizeof(struct in6_addr));
315 ub->ifindex = ip6->sin6_scope_id; 317 ub->ifindex = ip6->sin6_scope_id;
316 318
317 ip6 = (struct sockaddr_in6 *)sa_remote; 319 ip6 = (struct sockaddr_in6 *)&sa_remote;
318 remote->proto = htons(ETH_P_IPV6); 320 remote->proto = htons(ETH_P_IPV6);
319 remote->udp_port = ip6->sin6_port; 321 remote->udp_port = ip6->sin6_port;
320 remote->ipv6 = ip6->sin6_addr; 322 memcpy(&remote->ipv6, &ip6->sin6_addr, sizeof(struct in6_addr));
321 return 0; 323 return 0;
322#endif 324#endif
323 } 325 }