On Wed, Dec 9, 2020 at 2:51 AM <jma...@redhat.com> wrote:
>
> From: Jon Maloy <jma...@redhat.com>
>
> We simplify the signature if function tipc_nametbl_lookup_anycast(),
> using address structures instead of dicrete integers.
>
> This also makes it possible to make some improvements to the functions
> __tipc_sendmsg() in socket.c and tipc_msg_lookup_dest() in msg.c.
>
> Signed-off-by: Jon Maloy <jma...@redhat.com>
> ---
>  net/tipc/msg.c        | 23 ++++++------
>  net/tipc/name_table.c | 75 +++++++++++++++++++-------------------
>  net/tipc/name_table.h |  5 ++-
>  net/tipc/socket.c     | 83 +++++++++++++++++++++----------------------
>  4 files changed, 91 insertions(+), 95 deletions(-)
>
> diff --git a/net/tipc/msg.c b/net/tipc/msg.c
> index 9eddbddb2fec..931245e93830 100644
> --- a/net/tipc/msg.c
> +++ b/net/tipc/msg.c
> @@ -711,8 +711,11 @@ bool tipc_msg_skb_clone(struct sk_buff_head *msg, struct 
> sk_buff_head *cpy)
>  bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err)
>  {
>         struct tipc_msg *msg = buf_msg(skb);
> -       u32 dport, dnode;
> -       u32 onode = tipc_own_addr(net);
> +       u32 scope = msg_lookup_scope(msg);
> +       u32 self = tipc_own_addr(net);
> +       u32 inst = msg_nameinst(msg);
> +       struct tipc_socket_addr sk;
> +       struct tipc_uaddr ua;
>
>         if (!msg_isdata(msg))
>                 return false;
> @@ -726,16 +729,16 @@ bool tipc_msg_lookup_dest(struct net *net, struct 
> sk_buff *skb, int *err)
>         msg = buf_msg(skb);
>         if (msg_reroute_cnt(msg))
>                 return false;
> -       dnode = tipc_scope2node(net, msg_lookup_scope(msg));
> -       dport = tipc_nametbl_lookup_anycast(net, msg_nametype(msg),
> -                                           msg_nameinst(msg), &dnode);
> -       if (!dport)
> +       tipc_uaddr(&ua, TIPC_SERVICE_RANGE, scope,
> +                  msg_nametype(msg), inst, inst);
> +       sk.node = tipc_scope2node(net, scope);
> +       if (!tipc_nametbl_lookup_anycast(net, &ua, &sk))
>                 return false;
>         msg_incr_reroute_cnt(msg);
> -       if (dnode != onode)
> -               msg_set_prevnode(msg, onode);
> -       msg_set_destnode(msg, dnode);
> -       msg_set_destport(msg, dport);
> +       if (sk.node != self)
> +               msg_set_prevnode(msg, self);
> +       msg_set_destnode(msg, sk.node);
> +       msg_set_destport(msg, sk.ref);
>         *err = TIPC_OK;
>
>         return true;
> diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
> index e6177ccf1140..ed68db36bab9 100644
> --- a/net/tipc/name_table.c
> +++ b/net/tipc/name_table.c
> @@ -549,66 +549,64 @@ struct publication *tipc_nametbl_remove_publ(struct net 
> *net,
>  /**
>   * tipc_nametbl_lookup_anycast - perform service instance to socket 
> translation
>   * @net: network namespace
> - * @type: message type
> - * @instance: message instance
> - * @dnode: the search domain used during translation
> - *
> - * On entry, 'dnode' is the search domain used during the lookup
> + * @ua: service address to look ip
> + * @sk: address to socket we want to find
>   *
> + * On entry, a non-zero 'sk->node' indicates the node where we want lookup 
> to be
> + * performed, which may not be this one.
>   * On exit:
> - * - if lookup is deferred to another node, leave 'dnode' unchanged and 
> return 0
> - * - if lookup is attempted and succeeds, set 'dnode' to the publishing node 
> and
> - *   return the published (non-zero) port number
> - * - if lookup is attempted and fails, set 'dnode' to 0 and return 0
> + * - If lookup is deferred to another node, leave 'sk->node' unchanged and
> + *   return 'true'.
> + * - If lookup is successful, set the 'sk->node' and 'sk->ref' (== portid) 
> which
> + *   represent the bound socket and return 'true'.
> + * - If lookup fails, return 'false'
>   *
>   * Note that for legacy users (node configured with Z.C.N address format) the
> - * 'closest-first' lookup algorithm must be maintained, i.e., if dnode is 0
> + * 'closest-first' lookup algorithm must be maintained, i.e., if sk.node is 0
>   * we must look in the local binding list first
>   */
> -u32 tipc_nametbl_lookup_anycast(struct net *net, u32 type,
> -                               u32 instance, u32 *dnode)
> +bool tipc_nametbl_lookup_anycast(struct net *net,
> +                                struct tipc_uaddr *ua,
> +                                struct tipc_socket_addr *sk)
>  {
>         struct tipc_net *tn = tipc_net(net);
>         bool legacy = tn->legacy_addr_format;
>         u32 self = tipc_own_addr(net);
> -       struct service_range *sr;
> +       u32 inst = ua->sa.instance;
> +       struct service_range *r;
>         struct tipc_service *sc;
> -       struct list_head *list;
>         struct publication *p;
> -       u32 port = 0;
> -       u32 node = 0;
> +       struct list_head *l;
> +       bool res = false;
>
> -       if (!tipc_in_scope(legacy, *dnode, self))
> -               return 0;
> +       if (!tipc_in_scope(legacy, sk->node, self))
> +               return true;
>
>         rcu_read_lock();
> -       sc = tipc_service_find(net, type);
> +       sc = tipc_service_find(net, ua->sr.type);
>         if (unlikely(!sc))
>                 goto exit;
>
>         spin_lock_bh(&sc->lock);
> -       service_range_foreach_match(sr, sc, instance, instance) {
> +       service_range_foreach_match(r, sc, inst, inst) {
>                 /* Select lookup algo: local, closest-first or round-robin */
> -               if (*dnode == self) {
> -                       list = &sr->local_publ;
> -                       if (list_empty(list))
> +               if (sk->node == self) {
> +                       l = &r->local_publ;
> +                       if (list_empty(l))
>                                 continue;
> -                       p = list_first_entry(list, struct publication,
> -                                            local_publ);
> -                       list_move_tail(&p->local_publ, &sr->local_publ);
> -               } else if (legacy && !*dnode && !list_empty(&sr->local_publ)) 
> {
> -                       list = &sr->local_publ;
> -                       p = list_first_entry(list, struct publication,
> -                                            local_publ);
> -                       list_move_tail(&p->local_publ, &sr->local_publ);
> +                       p = list_first_entry(l, struct publication, 
> local_publ);
> +                       list_move_tail(&p->local_publ, &r->local_publ);
> +               } else if (legacy && !sk->node && 
> !list_empty(&r->local_publ)) {
> +                       l = &r->local_publ;
> +                       p = list_first_entry(l, struct publication, 
> local_publ);
> +                       list_move_tail(&p->local_publ, &r->local_publ);
>                 } else {
> -                       list = &sr->all_publ;
> -                       p = list_first_entry(list, struct publication,
> -                                            all_publ);
> -                       list_move_tail(&p->all_publ, &sr->all_publ);
> +                       l = &r->all_publ;
> +                       p = list_first_entry(l, struct publication, all_publ);
> +                       list_move_tail(&p->all_publ, &r->all_publ);
>                 }
> -               port = p->sk.ref;
> -               node = p->sk.node;
> +               *sk = p->sk;
> +               res = true;
>                 /* Todo: as for legacy, pick the first matching range only, a
>                  * "true" round-robin will be performed as needed.
>                  */
> @@ -618,8 +616,7 @@ u32 tipc_nametbl_lookup_anycast(struct net *net, u32 type,
>
>  exit:
>         rcu_read_unlock();
> -       *dnode = node;
> -       return port;
> +       return res;
>  }
>
>  /* tipc_nametbl_lookup_group(): lookup destinaton(s) in a communication group
> diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
> index 9f6e8efca00f..f5e37f90a2ba 100644
> --- a/net/tipc/name_table.h
> +++ b/net/tipc/name_table.h
> @@ -111,9 +111,8 @@ struct name_table {
>  };
>
>  int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback 
> *cb);
> -
> -u32 tipc_nametbl_lookup_anycast(struct net *net, u32 type, u32 instance,
> -                               u32 *node);
> +bool tipc_nametbl_lookup_anycast(struct net *net, struct tipc_uaddr *ua,
> +                                struct tipc_socket_addr *sk);
>  void tipc_nametbl_lookup_mcast_sockets(struct net *net, u32 type, u32 lower,
>                                        u32 upper, u32 scope, bool exact,
>                                    struct list_head *dports);
> diff --git a/net/tipc/socket.c b/net/tipc/socket.c
> index 05cfe179458e..913b1a7be25b 100644
> --- a/net/tipc/socket.c
> +++ b/net/tipc/socket.c
> @@ -1424,44 +1424,43 @@ static int __tipc_sendmsg(struct socket *sock, struct 
> msghdr *m, size_t dlen)
>         struct sock *sk = sock->sk;
>         struct net *net = sock_net(sk);
>         struct tipc_sock *tsk = tipc_sk(sk);
> -       DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
> +       struct tipc_uaddr *ua = (struct tipc_uaddr *)m->msg_name;
>         long timeout = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
>         struct list_head *clinks = &tsk->cong_links;
>         bool syn = !tipc_sk_type_connectionless(sk);
>         struct tipc_group *grp = tsk->group;
>         struct tipc_msg *hdr = &tsk->phdr;
> -       struct tipc_service_range *seq;
> +       struct tipc_socket_addr skaddr;
>         struct sk_buff_head pkts;
> -       u32 dport = 0, dnode = 0;
> -       u32 type = 0, inst = 0;
> -       int mtu, rc;
> +       int atype, mtu, rc;
>
>         if (unlikely(dlen > TIPC_MAX_USER_MSG_SIZE))
>                 return -EMSGSIZE;
>
> -       if (likely(dest)) {
> -               if (unlikely(m->msg_namelen < sizeof(*dest)))
> -                       return -EINVAL;
> -               if (unlikely(dest->family != AF_TIPC))
> +       if (ua) {
> +               if (!tipc_uaddr_valid(ua, m->msg_namelen))
>                         return -EINVAL;
> +                atype = ua->addrtype;
>         }
>
> +       /* If socket belongs to a communication group follow other paths */
>         if (grp) {
> -               if (!dest)
> +               if (!ua)
>                         return tipc_send_group_bcast(sock, m, dlen, timeout);
> -               if (dest->addrtype == TIPC_SERVICE_ADDR)
> +               if (atype == TIPC_SERVICE_ADDR)
>                         return tipc_send_group_anycast(sock, m, dlen, 
> timeout);
> -               if (dest->addrtype == TIPC_SOCKET_ADDR)
> +               if (atype == TIPC_SOCKET_ADDR)
>                         return tipc_send_group_unicast(sock, m, dlen, 
> timeout);
> -               if (dest->addrtype == TIPC_ADDR_MCAST)
> +               if (atype == TIPC_SERVICE_RANGE)
>                         return tipc_send_group_mcast(sock, m, dlen, timeout);
>                 return -EINVAL;
>         }
>
> -       if (unlikely(!dest)) {
> -               dest = &tsk->peer;
> -               if (!syn && dest->family != AF_TIPC)
> +       if (!ua) {
> +               ua = (struct tipc_uaddr *)&tsk->peer;
> +               if (!syn && ua->family != AF_TIPC)
>                         return -EDESTADDRREQ;
> +                atype = ua->addrtype;
>         }
>
>         if (unlikely(syn)) {
> @@ -1471,54 +1470,51 @@ static int __tipc_sendmsg(struct socket *sock, struct 
> msghdr *m, size_t dlen)
>                         return -EISCONN;
>                 if (tsk->published)
>                         return -EOPNOTSUPP;
> -               if (dest->addrtype == TIPC_SERVICE_ADDR) {
> -                       tsk->conn_type = dest->addr.name.name.type;
> -                       tsk->conn_instance = dest->addr.name.name.instance;
> +               if (atype == TIPC_SERVICE_ADDR) {
> +                       tsk->conn_type = ua->sa.type;
> +                       tsk->conn_instance = ua->sa.instance;
>                 }
>                 msg_set_syn(hdr, 1);
>         }
>
> -       seq = &dest->addr.nameseq;
> -       if (dest->addrtype == TIPC_ADDR_MCAST)
> -               return tipc_sendmcast(sock, seq, m, dlen, timeout);
> -
> -       if (dest->addrtype == TIPC_SERVICE_ADDR) {
> -               type = dest->addr.name.name.type;
> -               inst = dest->addr.name.name.instance;
> -               dnode = dest->addr.name.domain;
> -               dport = tipc_nametbl_lookup_anycast(net, type, inst, &dnode);
> -               if (unlikely(!dport && !dnode))
> +       /* Determine destination */
> +       if (atype == TIPC_SERVICE_RANGE) {
> +               return tipc_sendmcast(sock, &ua->sr, m, dlen, timeout);
> +       } else if (atype == TIPC_SERVICE_ADDR) {
> +               skaddr.node = ua->lookup_node;
> +               ua->scope = skaddr.node ? TIPC_NODE_SCOPE : 
> TIPC_CLUSTER_SCOPE;
tipc_node2scope() can be deleted if it's not used here.

> +               if (!tipc_nametbl_lookup_anycast(net, ua, &skaddr))
>                         return -EHOSTUNREACH;
> -       } else if (dest->addrtype == TIPC_SOCKET_ADDR) {
> -               dnode = dest->addr.id.node;
> +       } else if (atype == TIPC_SOCKET_ADDR) {
> +               skaddr = ua->sk;
>         } else {
>                 return -EINVAL;
>         }
>
>         /* Block or return if destination link is congested */
>         rc = tipc_wait_for_cond(sock, &timeout,
> -                               !tipc_dest_find(clinks, dnode, 0));
> +                               !tipc_dest_find(clinks, skaddr.node, 0));
>         if (unlikely(rc))
>                 return rc;
>
> -       if (dest->addrtype == TIPC_SERVICE_ADDR) {
> +       /* Finally build message header */
> +       msg_set_destnode(hdr, skaddr.node);
> +       msg_set_destport(hdr, skaddr.ref);
> +       if (atype == TIPC_SERVICE_ADDR) {
>                 msg_set_type(hdr, TIPC_NAMED_MSG);
>                 msg_set_hdr_sz(hdr, NAMED_H_SIZE);
> -               msg_set_nametype(hdr, type);
> -               msg_set_nameinst(hdr, inst);
> -               msg_set_lookup_scope(hdr, tipc_node2scope(dnode));
> -               msg_set_destnode(hdr, dnode);
> -               msg_set_destport(hdr, dport);
> +               msg_set_nametype(hdr, ua->sa.type);
> +               msg_set_nameinst(hdr, ua->sa.instance);
> +               msg_set_lookup_scope(hdr, ua->scope);
>         } else { /* TIPC_SOCKET_ADDR */
>                 msg_set_type(hdr, TIPC_DIRECT_MSG);
>                 msg_set_lookup_scope(hdr, 0);
> -               msg_set_destnode(hdr, dnode);
> -               msg_set_destport(hdr, dest->addr.id.ref);
>                 msg_set_hdr_sz(hdr, BASIC_H_SIZE);
>         }
>
> +       /* Add message body */
>         __skb_queue_head_init(&pkts);
> -       mtu = tipc_node_get_mtu(net, dnode, tsk->portid, true);
> +       mtu = tipc_node_get_mtu(net, skaddr.node, tsk->portid, true);
>         rc = tipc_msg_build(hdr, m, 0, dlen, mtu, &pkts);
>         if (unlikely(rc != dlen))
>                 return rc;
> @@ -1527,10 +1523,11 @@ static int __tipc_sendmsg(struct socket *sock, struct 
> msghdr *m, size_t dlen)
>                 return -ENOMEM;
>         }
>
> +       /* Send message */
>         trace_tipc_sk_sendmsg(sk, skb_peek(&pkts), TIPC_DUMP_SK_SNDQ, " ");
> -       rc = tipc_node_xmit(net, &pkts, dnode, tsk->portid);
> +       rc = tipc_node_xmit(net, &pkts, skaddr.node, tsk->portid);
>         if (unlikely(rc == -ELINKCONG)) {
> -               tipc_dest_push(clinks, dnode, 0);
> +               tipc_dest_push(clinks, skaddr.node, 0);
>                 tsk->cong_link_cnt++;
>                 rc = 0;
>         }
> --
> 2.28.0
>
>
>
> _______________________________________________
> tipc-discussion mailing list
> tipc-discussion@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/tipc-discussion


_______________________________________________
tipc-discussion mailing list
tipc-discussion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tipc-discussion

Reply via email to