aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c88
1 files changed, 53 insertions, 35 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index e3a02f1fcab5..b24dab3996c9 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -928,21 +928,22 @@ static int tipc_send_group_anycast(struct socket *sock, struct msghdr *m,
928 struct list_head *cong_links = &tsk->cong_links; 928 struct list_head *cong_links = &tsk->cong_links;
929 int blks = tsk_blocks(GROUP_H_SIZE + dlen); 929 int blks = tsk_blocks(GROUP_H_SIZE + dlen);
930 struct tipc_group *grp = tsk->group; 930 struct tipc_group *grp = tsk->group;
931 struct tipc_msg *hdr = &tsk->phdr;
931 struct tipc_member *first = NULL; 932 struct tipc_member *first = NULL;
932 struct tipc_member *mbr = NULL; 933 struct tipc_member *mbr = NULL;
933 struct net *net = sock_net(sk); 934 struct net *net = sock_net(sk);
934 u32 node, port, exclude; 935 u32 node, port, exclude;
935 u32 type, inst, domain;
936 struct list_head dsts; 936 struct list_head dsts;
937 u32 type, inst, scope;
937 int lookups = 0; 938 int lookups = 0;
938 int dstcnt, rc; 939 int dstcnt, rc;
939 bool cong; 940 bool cong;
940 941
941 INIT_LIST_HEAD(&dsts); 942 INIT_LIST_HEAD(&dsts);
942 943
943 type = dest->addr.name.name.type; 944 type = msg_nametype(hdr);
944 inst = dest->addr.name.name.instance; 945 inst = dest->addr.name.name.instance;
945 domain = addr_domain(net, dest->scope); 946 scope = msg_lookup_scope(hdr);
946 exclude = tipc_group_exclude(grp); 947 exclude = tipc_group_exclude(grp);
947 948
948 while (++lookups < 4) { 949 while (++lookups < 4) {
@@ -950,7 +951,7 @@ static int tipc_send_group_anycast(struct socket *sock, struct msghdr *m,
950 951
951 /* Look for a non-congested destination member, if any */ 952 /* Look for a non-congested destination member, if any */
952 while (1) { 953 while (1) {
953 if (!tipc_nametbl_lookup(net, type, inst, domain, &dsts, 954 if (!tipc_nametbl_lookup(net, type, inst, scope, &dsts,
954 &dstcnt, exclude, false)) 955 &dstcnt, exclude, false))
955 return -EHOSTUNREACH; 956 return -EHOSTUNREACH;
956 tipc_dest_pop(&dsts, &node, &port); 957 tipc_dest_pop(&dsts, &node, &port);
@@ -1079,22 +1080,23 @@ static int tipc_send_group_mcast(struct socket *sock, struct msghdr *m,
1079{ 1080{
1080 struct sock *sk = sock->sk; 1081 struct sock *sk = sock->sk;
1081 DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); 1082 DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
1082 struct tipc_name_seq *seq = &dest->addr.nameseq;
1083 struct tipc_sock *tsk = tipc_sk(sk); 1083 struct tipc_sock *tsk = tipc_sk(sk);
1084 struct tipc_group *grp = tsk->group; 1084 struct tipc_group *grp = tsk->group;
1085 struct tipc_msg *hdr = &tsk->phdr;
1085 struct net *net = sock_net(sk); 1086 struct net *net = sock_net(sk);
1086 u32 domain, exclude, dstcnt; 1087 u32 type, inst, scope, exclude;
1087 struct list_head dsts; 1088 struct list_head dsts;
1089 u32 dstcnt;
1088 1090
1089 INIT_LIST_HEAD(&dsts); 1091 INIT_LIST_HEAD(&dsts);
1090 1092
1091 if (seq->lower != seq->upper) 1093 type = msg_nametype(hdr);
1092 return -ENOTSUPP; 1094 inst = dest->addr.name.name.instance;
1093 1095 scope = msg_lookup_scope(hdr);
1094 domain = addr_domain(net, dest->scope);
1095 exclude = tipc_group_exclude(grp); 1096 exclude = tipc_group_exclude(grp);
1096 if (!tipc_nametbl_lookup(net, seq->type, seq->lower, domain, 1097
1097 &dsts, &dstcnt, exclude, true)) 1098 if (!tipc_nametbl_lookup(net, type, inst, scope, &dsts,
1099 &dstcnt, exclude, true))
1098 return -EHOSTUNREACH; 1100 return -EHOSTUNREACH;
1099 1101
1100 if (dstcnt == 1) { 1102 if (dstcnt == 1) {
@@ -1116,24 +1118,29 @@ static int tipc_send_group_mcast(struct socket *sock, struct msghdr *m,
1116void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, 1118void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq,
1117 struct sk_buff_head *inputq) 1119 struct sk_buff_head *inputq)
1118{ 1120{
1119 u32 scope = TIPC_CLUSTER_SCOPE;
1120 u32 self = tipc_own_addr(net); 1121 u32 self = tipc_own_addr(net);
1122 u32 type, lower, upper, scope;
1121 struct sk_buff *skb, *_skb; 1123 struct sk_buff *skb, *_skb;
1122 u32 lower = 0, upper = ~0;
1123 struct sk_buff_head tmpq;
1124 u32 portid, oport, onode; 1124 u32 portid, oport, onode;
1125 struct sk_buff_head tmpq;
1125 struct list_head dports; 1126 struct list_head dports;
1126 struct tipc_msg *msg; 1127 struct tipc_msg *hdr;
1127 int user, mtyp, hsz; 1128 int user, mtyp, hlen;
1129 bool exact;
1128 1130
1129 __skb_queue_head_init(&tmpq); 1131 __skb_queue_head_init(&tmpq);
1130 INIT_LIST_HEAD(&dports); 1132 INIT_LIST_HEAD(&dports);
1131 1133
1132 skb = tipc_skb_peek(arrvq, &inputq->lock); 1134 skb = tipc_skb_peek(arrvq, &inputq->lock);
1133 for (; skb; skb = tipc_skb_peek(arrvq, &inputq->lock)) { 1135 for (; skb; skb = tipc_skb_peek(arrvq, &inputq->lock)) {
1134 msg = buf_msg(skb); 1136 hdr = buf_msg(skb);
1135 user = msg_user(msg); 1137 user = msg_user(hdr);
1136 mtyp = msg_type(msg); 1138 mtyp = msg_type(hdr);
1139 hlen = skb_headroom(skb) + msg_hdr_sz(hdr);
1140 oport = msg_origport(hdr);
1141 onode = msg_orignode(hdr);
1142 type = msg_nametype(hdr);
1143
1137 if (mtyp == TIPC_GRP_UCAST_MSG || user == GROUP_PROTOCOL) { 1144 if (mtyp == TIPC_GRP_UCAST_MSG || user == GROUP_PROTOCOL) {
1138 spin_lock_bh(&inputq->lock); 1145 spin_lock_bh(&inputq->lock);
1139 if (skb_peek(arrvq) == skb) { 1146 if (skb_peek(arrvq) == skb) {
@@ -1144,21 +1151,31 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq,
1144 spin_unlock_bh(&inputq->lock); 1151 spin_unlock_bh(&inputq->lock);
1145 continue; 1152 continue;
1146 } 1153 }
1147 hsz = skb_headroom(skb) + msg_hdr_sz(msg); 1154
1148 oport = msg_origport(msg); 1155 /* Group messages require exact scope match */
1149 onode = msg_orignode(msg); 1156 if (msg_in_group(hdr)) {
1150 if (onode == self) 1157 lower = 0;
1151 scope = TIPC_NODE_SCOPE; 1158 upper = ~0;
1152 1159 scope = msg_lookup_scope(hdr);
1153 /* Create destination port list and message clones: */ 1160 exact = true;
1154 if (!msg_in_group(msg)) { 1161 } else {
1155 lower = msg_namelower(msg); 1162 /* TIPC_NODE_SCOPE means "any scope" in this context */
1156 upper = msg_nameupper(msg); 1163 if (onode == self)
1164 scope = TIPC_NODE_SCOPE;
1165 else
1166 scope = TIPC_CLUSTER_SCOPE;
1167 exact = false;
1168 lower = msg_namelower(hdr);
1169 upper = msg_nameupper(hdr);
1157 } 1170 }
1158 tipc_nametbl_mc_translate(net, msg_nametype(msg), lower, upper, 1171
1159 scope, &dports); 1172 /* Create destination port list: */
1173 tipc_nametbl_mc_lookup(net, type, lower, upper,
1174 scope, exact, &dports);
1175
1176 /* Clone message per destination */
1160 while (tipc_dest_pop(&dports, NULL, &portid)) { 1177 while (tipc_dest_pop(&dports, NULL, &portid)) {
1161 _skb = __pskb_copy(skb, hsz, GFP_ATOMIC); 1178 _skb = __pskb_copy(skb, hlen, GFP_ATOMIC);
1162 if (_skb) { 1179 if (_skb) {
1163 msg_set_destport(buf_msg(_skb), portid); 1180 msg_set_destport(buf_msg(_skb), portid);
1164 __skb_queue_tail(&tmpq, _skb); 1181 __skb_queue_tail(&tmpq, _skb);
@@ -2731,7 +2748,6 @@ void tipc_sk_rht_destroy(struct net *net)
2731static int tipc_sk_join(struct tipc_sock *tsk, struct tipc_group_req *mreq) 2748static int tipc_sk_join(struct tipc_sock *tsk, struct tipc_group_req *mreq)
2732{ 2749{
2733 struct net *net = sock_net(&tsk->sk); 2750 struct net *net = sock_net(&tsk->sk);
2734 u32 domain = addr_domain(net, mreq->scope);
2735 struct tipc_group *grp = tsk->group; 2751 struct tipc_group *grp = tsk->group;
2736 struct tipc_msg *hdr = &tsk->phdr; 2752 struct tipc_msg *hdr = &tsk->phdr;
2737 struct tipc_name_seq seq; 2753 struct tipc_name_seq seq;
@@ -2739,6 +2755,8 @@ static int tipc_sk_join(struct tipc_sock *tsk, struct tipc_group_req *mreq)
2739 2755
2740 if (mreq->type < TIPC_RESERVED_TYPES) 2756 if (mreq->type < TIPC_RESERVED_TYPES)
2741 return -EACCES; 2757 return -EACCES;
2758 if (mreq->scope > TIPC_NODE_SCOPE)
2759 return -EINVAL;
2742 if (grp) 2760 if (grp)
2743 return -EACCES; 2761 return -EACCES;
2744 grp = tipc_group_create(net, tsk->portid, mreq); 2762 grp = tipc_group_create(net, tsk->portid, mreq);
@@ -2751,7 +2769,7 @@ static int tipc_sk_join(struct tipc_sock *tsk, struct tipc_group_req *mreq)
2751 seq.type = mreq->type; 2769 seq.type = mreq->type;
2752 seq.lower = mreq->instance; 2770 seq.lower = mreq->instance;
2753 seq.upper = seq.lower; 2771 seq.upper = seq.lower;
2754 tipc_nametbl_build_group(net, grp, mreq->type, domain); 2772 tipc_nametbl_build_group(net, grp, mreq->type, mreq->scope);
2755 rc = tipc_sk_publish(tsk, mreq->scope, &seq); 2773 rc = tipc_sk_publish(tsk, mreq->scope, &seq);
2756 if (rc) { 2774 if (rc) {
2757 tipc_group_delete(net, grp); 2775 tipc_group_delete(net, grp);