diff options
author | Andreas Eversberg <andreas@eversberg.eu> | 2008-09-14 06:30:18 -0400 |
---|---|---|
committer | Karsten Keil <kkeil@suse.de> | 2009-01-09 16:44:27 -0500 |
commit | 1b4d33121f1d991f6ae226cc3333428ff87627bb (patch) | |
tree | 48fef7c8a422087a15a03c025b7709a100498a5a /drivers/isdn/mISDN | |
parent | 02282eee56b75a35e6bbc42cc34c9005eb1653f4 (diff) |
mISDN: Fix deactivation, if peer IP is removed from l1oip instance.
Added GETPEER operation.
Socket now checks if device is already busy at a differen mode.
Signed-off-by: Andreas Eversberg <andreas@eversberg.eu>
Signed-off-by: Karsten Keil <kkeil@suse.de>
Diffstat (limited to 'drivers/isdn/mISDN')
-rw-r--r-- | drivers/isdn/mISDN/l1oip_core.c | 22 | ||||
-rw-r--r-- | drivers/isdn/mISDN/socket.c | 20 | ||||
-rw-r--r-- | drivers/isdn/mISDN/stack.c | 18 |
3 files changed, 41 insertions, 19 deletions
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 0884dd6892f8..3ddcd2e09dc9 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c | |||
@@ -777,6 +777,8 @@ fail: | |||
777 | static void | 777 | static void |
778 | l1oip_socket_close(struct l1oip *hc) | 778 | l1oip_socket_close(struct l1oip *hc) |
779 | { | 779 | { |
780 | struct dchannel *dch = hc->chan[hc->d_idx].dch; | ||
781 | |||
780 | /* kill thread */ | 782 | /* kill thread */ |
781 | if (hc->socket_thread) { | 783 | if (hc->socket_thread) { |
782 | if (debug & DEBUG_L1OIP_SOCKET) | 784 | if (debug & DEBUG_L1OIP_SOCKET) |
@@ -785,6 +787,16 @@ l1oip_socket_close(struct l1oip *hc) | |||
785 | send_sig(SIGTERM, hc->socket_thread, 0); | 787 | send_sig(SIGTERM, hc->socket_thread, 0); |
786 | wait_for_completion(&hc->socket_complete); | 788 | wait_for_completion(&hc->socket_complete); |
787 | } | 789 | } |
790 | |||
791 | /* if active, we send up a PH_DEACTIVATE and deactivate */ | ||
792 | if (test_bit(FLG_ACTIVE, &dch->Flags)) { | ||
793 | if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET)) | ||
794 | printk(KERN_DEBUG "%s: interface become deactivated " | ||
795 | "due to timeout\n", __func__); | ||
796 | test_and_clear_bit(FLG_ACTIVE, &dch->Flags); | ||
797 | _queue_data(&dch->dev.D, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, | ||
798 | NULL, GFP_ATOMIC); | ||
799 | } | ||
788 | } | 800 | } |
789 | 801 | ||
790 | static int | 802 | static int |
@@ -944,7 +956,8 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq) | |||
944 | 956 | ||
945 | switch (cq->op) { | 957 | switch (cq->op) { |
946 | case MISDN_CTRL_GETOP: | 958 | case MISDN_CTRL_GETOP: |
947 | cq->op = MISDN_CTRL_SETPEER | MISDN_CTRL_UNSETPEER; | 959 | cq->op = MISDN_CTRL_SETPEER | MISDN_CTRL_UNSETPEER |
960 | | MISDN_CTRL_GETPEER; | ||
948 | break; | 961 | break; |
949 | case MISDN_CTRL_SETPEER: | 962 | case MISDN_CTRL_SETPEER: |
950 | hc->remoteip = (u32)cq->p1; | 963 | hc->remoteip = (u32)cq->p1; |
@@ -964,6 +977,13 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq) | |||
964 | hc->remoteip = 0; | 977 | hc->remoteip = 0; |
965 | l1oip_socket_open(hc); | 978 | l1oip_socket_open(hc); |
966 | break; | 979 | break; |
980 | case MISDN_CTRL_GETPEER: | ||
981 | if (debug & DEBUG_L1OIP_SOCKET) | ||
982 | printk(KERN_DEBUG "%s: getting ip address.\n", | ||
983 | __func__); | ||
984 | (u32)cq->p1 = hc->remoteip; | ||
985 | cq->p2 = hc->remoteport | (hc->localport << 16); | ||
986 | break; | ||
967 | default: | 987 | default: |
968 | printk(KERN_WARNING "%s: unknown Op %x\n", | 988 | printk(KERN_WARNING "%s: unknown Op %x\n", |
969 | __func__, cq->op); | 989 | __func__, cq->op); |
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c index 2f6d6e88ff2c..916569ca156d 100644 --- a/drivers/isdn/mISDN/socket.c +++ b/drivers/isdn/mISDN/socket.c | |||
@@ -460,6 +460,8 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) | |||
460 | { | 460 | { |
461 | struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr; | 461 | struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr; |
462 | struct sock *sk = sock->sk; | 462 | struct sock *sk = sock->sk; |
463 | struct hlist_node *node; | ||
464 | struct sock *csk; | ||
463 | int err = 0; | 465 | int err = 0; |
464 | 466 | ||
465 | if (*debug & DEBUG_SOCKET) | 467 | if (*debug & DEBUG_SOCKET) |
@@ -480,6 +482,24 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) | |||
480 | err = -ENODEV; | 482 | err = -ENODEV; |
481 | goto done; | 483 | goto done; |
482 | } | 484 | } |
485 | |||
486 | read_lock_bh(&data_sockets.lock); | ||
487 | sk_for_each(csk, node, &data_sockets.head) { | ||
488 | if (sk == csk) | ||
489 | continue; | ||
490 | if (_pms(csk)->dev != _pms(sk)->dev) | ||
491 | continue; | ||
492 | if (csk->sk_protocol >= ISDN_P_B_START) | ||
493 | continue; | ||
494 | if (IS_ISDN_P_TE(csk->sk_protocol) | ||
495 | == IS_ISDN_P_TE(sk->sk_protocol)) | ||
496 | continue; | ||
497 | read_unlock_bh(&data_sockets.lock); | ||
498 | err = -EBUSY; | ||
499 | goto done; | ||
500 | } | ||
501 | read_unlock_bh(&data_sockets.lock); | ||
502 | |||
483 | _pms(sk)->ch.send = mISDN_send; | 503 | _pms(sk)->ch.send = mISDN_send; |
484 | _pms(sk)->ch.ctrl = mISDN_ctrl; | 504 | _pms(sk)->ch.ctrl = mISDN_ctrl; |
485 | 505 | ||
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c index 8cff570bb8df..63afa8cf9e07 100644 --- a/drivers/isdn/mISDN/stack.c +++ b/drivers/isdn/mISDN/stack.c | |||
@@ -440,15 +440,6 @@ connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch, | |||
440 | case ISDN_P_NT_E1: | 440 | case ISDN_P_NT_E1: |
441 | case ISDN_P_TE_S0: | 441 | case ISDN_P_TE_S0: |
442 | case ISDN_P_TE_E1: | 442 | case ISDN_P_TE_E1: |
443 | #ifdef PROTOCOL_CHECK | ||
444 | /* this should be enhanced */ | ||
445 | if (!list_empty(&dev->D.st->layer2) | ||
446 | && dev->D.protocol != protocol) | ||
447 | return -EBUSY; | ||
448 | if (!hlist_empty(&dev->D.st->l1sock.head) | ||
449 | && dev->D.protocol != protocol) | ||
450 | return -EBUSY; | ||
451 | #endif | ||
452 | ch->recv = mISDN_queue_message; | 443 | ch->recv = mISDN_queue_message; |
453 | ch->peer = &dev->D.st->own; | 444 | ch->peer = &dev->D.st->own; |
454 | ch->st = dev->D.st; | 445 | ch->st = dev->D.st; |
@@ -546,15 +537,6 @@ create_l2entity(struct mISDNdevice *dev, struct mISDNchannel *ch, | |||
546 | if (dev->Dprotocols & (1 << ISDN_P_NT_E1)) | 537 | if (dev->Dprotocols & (1 << ISDN_P_NT_E1)) |
547 | rq.protocol = ISDN_P_NT_E1; | 538 | rq.protocol = ISDN_P_NT_E1; |
548 | case ISDN_P_LAPD_TE: | 539 | case ISDN_P_LAPD_TE: |
549 | #ifdef PROTOCOL_CHECK | ||
550 | /* this should be enhanced */ | ||
551 | if (!list_empty(&dev->D.st->layer2) | ||
552 | && dev->D.protocol != protocol) | ||
553 | return -EBUSY; | ||
554 | if (!hlist_empty(&dev->D.st->l1sock.head) | ||
555 | && dev->D.protocol != protocol) | ||
556 | return -EBUSY; | ||
557 | #endif | ||
558 | ch->recv = mISDN_queue_message; | 540 | ch->recv = mISDN_queue_message; |
559 | ch->peer = &dev->D.st->own; | 541 | ch->peer = &dev->D.st->own; |
560 | ch->st = dev->D.st; | 542 | ch->st = dev->D.st; |