clean up scary strncpy(dst, src, strlen(src)) uses
[deliverable/linux.git] / drivers / s390 / net / qeth_l3_sys.c
1 /*
2 * Copyright IBM Corp. 2007
3 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
4 * Frank Pavlic <fpavlic@de.ibm.com>,
5 * Thomas Spatzier <tspat@de.ibm.com>,
6 * Frank Blaschka <frank.blaschka@de.ibm.com>
7 */
8
9 #include <linux/slab.h>
10 #include <asm/ebcdic.h>
11 #include "qeth_l3.h"
12
13 #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
14 struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
15
16 static ssize_t qeth_l3_dev_route_show(struct qeth_card *card,
17 struct qeth_routing_info *route, char *buf)
18 {
19 switch (route->type) {
20 case PRIMARY_ROUTER:
21 return sprintf(buf, "%s\n", "primary router");
22 case SECONDARY_ROUTER:
23 return sprintf(buf, "%s\n", "secondary router");
24 case MULTICAST_ROUTER:
25 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
26 return sprintf(buf, "%s\n", "multicast router+");
27 else
28 return sprintf(buf, "%s\n", "multicast router");
29 case PRIMARY_CONNECTOR:
30 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
31 return sprintf(buf, "%s\n", "primary connector+");
32 else
33 return sprintf(buf, "%s\n", "primary connector");
34 case SECONDARY_CONNECTOR:
35 if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
36 return sprintf(buf, "%s\n", "secondary connector+");
37 else
38 return sprintf(buf, "%s\n", "secondary connector");
39 default:
40 return sprintf(buf, "%s\n", "no");
41 }
42 }
43
44 static ssize_t qeth_l3_dev_route4_show(struct device *dev,
45 struct device_attribute *attr, char *buf)
46 {
47 struct qeth_card *card = dev_get_drvdata(dev);
48
49 if (!card)
50 return -EINVAL;
51
52 return qeth_l3_dev_route_show(card, &card->options.route4, buf);
53 }
54
55 static ssize_t qeth_l3_dev_route_store(struct qeth_card *card,
56 struct qeth_routing_info *route, enum qeth_prot_versions prot,
57 const char *buf, size_t count)
58 {
59 enum qeth_routing_types old_route_type = route->type;
60 char *tmp;
61 int rc = 0;
62
63 tmp = strsep((char **) &buf, "\n");
64 mutex_lock(&card->conf_mutex);
65 if (!strcmp(tmp, "no_router")) {
66 route->type = NO_ROUTER;
67 } else if (!strcmp(tmp, "primary_connector")) {
68 route->type = PRIMARY_CONNECTOR;
69 } else if (!strcmp(tmp, "secondary_connector")) {
70 route->type = SECONDARY_CONNECTOR;
71 } else if (!strcmp(tmp, "primary_router")) {
72 route->type = PRIMARY_ROUTER;
73 } else if (!strcmp(tmp, "secondary_router")) {
74 route->type = SECONDARY_ROUTER;
75 } else if (!strcmp(tmp, "multicast_router")) {
76 route->type = MULTICAST_ROUTER;
77 } else {
78 rc = -EINVAL;
79 goto out;
80 }
81 if (((card->state == CARD_STATE_SOFTSETUP) ||
82 (card->state == CARD_STATE_UP)) &&
83 (old_route_type != route->type)) {
84 if (prot == QETH_PROT_IPV4)
85 rc = qeth_l3_setrouting_v4(card);
86 else if (prot == QETH_PROT_IPV6)
87 rc = qeth_l3_setrouting_v6(card);
88 }
89 out:
90 if (rc)
91 route->type = old_route_type;
92 mutex_unlock(&card->conf_mutex);
93 return rc ? rc : count;
94 }
95
96 static ssize_t qeth_l3_dev_route4_store(struct device *dev,
97 struct device_attribute *attr, const char *buf, size_t count)
98 {
99 struct qeth_card *card = dev_get_drvdata(dev);
100
101 if (!card)
102 return -EINVAL;
103
104 return qeth_l3_dev_route_store(card, &card->options.route4,
105 QETH_PROT_IPV4, buf, count);
106 }
107
108 static DEVICE_ATTR(route4, 0644, qeth_l3_dev_route4_show,
109 qeth_l3_dev_route4_store);
110
111 static ssize_t qeth_l3_dev_route6_show(struct device *dev,
112 struct device_attribute *attr, char *buf)
113 {
114 struct qeth_card *card = dev_get_drvdata(dev);
115
116 if (!card)
117 return -EINVAL;
118
119 return qeth_l3_dev_route_show(card, &card->options.route6, buf);
120 }
121
122 static ssize_t qeth_l3_dev_route6_store(struct device *dev,
123 struct device_attribute *attr, const char *buf, size_t count)
124 {
125 struct qeth_card *card = dev_get_drvdata(dev);
126
127 if (!card)
128 return -EINVAL;
129
130 return qeth_l3_dev_route_store(card, &card->options.route6,
131 QETH_PROT_IPV6, buf, count);
132 }
133
134 static DEVICE_ATTR(route6, 0644, qeth_l3_dev_route6_show,
135 qeth_l3_dev_route6_store);
136
137 static ssize_t qeth_l3_dev_fake_broadcast_show(struct device *dev,
138 struct device_attribute *attr, char *buf)
139 {
140 struct qeth_card *card = dev_get_drvdata(dev);
141
142 if (!card)
143 return -EINVAL;
144
145 return sprintf(buf, "%i\n", card->options.fake_broadcast? 1:0);
146 }
147
148 static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev,
149 struct device_attribute *attr, const char *buf, size_t count)
150 {
151 struct qeth_card *card = dev_get_drvdata(dev);
152 char *tmp;
153 int i, rc = 0;
154
155 if (!card)
156 return -EINVAL;
157
158 mutex_lock(&card->conf_mutex);
159 if ((card->state != CARD_STATE_DOWN) &&
160 (card->state != CARD_STATE_RECOVER)) {
161 rc = -EPERM;
162 goto out;
163 }
164
165 i = simple_strtoul(buf, &tmp, 16);
166 if ((i == 0) || (i == 1))
167 card->options.fake_broadcast = i;
168 else
169 rc = -EINVAL;
170 out:
171 mutex_unlock(&card->conf_mutex);
172 return rc ? rc : count;
173 }
174
175 static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show,
176 qeth_l3_dev_fake_broadcast_store);
177
178 static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
179 struct device_attribute *attr, char *buf)
180 {
181 struct qeth_card *card = dev_get_drvdata(dev);
182
183 if (!card)
184 return -EINVAL;
185
186 return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0);
187 }
188
189 static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
190 struct device_attribute *attr, const char *buf, size_t count)
191 {
192 struct qeth_card *card = dev_get_drvdata(dev);
193 int rc = 0;
194 unsigned long i;
195
196 if (!card)
197 return -EINVAL;
198
199 if (card->info.type != QETH_CARD_TYPE_IQD)
200 return -EPERM;
201 if (card->options.cq == QETH_CQ_ENABLED)
202 return -EPERM;
203
204 mutex_lock(&card->conf_mutex);
205 if ((card->state != CARD_STATE_DOWN) &&
206 (card->state != CARD_STATE_RECOVER)) {
207 rc = -EPERM;
208 goto out;
209 }
210
211 rc = strict_strtoul(buf, 16, &i);
212 if (rc) {
213 rc = -EINVAL;
214 goto out;
215 }
216 switch (i) {
217 case 0:
218 card->options.sniffer = i;
219 break;
220 case 1:
221 qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
222 if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) {
223 card->options.sniffer = i;
224 if (card->qdio.init_pool.buf_count !=
225 QETH_IN_BUF_COUNT_MAX)
226 qeth_realloc_buffer_pool(card,
227 QETH_IN_BUF_COUNT_MAX);
228 } else
229 rc = -EPERM;
230 break;
231 default:
232 rc = -EINVAL;
233 }
234 out:
235 mutex_unlock(&card->conf_mutex);
236 return rc ? rc : count;
237 }
238
239 static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
240 qeth_l3_dev_sniffer_store);
241
242
243 static ssize_t qeth_l3_dev_hsuid_show(struct device *dev,
244 struct device_attribute *attr, char *buf)
245 {
246 struct qeth_card *card = dev_get_drvdata(dev);
247 char tmp_hsuid[9];
248
249 if (!card)
250 return -EINVAL;
251
252 if (card->info.type != QETH_CARD_TYPE_IQD)
253 return -EPERM;
254
255 if (card->state == CARD_STATE_DOWN)
256 return -EPERM;
257
258 memcpy(tmp_hsuid, card->options.hsuid, sizeof(tmp_hsuid));
259 EBCASC(tmp_hsuid, 8);
260 return sprintf(buf, "%s\n", tmp_hsuid);
261 }
262
263 static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,
264 struct device_attribute *attr, const char *buf, size_t count)
265 {
266 struct qeth_card *card = dev_get_drvdata(dev);
267 struct qeth_ipaddr *addr;
268 char *tmp;
269 int i;
270
271 if (!card)
272 return -EINVAL;
273
274 if (card->info.type != QETH_CARD_TYPE_IQD)
275 return -EPERM;
276 if (card->state != CARD_STATE_DOWN &&
277 card->state != CARD_STATE_RECOVER)
278 return -EPERM;
279 if (card->options.sniffer)
280 return -EPERM;
281 if (card->options.cq == QETH_CQ_NOTAVAILABLE)
282 return -EPERM;
283
284 tmp = strsep((char **)&buf, "\n");
285 if (strlen(tmp) > 8)
286 return -EINVAL;
287
288 if (card->options.hsuid[0]) {
289 /* delete old ip address */
290 addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
291 if (addr != NULL) {
292 addr->u.a6.addr.s6_addr32[0] = 0xfe800000;
293 addr->u.a6.addr.s6_addr32[1] = 0x00000000;
294 for (i = 8; i < 16; i++)
295 addr->u.a6.addr.s6_addr[i] =
296 card->options.hsuid[i - 8];
297 addr->u.a6.pfxlen = 0;
298 addr->type = QETH_IP_TYPE_NORMAL;
299 } else
300 return -ENOMEM;
301 if (!qeth_l3_delete_ip(card, addr))
302 kfree(addr);
303 qeth_l3_set_ip_addr_list(card);
304 }
305
306 if (strlen(tmp) == 0) {
307 /* delete ip address only */
308 card->options.hsuid[0] = '\0';
309 if (card->dev)
310 memcpy(card->dev->perm_addr, card->options.hsuid, 9);
311 qeth_configure_cq(card, QETH_CQ_DISABLED);
312 return count;
313 }
314
315 if (qeth_configure_cq(card, QETH_CQ_ENABLED))
316 return -EPERM;
317
318 snprintf(card->options.hsuid, sizeof(card->options.hsuid),
319 "%-8s", tmp);
320 ASCEBC(card->options.hsuid, 8);
321 if (card->dev)
322 memcpy(card->dev->perm_addr, card->options.hsuid, 9);
323
324 addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
325 if (addr != NULL) {
326 addr->u.a6.addr.s6_addr32[0] = 0xfe800000;
327 addr->u.a6.addr.s6_addr32[1] = 0x00000000;
328 for (i = 8; i < 16; i++)
329 addr->u.a6.addr.s6_addr[i] = card->options.hsuid[i - 8];
330 addr->u.a6.pfxlen = 0;
331 addr->type = QETH_IP_TYPE_NORMAL;
332 } else
333 return -ENOMEM;
334 if (!qeth_l3_add_ip(card, addr))
335 kfree(addr);
336 qeth_l3_set_ip_addr_list(card);
337
338 return count;
339 }
340
341 static DEVICE_ATTR(hsuid, 0644, qeth_l3_dev_hsuid_show,
342 qeth_l3_dev_hsuid_store);
343
344
345 static struct attribute *qeth_l3_device_attrs[] = {
346 &dev_attr_route4.attr,
347 &dev_attr_route6.attr,
348 &dev_attr_fake_broadcast.attr,
349 &dev_attr_sniffer.attr,
350 &dev_attr_hsuid.attr,
351 NULL,
352 };
353
354 static struct attribute_group qeth_l3_device_attr_group = {
355 .attrs = qeth_l3_device_attrs,
356 };
357
358 static ssize_t qeth_l3_dev_ipato_enable_show(struct device *dev,
359 struct device_attribute *attr, char *buf)
360 {
361 struct qeth_card *card = dev_get_drvdata(dev);
362
363 if (!card)
364 return -EINVAL;
365
366 return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);
367 }
368
369 static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
370 struct device_attribute *attr, const char *buf, size_t count)
371 {
372 struct qeth_card *card = dev_get_drvdata(dev);
373 struct qeth_ipaddr *tmpipa, *t;
374 char *tmp;
375 int rc = 0;
376
377 if (!card)
378 return -EINVAL;
379
380 mutex_lock(&card->conf_mutex);
381 if ((card->state != CARD_STATE_DOWN) &&
382 (card->state != CARD_STATE_RECOVER)) {
383 rc = -EPERM;
384 goto out;
385 }
386
387 tmp = strsep((char **) &buf, "\n");
388 if (!strcmp(tmp, "toggle")) {
389 card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
390 } else if (!strcmp(tmp, "1")) {
391 card->ipato.enabled = 1;
392 list_for_each_entry_safe(tmpipa, t, card->ip_tbd_list, entry) {
393 if ((tmpipa->type == QETH_IP_TYPE_NORMAL) &&
394 qeth_l3_is_addr_covered_by_ipato(card, tmpipa))
395 tmpipa->set_flags |=
396 QETH_IPA_SETIP_TAKEOVER_FLAG;
397 }
398
399 } else if (!strcmp(tmp, "0")) {
400 card->ipato.enabled = 0;
401 list_for_each_entry_safe(tmpipa, t, card->ip_tbd_list, entry) {
402 if (tmpipa->set_flags &
403 QETH_IPA_SETIP_TAKEOVER_FLAG)
404 tmpipa->set_flags &=
405 ~QETH_IPA_SETIP_TAKEOVER_FLAG;
406 }
407 } else
408 rc = -EINVAL;
409 out:
410 mutex_unlock(&card->conf_mutex);
411 return rc ? rc : count;
412 }
413
414 static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
415 qeth_l3_dev_ipato_enable_show,
416 qeth_l3_dev_ipato_enable_store);
417
418 static ssize_t qeth_l3_dev_ipato_invert4_show(struct device *dev,
419 struct device_attribute *attr, char *buf)
420 {
421 struct qeth_card *card = dev_get_drvdata(dev);
422
423 if (!card)
424 return -EINVAL;
425
426 return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
427 }
428
429 static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
430 struct device_attribute *attr,
431 const char *buf, size_t count)
432 {
433 struct qeth_card *card = dev_get_drvdata(dev);
434 char *tmp;
435 int rc = 0;
436
437 if (!card)
438 return -EINVAL;
439
440 mutex_lock(&card->conf_mutex);
441 tmp = strsep((char **) &buf, "\n");
442 if (!strcmp(tmp, "toggle")) {
443 card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
444 } else if (!strcmp(tmp, "1")) {
445 card->ipato.invert4 = 1;
446 } else if (!strcmp(tmp, "0")) {
447 card->ipato.invert4 = 0;
448 } else
449 rc = -EINVAL;
450 mutex_unlock(&card->conf_mutex);
451 return rc ? rc : count;
452 }
453
454 static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
455 qeth_l3_dev_ipato_invert4_show,
456 qeth_l3_dev_ipato_invert4_store);
457
458 static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
459 enum qeth_prot_versions proto)
460 {
461 struct qeth_ipato_entry *ipatoe;
462 unsigned long flags;
463 char addr_str[40];
464 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
465 int i = 0;
466
467 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
468 /* add strlen for "/<mask>\n" */
469 entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
470 spin_lock_irqsave(&card->ip_lock, flags);
471 list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
472 if (ipatoe->proto != proto)
473 continue;
474 /* String must not be longer than PAGE_SIZE. So we check if
475 * string length gets near PAGE_SIZE. Then we can savely display
476 * the next IPv6 address (worst case, compared to IPv4) */
477 if ((PAGE_SIZE - i) <= entry_len)
478 break;
479 qeth_l3_ipaddr_to_string(proto, ipatoe->addr, addr_str);
480 i += snprintf(buf + i, PAGE_SIZE - i,
481 "%s/%i\n", addr_str, ipatoe->mask_bits);
482 }
483 spin_unlock_irqrestore(&card->ip_lock, flags);
484 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
485
486 return i;
487 }
488
489 static ssize_t qeth_l3_dev_ipato_add4_show(struct device *dev,
490 struct device_attribute *attr, char *buf)
491 {
492 struct qeth_card *card = dev_get_drvdata(dev);
493
494 if (!card)
495 return -EINVAL;
496
497 return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
498 }
499
500 static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto,
501 u8 *addr, int *mask_bits)
502 {
503 const char *start, *end;
504 char *tmp;
505 char buffer[40] = {0, };
506
507 start = buf;
508 /* get address string */
509 end = strchr(start, '/');
510 if (!end || (end - start >= 40)) {
511 return -EINVAL;
512 }
513 strncpy(buffer, start, end - start);
514 if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) {
515 return -EINVAL;
516 }
517 start = end + 1;
518 *mask_bits = simple_strtoul(start, &tmp, 10);
519 if (!strlen(start) ||
520 (tmp == start) ||
521 (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
522 return -EINVAL;
523 }
524 return 0;
525 }
526
527 static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count,
528 struct qeth_card *card, enum qeth_prot_versions proto)
529 {
530 struct qeth_ipato_entry *ipatoe;
531 u8 addr[16];
532 int mask_bits;
533 int rc = 0;
534
535 mutex_lock(&card->conf_mutex);
536 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
537 if (rc)
538 goto out;
539
540 ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL);
541 if (!ipatoe) {
542 rc = -ENOMEM;
543 goto out;
544 }
545 ipatoe->proto = proto;
546 memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
547 ipatoe->mask_bits = mask_bits;
548
549 rc = qeth_l3_add_ipato_entry(card, ipatoe);
550 if (rc)
551 kfree(ipatoe);
552 out:
553 mutex_unlock(&card->conf_mutex);
554 return rc ? rc : count;
555 }
556
557 static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev,
558 struct device_attribute *attr, const char *buf, size_t count)
559 {
560 struct qeth_card *card = dev_get_drvdata(dev);
561
562 if (!card)
563 return -EINVAL;
564
565 return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
566 }
567
568 static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
569 qeth_l3_dev_ipato_add4_show,
570 qeth_l3_dev_ipato_add4_store);
571
572 static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count,
573 struct qeth_card *card, enum qeth_prot_versions proto)
574 {
575 u8 addr[16];
576 int mask_bits;
577 int rc = 0;
578
579 mutex_lock(&card->conf_mutex);
580 rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
581 if (!rc)
582 qeth_l3_del_ipato_entry(card, proto, addr, mask_bits);
583 mutex_unlock(&card->conf_mutex);
584 return rc ? rc : count;
585 }
586
587 static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev,
588 struct device_attribute *attr, const char *buf, size_t count)
589 {
590 struct qeth_card *card = dev_get_drvdata(dev);
591
592 if (!card)
593 return -EINVAL;
594
595 return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
596 }
597
598 static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
599 qeth_l3_dev_ipato_del4_store);
600
601 static ssize_t qeth_l3_dev_ipato_invert6_show(struct device *dev,
602 struct device_attribute *attr, char *buf)
603 {
604 struct qeth_card *card = dev_get_drvdata(dev);
605
606 if (!card)
607 return -EINVAL;
608
609 return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
610 }
611
612 static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
613 struct device_attribute *attr, const char *buf, size_t count)
614 {
615 struct qeth_card *card = dev_get_drvdata(dev);
616 char *tmp;
617 int rc = 0;
618
619 if (!card)
620 return -EINVAL;
621
622 mutex_lock(&card->conf_mutex);
623 tmp = strsep((char **) &buf, "\n");
624 if (!strcmp(tmp, "toggle")) {
625 card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
626 } else if (!strcmp(tmp, "1")) {
627 card->ipato.invert6 = 1;
628 } else if (!strcmp(tmp, "0")) {
629 card->ipato.invert6 = 0;
630 } else
631 rc = -EINVAL;
632 mutex_unlock(&card->conf_mutex);
633 return rc ? rc : count;
634 }
635
636 static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
637 qeth_l3_dev_ipato_invert6_show,
638 qeth_l3_dev_ipato_invert6_store);
639
640
641 static ssize_t qeth_l3_dev_ipato_add6_show(struct device *dev,
642 struct device_attribute *attr, char *buf)
643 {
644 struct qeth_card *card = dev_get_drvdata(dev);
645
646 if (!card)
647 return -EINVAL;
648
649 return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV6);
650 }
651
652 static ssize_t qeth_l3_dev_ipato_add6_store(struct device *dev,
653 struct device_attribute *attr, const char *buf, size_t count)
654 {
655 struct qeth_card *card = dev_get_drvdata(dev);
656
657 if (!card)
658 return -EINVAL;
659
660 return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
661 }
662
663 static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
664 qeth_l3_dev_ipato_add6_show,
665 qeth_l3_dev_ipato_add6_store);
666
667 static ssize_t qeth_l3_dev_ipato_del6_store(struct device *dev,
668 struct device_attribute *attr, const char *buf, size_t count)
669 {
670 struct qeth_card *card = dev_get_drvdata(dev);
671
672 if (!card)
673 return -EINVAL;
674
675 return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
676 }
677
678 static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
679 qeth_l3_dev_ipato_del6_store);
680
681 static struct attribute *qeth_ipato_device_attrs[] = {
682 &dev_attr_ipato_enable.attr,
683 &dev_attr_ipato_invert4.attr,
684 &dev_attr_ipato_add4.attr,
685 &dev_attr_ipato_del4.attr,
686 &dev_attr_ipato_invert6.attr,
687 &dev_attr_ipato_add6.attr,
688 &dev_attr_ipato_del6.attr,
689 NULL,
690 };
691
692 static struct attribute_group qeth_device_ipato_group = {
693 .name = "ipa_takeover",
694 .attrs = qeth_ipato_device_attrs,
695 };
696
697 static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
698 enum qeth_prot_versions proto)
699 {
700 struct qeth_ipaddr *ipaddr;
701 char addr_str[40];
702 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
703 unsigned long flags;
704 int i = 0;
705
706 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
707 entry_len += 2; /* \n + terminator */
708 spin_lock_irqsave(&card->ip_lock, flags);
709 list_for_each_entry(ipaddr, &card->ip_list, entry) {
710 if (ipaddr->proto != proto)
711 continue;
712 if (ipaddr->type != QETH_IP_TYPE_VIPA)
713 continue;
714 /* String must not be longer than PAGE_SIZE. So we check if
715 * string length gets near PAGE_SIZE. Then we can savely display
716 * the next IPv6 address (worst case, compared to IPv4) */
717 if ((PAGE_SIZE - i) <= entry_len)
718 break;
719 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
720 addr_str);
721 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
722 }
723 spin_unlock_irqrestore(&card->ip_lock, flags);
724 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
725
726 return i;
727 }
728
729 static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
730 struct device_attribute *attr, char *buf)
731 {
732 struct qeth_card *card = dev_get_drvdata(dev);
733
734 if (!card)
735 return -EINVAL;
736
737 return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
738 }
739
740 static int qeth_l3_parse_vipae(const char *buf, enum qeth_prot_versions proto,
741 u8 *addr)
742 {
743 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
744 return -EINVAL;
745 }
746 return 0;
747 }
748
749 static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count,
750 struct qeth_card *card, enum qeth_prot_versions proto)
751 {
752 u8 addr[16] = {0, };
753 int rc;
754
755 mutex_lock(&card->conf_mutex);
756 rc = qeth_l3_parse_vipae(buf, proto, addr);
757 if (!rc)
758 rc = qeth_l3_add_vipa(card, proto, addr);
759 mutex_unlock(&card->conf_mutex);
760 return rc ? rc : count;
761 }
762
763 static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev,
764 struct device_attribute *attr, const char *buf, size_t count)
765 {
766 struct qeth_card *card = dev_get_drvdata(dev);
767
768 if (!card)
769 return -EINVAL;
770
771 return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV4);
772 }
773
774 static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
775 qeth_l3_dev_vipa_add4_show,
776 qeth_l3_dev_vipa_add4_store);
777
778 static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count,
779 struct qeth_card *card, enum qeth_prot_versions proto)
780 {
781 u8 addr[16];
782 int rc;
783
784 mutex_lock(&card->conf_mutex);
785 rc = qeth_l3_parse_vipae(buf, proto, addr);
786 if (!rc)
787 qeth_l3_del_vipa(card, proto, addr);
788 mutex_unlock(&card->conf_mutex);
789 return rc ? rc : count;
790 }
791
792 static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
793 struct device_attribute *attr, const char *buf, size_t count)
794 {
795 struct qeth_card *card = dev_get_drvdata(dev);
796
797 if (!card)
798 return -EINVAL;
799
800 return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV4);
801 }
802
803 static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
804 qeth_l3_dev_vipa_del4_store);
805
806 static ssize_t qeth_l3_dev_vipa_add6_show(struct device *dev,
807 struct device_attribute *attr, char *buf)
808 {
809 struct qeth_card *card = dev_get_drvdata(dev);
810
811 if (!card)
812 return -EINVAL;
813
814 return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV6);
815 }
816
817 static ssize_t qeth_l3_dev_vipa_add6_store(struct device *dev,
818 struct device_attribute *attr, const char *buf, size_t count)
819 {
820 struct qeth_card *card = dev_get_drvdata(dev);
821
822 if (!card)
823 return -EINVAL;
824
825 return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV6);
826 }
827
828 static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
829 qeth_l3_dev_vipa_add6_show,
830 qeth_l3_dev_vipa_add6_store);
831
832 static ssize_t qeth_l3_dev_vipa_del6_store(struct device *dev,
833 struct device_attribute *attr, const char *buf, size_t count)
834 {
835 struct qeth_card *card = dev_get_drvdata(dev);
836
837 if (!card)
838 return -EINVAL;
839
840 return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV6);
841 }
842
843 static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
844 qeth_l3_dev_vipa_del6_store);
845
846 static struct attribute *qeth_vipa_device_attrs[] = {
847 &dev_attr_vipa_add4.attr,
848 &dev_attr_vipa_del4.attr,
849 &dev_attr_vipa_add6.attr,
850 &dev_attr_vipa_del6.attr,
851 NULL,
852 };
853
854 static struct attribute_group qeth_device_vipa_group = {
855 .name = "vipa",
856 .attrs = qeth_vipa_device_attrs,
857 };
858
859 static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
860 enum qeth_prot_versions proto)
861 {
862 struct qeth_ipaddr *ipaddr;
863 char addr_str[40];
864 int entry_len; /* length of 1 entry string, differs between v4 and v6 */
865 unsigned long flags;
866 int i = 0;
867
868 entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
869 entry_len += 2; /* \n + terminator */
870 spin_lock_irqsave(&card->ip_lock, flags);
871 list_for_each_entry(ipaddr, &card->ip_list, entry) {
872 if (ipaddr->proto != proto)
873 continue;
874 if (ipaddr->type != QETH_IP_TYPE_RXIP)
875 continue;
876 /* String must not be longer than PAGE_SIZE. So we check if
877 * string length gets near PAGE_SIZE. Then we can savely display
878 * the next IPv6 address (worst case, compared to IPv4) */
879 if ((PAGE_SIZE - i) <= entry_len)
880 break;
881 qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
882 addr_str);
883 i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
884 }
885 spin_unlock_irqrestore(&card->ip_lock, flags);
886 i += snprintf(buf + i, PAGE_SIZE - i, "\n");
887
888 return i;
889 }
890
891 static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
892 struct device_attribute *attr, char *buf)
893 {
894 struct qeth_card *card = dev_get_drvdata(dev);
895
896 if (!card)
897 return -EINVAL;
898
899 return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
900 }
901
902 static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto,
903 u8 *addr)
904 {
905 if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
906 return -EINVAL;
907 }
908 return 0;
909 }
910
911 static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count,
912 struct qeth_card *card, enum qeth_prot_versions proto)
913 {
914 u8 addr[16] = {0, };
915 int rc;
916
917 mutex_lock(&card->conf_mutex);
918 rc = qeth_l3_parse_rxipe(buf, proto, addr);
919 if (!rc)
920 rc = qeth_l3_add_rxip(card, proto, addr);
921 mutex_unlock(&card->conf_mutex);
922 return rc ? rc : count;
923 }
924
925 static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev,
926 struct device_attribute *attr, const char *buf, size_t count)
927 {
928 struct qeth_card *card = dev_get_drvdata(dev);
929
930 if (!card)
931 return -EINVAL;
932
933 return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV4);
934 }
935
936 static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
937 qeth_l3_dev_rxip_add4_show,
938 qeth_l3_dev_rxip_add4_store);
939
940 static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count,
941 struct qeth_card *card, enum qeth_prot_versions proto)
942 {
943 u8 addr[16];
944 int rc;
945
946 mutex_lock(&card->conf_mutex);
947 rc = qeth_l3_parse_rxipe(buf, proto, addr);
948 if (!rc)
949 qeth_l3_del_rxip(card, proto, addr);
950 mutex_unlock(&card->conf_mutex);
951 return rc ? rc : count;
952 }
953
954 static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev,
955 struct device_attribute *attr, const char *buf, size_t count)
956 {
957 struct qeth_card *card = dev_get_drvdata(dev);
958
959 if (!card)
960 return -EINVAL;
961
962 return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV4);
963 }
964
965 static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
966 qeth_l3_dev_rxip_del4_store);
967
968 static ssize_t qeth_l3_dev_rxip_add6_show(struct device *dev,
969 struct device_attribute *attr, char *buf)
970 {
971 struct qeth_card *card = dev_get_drvdata(dev);
972
973 if (!card)
974 return -EINVAL;
975
976 return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV6);
977 }
978
979 static ssize_t qeth_l3_dev_rxip_add6_store(struct device *dev,
980 struct device_attribute *attr, const char *buf, size_t count)
981 {
982 struct qeth_card *card = dev_get_drvdata(dev);
983
984 if (!card)
985 return -EINVAL;
986
987 return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV6);
988 }
989
990 static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
991 qeth_l3_dev_rxip_add6_show,
992 qeth_l3_dev_rxip_add6_store);
993
994 static ssize_t qeth_l3_dev_rxip_del6_store(struct device *dev,
995 struct device_attribute *attr, const char *buf, size_t count)
996 {
997 struct qeth_card *card = dev_get_drvdata(dev);
998
999 if (!card)
1000 return -EINVAL;
1001
1002 return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV6);
1003 }
1004
1005 static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
1006 qeth_l3_dev_rxip_del6_store);
1007
1008 static struct attribute *qeth_rxip_device_attrs[] = {
1009 &dev_attr_rxip_add4.attr,
1010 &dev_attr_rxip_del4.attr,
1011 &dev_attr_rxip_add6.attr,
1012 &dev_attr_rxip_del6.attr,
1013 NULL,
1014 };
1015
1016 static struct attribute_group qeth_device_rxip_group = {
1017 .name = "rxip",
1018 .attrs = qeth_rxip_device_attrs,
1019 };
1020
1021 int qeth_l3_create_device_attributes(struct device *dev)
1022 {
1023 int ret;
1024
1025 ret = sysfs_create_group(&dev->kobj, &qeth_l3_device_attr_group);
1026 if (ret)
1027 return ret;
1028
1029 ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group);
1030 if (ret) {
1031 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1032 return ret;
1033 }
1034
1035 ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group);
1036 if (ret) {
1037 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1038 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1039 return ret;
1040 }
1041
1042 ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group);
1043 if (ret) {
1044 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1045 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1046 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1047 return ret;
1048 }
1049 return 0;
1050 }
1051
1052 void qeth_l3_remove_device_attributes(struct device *dev)
1053 {
1054 sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
1055 sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
1056 sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
1057 sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);
1058 }
This page took 0.080198 seconds and 5 git commands to generate.