aboutsummaryrefslogtreecommitdiffstats
path: root/net/x25/af_x25.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/x25/af_x25.c')
-rw-r--r--net/x25/af_x25.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index b5c80b189902..0872025821c5 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -846,7 +846,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
846 struct x25_address source_addr, dest_addr; 846 struct x25_address source_addr, dest_addr;
847 struct x25_facilities facilities; 847 struct x25_facilities facilities;
848 struct x25_dte_facilities dte_facilities; 848 struct x25_dte_facilities dte_facilities;
849 int len, rc; 849 int len, addr_len, rc;
850 850
851 /* 851 /*
852 * Remove the LCI and frame type. 852 * Remove the LCI and frame type.
@@ -857,7 +857,8 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
857 * Extract the X.25 addresses and convert them to ASCII strings, 857 * Extract the X.25 addresses and convert them to ASCII strings,
858 * and remove them. 858 * and remove them.
859 */ 859 */
860 skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr)); 860 addr_len = x25_addr_ntoa(skb->data, &source_addr, &dest_addr);
861 skb_pull(skb, addr_len);
861 862
862 /* 863 /*
863 * Get the length of the facilities, skip past them for the moment 864 * Get the length of the facilities, skip past them for the moment
@@ -873,11 +874,27 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
873 sk = x25_find_listener(&source_addr,skb); 874 sk = x25_find_listener(&source_addr,skb);
874 skb_push(skb,len); 875 skb_push(skb,len);
875 876
877 if (sk != NULL && sk_acceptq_is_full(sk)) {
878 goto out_sock_put;
879 }
880
876 /* 881 /*
877 * We can't accept the Call Request. 882 * We dont have any listeners for this incoming call.
883 * Try forwarding it.
878 */ 884 */
879 if (sk == NULL || sk_acceptq_is_full(sk)) 885 if (sk == NULL) {
880 goto out_clear_request; 886 skb_push(skb, addr_len + X25_STD_MIN_LEN);
887 if (x25_forward_call(&dest_addr, nb, skb, lci) > 0)
888 {
889 /* Call was forwarded, dont process it any more */
890 kfree_skb(skb);
891 rc = 1;
892 goto out;
893 } else {
894 /* No listeners, can't forward, clear the call */
895 goto out_clear_request;
896 }
897 }
881 898
882 /* 899 /*
883 * Try to reach a compromise on the requested facilities. 900 * Try to reach a compromise on the requested facilities.
@@ -1598,6 +1615,9 @@ void x25_kill_by_neigh(struct x25_neigh *nb)
1598 x25_disconnect(s, ENETUNREACH, 0, 0); 1615 x25_disconnect(s, ENETUNREACH, 0, 0);
1599 1616
1600 write_unlock_bh(&x25_list_lock); 1617 write_unlock_bh(&x25_list_lock);
1618
1619 /* Remove any related forwards */
1620 x25_clear_forward_by_dev(nb->dev);
1601} 1621}
1602 1622
1603static int __init x25_init(void) 1623static int __init x25_init(void)