]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/tipc/link.c
Merge remote-tracking branch 'net-next/master'
[karo-tx-linux.git] / net / tipc / link.c
index 0cc3d9015c5d5bb6a1629251d7a636f41239db6f..e8153f64d2d6fb3c23d7f24f42e50ee2ea019df6 100644 (file)
@@ -75,20 +75,6 @@ static const char *link_unk_evt = "Unknown link event ";
  */
 #define START_CHANGEOVER 100000u
 
-/**
- * struct tipc_link_name - deconstructed link name
- * @addr_local: network address of node at this end
- * @if_local: name of interface at this end
- * @addr_peer: network address of node at far end
- * @if_peer: name of interface at far end
- */
-struct tipc_link_name {
-       u32 addr_local;
-       char if_local[TIPC_MAX_IF_NAME];
-       u32 addr_peer;
-       char if_peer[TIPC_MAX_IF_NAME];
-};
-
 static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
                                       struct sk_buff *buf);
 static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf);
@@ -97,8 +83,7 @@ static int  link_recv_changeover_msg(struct tipc_link **l_ptr,
 static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance);
 static int  link_send_sections_long(struct tipc_port *sender,
                                    struct iovec const *msg_sect,
-                                   u32 num_sect, unsigned int total_len,
-                                   u32 destnode);
+                                   unsigned int len, u32 destnode);
 static void link_state_event(struct tipc_link *l_ptr, u32 event);
 static void link_reset_statistics(struct tipc_link *l_ptr);
 static void link_print(struct tipc_link *l_ptr, const char *str);
@@ -160,72 +145,6 @@ int tipc_link_is_active(struct tipc_link *l_ptr)
                (l_ptr->owner->active_links[1] == l_ptr);
 }
 
-/**
- * link_name_validate - validate & (optionally) deconstruct tipc_link name
- * @name: ptr to link name string
- * @name_parts: ptr to area for link name components (or NULL if not needed)
- *
- * Returns 1 if link name is valid, otherwise 0.
- */
-static int link_name_validate(const char *name,
-                               struct tipc_link_name *name_parts)
-{
-       char name_copy[TIPC_MAX_LINK_NAME];
-       char *addr_local;
-       char *if_local;
-       char *addr_peer;
-       char *if_peer;
-       char dummy;
-       u32 z_local, c_local, n_local;
-       u32 z_peer, c_peer, n_peer;
-       u32 if_local_len;
-       u32 if_peer_len;
-
-       /* copy link name & ensure length is OK */
-       name_copy[TIPC_MAX_LINK_NAME - 1] = 0;
-       /* need above in case non-Posix strncpy() doesn't pad with nulls */
-       strncpy(name_copy, name, TIPC_MAX_LINK_NAME);
-       if (name_copy[TIPC_MAX_LINK_NAME - 1] != 0)
-               return 0;
-
-       /* ensure all component parts of link name are present */
-       addr_local = name_copy;
-       if_local = strchr(addr_local, ':');
-       if (if_local == NULL)
-               return 0;
-       *(if_local++) = 0;
-       addr_peer = strchr(if_local, '-');
-       if (addr_peer == NULL)
-               return 0;
-       *(addr_peer++) = 0;
-       if_local_len = addr_peer - if_local;
-       if_peer = strchr(addr_peer, ':');
-       if (if_peer == NULL)
-               return 0;
-       *(if_peer++) = 0;
-       if_peer_len = strlen(if_peer) + 1;
-
-       /* validate component parts of link name */
-       if ((sscanf(addr_local, "%u.%u.%u%c",
-                   &z_local, &c_local, &n_local, &dummy) != 3) ||
-           (sscanf(addr_peer, "%u.%u.%u%c",
-                   &z_peer, &c_peer, &n_peer, &dummy) != 3) ||
-           (z_local > 255) || (c_local > 4095) || (n_local > 4095) ||
-           (z_peer  > 255) || (c_peer  > 4095) || (n_peer  > 4095) ||
-           (if_local_len <= 1) || (if_local_len > TIPC_MAX_IF_NAME) ||
-           (if_peer_len  <= 1) || (if_peer_len  > TIPC_MAX_IF_NAME))
-               return 0;
-
-       /* return link name components, if necessary */
-       if (name_parts) {
-               name_parts->addr_local = tipc_addr(z_local, c_local, n_local);
-               strcpy(name_parts->if_local, if_local);
-               name_parts->addr_peer = tipc_addr(z_peer, c_peer, n_peer);
-               strcpy(name_parts->if_peer, if_peer);
-       }
-       return 1;
-}
-
 /**
  * link_timeout - handle expiration of link timer
  * @l_ptr: pointer to link
@@ -1065,8 +984,7 @@ static int link_send_buf_fast(struct tipc_link *l_ptr, struct sk_buff *buf,
  */
 int tipc_link_send_sections_fast(struct tipc_port *sender,
                                 struct iovec const *msg_sect,
-                                const u32 num_sect, unsigned int total_len,
-                                u32 destaddr)
+                                unsigned int len, u32 destaddr)
 {
        struct tipc_msg *hdr = &sender->phdr;
        struct tipc_link *l_ptr;
@@ -1080,8 +998,7 @@ again:
         * Try building message using port's max_pkt hint.
         * (Must not hold any locks while building message.)
         */
-       res = tipc_msg_build(hdr, msg_sect, num_sect, total_len,
-                            sender->max_pkt, &buf);
+       res = tipc_msg_build(hdr, msg_sect, len, sender->max_pkt, &buf);
        /* Exit if build request was invalid */
        if (unlikely(res < 0))
                return res;
@@ -1121,8 +1038,7 @@ exit:
                        if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
                                goto again;
 
-                       return link_send_sections_long(sender, msg_sect,
-                                                      num_sect, total_len,
+                       return link_send_sections_long(sender, msg_sect, len,
                                                       destaddr);
                }
                tipc_node_unlock(node);
@@ -1133,8 +1049,8 @@ exit:
        if (buf)
                return tipc_reject_msg(buf, TIPC_ERR_NO_NODE);
        if (res >= 0)
-               return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
-                                                total_len, TIPC_ERR_NO_NODE);
+               return tipc_port_reject_sections(sender, hdr, msg_sect,
+                                                len, TIPC_ERR_NO_NODE);
        return res;
 }
 
