aboutsummaryrefslogtreecommitdiffstats
path: root/net/x25/af_x25.c
diff options
context:
space:
mode:
authorAndrew Hendry <andrew.hendry@gmail.com>2007-02-08 16:34:02 -0500
committerDavid S. Miller <davem@davemloft.net>2007-02-08 16:34:02 -0500
commit95a9dc4390c8215d922e0ca2ebb95279261fe795 (patch)
tree8b4be0c3a672ebd30d2777227e9a466819483ab8 /net/x25/af_x25.c
parente610e679dd0057403c96cd31f8739792780732ee (diff)
[X.25]: Add call forwarding
Adds call forwarding to X.25, allowing it to operate like an X.25 router. Useful if one needs to manipulate X.25 traffic with tools like tc. This is an update/cleanup based off a patch submitted by Daniel Ferenci a few years ago. Thanks Alan for the feedback. Added the null check to the clones. Moved the skb_clone's into the forwarding functions. Worked ok with Cisco XoT, linux X.25 back to back, and some old NTUs/PADs. Signed-off-by: Andrew Hendry <andrew.hendry@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
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)