aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-09-26 11:59:41 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-09-26 11:59:41 -0400
commitd85f57938ad1d674dff8077a2e6a36a45dbe0e22 (patch)
tree4a3343918da062ca5270429cd9764b0266031463 /net
parentacbbe6c28a914db837ad8b75773b0a8f873a718a (diff)
parent45dfd5b5dd20f17fe23dafc5cfe921474d27f849 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: [PPP_MPPE]: Don't put InterimKey on the stack SCTP : Add paramters validity check for ASCONF chunk SCTP: Discard OOTB packetes with bundled INIT early. SCTP: Clean up OOTB handling and fix infinite loop processing SCTP: Explicitely discard OOTB chunks SCTP: Send ABORT chunk with correct tag in response to INIT ACK SCTP: Validate buffer room when processing sequential chunks [PATCH] mac80211: fix initialisation when built-in [PATCH] net/mac80211/wme.c: fix sparse warning [PATCH] cfg80211: fix initialisation if built-in [PATCH] net/wireless/sysfs.c: Shut up build warning
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211.c2
-rw-r--r--net/mac80211/rc80211_simple.c2
-rw-r--r--net/mac80211/wme.c2
-rw-r--r--net/sctp/input.c8
-rw-r--r--net/sctp/inqueue.c8
-rw-r--r--net/sctp/sm_make_chunk.c46
-rw-r--r--net/sctp/sm_statefuns.c243
-rw-r--r--net/sctp/sm_statetable.c16
-rw-r--r--net/wireless/core.c2
-rw-r--r--net/wireless/sysfs.c2
10 files changed, 280 insertions, 51 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 7286c389a4d0..ff2172ffd861 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -5259,7 +5259,7 @@ static void __exit ieee80211_exit(void)
5259} 5259}
5260 5260
5261 5261
5262module_init(ieee80211_init); 5262subsys_initcall(ieee80211_init);
5263module_exit(ieee80211_exit); 5263module_exit(ieee80211_exit);
5264 5264
5265MODULE_DESCRIPTION("IEEE 802.11 subsystem"); 5265MODULE_DESCRIPTION("IEEE 802.11 subsystem");
diff --git a/net/mac80211/rc80211_simple.c b/net/mac80211/rc80211_simple.c
index f6780d63b342..17b9f46bbf2b 100644
--- a/net/mac80211/rc80211_simple.c
+++ b/net/mac80211/rc80211_simple.c
@@ -431,7 +431,7 @@ static void __exit rate_control_simple_exit(void)
431} 431}
432 432
433 433
434module_init(rate_control_simple_init); 434subsys_initcall(rate_control_simple_init);
435module_exit(rate_control_simple_exit); 435module_exit(rate_control_simple_exit);
436 436
437MODULE_DESCRIPTION("Simple rate control algorithm for ieee80211"); 437MODULE_DESCRIPTION("Simple rate control algorithm for ieee80211");
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 89ce81529694..7ab82b376e1b 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -424,7 +424,7 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct rtattr *opt)
424 skb_queue_head_init(&q->requeued[i]); 424 skb_queue_head_init(&q->requeued[i]);
425 q->queues[i] = qdisc_create_dflt(qd->dev, &pfifo_qdisc_ops, 425 q->queues[i] = qdisc_create_dflt(qd->dev, &pfifo_qdisc_ops,
426 qd->handle); 426 qd->handle);
427 if (q->queues[i] == 0) { 427 if (!q->queues[i]) {
428 q->queues[i] = &noop_qdisc; 428 q->queues[i] = &noop_qdisc;
429 printk(KERN_ERR "%s child qdisc %i creation failed", dev->name, i); 429 printk(KERN_ERR "%s child qdisc %i creation failed", dev->name, i);
430 } 430 }
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 47e56017f4ce..f9a0c9276e3b 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -622,6 +622,14 @@ static int sctp_rcv_ootb(struct sk_buff *skb)
622 if (SCTP_CID_SHUTDOWN_COMPLETE == ch->type) 622 if (SCTP_CID_SHUTDOWN_COMPLETE == ch->type)
623 goto discard; 623 goto discard;
624 624
625 /* RFC 4460, 2.11.2
626 * This will discard packets with INIT chunk bundled as
627 * subsequent chunks in the packet. When INIT is first,
628 * the normal INIT processing will discard the chunk.
629 */
630 if (SCTP_CID_INIT == ch->type && (void *)ch != skb->data)
631 goto discard;
632
625 /* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR 633 /* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR
626 * or a COOKIE ACK the SCTP Packet should be silently 634 * or a COOKIE ACK the SCTP Packet should be silently
627 * discarded. 635 * discarded.
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c
index 88aa22407549..e4ea7fdf36ed 100644
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -130,6 +130,14 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
130 /* Force chunk->skb->data to chunk->chunk_end. */ 130 /* Force chunk->skb->data to chunk->chunk_end. */
131 skb_pull(chunk->skb, 131 skb_pull(chunk->skb,
132 chunk->chunk_end - chunk->skb->data); 132 chunk->chunk_end - chunk->skb->data);
133
134 /* Verify that we have at least chunk headers
135 * worth of buffer left.
136 */
137 if (skb_headlen(chunk->skb) < sizeof(sctp_chunkhdr_t)) {
138 sctp_chunk_free(chunk);
139 chunk = queue->in_progress = NULL;
140 }
133 } 141 }
134 } 142 }
135 143
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 2e34220d94cd..23ae37ec8711 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2499,6 +2499,52 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
2499 return SCTP_ERROR_NO_ERROR; 2499 return SCTP_ERROR_NO_ERROR;
2500} 2500}
2501 2501
2502/* Verify the ASCONF packet before we process it. */
2503int sctp_verify_asconf(const struct sctp_association *asoc,
2504 struct sctp_paramhdr *param_hdr, void *chunk_end,
2505 struct sctp_paramhdr **errp) {
2506 sctp_addip_param_t *asconf_param;
2507 union sctp_params param;
2508 int length, plen;
2509
2510 param.v = (sctp_paramhdr_t *) param_hdr;
2511 while (param.v <= chunk_end - sizeof(sctp_paramhdr_t)) {
2512 length = ntohs(param.p->length);
2513 *errp = param.p;
2514
2515 if (param.v > chunk_end - length ||
2516 length < sizeof(sctp_paramhdr_t))
2517 return 0;
2518
2519 switch (param.p->type) {
2520 case SCTP_PARAM_ADD_IP:
2521 case SCTP_PARAM_DEL_IP:
2522 case SCTP_PARAM_SET_PRIMARY:
2523 asconf_param = (sctp_addip_param_t *)param.v;
2524 plen = ntohs(asconf_param->param_hdr.length);
2525 if (plen < sizeof(sctp_addip_param_t) +
2526 sizeof(sctp_paramhdr_t))
2527 return 0;
2528 break;
2529 case SCTP_PARAM_SUCCESS_REPORT:
2530 case SCTP_PARAM_ADAPTATION_LAYER_IND:
2531 if (length != sizeof(sctp_addip_param_t))
2532 return 0;
2533
2534 break;
2535 default:
2536 break;
2537 }
2538
2539 param.v += WORD_ROUND(length);
2540 }
2541
2542 if (param.v != chunk_end)
2543 return 0;
2544
2545 return 1;
2546}
2547
2502/* Process an incoming ASCONF chunk with the next expected serial no. and 2548/* Process an incoming ASCONF chunk with the next expected serial no. and
2503 * return an ASCONF_ACK chunk to be sent in response. 2549 * return an ASCONF_ACK chunk to be sent in response.
2504 */ 2550 */
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 177528ed3e1b..a583d67cab63 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -90,6 +90,11 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
90 const sctp_subtype_t type, 90 const sctp_subtype_t type,
91 void *arg, 91 void *arg,
92 sctp_cmd_seq_t *commands); 92 sctp_cmd_seq_t *commands);
93static sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
94 const struct sctp_association *asoc,
95 const sctp_subtype_t type,
96 void *arg,
97 sctp_cmd_seq_t *commands);
93static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk); 98static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk);
94 99
95static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, 100static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
@@ -98,6 +103,7 @@ static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
98 struct sctp_transport *transport); 103 struct sctp_transport *transport);
99 104
100static sctp_disposition_t sctp_sf_abort_violation( 105static sctp_disposition_t sctp_sf_abort_violation(
106 const struct sctp_endpoint *ep,
101 const struct sctp_association *asoc, 107 const struct sctp_association *asoc,
102 void *arg, 108 void *arg,
103 sctp_cmd_seq_t *commands, 109 sctp_cmd_seq_t *commands,
@@ -111,6 +117,13 @@ static sctp_disposition_t sctp_sf_violation_chunklen(
111 void *arg, 117 void *arg,
112 sctp_cmd_seq_t *commands); 118 sctp_cmd_seq_t *commands);
113 119
120static sctp_disposition_t sctp_sf_violation_paramlen(
121 const struct sctp_endpoint *ep,
122 const struct sctp_association *asoc,
123 const sctp_subtype_t type,
124 void *arg,
125 sctp_cmd_seq_t *commands);
126
114static sctp_disposition_t sctp_sf_violation_ctsn( 127static sctp_disposition_t sctp_sf_violation_ctsn(
115 const struct sctp_endpoint *ep, 128 const struct sctp_endpoint *ep,
116 const struct sctp_association *asoc, 129 const struct sctp_association *asoc,
@@ -118,6 +131,13 @@ static sctp_disposition_t sctp_sf_violation_ctsn(
118 void *arg, 131 void *arg,
119 sctp_cmd_seq_t *commands); 132 sctp_cmd_seq_t *commands);
120 133
134static sctp_disposition_t sctp_sf_violation_chunk(
135 const struct sctp_endpoint *ep,
136 const struct sctp_association *asoc,
137 const sctp_subtype_t type,
138 void *arg,
139 sctp_cmd_seq_t *commands);
140
121/* Small helper function that checks if the chunk length 141/* Small helper function that checks if the chunk length
122 * is of the appropriate length. The 'required_length' argument 142 * is of the appropriate length. The 'required_length' argument
123 * is set to be the size of a specific chunk we are testing. 143 * is set to be the size of a specific chunk we are testing.
@@ -181,16 +201,21 @@ sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep,
181 struct sctp_chunk *chunk = arg; 201 struct sctp_chunk *chunk = arg;
182 struct sctp_ulpevent *ev; 202 struct sctp_ulpevent *ev;
183 203
204 if (!sctp_vtag_verify_either(chunk, asoc))
205 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
206
184 /* RFC 2960 6.10 Bundling 207 /* RFC 2960 6.10 Bundling
185 * 208 *
186 * An endpoint MUST NOT bundle INIT, INIT ACK or 209 * An endpoint MUST NOT bundle INIT, INIT ACK or
187 * SHUTDOWN COMPLETE with any other chunks. 210 * SHUTDOWN COMPLETE with any other chunks.
188 */ 211 */
189 if (!chunk->singleton) 212 if (!chunk->singleton)
190 return SCTP_DISPOSITION_VIOLATION; 213 return sctp_sf_violation_chunk(ep, asoc, type, arg, commands);
191 214
192 if (!sctp_vtag_verify_either(chunk, asoc)) 215 /* Make sure that the SHUTDOWN_COMPLETE chunk has a valid length. */
193 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 216 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
217 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
218 commands);
194 219
195 /* RFC 2960 10.2 SCTP-to-ULP 220 /* RFC 2960 10.2 SCTP-to-ULP
196 * 221 *
@@ -450,17 +475,17 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
450 if (!sctp_vtag_verify(chunk, asoc)) 475 if (!sctp_vtag_verify(chunk, asoc))
451 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 476 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
452 477
453 /* Make sure that the INIT-ACK chunk has a valid length */
454 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_initack_chunk_t)))
455 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
456 commands);
457 /* 6.10 Bundling 478 /* 6.10 Bundling
458 * An endpoint MUST NOT bundle INIT, INIT ACK or 479 * An endpoint MUST NOT bundle INIT, INIT ACK or
459 * SHUTDOWN COMPLETE with any other chunks. 480 * SHUTDOWN COMPLETE with any other chunks.
460 */ 481 */
461 if (!chunk->singleton) 482 if (!chunk->singleton)
462 return SCTP_DISPOSITION_VIOLATION; 483 return sctp_sf_violation_chunk(ep, asoc, type, arg, commands);
463 484
485 /* Make sure that the INIT-ACK chunk has a valid length */
486 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_initack_chunk_t)))
487 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
488 commands);
464 /* Grab the INIT header. */ 489 /* Grab the INIT header. */
465 chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data; 490 chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
466 491
@@ -585,7 +610,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
585 * control endpoint, respond with an ABORT. 610 * control endpoint, respond with an ABORT.
586 */ 611 */
587 if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) 612 if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
588 return sctp_sf_ootb(ep, asoc, type, arg, commands); 613 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
589 614
590 /* Make sure that the COOKIE_ECHO chunk has a valid length. 615 /* Make sure that the COOKIE_ECHO chunk has a valid length.
591 * In this case, we check that we have enough for at least a 616 * In this case, we check that we have enough for at least a
@@ -2496,6 +2521,11 @@ sctp_disposition_t sctp_sf_do_9_2_reshutack(const struct sctp_endpoint *ep,
2496 struct sctp_chunk *chunk = (struct sctp_chunk *) arg; 2521 struct sctp_chunk *chunk = (struct sctp_chunk *) arg;
2497 struct sctp_chunk *reply; 2522 struct sctp_chunk *reply;
2498 2523
2524 /* Make sure that the chunk has a valid length */
2525 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
2526 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
2527 commands);
2528
2499 /* Since we are not going to really process this INIT, there 2529 /* Since we are not going to really process this INIT, there
2500 * is no point in verifying chunk boundries. Just generate 2530 * is no point in verifying chunk boundries. Just generate
2501 * the SHUTDOWN ACK. 2531 * the SHUTDOWN ACK.
@@ -2929,7 +2959,7 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
2929 * 2959 *
2930 * The return value is the disposition of the chunk. 2960 * The return value is the disposition of the chunk.
2931*/ 2961*/
2932sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep, 2962static sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
2933 const struct sctp_association *asoc, 2963 const struct sctp_association *asoc,
2934 const sctp_subtype_t type, 2964 const sctp_subtype_t type,
2935 void *arg, 2965 void *arg,
@@ -2965,6 +2995,7 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
2965 2995
2966 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); 2996 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
2967 2997
2998 sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2968 return SCTP_DISPOSITION_CONSUME; 2999 return SCTP_DISPOSITION_CONSUME;
2969 } 3000 }
2970 3001
@@ -3125,14 +3156,14 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
3125 3156
3126 ch = (sctp_chunkhdr_t *) chunk->chunk_hdr; 3157 ch = (sctp_chunkhdr_t *) chunk->chunk_hdr;
3127 do { 3158 do {
3128 /* Break out if chunk length is less then minimal. */ 3159 /* Report violation if the chunk is less then minimal */
3129 if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t)) 3160 if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t))
3130 break; 3161 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3131 3162 commands);
3132 ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
3133 if (ch_end > skb_tail_pointer(skb))
3134 break;
3135 3163
3164 /* Now that we know we at least have a chunk header,
3165 * do things that are type appropriate.
3166 */
3136 if (SCTP_CID_SHUTDOWN_ACK == ch->type) 3167 if (SCTP_CID_SHUTDOWN_ACK == ch->type)
3137 ootb_shut_ack = 1; 3168 ootb_shut_ack = 1;
3138 3169
@@ -3144,15 +3175,19 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
3144 if (SCTP_CID_ABORT == ch->type) 3175 if (SCTP_CID_ABORT == ch->type)
3145 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 3176 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3146 3177
3178 /* Report violation if chunk len overflows */
3179 ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
3180 if (ch_end > skb_tail_pointer(skb))
3181 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3182 commands);
3183
3147 ch = (sctp_chunkhdr_t *) ch_end; 3184 ch = (sctp_chunkhdr_t *) ch_end;
3148 } while (ch_end < skb_tail_pointer(skb)); 3185 } while (ch_end < skb_tail_pointer(skb));
3149 3186
3150 if (ootb_shut_ack) 3187 if (ootb_shut_ack)
3151 sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands); 3188 return sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands);
3152 else 3189 else
3153 sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); 3190 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
3154
3155 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3156} 3191}
3157 3192
3158/* 3193/*
@@ -3218,7 +3253,11 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
3218 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t))) 3253 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
3219 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 3254 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3220 3255
3221 return SCTP_DISPOSITION_CONSUME; 3256 /* We need to discard the rest of the packet to prevent
3257 * potential bomming attacks from additional bundled chunks.
3258 * This is documented in SCTP Threats ID.
3259 */
3260 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3222 } 3261 }
3223 3262
3224 return SCTP_DISPOSITION_NOMEM; 3263 return SCTP_DISPOSITION_NOMEM;
@@ -3241,6 +3280,13 @@ sctp_disposition_t sctp_sf_do_8_5_1_E_sa(const struct sctp_endpoint *ep,
3241 void *arg, 3280 void *arg,
3242 sctp_cmd_seq_t *commands) 3281 sctp_cmd_seq_t *commands)
3243{ 3282{
3283 struct sctp_chunk *chunk = arg;
3284
3285 /* Make sure that the SHUTDOWN_ACK chunk has a valid length. */
3286 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
3287 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3288 commands);
3289
3244 /* Although we do have an association in this case, it corresponds 3290 /* Although we do have an association in this case, it corresponds
3245 * to a restarted association. So the packet is treated as an OOTB 3291 * to a restarted association. So the packet is treated as an OOTB
3246 * packet and the state function that handles OOTB SHUTDOWN_ACK is 3292 * packet and the state function that handles OOTB SHUTDOWN_ACK is
@@ -3257,8 +3303,11 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
3257{ 3303{
3258 struct sctp_chunk *chunk = arg; 3304 struct sctp_chunk *chunk = arg;
3259 struct sctp_chunk *asconf_ack = NULL; 3305 struct sctp_chunk *asconf_ack = NULL;
3306 struct sctp_paramhdr *err_param = NULL;
3260 sctp_addiphdr_t *hdr; 3307 sctp_addiphdr_t *hdr;
3308 union sctp_addr_param *addr_param;
3261 __u32 serial; 3309 __u32 serial;
3310 int length;
3262 3311
3263 if (!sctp_vtag_verify(chunk, asoc)) { 3312 if (!sctp_vtag_verify(chunk, asoc)) {
3264 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG, 3313 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
@@ -3274,6 +3323,20 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
3274 hdr = (sctp_addiphdr_t *)chunk->skb->data; 3323 hdr = (sctp_addiphdr_t *)chunk->skb->data;
3275 serial = ntohl(hdr->serial); 3324 serial = ntohl(hdr->serial);
3276 3325
3326 addr_param = (union sctp_addr_param *)hdr->params;
3327 length = ntohs(addr_param->p.length);
3328 if (length < sizeof(sctp_paramhdr_t))
3329 return sctp_sf_violation_paramlen(ep, asoc, type,
3330 (void *)addr_param, commands);
3331
3332 /* Verify the ASCONF chunk before processing it. */
3333 if (!sctp_verify_asconf(asoc,
3334 (sctp_paramhdr_t *)((void *)addr_param + length),
3335 (void *)chunk->chunk_end,
3336 &err_param))
3337 return sctp_sf_violation_paramlen(ep, asoc, type,
3338 (void *)&err_param, commands);
3339
3277 /* ADDIP 4.2 C1) Compare the value of the serial number to the value 3340 /* ADDIP 4.2 C1) Compare the value of the serial number to the value
3278 * the endpoint stored in a new association variable 3341 * the endpoint stored in a new association variable
3279 * 'Peer-Serial-Number'. 3342 * 'Peer-Serial-Number'.
@@ -3328,6 +3391,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
3328 struct sctp_chunk *asconf_ack = arg; 3391 struct sctp_chunk *asconf_ack = arg;
3329 struct sctp_chunk *last_asconf = asoc->addip_last_asconf; 3392 struct sctp_chunk *last_asconf = asoc->addip_last_asconf;
3330 struct sctp_chunk *abort; 3393 struct sctp_chunk *abort;
3394 struct sctp_paramhdr *err_param = NULL;
3331 sctp_addiphdr_t *addip_hdr; 3395 sctp_addiphdr_t *addip_hdr;
3332 __u32 sent_serial, rcvd_serial; 3396 __u32 sent_serial, rcvd_serial;
3333 3397
@@ -3345,6 +3409,14 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
3345 addip_hdr = (sctp_addiphdr_t *)asconf_ack->skb->data; 3409 addip_hdr = (sctp_addiphdr_t *)asconf_ack->skb->data;
3346 rcvd_serial = ntohl(addip_hdr->serial); 3410 rcvd_serial = ntohl(addip_hdr->serial);
3347 3411
3412 /* Verify the ASCONF-ACK chunk before processing it. */
3413 if (!sctp_verify_asconf(asoc,
3414 (sctp_paramhdr_t *)addip_hdr->params,
3415 (void *)asconf_ack->chunk_end,
3416 &err_param))
3417 return sctp_sf_violation_paramlen(ep, asoc, type,
3418 (void *)&err_param, commands);
3419
3348 if (last_asconf) { 3420 if (last_asconf) {
3349 addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr; 3421 addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr;
3350 sent_serial = ntohl(addip_hdr->serial); 3422 sent_serial = ntohl(addip_hdr->serial);
@@ -3655,6 +3727,16 @@ sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep,
3655 void *arg, 3727 void *arg,
3656 sctp_cmd_seq_t *commands) 3728 sctp_cmd_seq_t *commands)
3657{ 3729{
3730 struct sctp_chunk *chunk = arg;
3731
3732 /* Make sure that the chunk has a valid length.
3733 * Since we don't know the chunk type, we use a general
3734 * chunkhdr structure to make a comparison.
3735 */
3736 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
3737 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3738 commands);
3739
3658 SCTP_DEBUG_PRINTK("Chunk %d is discarded\n", type.chunk); 3740 SCTP_DEBUG_PRINTK("Chunk %d is discarded\n", type.chunk);
3659 return SCTP_DISPOSITION_DISCARD; 3741 return SCTP_DISPOSITION_DISCARD;
3660} 3742}
@@ -3710,6 +3792,13 @@ sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep,
3710 void *arg, 3792 void *arg,
3711 sctp_cmd_seq_t *commands) 3793 sctp_cmd_seq_t *commands)
3712{ 3794{
3795 struct sctp_chunk *chunk = arg;
3796
3797 /* Make sure that the chunk has a valid length. */
3798 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
3799 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3800 commands);
3801
3713 return SCTP_DISPOSITION_VIOLATION; 3802 return SCTP_DISPOSITION_VIOLATION;
3714} 3803}
3715 3804
@@ -3717,12 +3806,14 @@ sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep,
3717 * Common function to handle a protocol violation. 3806 * Common function to handle a protocol violation.
3718 */ 3807 */
3719static sctp_disposition_t sctp_sf_abort_violation( 3808static sctp_disposition_t sctp_sf_abort_violation(
3809 const struct sctp_endpoint *ep,
3720 const struct sctp_association *asoc, 3810 const struct sctp_association *asoc,
3721 void *arg, 3811 void *arg,
3722 sctp_cmd_seq_t *commands, 3812 sctp_cmd_seq_t *commands,
3723 const __u8 *payload, 3813 const __u8 *payload,
3724 const size_t paylen) 3814 const size_t paylen)
3725{ 3815{
3816 struct sctp_packet *packet = NULL;
3726 struct sctp_chunk *chunk = arg; 3817 struct sctp_chunk *chunk = arg;
3727 struct sctp_chunk *abort = NULL; 3818 struct sctp_chunk *abort = NULL;
3728 3819
@@ -3731,30 +3822,51 @@ static sctp_disposition_t sctp_sf_abort_violation(
3731 if (!abort) 3822 if (!abort)
3732 goto nomem; 3823 goto nomem;
3733 3824
3734 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); 3825 if (asoc) {
3735 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); 3826 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
3827 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
3736 3828
3737 if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) { 3829 if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) {
3738 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, 3830 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
3739 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); 3831 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
3740 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, 3832 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
3741 SCTP_ERROR(ECONNREFUSED)); 3833 SCTP_ERROR(ECONNREFUSED));
3742 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 3834 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
3743 SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION)); 3835 SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
3836 } else {
3837 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
3838 SCTP_ERROR(ECONNABORTED));
3839 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
3840 SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
3841 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
3842 }
3744 } else { 3843 } else {
3745 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, 3844 packet = sctp_ootb_pkt_new(asoc, chunk);
3746 SCTP_ERROR(ECONNABORTED)); 3845
3747 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 3846 if (!packet)
3748 SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION)); 3847 goto nomem_pkt;
3749 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); 3848
3849 if (sctp_test_T_bit(abort))
3850 packet->vtag = ntohl(chunk->sctp_hdr->vtag);
3851
3852 abort->skb->sk = ep->base.sk;
3853
3854 sctp_packet_append_chunk(packet, abort);
3855
3856 sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
3857 SCTP_PACKET(packet));
3858
3859 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
3750 } 3860 }
3751 3861
3752 sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL()); 3862 sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
3753 3863
3754 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 3864 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
3755 3865
3756 return SCTP_DISPOSITION_ABORT; 3866 return SCTP_DISPOSITION_ABORT;
3757 3867
3868nomem_pkt:
3869 sctp_chunk_free(abort);
3758nomem: 3870nomem:
3759 return SCTP_DISPOSITION_NOMEM; 3871 return SCTP_DISPOSITION_NOMEM;
3760} 3872}
@@ -3787,7 +3899,24 @@ static sctp_disposition_t sctp_sf_violation_chunklen(
3787{ 3899{
3788 char err_str[]="The following chunk had invalid length:"; 3900 char err_str[]="The following chunk had invalid length:";
3789 3901
3790 return sctp_sf_abort_violation(asoc, arg, commands, err_str, 3902 return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
3903 sizeof(err_str));
3904}
3905
3906/*
3907 * Handle a protocol violation when the parameter length is invalid.
3908 * "Invalid" length is identified as smaller then the minimal length a
3909 * given parameter can be.
3910 */
3911static sctp_disposition_t sctp_sf_violation_paramlen(
3912 const struct sctp_endpoint *ep,
3913 const struct sctp_association *asoc,
3914 const sctp_subtype_t type,
3915 void *arg,
3916 sctp_cmd_seq_t *commands) {
3917 char err_str[] = "The following parameter had invalid length:";
3918
3919 return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
3791 sizeof(err_str)); 3920 sizeof(err_str));
3792} 3921}
3793 3922
@@ -3806,10 +3935,31 @@ static sctp_disposition_t sctp_sf_violation_ctsn(
3806{ 3935{
3807 char err_str[]="The cumulative tsn ack beyond the max tsn currently sent:"; 3936 char err_str[]="The cumulative tsn ack beyond the max tsn currently sent:";
3808 3937
3809 return sctp_sf_abort_violation(asoc, arg, commands, err_str, 3938 return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
3810 sizeof(err_str)); 3939 sizeof(err_str));
3811} 3940}
3812 3941
3942/* Handle protocol violation of an invalid chunk bundling. For example,
3943 * when we have an association and we recieve bundled INIT-ACK, or
3944 * SHUDOWN-COMPLETE, our peer is clearly violationg the "MUST NOT bundle"
3945 * statement from the specs. Additinally, there might be an attacker
3946 * on the path and we may not want to continue this communication.
3947 */
3948static sctp_disposition_t sctp_sf_violation_chunk(
3949 const struct sctp_endpoint *ep,
3950 const struct sctp_association *asoc,
3951 const sctp_subtype_t type,
3952 void *arg,
3953 sctp_cmd_seq_t *commands)
3954{
3955 char err_str[]="The following chunk violates protocol:";
3956
3957 if (!asoc)
3958 return sctp_sf_violation(ep, asoc, type, arg, commands);
3959
3960 return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
3961 sizeof(err_str));
3962}
3813/*************************************************************************** 3963/***************************************************************************
3814 * These are the state functions for handling primitive (Section 10) events. 3964 * These are the state functions for handling primitive (Section 10) events.
3815 ***************************************************************************/ 3965 ***************************************************************************/
@@ -5176,7 +5326,22 @@ static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc
5176 * association exists, otherwise, use the peer's vtag. 5326 * association exists, otherwise, use the peer's vtag.
5177 */ 5327 */
5178 if (asoc) { 5328 if (asoc) {
5179 vtag = asoc->peer.i.init_tag; 5329 /* Special case the INIT-ACK as there is no peer's vtag
5330 * yet.
5331 */
5332 switch(chunk->chunk_hdr->type) {
5333 case SCTP_CID_INIT_ACK:
5334 {
5335 sctp_initack_chunk_t *initack;
5336
5337 initack = (sctp_initack_chunk_t *)chunk->chunk_hdr;
5338 vtag = ntohl(initack->init_hdr.init_tag);
5339 break;
5340 }
5341 default:
5342 vtag = asoc->peer.i.init_tag;
5343 break;
5344 }
5180 } else { 5345 } else {
5181 /* Special case the INIT and stale COOKIE_ECHO as there is no 5346 /* Special case the INIT and stale COOKIE_ECHO as there is no
5182 * vtag yet. 5347 * vtag yet.
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index 70a91ece3c49..ddb0ba3974b0 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -110,7 +110,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
110 /* SCTP_STATE_EMPTY */ \ 110 /* SCTP_STATE_EMPTY */ \
111 TYPE_SCTP_FUNC(sctp_sf_ootb), \ 111 TYPE_SCTP_FUNC(sctp_sf_ootb), \
112 /* SCTP_STATE_CLOSED */ \ 112 /* SCTP_STATE_CLOSED */ \
113 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \ 113 TYPE_SCTP_FUNC(sctp_sf_ootb), \
114 /* SCTP_STATE_COOKIE_WAIT */ \ 114 /* SCTP_STATE_COOKIE_WAIT */ \
115 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ 115 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
116 /* SCTP_STATE_COOKIE_ECHOED */ \ 116 /* SCTP_STATE_COOKIE_ECHOED */ \
@@ -173,7 +173,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
173 /* SCTP_STATE_EMPTY */ \ 173 /* SCTP_STATE_EMPTY */ \
174 TYPE_SCTP_FUNC(sctp_sf_ootb), \ 174 TYPE_SCTP_FUNC(sctp_sf_ootb), \
175 /* SCTP_STATE_CLOSED */ \ 175 /* SCTP_STATE_CLOSED */ \
176 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \ 176 TYPE_SCTP_FUNC(sctp_sf_ootb), \
177 /* SCTP_STATE_COOKIE_WAIT */ \ 177 /* SCTP_STATE_COOKIE_WAIT */ \
178 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ 178 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
179 /* SCTP_STATE_COOKIE_ECHOED */ \ 179 /* SCTP_STATE_COOKIE_ECHOED */ \
@@ -194,7 +194,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
194 /* SCTP_STATE_EMPTY */ \ 194 /* SCTP_STATE_EMPTY */ \
195 TYPE_SCTP_FUNC(sctp_sf_ootb), \ 195 TYPE_SCTP_FUNC(sctp_sf_ootb), \
196 /* SCTP_STATE_CLOSED */ \ 196 /* SCTP_STATE_CLOSED */ \
197 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \ 197 TYPE_SCTP_FUNC(sctp_sf_ootb), \
198 /* SCTP_STATE_COOKIE_WAIT */ \ 198 /* SCTP_STATE_COOKIE_WAIT */ \
199 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ 199 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
200 /* SCTP_STATE_COOKIE_ECHOED */ \ 200 /* SCTP_STATE_COOKIE_ECHOED */ \
@@ -216,7 +216,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
216 /* SCTP_STATE_EMPTY */ \ 216 /* SCTP_STATE_EMPTY */ \
217 TYPE_SCTP_FUNC(sctp_sf_ootb), \ 217 TYPE_SCTP_FUNC(sctp_sf_ootb), \
218 /* SCTP_STATE_CLOSED */ \ 218 /* SCTP_STATE_CLOSED */ \
219 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \ 219 TYPE_SCTP_FUNC(sctp_sf_ootb), \
220 /* SCTP_STATE_COOKIE_WAIT */ \ 220 /* SCTP_STATE_COOKIE_WAIT */ \
221 TYPE_SCTP_FUNC(sctp_sf_violation), \ 221 TYPE_SCTP_FUNC(sctp_sf_violation), \
222 /* SCTP_STATE_COOKIE_ECHOED */ \ 222 /* SCTP_STATE_COOKIE_ECHOED */ \
@@ -258,7 +258,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
258 /* SCTP_STATE_EMPTY */ \ 258 /* SCTP_STATE_EMPTY */ \
259 TYPE_SCTP_FUNC(sctp_sf_ootb), \ 259 TYPE_SCTP_FUNC(sctp_sf_ootb), \
260 /* SCTP_STATE_CLOSED */ \ 260 /* SCTP_STATE_CLOSED */ \
261 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \ 261 TYPE_SCTP_FUNC(sctp_sf_ootb), \
262 /* SCTP_STATE_COOKIE_WAIT */ \ 262 /* SCTP_STATE_COOKIE_WAIT */ \
263 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ 263 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
264 /* SCTP_STATE_COOKIE_ECHOED */ \ 264 /* SCTP_STATE_COOKIE_ECHOED */ \
@@ -300,7 +300,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
300 /* SCTP_STATE_EMPTY */ \ 300 /* SCTP_STATE_EMPTY */ \
301 TYPE_SCTP_FUNC(sctp_sf_ootb), \ 301 TYPE_SCTP_FUNC(sctp_sf_ootb), \
302 /* SCTP_STATE_CLOSED */ \ 302 /* SCTP_STATE_CLOSED */ \
303 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \ 303 TYPE_SCTP_FUNC(sctp_sf_ootb), \
304 /* SCTP_STATE_COOKIE_WAIT */ \ 304 /* SCTP_STATE_COOKIE_WAIT */ \
305 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ 305 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
306 /* SCTP_STATE_COOKIE_ECHOED */ \ 306 /* SCTP_STATE_COOKIE_ECHOED */ \
@@ -499,7 +499,7 @@ static const sctp_sm_table_entry_t addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_
499 /* SCTP_STATE_EMPTY */ \ 499 /* SCTP_STATE_EMPTY */ \
500 TYPE_SCTP_FUNC(sctp_sf_ootb), \ 500 TYPE_SCTP_FUNC(sctp_sf_ootb), \
501 /* SCTP_STATE_CLOSED */ \ 501 /* SCTP_STATE_CLOSED */ \
502 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \ 502 TYPE_SCTP_FUNC(sctp_sf_ootb), \
503 /* SCTP_STATE_COOKIE_WAIT */ \ 503 /* SCTP_STATE_COOKIE_WAIT */ \
504 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ 504 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
505 /* SCTP_STATE_COOKIE_ECHOED */ \ 505 /* SCTP_STATE_COOKIE_ECHOED */ \
@@ -528,7 +528,7 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
528 /* SCTP_STATE_EMPTY */ 528 /* SCTP_STATE_EMPTY */
529 TYPE_SCTP_FUNC(sctp_sf_ootb), 529 TYPE_SCTP_FUNC(sctp_sf_ootb),
530 /* SCTP_STATE_CLOSED */ 530 /* SCTP_STATE_CLOSED */
531 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), 531 TYPE_SCTP_FUNC(sctp_sf_ootb),
532 /* SCTP_STATE_COOKIE_WAIT */ 532 /* SCTP_STATE_COOKIE_WAIT */
533 TYPE_SCTP_FUNC(sctp_sf_unk_chunk), 533 TYPE_SCTP_FUNC(sctp_sf_unk_chunk),
534 /* SCTP_STATE_COOKIE_ECHOED */ 534 /* SCTP_STATE_COOKIE_ECHOED */
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 7eabd55417a5..9771451eae21 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -213,7 +213,7 @@ out_fail_notifier:
213out_fail_sysfs: 213out_fail_sysfs:
214 return err; 214 return err;
215} 215}
216module_init(cfg80211_init); 216subsys_initcall(cfg80211_init);
217 217
218static void cfg80211_exit(void) 218static void cfg80211_exit(void)
219{ 219{
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 88aaacd9f822..2d5d2255a27c 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -52,12 +52,14 @@ static void wiphy_dev_release(struct device *dev)
52 cfg80211_dev_free(rdev); 52 cfg80211_dev_free(rdev);
53} 53}
54 54
55#ifdef CONFIG_HOTPLUG
55static int wiphy_uevent(struct device *dev, char **envp, 56static int wiphy_uevent(struct device *dev, char **envp,
56 int num_envp, char *buf, int size) 57 int num_envp, char *buf, int size)
57{ 58{
58 /* TODO, we probably need stuff here */ 59 /* TODO, we probably need stuff here */
59 return 0; 60 return 0;
60} 61}
62#endif
61 63
62struct class ieee80211_class = { 64struct class ieee80211_class = {
63 .name = "ieee80211", 65 .name = "ieee80211",