aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-01-31 17:31:10 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-01-31 17:31:10 -0500
commitb2fe5fa68642860e7de76167c3111623aa0d5de1 (patch)
treeb7f9b89b7039ecefbc35fe3c8e73a6ff972641dd /net/tipc/socket.c
parenta103950e0dd2058df5e8a8d4a915707bdcf205f0 (diff)
parenta54667f6728c2714a400f3c884727da74b6d1717 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) Significantly shrink the core networking routing structures. Result of http://vger.kernel.org/~davem/seoul2017_netdev_keynote.pdf 2) Add netdevsim driver for testing various offloads, from Jakub Kicinski. 3) Support cross-chip FDB operations in DSA, from Vivien Didelot. 4) Add a 2nd listener hash table for TCP, similar to what was done for UDP. From Martin KaFai Lau. 5) Add eBPF based queue selection to tun, from Jason Wang. 6) Lockless qdisc support, from John Fastabend. 7) SCTP stream interleave support, from Xin Long. 8) Smoother TCP receive autotuning, from Eric Dumazet. 9) Lots of erspan tunneling enhancements, from William Tu. 10) Add true function call support to BPF, from Alexei Starovoitov. 11) Add explicit support for GRO HW offloading, from Michael Chan. 12) Support extack generation in more netlink subsystems. From Alexander Aring, Quentin Monnet, and Jakub Kicinski. 13) Add 1000BaseX, flow control, and EEE support to mvneta driver. From Russell King. 14) Add flow table abstraction to netfilter, from Pablo Neira Ayuso. 15) Many improvements and simplifications to the NFP driver bpf JIT, from Jakub Kicinski. 16) Support for ipv6 non-equal cost multipath routing, from Ido Schimmel. 17) Add resource abstration to devlink, from Arkadi Sharshevsky. 18) Packet scheduler classifier shared filter block support, from Jiri Pirko. 19) Avoid locking in act_csum, from Davide Caratti. 20) devinet_ioctl() simplifications from Al viro. 21) More TCP bpf improvements from Lawrence Brakmo. 22) Add support for onlink ipv6 route flag, similar to ipv4, from David Ahern. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1925 commits) tls: Add support for encryption using async offload accelerator ip6mr: fix stale iterator net/sched: kconfig: Remove blank help texts openvswitch: meter: Use 64-bit arithmetic instead of 32-bit tcp_nv: fix potential integer overflow in tcpnv_acked r8169: fix RTL8168EP take too long to complete driver initialization. qmi_wwan: Add support for Quectel EP06 rtnetlink: enable IFLA_IF_NETNSID for RTM_NEWLINK ipmr: Fix ptrdiff_t print formatting ibmvnic: Wait for device response when changing MAC qlcnic: fix deadlock bug tcp: release sk_frag.page in tcp_disconnect ipv4: Get the address of interface correctly. net_sched: gen_estimator: fix lockdep splat net: macb: Handle HRESP error net/mlx5e: IPoIB, Fix copy-paste bug in flow steering refactoring ipv6: addrconf: break critical section in addrconf_verify_rtnl() ipv6: change route cache aging logic i40e/i40evf: Update DESC_NEEDED value to reflect larger value bnxt_en: cleanup DIM work on device shutdown ...
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c114
1 files changed, 64 insertions, 50 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 2aa46e8cd8fe..163f3a547501 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -116,6 +116,7 @@ struct tipc_sock {
116 struct tipc_mc_method mc_method; 116 struct tipc_mc_method mc_method;
117 struct rcu_head rcu; 117 struct rcu_head rcu;
118 struct tipc_group *group; 118 struct tipc_group *group;
119 bool group_is_open;
119}; 120};
120 121
121static int tipc_sk_backlog_rcv(struct sock *sk, struct sk_buff *skb); 122static int tipc_sk_backlog_rcv(struct sock *sk, struct sk_buff *skb);
@@ -715,7 +716,6 @@ static __poll_t tipc_poll(struct file *file, struct socket *sock,
715{ 716{
716 struct sock *sk = sock->sk; 717 struct sock *sk = sock->sk;
717 struct tipc_sock *tsk = tipc_sk(sk); 718 struct tipc_sock *tsk = tipc_sk(sk);
718 struct tipc_group *grp = tsk->group;
719 __poll_t revents = 0; 719 __poll_t revents = 0;
720 720
721 sock_poll_wait(file, sk_sleep(sk), wait); 721 sock_poll_wait(file, sk_sleep(sk), wait);
@@ -736,9 +736,8 @@ static __poll_t tipc_poll(struct file *file, struct socket *sock,
736 revents |= POLLIN | POLLRDNORM; 736 revents |= POLLIN | POLLRDNORM;
737 break; 737 break;
738 case TIPC_OPEN: 738 case TIPC_OPEN:
739 if (!grp || tipc_group_size(grp)) 739 if (tsk->group_is_open && !tsk->cong_link_cnt)
740 if (!tsk->cong_link_cnt) 740 revents |= POLLOUT;
741 revents |= POLLOUT;
742 if (!tipc_sk_type_connectionless(sk)) 741 if (!tipc_sk_type_connectionless(sk))
743 break; 742 break;
744 if (skb_queue_empty(&sk->sk_receive_queue)) 743 if (skb_queue_empty(&sk->sk_receive_queue))
@@ -772,7 +771,6 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
772 struct net *net = sock_net(sk); 771 struct net *net = sock_net(sk);
773 int mtu = tipc_bcast_get_mtu(net); 772 int mtu = tipc_bcast_get_mtu(net);
774 struct tipc_mc_method *method = &tsk->mc_method; 773 struct tipc_mc_method *method = &tsk->mc_method;
775 u32 domain = addr_domain(net, TIPC_CLUSTER_SCOPE);
776 struct sk_buff_head pkts; 774 struct sk_buff_head pkts;
777 struct tipc_nlist dsts; 775 struct tipc_nlist dsts;
778 int rc; 776 int rc;
@@ -788,7 +786,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
788 /* Lookup destination nodes */ 786 /* Lookup destination nodes */
789 tipc_nlist_init(&dsts, tipc_own_addr(net)); 787 tipc_nlist_init(&dsts, tipc_own_addr(net));
790 tipc_nametbl_lookup_dst_nodes(net, seq->type, seq->lower, 788 tipc_nametbl_lookup_dst_nodes(net, seq->type, seq->lower,
791 seq->upper, domain, &dsts); 789 seq->upper, &dsts);
792 if (!dsts.local && !dsts.remote) 790 if (!dsts.local && !dsts.remote)
793 return -EHOSTUNREACH; 791 return -EHOSTUNREACH;
794 792
@@ -928,21 +926,22 @@ static int tipc_send_group_anycast(struct socket *sock, struct msghdr *m,
928 struct list_head *cong_links = &tsk->cong_links; 926 struct list_head *cong_links = &tsk->cong_links;
929 int blks = tsk_blocks(GROUP_H_SIZE + dlen); 927 int blks = tsk_blocks(GROUP_H_SIZE + dlen);
930 struct tipc_group *grp = tsk->group; 928 struct tipc_group *grp = tsk->group;
929 struct tipc_msg *hdr = &tsk->phdr;
931 struct tipc_member *first = NULL; 930 struct tipc_member *first = NULL;
932 struct tipc_member *mbr = NULL; 931 struct tipc_member *mbr = NULL;
933 struct net *net = sock_net(sk); 932 struct net *net = sock_net(sk);
934 u32 node, port, exclude; 933 u32 node, port, exclude;
935 u32 type, inst, domain;
936 struct list_head dsts; 934 struct list_head dsts;
935 u32 type, inst, scope;
937 int lookups = 0; 936 int lookups = 0;
938 int dstcnt, rc; 937 int dstcnt, rc;
939 bool cong; 938 bool cong;
940 939
941 INIT_LIST_HEAD(&dsts); 940 INIT_LIST_HEAD(&dsts);
942 941
943 type = dest->addr.name.name.type; 942 type = msg_nametype(hdr);
944 inst = dest->addr.name.name.instance; 943 inst = dest->addr.name.name.instance;
945 domain = addr_domain(net, dest->scope); 944 scope = msg_lookup_scope(hdr);
946 exclude = tipc_group_exclude(grp); 945 exclude = tipc_group_exclude(grp);
947 946
948 while (++lookups < 4) { 947 while (++lookups < 4) {
@@ -950,7 +949,7 @@ static int tipc_send_group_anycast(struct socket *sock, struct msghdr *m,
950 949
951 /* Look for a non-congested destination member, if any */ 950 /* Look for a non-congested destination member, if any */
952 while (1) { 951 while (1) {
953 if (!tipc_nametbl_lookup(net, type, inst, domain, &dsts, 952 if (!tipc_nametbl_lookup(net, type, inst, scope, &dsts,
954 &dstcnt, exclude, false)) 953 &dstcnt, exclude, false))
955 return -EHOSTUNREACH; 954 return -EHOSTUNREACH;
956 tipc_dest_pop(&dsts, &node, &port); 955 tipc_dest_pop(&dsts, &node, &port);
@@ -1079,22 +1078,23 @@ static int tipc_send_group_mcast(struct socket *sock, struct msghdr *m,
1079{ 1078{
1080 struct sock *sk = sock->sk; 1079 struct sock *sk = sock->sk;
1081 DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); 1080 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); 1081 struct tipc_sock *tsk = tipc_sk(sk);
1084 struct tipc_group *grp = tsk->group; 1082 struct tipc_group *grp = tsk->group;
1083 struct tipc_msg *hdr = &tsk->phdr;
1085 struct net *net = sock_net(sk); 1084 struct net *net = sock_net(sk);
1086 u32 domain, exclude, dstcnt; 1085 u32 type, inst, scope, exclude;
1087 struct list_head dsts; 1086 struct list_head dsts;
1087 u32 dstcnt;
1088 1088
1089 INIT_LIST_HEAD(&dsts); 1089 INIT_LIST_HEAD(&dsts);
1090 1090
1091 if (seq->lower != seq->upper) 1091 type = msg_nametype(hdr);
1092 return -ENOTSUPP; 1092 inst = dest->addr.name.name.instance;
1093 1093 scope = msg_lookup_scope(hdr);
1094 domain = addr_domain(net, dest->scope);
1095 exclude = tipc_group_exclude(grp); 1094 exclude = tipc_group_exclude(grp);
1096 if (!tipc_nametbl_lookup(net, seq->type, seq->lower, domain, 1095
1097 &dsts, &dstcnt, exclude, true)) 1096 if (!tipc_nametbl_lookup(net, type, inst, scope, &dsts,
1097 &dstcnt, exclude, true))
1098 return -EHOSTUNREACH; 1098 return -EHOSTUNREACH;
1099 1099
1100 if (dstcnt == 1) { 1100 if (dstcnt == 1) {
@@ -1116,24 +1116,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, 1116void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq,
1117 struct sk_buff_head *inputq) 1117 struct sk_buff_head *inputq)
1118{ 1118{
1119 u32 scope = TIPC_CLUSTER_SCOPE;
1120 u32 self = tipc_own_addr(net); 1119 u32 self = tipc_own_addr(net);
1120 u32 type, lower, upper, scope;
1121 struct sk_buff *skb, *_skb; 1121 struct sk_buff *skb, *_skb;
1122 u32 lower = 0, upper = ~0;
1123 struct sk_buff_head tmpq;
1124 u32 portid, oport, onode; 1122 u32 portid, oport, onode;
1123 struct sk_buff_head tmpq;
1125 struct list_head dports; 1124 struct list_head dports;
1126 struct tipc_msg *msg; 1125 struct tipc_msg *hdr;
1127 int user, mtyp, hsz; 1126 int user, mtyp, hlen;
1127 bool exact;
1128 1128
1129 __skb_queue_head_init(&tmpq); 1129 __skb_queue_head_init(&tmpq);
1130 INIT_LIST_HEAD(&dports); 1130 INIT_LIST_HEAD(&dports);
1131 1131
1132 skb = tipc_skb_peek(arrvq, &inputq->lock); 1132 skb = tipc_skb_peek(arrvq, &inputq->lock);
1133 for (; skb; skb = tipc_skb_peek(arrvq, &inputq->lock)) { 1133 for (; skb; skb = tipc_skb_peek(arrvq, &inputq->lock)) {
1134 msg = buf_msg(skb); 1134 hdr = buf_msg(skb);
1135 user = msg_user(msg); 1135 user = msg_user(hdr);
1136 mtyp = msg_type(msg); 1136 mtyp = msg_type(hdr);
1137 hlen = skb_headroom(skb) + msg_hdr_sz(hdr);
1138 oport = msg_origport(hdr);
1139 onode = msg_orignode(hdr);
1140 type = msg_nametype(hdr);
1141
1137 if (mtyp == TIPC_GRP_UCAST_MSG || user == GROUP_PROTOCOL) { 1142 if (mtyp == TIPC_GRP_UCAST_MSG || user == GROUP_PROTOCOL) {
1138 spin_lock_bh(&inputq->lock); 1143 spin_lock_bh(&inputq->lock);
1139 if (skb_peek(arrvq) == skb) { 1144 if (skb_peek(arrvq) == skb) {
@@ -1144,21 +1149,31 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq,
1144 spin_unlock_bh(&inputq->lock); 1149 spin_unlock_bh(&inputq->lock);
1145 continue; 1150 continue;
1146 } 1151 }
1147 hsz = skb_headroom(skb) + msg_hdr_sz(msg); 1152
1148 oport = msg_origport(msg); 1153 /* Group messages require exact scope match */
1149 onode = msg_orignode(msg); 1154 if (msg_in_group(hdr)) {
1150 if (onode == self) 1155 lower = 0;
1151 scope = TIPC_NODE_SCOPE; 1156 upper = ~0;
1152 1157 scope = msg_lookup_scope(hdr);
1153 /* Create destination port list and message clones: */ 1158 exact = true;
1154 if (!msg_in_group(msg)) { 1159 } else {
1155 lower = msg_namelower(msg); 1160 /* TIPC_NODE_SCOPE means "any scope" in this context */
1156 upper = msg_nameupper(msg); 1161 if (onode == self)
1162 scope = TIPC_NODE_SCOPE;
1163 else
1164 scope = TIPC_CLUSTER_SCOPE;
1165 exact = false;
1166 lower = msg_namelower(hdr);
1167 upper = msg_nameupper(hdr);
1157 } 1168 }
1158 tipc_nametbl_mc_translate(net, msg_nametype(msg), lower, upper, 1169
1159 scope, &dports); 1170 /* Create destination port list: */
1171 tipc_nametbl_mc_lookup(net, type, lower, upper,
1172 scope, exact, &dports);
1173
1174 /* Clone message per destination */
1160 while (tipc_dest_pop(&dports, NULL, &portid)) { 1175 while (tipc_dest_pop(&dports, NULL, &portid)) {
1161 _skb = __pskb_copy(skb, hsz, GFP_ATOMIC); 1176 _skb = __pskb_copy(skb, hlen, GFP_ATOMIC);
1162 if (_skb) { 1177 if (_skb) {
1163 msg_set_destport(buf_msg(_skb), portid); 1178 msg_set_destport(buf_msg(_skb), portid);
1164 __skb_queue_tail(&tmpq, _skb); 1179 __skb_queue_tail(&tmpq, _skb);
@@ -1933,8 +1948,7 @@ static void tipc_sk_proto_rcv(struct sock *sk,
1933 break; 1948 break;
1934 case TOP_SRV: 1949 case TOP_SRV:
1935 tipc_group_member_evt(tsk->group, &wakeup, &sk->sk_rcvbuf, 1950 tipc_group_member_evt(tsk->group, &wakeup, &sk->sk_rcvbuf,
1936 skb, inputq, xmitq); 1951 hdr, inputq, xmitq);
1937 skb = NULL;
1938 break; 1952 break;
1939 default: 1953 default:
1940 break; 1954 break;
@@ -2640,9 +2654,7 @@ void tipc_sk_reinit(struct net *net)
2640 rhashtable_walk_enter(&tn->sk_rht, &iter); 2654 rhashtable_walk_enter(&tn->sk_rht, &iter);
2641 2655
2642 do { 2656 do {
2643 tsk = ERR_PTR(rhashtable_walk_start(&iter)); 2657 rhashtable_walk_start(&iter);
2644 if (IS_ERR(tsk))
2645 goto walk_stop;
2646 2658
2647 while ((tsk = rhashtable_walk_next(&iter)) && !IS_ERR(tsk)) { 2659 while ((tsk = rhashtable_walk_next(&iter)) && !IS_ERR(tsk)) {
2648 spin_lock_bh(&tsk->sk.sk_lock.slock); 2660 spin_lock_bh(&tsk->sk.sk_lock.slock);
@@ -2651,7 +2663,7 @@ void tipc_sk_reinit(struct net *net)
2651 msg_set_orignode(msg, tn->own_addr); 2663 msg_set_orignode(msg, tn->own_addr);
2652 spin_unlock_bh(&tsk->sk.sk_lock.slock); 2664 spin_unlock_bh(&tsk->sk.sk_lock.slock);
2653 } 2665 }
2654walk_stop: 2666
2655 rhashtable_walk_stop(&iter); 2667 rhashtable_walk_stop(&iter);
2656 } while (tsk == ERR_PTR(-EAGAIN)); 2668 } while (tsk == ERR_PTR(-EAGAIN));
2657} 2669}
@@ -2734,7 +2746,6 @@ void tipc_sk_rht_destroy(struct net *net)
2734static int tipc_sk_join(struct tipc_sock *tsk, struct tipc_group_req *mreq) 2746static int tipc_sk_join(struct tipc_sock *tsk, struct tipc_group_req *mreq)
2735{ 2747{
2736 struct net *net = sock_net(&tsk->sk); 2748 struct net *net = sock_net(&tsk->sk);
2737 u32 domain = addr_domain(net, mreq->scope);
2738 struct tipc_group *grp = tsk->group; 2749 struct tipc_group *grp = tsk->group;
2739 struct tipc_msg *hdr = &tsk->phdr; 2750 struct tipc_msg *hdr = &tsk->phdr;
2740 struct tipc_name_seq seq; 2751 struct tipc_name_seq seq;
@@ -2742,9 +2753,11 @@ static int tipc_sk_join(struct tipc_sock *tsk, struct tipc_group_req *mreq)
2742 2753
2743 if (mreq->type < TIPC_RESERVED_TYPES) 2754 if (mreq->type < TIPC_RESERVED_TYPES)
2744 return -EACCES; 2755 return -EACCES;
2756 if (mreq->scope > TIPC_NODE_SCOPE)
2757 return -EINVAL;
2745 if (grp) 2758 if (grp)
2746 return -EACCES; 2759 return -EACCES;
2747 grp = tipc_group_create(net, tsk->portid, mreq); 2760 grp = tipc_group_create(net, tsk->portid, mreq, &tsk->group_is_open);
2748 if (!grp) 2761 if (!grp)
2749 return -ENOMEM; 2762 return -ENOMEM;
2750 tsk->group = grp; 2763 tsk->group = grp;
@@ -2754,16 +2767,17 @@ static int tipc_sk_join(struct tipc_sock *tsk, struct tipc_group_req *mreq)
2754 seq.type = mreq->type; 2767 seq.type = mreq->type;
2755 seq.lower = mreq->instance; 2768 seq.lower = mreq->instance;
2756 seq.upper = seq.lower; 2769 seq.upper = seq.lower;
2757 tipc_nametbl_build_group(net, grp, mreq->type, domain); 2770 tipc_nametbl_build_group(net, grp, mreq->type, mreq->scope);
2758 rc = tipc_sk_publish(tsk, mreq->scope, &seq); 2771 rc = tipc_sk_publish(tsk, mreq->scope, &seq);
2759 if (rc) { 2772 if (rc) {
2760 tipc_group_delete(net, grp); 2773 tipc_group_delete(net, grp);
2761 tsk->group = NULL; 2774 tsk->group = NULL;
2775 return rc;
2762 } 2776 }
2763 2777 /* Eliminate any risk that a broadcast overtakes sent JOINs */
2764 /* Eliminate any risk that a broadcast overtakes the sent JOIN */
2765 tsk->mc_method.rcast = true; 2778 tsk->mc_method.rcast = true;
2766 tsk->mc_method.mandatory = true; 2779 tsk->mc_method.mandatory = true;
2780 tipc_group_join(net, grp, &tsk->sk.sk_rcvbuf);
2767 return rc; 2781 return rc;
2768} 2782}
2769 2783