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>
This commit is contained in:
committed by
Karsten Keil
parent
02282eee56
commit
1b4d33121f
@@ -777,6 +777,8 @@ fail:
|
|||||||
static void
|
static void
|
||||||
l1oip_socket_close(struct l1oip *hc)
|
l1oip_socket_close(struct l1oip *hc)
|
||||||
{
|
{
|
||||||
|
struct dchannel *dch = hc->chan[hc->d_idx].dch;
|
||||||
|
|
||||||
/* kill thread */
|
/* kill thread */
|
||||||
if (hc->socket_thread) {
|
if (hc->socket_thread) {
|
||||||
if (debug & DEBUG_L1OIP_SOCKET)
|
if (debug & DEBUG_L1OIP_SOCKET)
|
||||||
@@ -785,6 +787,16 @@ l1oip_socket_close(struct l1oip *hc)
|
|||||||
send_sig(SIGTERM, hc->socket_thread, 0);
|
send_sig(SIGTERM, hc->socket_thread, 0);
|
||||||
wait_for_completion(&hc->socket_complete);
|
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
|
static int
|
||||||
@@ -944,7 +956,8 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
|
|||||||
|
|
||||||
switch (cq->op) {
|
switch (cq->op) {
|
||||||
case MISDN_CTRL_GETOP:
|
case MISDN_CTRL_GETOP:
|
||||||
cq->op = MISDN_CTRL_SETPEER | MISDN_CTRL_UNSETPEER;
|
cq->op = MISDN_CTRL_SETPEER | MISDN_CTRL_UNSETPEER
|
||||||
|
| MISDN_CTRL_GETPEER;
|
||||||
break;
|
break;
|
||||||
case MISDN_CTRL_SETPEER:
|
case MISDN_CTRL_SETPEER:
|
||||||
hc->remoteip = (u32)cq->p1;
|
hc->remoteip = (u32)cq->p1;
|
||||||
@@ -964,6 +977,13 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
|
|||||||
hc->remoteip = 0;
|
hc->remoteip = 0;
|
||||||
l1oip_socket_open(hc);
|
l1oip_socket_open(hc);
|
||||||
break;
|
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:
|
default:
|
||||||
printk(KERN_WARNING "%s: unknown Op %x\n",
|
printk(KERN_WARNING "%s: unknown Op %x\n",
|
||||||
__func__, cq->op);
|
__func__, cq->op);
|
||||||
|
@@ -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 sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
|
struct hlist_node *node;
|
||||||
|
struct sock *csk;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (*debug & DEBUG_SOCKET)
|
if (*debug & DEBUG_SOCKET)
|
||||||
@@ -480,6 +482,24 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
|
|||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto done;
|
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.send = mISDN_send;
|
||||||
_pms(sk)->ch.ctrl = mISDN_ctrl;
|
_pms(sk)->ch.ctrl = mISDN_ctrl;
|
||||||
|
|
||||||
|
@@ -440,15 +440,6 @@ connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch,
|
|||||||
case ISDN_P_NT_E1:
|
case ISDN_P_NT_E1:
|
||||||
case ISDN_P_TE_S0:
|
case ISDN_P_TE_S0:
|
||||||
case ISDN_P_TE_E1:
|
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->recv = mISDN_queue_message;
|
||||||
ch->peer = &dev->D.st->own;
|
ch->peer = &dev->D.st->own;
|
||||||
ch->st = dev->D.st;
|
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))
|
if (dev->Dprotocols & (1 << ISDN_P_NT_E1))
|
||||||
rq.protocol = ISDN_P_NT_E1;
|
rq.protocol = ISDN_P_NT_E1;
|
||||||
case ISDN_P_LAPD_TE:
|
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->recv = mISDN_queue_message;
|
||||||
ch->peer = &dev->D.st->own;
|
ch->peer = &dev->D.st->own;
|
||||||
ch->st = dev->D.st;
|
ch->st = dev->D.st;
|
||||||
|
@@ -204,9 +204,9 @@
|
|||||||
#define ISDN_P_NT_UP0 0x06
|
#define ISDN_P_NT_UP0 0x06
|
||||||
|
|
||||||
#define IS_ISDN_P_TE(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_TE_E1) || \
|
#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) || \
|
#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_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_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))
|
#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_UNSETPEER 0x0080
|
||||||
#define MISDN_CTRL_RX_OFF 0x0100
|
#define MISDN_CTRL_RX_OFF 0x0100
|
||||||
#define MISDN_CTRL_FILL_EMPTY 0x0200
|
#define MISDN_CTRL_FILL_EMPTY 0x0200
|
||||||
|
#define MISDN_CTRL_GETPEER 0x0400
|
||||||
#define MISDN_CTRL_HW_FEATURES_OP 0x2000
|
#define MISDN_CTRL_HW_FEATURES_OP 0x2000
|
||||||
#define MISDN_CTRL_HW_FEATURES 0x2001
|
#define MISDN_CTRL_HW_FEATURES 0x2001
|
||||||
#define MISDN_CTRL_HFC_OP 0x4000
|
#define MISDN_CTRL_HFC_OP 0x4000
|
||||||
|
Reference in New Issue
Block a user