diff options
-rw-r--r-- | drivers/isdn/mISDN/layer2.c | 13 | ||||
-rw-r--r-- | drivers/isdn/mISDN/layer2.h | 2 | ||||
-rw-r--r-- | drivers/isdn/mISDN/tei.c | 40 |
3 files changed, 29 insertions, 26 deletions
diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c index d6e2863f224a..2d2f58195477 100644 --- a/drivers/isdn/mISDN/layer2.c +++ b/drivers/isdn/mISDN/layer2.c | |||
@@ -2068,7 +2068,8 @@ l2_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg) | |||
2068 | } | 2068 | } |
2069 | 2069 | ||
2070 | struct layer2 * | 2070 | struct layer2 * |
2071 | create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg) | 2071 | create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei, |
2072 | int sapi) | ||
2072 | { | 2073 | { |
2073 | struct layer2 *l2; | 2074 | struct layer2 *l2; |
2074 | struct channel_req rq; | 2075 | struct channel_req rq; |
@@ -2089,7 +2090,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg) | |||
2089 | test_and_set_bit(FLG_LAPD, &l2->flag); | 2090 | test_and_set_bit(FLG_LAPD, &l2->flag); |
2090 | test_and_set_bit(FLG_LAPD_NET, &l2->flag); | 2091 | test_and_set_bit(FLG_LAPD_NET, &l2->flag); |
2091 | test_and_set_bit(FLG_MOD128, &l2->flag); | 2092 | test_and_set_bit(FLG_MOD128, &l2->flag); |
2092 | l2->sapi = 0; | 2093 | l2->sapi = sapi; |
2093 | l2->maxlen = MAX_DFRAME_LEN; | 2094 | l2->maxlen = MAX_DFRAME_LEN; |
2094 | if (test_bit(OPTION_L2_PMX, &options)) | 2095 | if (test_bit(OPTION_L2_PMX, &options)) |
2095 | l2->window = 7; | 2096 | l2->window = 7; |
@@ -2099,7 +2100,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg) | |||
2099 | test_and_set_bit(FLG_PTP, &l2->flag); | 2100 | test_and_set_bit(FLG_PTP, &l2->flag); |
2100 | if (test_bit(OPTION_L2_FIXEDTEI, &options)) | 2101 | if (test_bit(OPTION_L2_FIXEDTEI, &options)) |
2101 | test_and_set_bit(FLG_FIXED_TEI, &l2->flag); | 2102 | test_and_set_bit(FLG_FIXED_TEI, &l2->flag); |
2102 | l2->tei = (u_int)arg; | 2103 | l2->tei = tei; |
2103 | l2->T200 = 1000; | 2104 | l2->T200 = 1000; |
2104 | l2->N200 = 3; | 2105 | l2->N200 = 3; |
2105 | l2->T203 = 10000; | 2106 | l2->T203 = 10000; |
@@ -2114,7 +2115,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg) | |||
2114 | test_and_set_bit(FLG_LAPD, &l2->flag); | 2115 | test_and_set_bit(FLG_LAPD, &l2->flag); |
2115 | test_and_set_bit(FLG_MOD128, &l2->flag); | 2116 | test_and_set_bit(FLG_MOD128, &l2->flag); |
2116 | test_and_set_bit(FLG_ORIG, &l2->flag); | 2117 | test_and_set_bit(FLG_ORIG, &l2->flag); |
2117 | l2->sapi = 0; | 2118 | l2->sapi = sapi; |
2118 | l2->maxlen = MAX_DFRAME_LEN; | 2119 | l2->maxlen = MAX_DFRAME_LEN; |
2119 | if (test_bit(OPTION_L2_PMX, &options)) | 2120 | if (test_bit(OPTION_L2_PMX, &options)) |
2120 | l2->window = 7; | 2121 | l2->window = 7; |
@@ -2124,7 +2125,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg) | |||
2124 | test_and_set_bit(FLG_PTP, &l2->flag); | 2125 | test_and_set_bit(FLG_PTP, &l2->flag); |
2125 | if (test_bit(OPTION_L2_FIXEDTEI, &options)) | 2126 | if (test_bit(OPTION_L2_FIXEDTEI, &options)) |
2126 | test_and_set_bit(FLG_FIXED_TEI, &l2->flag); | 2127 | test_and_set_bit(FLG_FIXED_TEI, &l2->flag); |
2127 | l2->tei = (u_int)arg; | 2128 | l2->tei = tei; |
2128 | l2->T200 = 1000; | 2129 | l2->T200 = 1000; |
2129 | l2->N200 = 3; | 2130 | l2->N200 = 3; |
2130 | l2->T203 = 10000; | 2131 | l2->T203 = 10000; |
@@ -2180,7 +2181,7 @@ x75create(struct channel_req *crq) | |||
2180 | 2181 | ||
2181 | if (crq->protocol != ISDN_P_B_X75SLP) | 2182 | if (crq->protocol != ISDN_P_B_X75SLP) |
2182 | return -EPROTONOSUPPORT; | 2183 | return -EPROTONOSUPPORT; |
2183 | l2 = create_l2(crq->ch, crq->protocol, 0, 0); | 2184 | l2 = create_l2(crq->ch, crq->protocol, 0, 0, 0); |
2184 | if (!l2) | 2185 | if (!l2) |
2185 | return -ENOMEM; | 2186 | return -ENOMEM; |
2186 | crq->ch = &l2->ch; | 2187 | crq->ch = &l2->ch; |
diff --git a/drivers/isdn/mISDN/layer2.h b/drivers/isdn/mISDN/layer2.h index 6293f80dc2d3..9547fb3707a3 100644 --- a/drivers/isdn/mISDN/layer2.h +++ b/drivers/isdn/mISDN/layer2.h | |||
@@ -90,7 +90,7 @@ enum { | |||
90 | #define L2_STATE_COUNT (ST_L2_8+1) | 90 | #define L2_STATE_COUNT (ST_L2_8+1) |
91 | 91 | ||
92 | extern struct layer2 *create_l2(struct mISDNchannel *, u_int, | 92 | extern struct layer2 *create_l2(struct mISDNchannel *, u_int, |
93 | u_long, u_long); | 93 | u_long, int, int); |
94 | extern int tei_l2(struct layer2 *, u_int, u_long arg); | 94 | extern int tei_l2(struct layer2 *, u_int, u_long arg); |
95 | 95 | ||
96 | 96 | ||
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c index c75af762a067..55a7c3dac3c2 100644 --- a/drivers/isdn/mISDN/tei.c +++ b/drivers/isdn/mISDN/tei.c | |||
@@ -426,7 +426,7 @@ done: | |||
426 | } | 426 | } |
427 | 427 | ||
428 | static void | 428 | static void |
429 | put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, u_char tei) | 429 | put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, int tei) |
430 | { | 430 | { |
431 | struct sk_buff *skb; | 431 | struct sk_buff *skb; |
432 | u_char bp[8]; | 432 | u_char bp[8]; |
@@ -440,9 +440,8 @@ put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, u_char tei) | |||
440 | bp[4] = ri >> 8; | 440 | bp[4] = ri >> 8; |
441 | bp[5] = ri & 0xff; | 441 | bp[5] = ri & 0xff; |
442 | bp[6] = m_id; | 442 | bp[6] = m_id; |
443 | bp[7] = (tei << 1) | 1; | 443 | bp[7] = ((tei << 1) & 0xff) | 1; |
444 | skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr), | 444 | skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr), 8, bp, GFP_ATOMIC); |
445 | 8, bp, GFP_ATOMIC); | ||
446 | if (!skb) { | 445 | if (!skb) { |
447 | printk(KERN_WARNING "%s: no skb for tei msg\n", __func__); | 446 | printk(KERN_WARNING "%s: no skb for tei msg\n", __func__); |
448 | return; | 447 | return; |
@@ -777,7 +776,7 @@ tei_ph_data_ind(struct teimgr *tm, u_int mt, u_char *dp, int len) | |||
777 | } | 776 | } |
778 | 777 | ||
779 | static struct layer2 * | 778 | static struct layer2 * |
780 | create_new_tei(struct manager *mgr, int tei) | 779 | create_new_tei(struct manager *mgr, int tei, int sapi) |
781 | { | 780 | { |
782 | u_long opt = 0; | 781 | u_long opt = 0; |
783 | u_long flags; | 782 | u_long flags; |
@@ -786,12 +785,12 @@ create_new_tei(struct manager *mgr, int tei) | |||
786 | 785 | ||
787 | if (!mgr->up) | 786 | if (!mgr->up) |
788 | return NULL; | 787 | return NULL; |
789 | if (tei < 64) | 788 | if ((tei >= 0) && (tei < 64)) |
790 | test_and_set_bit(OPTION_L2_FIXEDTEI, &opt); | 789 | test_and_set_bit(OPTION_L2_FIXEDTEI, &opt); |
791 | if (mgr->ch.st->dev->Dprotocols | 790 | if (mgr->ch.st->dev->Dprotocols |
792 | & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1))) | 791 | & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1))) |
793 | test_and_set_bit(OPTION_L2_PMX, &opt); | 792 | test_and_set_bit(OPTION_L2_PMX, &opt); |
794 | l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, (u_int)opt, (u_long)tei); | 793 | l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, opt, tei, sapi); |
795 | if (!l2) { | 794 | if (!l2) { |
796 | printk(KERN_WARNING "%s:no memory for layer2\n", __func__); | 795 | printk(KERN_WARNING "%s:no memory for layer2\n", __func__); |
797 | return NULL; | 796 | return NULL; |
@@ -839,12 +838,17 @@ new_tei_req(struct manager *mgr, u_char *dp) | |||
839 | ri += dp[1]; | 838 | ri += dp[1]; |
840 | if (!mgr->up) | 839 | if (!mgr->up) |
841 | goto denied; | 840 | goto denied; |
842 | tei = get_free_tei(mgr); | 841 | if (!(dp[3] & 1)) /* Extension bit != 1 */ |
842 | goto denied; | ||
843 | if (dp[3] != 0xff) | ||
844 | tei = dp[3] >> 1; /* 3GPP TS 08.56 6.1.11.2 */ | ||
845 | else | ||
846 | tei = get_free_tei(mgr); | ||
843 | if (tei < 0) { | 847 | if (tei < 0) { |
844 | printk(KERN_WARNING "%s:No free tei\n", __func__); | 848 | printk(KERN_WARNING "%s:No free tei\n", __func__); |
845 | goto denied; | 849 | goto denied; |
846 | } | 850 | } |
847 | l2 = create_new_tei(mgr, tei); | 851 | l2 = create_new_tei(mgr, tei, CTRL_SAPI); |
848 | if (!l2) | 852 | if (!l2) |
849 | goto denied; | 853 | goto denied; |
850 | else | 854 | else |
@@ -976,8 +980,6 @@ create_teimgr(struct manager *mgr, struct channel_req *crq) | |||
976 | __func__, dev_name(&mgr->ch.st->dev->dev), | 980 | __func__, dev_name(&mgr->ch.st->dev->dev), |
977 | crq->protocol, crq->adr.dev, crq->adr.channel, | 981 | crq->protocol, crq->adr.dev, crq->adr.channel, |
978 | crq->adr.sapi, crq->adr.tei); | 982 | crq->adr.sapi, crq->adr.tei); |
979 | if (crq->adr.sapi != 0) /* not supported yet */ | ||
980 | return -EINVAL; | ||
981 | if (crq->adr.tei > GROUP_TEI) | 983 | if (crq->adr.tei > GROUP_TEI) |
982 | return -EINVAL; | 984 | return -EINVAL; |
983 | if (crq->adr.tei < 64) | 985 | if (crq->adr.tei < 64) |
@@ -1024,8 +1026,8 @@ create_teimgr(struct manager *mgr, struct channel_req *crq) | |||
1024 | } | 1026 | } |
1025 | return 0; | 1027 | return 0; |
1026 | } | 1028 | } |
1027 | l2 = create_l2(crq->ch, crq->protocol, (u_int)opt, | 1029 | l2 = create_l2(crq->ch, crq->protocol, opt, |
1028 | (u_long)crq->adr.tei); | 1030 | crq->adr.tei, crq->adr.sapi); |
1029 | if (!l2) | 1031 | if (!l2) |
1030 | return -ENOMEM; | 1032 | return -ENOMEM; |
1031 | l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL); | 1033 | l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL); |
@@ -1166,7 +1168,7 @@ static int | |||
1166 | check_data(struct manager *mgr, struct sk_buff *skb) | 1168 | check_data(struct manager *mgr, struct sk_buff *skb) |
1167 | { | 1169 | { |
1168 | struct mISDNhead *hh = mISDN_HEAD_P(skb); | 1170 | struct mISDNhead *hh = mISDN_HEAD_P(skb); |
1169 | int ret, tei; | 1171 | int ret, tei, sapi; |
1170 | struct layer2 *l2; | 1172 | struct layer2 *l2; |
1171 | 1173 | ||
1172 | if (*debug & DEBUG_L2_CTRL) | 1174 | if (*debug & DEBUG_L2_CTRL) |
@@ -1178,18 +1180,18 @@ check_data(struct manager *mgr, struct sk_buff *skb) | |||
1178 | return -ENOTCONN; | 1180 | return -ENOTCONN; |
1179 | if (skb->len != 3) | 1181 | if (skb->len != 3) |
1180 | return -ENOTCONN; | 1182 | return -ENOTCONN; |
1181 | if (skb->data[0] != 0) | 1183 | if (skb->data[0] & 3) /* EA0 and CR must be 0 */ |
1182 | /* only SAPI 0 command */ | 1184 | return -EINVAL; |
1183 | return -ENOTCONN; | 1185 | sapi = skb->data[0] >> 2; |
1184 | if (!(skb->data[1] & 1)) /* invalid EA1 */ | 1186 | if (!(skb->data[1] & 1)) /* invalid EA1 */ |
1185 | return -EINVAL; | 1187 | return -EINVAL; |
1186 | tei = skb->data[1] >> 0; | 1188 | tei = skb->data[1] >> 1; |
1187 | if (tei > 63) /* not a fixed tei */ | 1189 | if (tei > 63) /* not a fixed tei */ |
1188 | return -ENOTCONN; | 1190 | return -ENOTCONN; |
1189 | if ((skb->data[2] & ~0x10) != SABME) | 1191 | if ((skb->data[2] & ~0x10) != SABME) |
1190 | return -ENOTCONN; | 1192 | return -ENOTCONN; |
1191 | /* We got a SABME for a fixed TEI */ | 1193 | /* We got a SABME for a fixed TEI */ |
1192 | l2 = create_new_tei(mgr, tei); | 1194 | l2 = create_new_tei(mgr, tei, sapi); |
1193 | if (!l2) | 1195 | if (!l2) |
1194 | return -ENOMEM; | 1196 | return -ENOMEM; |
1195 | ret = l2->ch.send(&l2->ch, skb); | 1197 | ret = l2->ch.send(&l2->ch, skb); |