]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
mISDN: Fix deactivation, if peer IP is removed from l1oip instance.
authorAndreas Eversberg <andreas@eversberg.eu>
Sun, 14 Sep 2008 10:30:18 +0000 (12:30 +0200)
committerKarsten Keil <kkeil@suse.de>
Fri, 9 Jan 2009 21:44:27 +0000 (22:44 +0100)
 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>
drivers/isdn/mISDN/l1oip_core.c
drivers/isdn/mISDN/socket.c
drivers/isdn/mISDN/stack.c
include/linux/mISDNif.h

index 0884dd6892f813868417a8b54d90bdf7025227f5..3ddcd2e09dc9216d563ba40be5128bb7ddbae339 100644 (file)
@@ -777,6 +777,8 @@ fail:
 static void
 l1oip_socket_close(struct l1oip *hc)
 {
+       struct dchannel *dch = hc->chan[hc->d_idx].dch;
+
        /* kill thread */
        if (hc->socket_thread) {
                if (debug & DEBUG_L1OIP_SOCKET)
@@ -785,6 +787,16 @@ l1oip_socket_close(struct l1oip *hc)
                send_sig(SIGTERM, hc->socket_thread, 0);
                wait_for_completion(&hc->socket_complete);
        }
+
+       /* if active, we send up a PH_DEACTIVATE and deactivate */
+       if (test_bit(FLG_ACTIVE, &dch->Flags)) {
+               if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
+                       printk(KERN_DEBUG "%s: interface become deactivated "
+                               "due to timeout\n", __func__);
+               test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
+               _queue_data(&dch->dev.D, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
+                       NULL, GFP_ATOMIC);
+       }
 }
 
 static int
@@ -944,7 +956,8 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
 
        switch (cq->op) {
        case MISDN_CTRL_GETOP:
-               cq->op = MISDN_CTRL_SETPEER | MISDN_CTRL_UNSETPEER;
+               cq->op = MISDN_CTRL_SETPEER | MISDN_CTRL_UNSETPEER
+                       | MISDN_CTRL_GETPEER;
                break;
        case MISDN_CTRL_SETPEER:
                hc->remoteip = (u32)cq->p1;
@@ -964,6 +977,13 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
                hc->remoteip = 0;
                l1oip_socket_open(hc);
                break;
+       case MISDN_CTRL_GETPEER:
+               if (debug & DEBUG_L1OIP_SOCKET)
+                       printk(KERN_DEBUG "%s: getting ip address.\n",
+                               __func__);
+               (u32)cq->p1 = hc->remoteip;
+               cq->p2 = hc->remoteport | (hc->localport << 16);
+               break;
        default:
                printk(KERN_WARNING "%s: unknown Op %x\n",
                    __func__, cq->op);
index 2f6d6e88ff2c23d14fc6217a724b9e419610b830..916569ca156d4daf1b699fef711599f7b30b1b77 100644 (file)
@@ -460,6 +460,8 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
 {
        struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
        struct sock *sk = sock->sk;
+       struct hlist_node *node;
+       struct sock *csk;
        int err = 0;
 
        if (*debug & DEBUG_SOCKET)
@@ -480,6 +482,24 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
                err = -ENODEV;
                goto done;
        }
+
+       read_lock_bh(&data_sockets.lock);
+       sk_for_each(csk, node, &data_sockets.head) {
+               if (sk == csk)
+                       continue;
+               if (_pms(csk)->dev != _pms(sk)->dev)
+                       continue;
+               if (csk->sk_protocol >= ISDN_P_B_START)
+                       continue;
+               if (IS_ISDN_P_TE(csk->sk_protocol)
+                               == IS_ISDN_P_TE(sk->sk_protocol))
+                       continue;
+               read_unlock_bh(&data_sockets.lock);
+               err = -EBUSY;
+               goto done;
+       }
+       read_unlock_bh(&data_sockets.lock);
+
        _pms(sk)->ch.send = mISDN_send;
        _pms(sk)->ch.ctrl = mISDN_ctrl;
 
index 8cff570bb8df58bf2a8f929a5ea900a06c009789..63afa8cf9e07f1e3b408d3665d9e814c47bc7c13 100644 (file)
@@ -440,15 +440,6 @@ connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch,
        case ISDN_P_NT_E1:
        case ISDN_P_TE_S0:
        case ISDN_P_TE_E1:
-#ifdef PROTOCOL_CHECK
-               /* this should be enhanced */
-               if (!list_empty(&dev->D.st->layer2)
-                       && dev->D.protocol != protocol)
-                       return -EBUSY;
-               if (!hlist_empty(&dev->D.st->l1sock.head)
-                       && dev->D.protocol != protocol)
-                       return -EBUSY;
-#endif
                ch->recv = mISDN_queue_message;
                ch->peer = &dev->D.st->own;
                ch->st = dev->D.st;
@@ -546,15 +537,6 @@ create_l2entity(struct mISDNdevice *dev, struct mISDNchannel *ch,
                if (dev->Dprotocols & (1 << ISDN_P_NT_E1))
                        rq.protocol = ISDN_P_NT_E1;
        case ISDN_P_LAPD_TE:
-#ifdef PROTOCOL_CHECK
-               /* this should be enhanced */
-               if (!list_empty(&dev->D.st->layer2)
-                       && dev->D.protocol != protocol)
-                       return -EBUSY;
-               if (!hlist_empty(&dev->D.st->l1sock.head)
-                       && dev->D.protocol != protocol)
-                       return -EBUSY;
-#endif
                ch->recv = mISDN_queue_message;
                ch->peer = &dev->D.st->own;
                ch->st = dev->D.st;
index 7f65aa0c1cc579e45c3339073717bec410b27446..3f9988849f32eb2dec5e9dd4a994cbe890077fe9 100644 (file)
 #define ISDN_P_NT_UP0          0x06
 
 #define IS_ISDN_P_TE(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_TE_E1) || \
-                               (p == ISDN_P_TE_UP0))
+                               (p == ISDN_P_TE_UP0) || (p == ISDN_P_LAPD_TE))
 #define IS_ISDN_P_NT(p) ((p == ISDN_P_NT_S0) || (p == ISDN_P_NT_E1) || \
-                               (p == ISDN_P_NT_UP0))
+                               (p == ISDN_P_NT_UP0) || (p == ISDN_P_LAPD_NT))
 #define IS_ISDN_P_S0(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_NT_S0))
 #define IS_ISDN_P_E1(p) ((p == ISDN_P_TE_E1) || (p == ISDN_P_NT_E1))
 #define IS_ISDN_P_UP0(p) ((p == ISDN_P_TE_UP0) || (p == ISDN_P_NT_UP0))
@@ -333,6 +333,7 @@ clear_channelmap(u_int nr, u_char *map)
 #define MISDN_CTRL_UNSETPEER           0x0080
 #define MISDN_CTRL_RX_OFF              0x0100
 #define MISDN_CTRL_FILL_EMPTY          0x0200
+#define MISDN_CTRL_GETPEER             0x0400
 #define MISDN_CTRL_HW_FEATURES_OP      0x2000
 #define MISDN_CTRL_HW_FEATURES         0x2001
 #define MISDN_CTRL_HFC_OP              0x4000