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