aboutsummaryrefslogtreecommitdiffstats
path: root/net/rose/rose_route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/rose/rose_route.c')
-rw-r--r--net/rose/rose_route.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index b4fdaac233f7..479cae57d187 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -587,7 +587,7 @@ static int rose_clear_routes(void)
587 587
588/* 588/*
589 * Check that the device given is a valid AX.25 interface that is "up". 589 * Check that the device given is a valid AX.25 interface that is "up".
590 * called whith RTNL 590 * called with RTNL
591 */ 591 */
592static struct net_device *rose_ax25_dev_find(char *devname) 592static struct net_device *rose_ax25_dev_find(char *devname)
593{ 593{
@@ -674,29 +674,34 @@ struct rose_route *rose_route_free_lci(unsigned int lci, struct rose_neigh *neig
674 * Find a neighbour or a route given a ROSE address. 674 * Find a neighbour or a route given a ROSE address.
675 */ 675 */
676struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause, 676struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
677 unsigned char *diagnostic, int new) 677 unsigned char *diagnostic, int route_frame)
678{ 678{
679 struct rose_neigh *res = NULL; 679 struct rose_neigh *res = NULL;
680 struct rose_node *node; 680 struct rose_node *node;
681 int failed = 0; 681 int failed = 0;
682 int i; 682 int i;
683 683
684 if (!new) spin_lock_bh(&rose_node_list_lock); 684 if (!route_frame) spin_lock_bh(&rose_node_list_lock);
685 for (node = rose_node_list; node != NULL; node = node->next) { 685 for (node = rose_node_list; node != NULL; node = node->next) {
686 if (rosecmpm(addr, &node->address, node->mask) == 0) { 686 if (rosecmpm(addr, &node->address, node->mask) == 0) {
687 for (i = 0; i < node->count; i++) { 687 for (i = 0; i < node->count; i++) {
688 if (new) { 688 if (node->neighbour[i]->restarted) {
689 if (node->neighbour[i]->restarted) { 689 res = node->neighbour[i];
690 res = node->neighbour[i]; 690 goto out;
691 goto out;
692 }
693 } 691 }
694 else { 692 }
693 }
694 }
695 if (!route_frame) { /* connect request */
696 for (node = rose_node_list; node != NULL; node = node->next) {
697 if (rosecmpm(addr, &node->address, node->mask) == 0) {
698 for (i = 0; i < node->count; i++) {
695 if (!rose_ftimer_running(node->neighbour[i])) { 699 if (!rose_ftimer_running(node->neighbour[i])) {
696 res = node->neighbour[i]; 700 res = node->neighbour[i];
701 failed = 0;
697 goto out; 702 goto out;
698 } else 703 }
699 failed = 1; 704 failed = 1;
700 } 705 }
701 } 706 }
702 } 707 }
@@ -711,8 +716,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
711 } 716 }
712 717
713out: 718out:
714 if (!new) spin_unlock_bh(&rose_node_list_lock); 719 if (!route_frame) spin_unlock_bh(&rose_node_list_lock);
715
716 return res; 720 return res;
717} 721}
718 722
@@ -857,7 +861,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
857 unsigned int lci, new_lci; 861 unsigned int lci, new_lci;
858 unsigned char cause, diagnostic; 862 unsigned char cause, diagnostic;
859 struct net_device *dev; 863 struct net_device *dev;
860 int len, res = 0; 864 int res = 0;
861 char buf[11]; 865 char buf[11];
862 866
863#if 0 867#if 0
@@ -865,10 +869,17 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
865 return res; 869 return res;
866#endif 870#endif
867 871
872 if (skb->len < ROSE_MIN_LEN)
873 return res;
868 frametype = skb->data[2]; 874 frametype = skb->data[2];
869 lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF); 875 lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
870 src_addr = (rose_address *)(skb->data + 9); 876 if (frametype == ROSE_CALL_REQUEST &&
871 dest_addr = (rose_address *)(skb->data + 4); 877 (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF ||
878 skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] !=
879 ROSE_CALL_REQ_ADDR_LEN_VAL))
880 return res;
881 src_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_SRC_ADDR_OFF);
882 dest_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF);
872 883
873 spin_lock_bh(&rose_neigh_list_lock); 884 spin_lock_bh(&rose_neigh_list_lock);
874 spin_lock_bh(&rose_route_list_lock); 885 spin_lock_bh(&rose_route_list_lock);
@@ -1006,12 +1017,11 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
1006 goto out; 1017 goto out;
1007 } 1018 }
1008 1019
1009 len = (((skb->data[3] >> 4) & 0x0F) + 1) >> 1;
1010 len += (((skb->data[3] >> 0) & 0x0F) + 1) >> 1;
1011
1012 memset(&facilities, 0x00, sizeof(struct rose_facilities_struct)); 1020 memset(&facilities, 0x00, sizeof(struct rose_facilities_struct));
1013 1021
1014 if (!rose_parse_facilities(skb->data + len + 4, &facilities)) { 1022 if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF,
1023 skb->len - ROSE_CALL_REQ_FACILITIES_OFF,
1024 &facilities)) {
1015 rose_transmit_clear_request(rose_neigh, lci, ROSE_INVALID_FACILITY, 76); 1025 rose_transmit_clear_request(rose_neigh, lci, ROSE_INVALID_FACILITY, 76);
1016 goto out; 1026 goto out;
1017 } 1027 }