linux/net/bridge/br_sysfs_br.c
<<
>>
Prefs
   1/*
   2 *      Sysfs attributes of bridge ports
   3 *      Linux ethernet bridge
   4 *
   5 *      Authors:
   6 *      Stephen Hemminger               <shemminger@osdl.org>
   7 *
   8 *      This program is free software; you can redistribute it and/or
   9 *      modify it under the terms of the GNU General Public License
  10 *      as published by the Free Software Foundation; either version
  11 *      2 of the License, or (at your option) any later version.
  12 */
  13
  14#include <linux/capability.h>
  15#include <linux/kernel.h>
  16#include <linux/netdevice.h>
  17#include <linux/if_bridge.h>
  18#include <linux/rtnetlink.h>
  19#include <linux/spinlock.h>
  20#include <linux/times.h>
  21
  22#include "br_private.h"
  23
  24#define to_dev(obj)     container_of(obj, struct device, kobj)
  25#define to_bridge(cd)   ((struct net_bridge *)netdev_priv(to_net_dev(cd)))
  26
  27/*
  28 * Common code for storing bridge parameters.
  29 */
  30static ssize_t store_bridge_parm(struct device *d,
  31                                 const char *buf, size_t len,
  32                                 int (*set)(struct net_bridge *, unsigned long))
  33{
  34        struct net_bridge *br = to_bridge(d);
  35        char *endp;
  36        unsigned long val;
  37        int err;
  38
  39        if (!capable(CAP_NET_ADMIN))
  40                return -EPERM;
  41
  42        val = simple_strtoul(buf, &endp, 0);
  43        if (endp == buf)
  44                return -EINVAL;
  45
  46        err = (*set)(br, val);
  47        return err ? err : len;
  48}
  49
  50
  51static ssize_t show_forward_delay(struct device *d,
  52                                  struct device_attribute *attr, char *buf)
  53{
  54        struct net_bridge *br = to_bridge(d);
  55        return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->forward_delay));
  56}
  57
  58static ssize_t store_forward_delay(struct device *d,
  59                                   struct device_attribute *attr,
  60                                   const char *buf, size_t len)
  61{
  62        return store_bridge_parm(d, buf, len, br_set_forward_delay);
  63}
  64static DEVICE_ATTR(forward_delay, S_IRUGO | S_IWUSR,
  65                   show_forward_delay, store_forward_delay);
  66
  67static ssize_t show_hello_time(struct device *d, struct device_attribute *attr,
  68                               char *buf)
  69{
  70        return sprintf(buf, "%lu\n",
  71                       jiffies_to_clock_t(to_bridge(d)->hello_time));
  72}
  73
  74static ssize_t store_hello_time(struct device *d,
  75                                struct device_attribute *attr, const char *buf,
  76                                size_t len)
  77{
  78        return store_bridge_parm(d, buf, len, br_set_hello_time);
  79}
  80static DEVICE_ATTR(hello_time, S_IRUGO | S_IWUSR, show_hello_time,
  81                   store_hello_time);
  82
  83static ssize_t show_max_age(struct device *d, struct device_attribute *attr,
  84                            char *buf)
  85{
  86        return sprintf(buf, "%lu\n",
  87                       jiffies_to_clock_t(to_bridge(d)->max_age));
  88}
  89
  90static ssize_t store_max_age(struct device *d, struct device_attribute *attr,
  91                             const char *buf, size_t len)
  92{
  93        return store_bridge_parm(d, buf, len, br_set_max_age);
  94}
  95static DEVICE_ATTR(max_age, S_IRUGO | S_IWUSR, show_max_age, store_max_age);
  96
  97static ssize_t show_ageing_time(struct device *d,
  98                                struct device_attribute *attr, char *buf)
  99{
 100        struct net_bridge *br = to_bridge(d);
 101        return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->ageing_time));
 102}
 103
 104static int set_ageing_time(struct net_bridge *br, unsigned long val)
 105{
 106        br->ageing_time = clock_t_to_jiffies(val);
 107        return 0;
 108}
 109
 110static ssize_t store_ageing_time(struct device *d,
 111                                 struct device_attribute *attr,
 112                                 const char *buf, size_t len)
 113{
 114        return store_bridge_parm(d, buf, len, set_ageing_time);
 115}
 116static DEVICE_ATTR(ageing_time, S_IRUGO | S_IWUSR, show_ageing_time,
 117                   store_ageing_time);
 118
 119static ssize_t show_stp_state(struct device *d,
 120                              struct device_attribute *attr, char *buf)
 121{
 122        struct net_bridge *br = to_bridge(d);
 123        return sprintf(buf, "%d\n", br->stp_enabled);
 124}
 125
 126
 127static ssize_t store_stp_state(struct device *d,
 128                               struct device_attribute *attr, const char *buf,
 129                               size_t len)
 130{
 131        struct net_bridge *br = to_bridge(d);
 132        char *endp;
 133        unsigned long val;
 134
 135        if (!capable(CAP_NET_ADMIN))
 136                return -EPERM;
 137
 138        val = simple_strtoul(buf, &endp, 0);
 139        if (endp == buf)
 140                return -EINVAL;
 141
 142        if (!rtnl_trylock())
 143                return restart_syscall();
 144        br_stp_set_enabled(br, val);
 145        rtnl_unlock();
 146
 147        return len;
 148}
 149static DEVICE_ATTR(stp_state, S_IRUGO | S_IWUSR, show_stp_state,
 150                   store_stp_state);
 151
 152static ssize_t show_group_fwd_mask(struct device *d,
 153                              struct device_attribute *attr, char *buf)
 154{
 155        struct net_bridge *br = to_bridge(d);
 156        return sprintf(buf, "%#x\n", br->group_fwd_mask);
 157}
 158
 159
 160static ssize_t store_group_fwd_mask(struct device *d,
 161                               struct device_attribute *attr, const char *buf,
 162                               size_t len)
 163{
 164        struct net_bridge *br = to_bridge(d);
 165        char *endp;
 166        unsigned long val;
 167
 168        if (!capable(CAP_NET_ADMIN))
 169                return -EPERM;
 170
 171        val = simple_strtoul(buf, &endp, 0);
 172        if (endp == buf)
 173                return -EINVAL;
 174
 175        if (val & BR_GROUPFWD_RESTRICTED)
 176                return -EINVAL;
 177
 178        br->group_fwd_mask = val;
 179
 180        return len;
 181}
 182static DEVICE_ATTR(group_fwd_mask, S_IRUGO | S_IWUSR, show_group_fwd_mask,
 183                   store_group_fwd_mask);
 184
 185static ssize_t show_priority(struct device *d, struct device_attribute *attr,
 186                             char *buf)
 187{
 188        struct net_bridge *br = to_bridge(d);
 189        return sprintf(buf, "%d\n",
 190                       (br->bridge_id.prio[0] << 8) | br->bridge_id.prio[1]);
 191}
 192
 193static int set_priority(struct net_bridge *br, unsigned long val)
 194{
 195        br_stp_set_bridge_priority(br, (u16) val);
 196        return 0;
 197}
 198
 199static ssize_t store_priority(struct device *d, struct device_attribute *attr,
 200                               const char *buf, size_t len)
 201{
 202        return store_bridge_parm(d, buf, len, set_priority);
 203}
 204static DEVICE_ATTR(priority, S_IRUGO | S_IWUSR, show_priority, store_priority);
 205
 206static ssize_t show_root_id(struct device *d, struct device_attribute *attr,
 207                            char *buf)
 208{
 209        return br_show_bridge_id(buf, &to_bridge(d)->designated_root);
 210}
 211static DEVICE_ATTR(root_id, S_IRUGO, show_root_id, NULL);
 212
 213static ssize_t show_bridge_id(struct device *d, struct device_attribute *attr,
 214                              char *buf)
 215{
 216        return br_show_bridge_id(buf, &to_bridge(d)->bridge_id);
 217}
 218static DEVICE_ATTR(bridge_id, S_IRUGO, show_bridge_id, NULL);
 219
 220static ssize_t show_root_port(struct device *d, struct device_attribute *attr,
 221                              char *buf)
 222{
 223        return sprintf(buf, "%d\n", to_bridge(d)->root_port);
 224}
 225static DEVICE_ATTR(root_port, S_IRUGO, show_root_port, NULL);
 226
 227static ssize_t show_root_path_cost(struct device *d,
 228                                   struct device_attribute *attr, char *buf)
 229{
 230        return sprintf(buf, "%d\n", to_bridge(d)->root_path_cost);
 231}
 232static DEVICE_ATTR(root_path_cost, S_IRUGO, show_root_path_cost, NULL);
 233
 234static ssize_t show_topology_change(struct device *d,
 235                                    struct device_attribute *attr, char *buf)
 236{
 237        return sprintf(buf, "%d\n", to_bridge(d)->topology_change);
 238}
 239static DEVICE_ATTR(topology_change, S_IRUGO, show_topology_change, NULL);
 240
 241static ssize_t show_topology_change_detected(struct device *d,
 242                                             struct device_attribute *attr,
 243                                             char *buf)
 244{
 245        struct net_bridge *br = to_bridge(d);
 246        return sprintf(buf, "%d\n", br->topology_change_detected);
 247}
 248static DEVICE_ATTR(topology_change_detected, S_IRUGO,
 249                   show_topology_change_detected, NULL);
 250
 251static ssize_t show_hello_timer(struct device *d,
 252                                struct device_attribute *attr, char *buf)
 253{
 254        struct net_bridge *br = to_bridge(d);
 255        return sprintf(buf, "%ld\n", br_timer_value(&br->hello_timer));
 256}
 257static DEVICE_ATTR(hello_timer, S_IRUGO, show_hello_timer, NULL);
 258
 259static ssize_t show_tcn_timer(struct device *d, struct device_attribute *attr,
 260                              char *buf)
 261{
 262        struct net_bridge *br = to_bridge(d);
 263        return sprintf(buf, "%ld\n", br_timer_value(&br->tcn_timer));
 264}
 265static DEVICE_ATTR(tcn_timer, S_IRUGO, show_tcn_timer, NULL);
 266
 267static ssize_t show_topology_change_timer(struct device *d,
 268                                          struct device_attribute *attr,
 269                                          char *buf)
 270{
 271        struct net_bridge *br = to_bridge(d);
 272        return sprintf(buf, "%ld\n", br_timer_value(&br->topology_change_timer));
 273}
 274static DEVICE_ATTR(topology_change_timer, S_IRUGO, show_topology_change_timer,
 275                   NULL);
 276
 277static ssize_t show_gc_timer(struct device *d, struct device_attribute *attr,
 278                             char *buf)
 279{
 280        struct net_bridge *br = to_bridge(d);
 281        return sprintf(buf, "%ld\n", br_timer_value(&br->gc_timer));
 282}
 283static DEVICE_ATTR(gc_timer, S_IRUGO, show_gc_timer, NULL);
 284
 285static ssize_t show_group_addr(struct device *d,
 286                               struct device_attribute *attr, char *buf)
 287{
 288        struct net_bridge *br = to_bridge(d);
 289        return sprintf(buf, "%x:%x:%x:%x:%x:%x\n",
 290                       br->group_addr[0], br->group_addr[1],
 291                       br->group_addr[2], br->group_addr[3],
 292                       br->group_addr[4], br->group_addr[5]);
 293}
 294
 295static ssize_t store_group_addr(struct device *d,
 296                                struct device_attribute *attr,
 297                                const char *buf, size_t len)
 298{
 299        struct net_bridge *br = to_bridge(d);
 300        unsigned int new_addr[6];
 301        int i;
 302
 303        if (!capable(CAP_NET_ADMIN))
 304                return -EPERM;
 305
 306        if (sscanf(buf, "%x:%x:%x:%x:%x:%x",
 307                   &new_addr[0], &new_addr[1], &new_addr[2],
 308                   &new_addr[3], &new_addr[4], &new_addr[5]) != 6)
 309                return -EINVAL;
 310
 311        /* Must be 01:80:c2:00:00:0X */
 312        for (i = 0; i < 5; i++)
 313                if (new_addr[i] != br_group_address[i])
 314                        return -EINVAL;
 315
 316        if (new_addr[5] & ~0xf)
 317                return -EINVAL;
 318
 319        if (new_addr[5] == 1 ||         /* 802.3x Pause address */
 320            new_addr[5] == 2 ||         /* 802.3ad Slow protocols */
 321            new_addr[5] == 3)           /* 802.1X PAE address */
 322                return -EINVAL;
 323
 324        spin_lock_bh(&br->lock);
 325        for (i = 0; i < 6; i++)
 326                br->group_addr[i] = new_addr[i];
 327        spin_unlock_bh(&br->lock);
 328        return len;
 329}
 330
 331static DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR,
 332                   show_group_addr, store_group_addr);
 333
 334static ssize_t store_flush(struct device *d,
 335                           struct device_attribute *attr,
 336                           const char *buf, size_t len)
 337{
 338        struct net_bridge *br = to_bridge(d);
 339
 340        if (!capable(CAP_NET_ADMIN))
 341                return -EPERM;
 342
 343        br_fdb_flush(br);
 344        return len;
 345}
 346static DEVICE_ATTR(flush, S_IWUSR, NULL, store_flush);
 347
 348#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
 349static ssize_t show_multicast_router(struct device *d,
 350                                     struct device_attribute *attr, char *buf)
 351{
 352        struct net_bridge *br = to_bridge(d);
 353        return sprintf(buf, "%d\n", br->multicast_router);
 354}
 355
 356static ssize_t store_multicast_router(struct device *d,
 357                                      struct device_attribute *attr,
 358                                      const char *buf, size_t len)
 359{
 360        return store_bridge_parm(d, buf, len, br_multicast_set_router);
 361}
 362static DEVICE_ATTR(multicast_router, S_IRUGO | S_IWUSR, show_multicast_router,
 363                   store_multicast_router);
 364
 365static ssize_t show_multicast_snooping(struct device *d,
 366                                       struct device_attribute *attr,
 367                                       char *buf)
 368{
 369        struct net_bridge *br = to_bridge(d);
 370        return sprintf(buf, "%d\n", !br->multicast_disabled);
 371}
 372
 373static ssize_t store_multicast_snooping(struct device *d,
 374                                        struct device_attribute *attr,
 375                                        const char *buf, size_t len)
 376{
 377        return store_bridge_parm(d, buf, len, br_multicast_toggle);
 378}
 379static DEVICE_ATTR(multicast_snooping, S_IRUGO | S_IWUSR,
 380                   show_multicast_snooping, store_multicast_snooping);
 381
 382static ssize_t show_multicast_querier(struct device *d,
 383                                      struct device_attribute *attr,
 384                                      char *buf)
 385{
 386        struct net_bridge *br = to_bridge(d);
 387        return sprintf(buf, "%d\n", br->multicast_querier);
 388}
 389
 390static ssize_t store_multicast_querier(struct device *d,
 391                                       struct device_attribute *attr,
 392                                       const char *buf, size_t len)
 393{
 394        return store_bridge_parm(d, buf, len, br_multicast_set_querier);
 395}
 396static DEVICE_ATTR(multicast_querier, S_IRUGO | S_IWUSR,
 397                   show_multicast_querier, store_multicast_querier);
 398
 399static ssize_t show_hash_elasticity(struct device *d,
 400                                    struct device_attribute *attr, char *buf)
 401{
 402        struct net_bridge *br = to_bridge(d);
 403        return sprintf(buf, "%u\n", br->hash_elasticity);
 404}
 405
 406static int set_elasticity(struct net_bridge *br, unsigned long val)
 407{
 408        br->hash_elasticity = val;
 409        return 0;
 410}
 411
 412static ssize_t store_hash_elasticity(struct device *d,
 413                                     struct device_attribute *attr,
 414                                     const char *buf, size_t len)
 415{
 416        return store_bridge_parm(d, buf, len, set_elasticity);
 417}
 418static DEVICE_ATTR(hash_elasticity, S_IRUGO | S_IWUSR, show_hash_elasticity,
 419                   store_hash_elasticity);
 420
 421static ssize_t show_hash_max(struct device *d, struct device_attribute *attr,
 422                             char *buf)
 423{
 424        struct net_bridge *br = to_bridge(d);
 425        return sprintf(buf, "%u\n", br->hash_max);
 426}
 427
 428static ssize_t store_hash_max(struct device *d, struct device_attribute *attr,
 429                              const char *buf, size_t len)
 430{
 431        return store_bridge_parm(d, buf, len, br_multicast_set_hash_max);
 432}
 433static DEVICE_ATTR(hash_max, S_IRUGO | S_IWUSR, show_hash_max,
 434                   store_hash_max);
 435
 436static ssize_t show_multicast_last_member_count(struct device *d,
 437                                                struct device_attribute *attr,
 438                                                char *buf)
 439{
 440        struct net_bridge *br = to_bridge(d);
 441        return sprintf(buf, "%u\n", br->multicast_last_member_count);
 442}
 443
 444static int set_last_member_count(struct net_bridge *br, unsigned long val)
 445{
 446        br->multicast_last_member_count = val;
 447        return 0;
 448}
 449
 450static ssize_t store_multicast_last_member_count(struct device *d,
 451                                                 struct device_attribute *attr,
 452                                                 const char *buf, size_t len)
 453{
 454        return store_bridge_parm(d, buf, len, set_last_member_count);
 455}
 456static DEVICE_ATTR(multicast_last_member_count, S_IRUGO | S_IWUSR,
 457                   show_multicast_last_member_count,
 458                   store_multicast_last_member_count);
 459
 460static ssize_t show_multicast_startup_query_count(
 461        struct device *d, struct device_attribute *attr, char *buf)
 462{
 463        struct net_bridge *br = to_bridge(d);
 464        return sprintf(buf, "%u\n", br->multicast_startup_query_count);
 465}
 466
 467static int set_startup_query_count(struct net_bridge *br, unsigned long val)
 468{
 469        br->multicast_startup_query_count = val;
 470        return 0;
 471}
 472
 473static ssize_t store_multicast_startup_query_count(
 474        struct device *d, struct device_attribute *attr, const char *buf,
 475        size_t len)
 476{
 477        return store_bridge_parm(d, buf, len, set_startup_query_count);
 478}
 479static DEVICE_ATTR(multicast_startup_query_count, S_IRUGO | S_IWUSR,
 480                   show_multicast_startup_query_count,
 481                   store_multicast_startup_query_count);
 482
 483static ssize_t show_multicast_last_member_interval(
 484        struct device *d, struct device_attribute *attr, char *buf)
 485{
 486        struct net_bridge *br = to_bridge(d);
 487        return sprintf(buf, "%lu\n",
 488                       jiffies_to_clock_t(br->multicast_last_member_interval));
 489}
 490
 491static int set_last_member_interval(struct net_bridge *br, unsigned long val)
 492{
 493        br->multicast_last_member_interval = clock_t_to_jiffies(val);
 494        return 0;
 495}
 496
 497static ssize_t store_multicast_last_member_interval(
 498        struct device *d, struct device_attribute *attr, const char *buf,
 499        size_t len)
 500{
 501        return store_bridge_parm(d, buf, len, set_last_member_interval);
 502}
 503static DEVICE_ATTR(multicast_last_member_interval, S_IRUGO | S_IWUSR,
 504                   show_multicast_last_member_interval,
 505                   store_multicast_last_member_interval);
 506
 507static ssize_t show_multicast_membership_interval(
 508        struct device *d, struct device_attribute *attr, char *buf)
 509{
 510        struct net_bridge *br = to_bridge(d);
 511        return sprintf(buf, "%lu\n",
 512                       jiffies_to_clock_t(br->multicast_membership_interval));
 513}
 514
 515static int set_membership_interval(struct net_bridge *br, unsigned long val)
 516{
 517        br->multicast_membership_interval = clock_t_to_jiffies(val);
 518        return 0;
 519}
 520
 521static ssize_t store_multicast_membership_interval(
 522        struct device *d, struct device_attribute *attr, const char *buf,
 523        size_t len)
 524{
 525        return store_bridge_parm(d, buf, len, set_membership_interval);
 526}
 527static DEVICE_ATTR(multicast_membership_interval, S_IRUGO | S_IWUSR,
 528                   show_multicast_membership_interval,
 529                   store_multicast_membership_interval);
 530
 531static ssize_t show_multicast_querier_interval(struct device *d,
 532                                               struct device_attribute *attr,
 533                                               char *buf)
 534{
 535        struct net_bridge *br = to_bridge(d);
 536        return sprintf(buf, "%lu\n",
 537                       jiffies_to_clock_t(br->multicast_querier_interval));
 538}
 539
 540static int set_querier_interval(struct net_bridge *br, unsigned long val)
 541{
 542        br->multicast_querier_interval = clock_t_to_jiffies(val);
 543        return 0;
 544}
 545
 546static ssize_t store_multicast_querier_interval(struct device *d,
 547                                                struct device_attribute *attr,
 548                                                const char *buf, size_t len)
 549{
 550        return store_bridge_parm(d, buf, len, set_querier_interval);
 551}
 552static DEVICE_ATTR(multicast_querier_interval, S_IRUGO | S_IWUSR,
 553                   show_multicast_querier_interval,
 554                   store_multicast_querier_interval);
 555
 556static ssize_t show_multicast_query_interval(struct device *d,
 557                                             struct device_attribute *attr,
 558                                             char *buf)
 559{
 560        struct net_bridge *br = to_bridge(d);
 561        return sprintf(buf, "%lu\n",
 562                       jiffies_to_clock_t(br->multicast_query_interval));
 563}
 564
 565static int set_query_interval(struct net_bridge *br, unsigned long val)
 566{
 567        br->multicast_query_interval = clock_t_to_jiffies(val);
 568        return 0;
 569}
 570
 571static ssize_t store_multicast_query_interval(struct device *d,
 572                                              struct device_attribute *attr,
 573                                              const char *buf, size_t len)
 574{
 575        return store_bridge_parm(d, buf, len, set_query_interval);
 576}
 577static DEVICE_ATTR(multicast_query_interval, S_IRUGO | S_IWUSR,
 578                   show_multicast_query_interval,
 579                   store_multicast_query_interval);
 580
 581static ssize_t show_multicast_query_response_interval(
 582        struct device *d, struct device_attribute *attr, char *buf)
 583{
 584        struct net_bridge *br = to_bridge(d);
 585        return sprintf(
 586                buf, "%lu\n",
 587                jiffies_to_clock_t(br->multicast_query_response_interval));
 588}
 589
 590static int set_query_response_interval(struct net_bridge *br, unsigned long val)
 591{
 592        br->multicast_query_response_interval = clock_t_to_jiffies(val);
 593        return 0;
 594}
 595
 596static ssize_t store_multicast_query_response_interval(
 597        struct device *d, struct device_attribute *attr, const char *buf,
 598        size_t len)
 599{
 600        return store_bridge_parm(d, buf, len, set_query_response_interval);
 601}
 602static DEVICE_ATTR(multicast_query_response_interval, S_IRUGO | S_IWUSR,
 603                   show_multicast_query_response_interval,
 604                   store_multicast_query_response_interval);
 605
 606static ssize_t show_multicast_startup_query_interval(
 607        struct device *d, struct device_attribute *attr, char *buf)
 608{
 609        struct net_bridge *br = to_bridge(d);
 610        return sprintf(
 611                buf, "%lu\n",
 612                jiffies_to_clock_t(br->multicast_startup_query_interval));
 613}
 614
 615static int set_startup_query_interval(struct net_bridge *br, unsigned long val)
 616{
 617        br->multicast_startup_query_interval = clock_t_to_jiffies(val);
 618        return 0;
 619}
 620
 621static ssize_t store_multicast_startup_query_interval(
 622        struct device *d, struct device_attribute *attr, const char *buf,
 623        size_t len)
 624{
 625        return store_bridge_parm(d, buf, len, set_startup_query_interval);
 626}
 627static DEVICE_ATTR(multicast_startup_query_interval, S_IRUGO | S_IWUSR,
 628                   show_multicast_startup_query_interval,
 629                   store_multicast_startup_query_interval);
 630#endif
 631#ifdef CONFIG_BRIDGE_NETFILTER
 632static ssize_t show_nf_call_iptables(
 633        struct device *d, struct device_attribute *attr, char *buf)
 634{
 635        struct net_bridge *br = to_bridge(d);
 636        return sprintf(buf, "%u\n", br->nf_call_iptables);
 637}
 638
 639static int set_nf_call_iptables(struct net_bridge *br, unsigned long val)
 640{
 641        br->nf_call_iptables = val ? true : false;
 642        return 0;
 643}
 644
 645static ssize_t store_nf_call_iptables(
 646        struct device *d, struct device_attribute *attr, const char *buf,
 647        size_t len)
 648{
 649        return store_bridge_parm(d, buf, len, set_nf_call_iptables);
 650}
 651static DEVICE_ATTR(nf_call_iptables, S_IRUGO | S_IWUSR,
 652                   show_nf_call_iptables, store_nf_call_iptables);
 653
 654static ssize_t show_nf_call_ip6tables(
 655        struct device *d, struct device_attribute *attr, char *buf)
 656{
 657        struct net_bridge *br = to_bridge(d);
 658        return sprintf(buf, "%u\n", br->nf_call_ip6tables);
 659}
 660
 661static int set_nf_call_ip6tables(struct net_bridge *br, unsigned long val)
 662{
 663        br->nf_call_ip6tables = val ? true : false;
 664        return 0;
 665}
 666
 667static ssize_t store_nf_call_ip6tables(
 668        struct device *d, struct device_attribute *attr, const char *buf,
 669        size_t len)
 670{
 671        return store_bridge_parm(d, buf, len, set_nf_call_ip6tables);
 672}
 673static DEVICE_ATTR(nf_call_ip6tables, S_IRUGO | S_IWUSR,
 674                   show_nf_call_ip6tables, store_nf_call_ip6tables);
 675
 676static ssize_t show_nf_call_arptables(
 677        struct device *d, struct device_attribute *attr, char *buf)
 678{
 679        struct net_bridge *br = to_bridge(d);
 680        return sprintf(buf, "%u\n", br->nf_call_arptables);
 681}
 682
 683static int set_nf_call_arptables(struct net_bridge *br, unsigned long val)
 684{
 685        br->nf_call_arptables = val ? true : false;
 686        return 0;
 687}
 688
 689static ssize_t store_nf_call_arptables(
 690        struct device *d, struct device_attribute *attr, const char *buf,
 691        size_t len)
 692{
 693        return store_bridge_parm(d, buf, len, set_nf_call_arptables);
 694}
 695static DEVICE_ATTR(nf_call_arptables, S_IRUGO | S_IWUSR,
 696                   show_nf_call_arptables, store_nf_call_arptables);
 697#endif
 698
 699static struct attribute *bridge_attrs[] = {
 700        &dev_attr_forward_delay.attr,
 701        &dev_attr_hello_time.attr,
 702        &dev_attr_max_age.attr,
 703        &dev_attr_ageing_time.attr,
 704        &dev_attr_stp_state.attr,
 705        &dev_attr_group_fwd_mask.attr,
 706        &dev_attr_priority.attr,
 707        &dev_attr_bridge_id.attr,
 708        &dev_attr_root_id.attr,
 709        &dev_attr_root_path_cost.attr,
 710        &dev_attr_root_port.attr,
 711        &dev_attr_topology_change.attr,
 712        &dev_attr_topology_change_detected.attr,
 713        &dev_attr_hello_timer.attr,
 714        &dev_attr_tcn_timer.attr,
 715        &dev_attr_topology_change_timer.attr,
 716        &dev_attr_gc_timer.attr,
 717        &dev_attr_group_addr.attr,
 718        &dev_attr_flush.attr,
 719#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
 720        &dev_attr_multicast_router.attr,
 721        &dev_attr_multicast_snooping.attr,
 722        &dev_attr_multicast_querier.attr,
 723        &dev_attr_hash_elasticity.attr,
 724        &dev_attr_hash_max.attr,
 725        &dev_attr_multicast_last_member_count.attr,
 726        &dev_attr_multicast_startup_query_count.attr,
 727        &dev_attr_multicast_last_member_interval.attr,
 728        &dev_attr_multicast_membership_interval.attr,
 729        &dev_attr_multicast_querier_interval.attr,
 730        &dev_attr_multicast_query_interval.attr,
 731        &dev_attr_multicast_query_response_interval.attr,
 732        &dev_attr_multicast_startup_query_interval.attr,
 733#endif
 734#ifdef CONFIG_BRIDGE_NETFILTER
 735        &dev_attr_nf_call_iptables.attr,
 736        &dev_attr_nf_call_ip6tables.attr,
 737        &dev_attr_nf_call_arptables.attr,
 738#endif
 739        NULL
 740};
 741
 742static struct attribute_group bridge_group = {
 743        .name = SYSFS_BRIDGE_ATTR,
 744        .attrs = bridge_attrs,
 745};
 746
 747/*
 748 * Export the forwarding information table as a binary file
 749 * The records are struct __fdb_entry.
 750 *
 751 * Returns the number of bytes read.
 752 */
 753static ssize_t brforward_read(struct file *filp, struct kobject *kobj,
 754                              struct bin_attribute *bin_attr,
 755                              char *buf, loff_t off, size_t count)
 756{
 757        struct device *dev = to_dev(kobj);
 758        struct net_bridge *br = to_bridge(dev);
 759        int n;
 760
 761        /* must read whole records */
 762        if (off % sizeof(struct __fdb_entry) != 0)
 763                return -EINVAL;
 764
 765        n =  br_fdb_fillbuf(br, buf,
 766                            count / sizeof(struct __fdb_entry),
 767                            off / sizeof(struct __fdb_entry));
 768
 769        if (n > 0)
 770                n *= sizeof(struct __fdb_entry);
 771
 772        return n;
 773}
 774
 775static struct bin_attribute bridge_forward = {
 776        .attr = { .name = SYSFS_BRIDGE_FDB,
 777                  .mode = S_IRUGO, },
 778        .read = brforward_read,
 779};
 780
 781/*
 782 * Add entries in sysfs onto the existing network class device
 783 * for the bridge.
 784 *   Adds a attribute group "bridge" containing tuning parameters.
 785 *   Binary attribute containing the forward table
 786 *   Sub directory to hold links to interfaces.
 787 *
 788 * Note: the ifobj exists only to be a subdirectory
 789 *   to hold links.  The ifobj exists in same data structure
 790 *   as it's parent the bridge so reference counting works.
 791 */
 792int br_sysfs_addbr(struct net_device *dev)
 793{
 794        struct kobject *brobj = &dev->dev.kobj;
 795        struct net_bridge *br = netdev_priv(dev);
 796        int err;
 797
 798        err = sysfs_create_group(brobj, &bridge_group);
 799        if (err) {
 800                pr_info("%s: can't create group %s/%s\n",
 801                        __func__, dev->name, bridge_group.name);
 802                goto out1;
 803        }
 804
 805        err = sysfs_create_bin_file(brobj, &bridge_forward);
 806        if (err) {
 807                pr_info("%s: can't create attribute file %s/%s\n",
 808                        __func__, dev->name, bridge_forward.attr.name);
 809                goto out2;
 810        }
 811
 812        br->ifobj = kobject_create_and_add(SYSFS_BRIDGE_PORT_SUBDIR, brobj);
 813        if (!br->ifobj) {
 814                pr_info("%s: can't add kobject (directory) %s/%s\n",
 815                        __func__, dev->name, SYSFS_BRIDGE_PORT_SUBDIR);
 816                goto out3;
 817        }
 818        return 0;
 819 out3:
 820        sysfs_remove_bin_file(&dev->dev.kobj, &bridge_forward);
 821 out2:
 822        sysfs_remove_group(&dev->dev.kobj, &bridge_group);
 823 out1:
 824        return err;
 825
 826}
 827
 828void br_sysfs_delbr(struct net_device *dev)
 829{
 830        struct kobject *kobj = &dev->dev.kobj;
 831        struct net_bridge *br = netdev_priv(dev);
 832
 833        kobject_put(br->ifobj);
 834        sysfs_remove_bin_file(kobj, &bridge_forward);
 835        sysfs_remove_group(kobj, &bridge_group);
 836}
 837
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.