@@ -1154,18 +1070,17 @@ exit:
  */
 static int link_send_sections_long(struct tipc_port *sender,
                                   struct iovec const *msg_sect,
-                                  u32 num_sect, unsigned int total_len,
-                                  u32 destaddr)
+                                  unsigned int len, u32 destaddr)
 {
        struct tipc_link *l_ptr;
        struct tipc_node *node;
        struct tipc_msg *hdr = &sender->phdr;
-       u32 dsz = total_len;
+       u32 dsz = len;
        u32 max_pkt, fragm_sz, rest;
        struct tipc_msg fragm_hdr;
        struct sk_buff *buf, *buf_chain, *prev;
        u32 fragm_crs, fragm_rest, hsz, sect_rest;
-       const unchar *sect_crs;
+       const unchar __user *sect_crs;
        int curr_sect;
        u32 fragm_no;
        int res = 0;
@@ -1207,7 +1122,7 @@ again:
 
                if (!sect_rest) {
                        sect_rest = msg_sect[++curr_sect].iov_len;
-                       sect_crs = (const unchar *)msg_sect[curr_sect].iov_base;
+                       sect_crs = msg_sect[curr_sect].iov_base;
                }
 
                if (sect_rest < fragm_rest)
@@ -1283,8 +1198,8 @@ reject:
                        buf = buf_chain->next;
                        kfree_skb(buf_chain);
                }
-               return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
-                                                total_len, TIPC_ERR_NO_NODE);
+               return tipc_port_reject_sections(sender, hdr, msg_sect,
+                                                len, TIPC_ERR_NO_NODE);
        }
 
        /* Append chain of fragments to send queue & send them */
@@ -2585,25 +2500,21 @@ void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window)
 static struct tipc_link *link_find_link(const char *name,
                                        struct tipc_node **node)
 {
-       struct tipc_link_name link_name_parts;
-       struct tipc_bearer *b_ptr;
        struct tipc_link *l_ptr;
+       struct tipc_node *n_ptr;
+       int i;
 
-       if (!link_name_validate(name, &link_name_parts))
-               return NULL;
-
-       b_ptr = tipc_bearer_find_interface(link_name_parts.if_local);
-       if (!b_ptr)
-               return NULL;
-
-       *node = tipc_node_find(link_name_parts.addr_peer);
-       if (!*node)
-               return NULL;
-
-       l_ptr = (*node)->links[b_ptr->identity];
-       if (!l_ptr || strcmp(l_ptr->name, name))
-               return NULL;
-
+       list_for_each_entry(n_ptr, &tipc_node_list, list) {
+               for (i = 0; i < MAX_BEARERS; i++) {
+                       l_ptr = n_ptr->links[i];
+                       if (l_ptr && !strcmp(l_ptr->name, name))
+                               goto found;
+               }
+       }
+       l_ptr = NULL;
+       n_ptr = NULL;
+found:
+       *node = n_ptr;
        return l_ptr;
 }
 
@@ -2646,6 +2557,7 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
        struct tipc_link *l_ptr;
        struct tipc_bearer *b_ptr;
        struct tipc_media *m_ptr;
+       int res = 0;
 
        l_ptr = link_find_link(name, &node);
        if (l_ptr) {
@@ -2668,9 +2580,12 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
                case TIPC_CMD_SET_LINK_WINDOW:
                        tipc_link_set_queue_limits(l_ptr, new_value);
                        break;
+               default:
+                       res = -EINVAL;
+                       break;
                }
                tipc_node_unlock(node);
-               return 0;
+               return res;
        }
 
        b_ptr = tipc_bearer_find(name);
@@ -2678,15 +2593,18 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
                switch (cmd) {
                case TIPC_CMD_SET_LINK_TOL:
                        b_ptr->tolerance = new_value;
-                       return 0;
+                       break;
                case TIPC_CMD_SET_LINK_PRI:
                        b_ptr->priority = new_value;
-                       return 0;
+                       break;
                case TIPC_CMD_SET_LINK_WINDOW:
                        b_ptr->window = new_value;
-                       return 0;
+                       break;
+               default:
+                       res = -EINVAL;
+                       break;
                }
-               return -EINVAL;
+               return res;
        }
 
        m_ptr = tipc_media_find(name);
@@ -2695,15 +2613,18 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
        switch (cmd) {
        case TIPC_CMD_SET_LINK_TOL:
                m_ptr->tolerance = new_value;
-               return 0;
+               break;
        case TIPC_CMD_SET_LINK_PRI:
                m_ptr->priority = new_value;
-               return 0;
+               break;
        case TIPC_CMD_SET_LINK_WINDOW:
                m_ptr->window = new_value;
-               return 0;
+               break;
+       default:
+               res = -EINVAL;
+               break;
        }
-       return -EINVAL;
+       return res;
 }
 
 struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space,