Commit 1b4d3312 authored by Andreas Eversberg's avatar Andreas Eversberg Committed by Karsten Keil

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: default avatarAndreas Eversberg <andreas@eversberg.eu>
Signed-off-by: default avatarKarsten Keil <kkeil@suse.de>
parent 02282eee
...@@ -777,6 +777,8 @@ l1oip_socket_thread(void *data) ...@@ -777,6 +777,8 @@ l1oip_socket_thread(void *data)
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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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) ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment