Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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