diff -up bridge-utils-1.1/brctl/brctl_cmd.c.igmp-snoping bridge-utils-1.1/brctl/brctl_cmd.c --- bridge-utils-1.1/brctl/brctl_cmd.c.igmp-snoping 2011-06-01 15:06:12.000000000 +0200 +++ bridge-utils-1.1/brctl/brctl_cmd.c 2011-06-01 15:06:12.000000000 +0200 @@ -247,6 +247,209 @@ static int br_cmd_setmaxage(int argc, ch return err != 0; } +static int br_cmd_sethashel(int argc, char *const* argv) +{ + int elasticity; + int err; + + if (sscanf(argv[2], "%i", &elasticity) != 1) { + fprintf(stderr,"bad elasticity\n"); + return 1; + } + err = br_set(argv[1], "hash_elasticity", elasticity, 0); + if (err) + fprintf(stderr, "set hash elasticity failed: %s\n", + strerror(err)); + + return err != 0; +} + +static int br_cmd_sethashmax(int argc, char *const* argv) +{ + int max; + int err; + + if (sscanf(argv[2], "%i", &max) != 1) { + fprintf(stderr,"bad max\n"); + return 1; + } + err = br_set(argv[1], "hash_max", max, 0); + if (err) + fprintf(stderr, "set hash max failed: %s\n", strerror(err)); + + return err != 0; +} + +static int br_cmd_setmclmc(int argc, char *const* argv) +{ + int lmc; + int err; + + if (sscanf(argv[2], "%i", &lmc) != 1) { + fprintf(stderr,"bad count\n"); + return 1; + } + err = br_set(argv[1], "multicast_last_member_count", lmc, 0); + if (err) + fprintf(stderr, "set multicast last member count failed: %s\n", + strerror(err)); + + return err != 0; +} + +static int br_cmd_setmcrouter(int argc, char *const* argv) +{ + int router; + int err; + + if (sscanf(argv[2], "%i", &router) != 1) { + fprintf(stderr,"bad router\n"); + return 1; + } + err = br_set(argv[1], "multicast_router", router, 0); + if (err) + fprintf(stderr, "set multicast router failed: %s\n", + strerror(err)); + + return err != 0; +} + +static int br_cmd_setmcsnoop(int argc, char *const* argv) +{ + int snoop; + int err; + + if (sscanf(argv[2], "%i", &snoop) != 1) { + fprintf(stderr,"bad snooping\n"); + return 1; + } + err = br_set(argv[1], "multicast_snooping", snoop, 0); + if (err) + fprintf(stderr, "set multicast snooping failed: %s\n", + strerror(err)); + + return err != 0; +} + +static int br_cmd_setmcsqc(int argc, char *const* argv) +{ + int sqc; + int err; + + if (sscanf(argv[2], "%i", &sqc) != 1) { + fprintf(stderr,"bad count\n"); + return 1; + } + err = br_set(argv[1], "multicast_startup_query_count", sqc, 0); + if (err) + fprintf(stderr, "set multicast startup query count failed: " + "%s\n", strerror(err)); + + return err != 0; +} + +static int br_cmd_setmclmi(int argc, char *const* argv) +{ + struct timeval tv; + int err; + + if (strtotimeval(&tv, argv[2])) { + fprintf(stderr, "bad interval\n"); + return 1; + } + err = br_set_time(argv[1], "multicast_last_member_interval", &tv); + if (err) + fprintf(stderr, "set multicast last member interval failed: " + "%s\n", strerror(err)); + + return err != 0; +} + +static int br_cmd_setmcmi(int argc, char *const* argv) +{ + struct timeval tv; + int err; + + if (strtotimeval(&tv, argv[2])) { + fprintf(stderr, "bad interval\n"); + return 1; + } + err = br_set_time(argv[1], "multicast_membership_interval", &tv); + if (err) + fprintf(stderr, "set multicast membership interval failed: " + "%s\n", strerror(err)); + + return err != 0; +} + +static int br_cmd_setmcqpi(int argc, char *const* argv) +{ + struct timeval tv; + int err; + + if (strtotimeval(&tv, argv[2])) { + fprintf(stderr, "bad interval\n"); + return 1; + } + err = br_set_time(argv[1], "multicast_querier_interval", &tv); + if (err) + fprintf(stderr, "set multicast querier interval failed: %s\n", + strerror(err)); + + return err != 0; +} + +static int br_cmd_setmcqi(int argc, char *const* argv) +{ + struct timeval tv; + int err; + + if (strtotimeval(&tv, argv[2])) { + fprintf(stderr, "bad interval\n"); + return 1; + } + err = br_set_time(argv[1], "multicast_query_interval", &tv); + if (err) + fprintf(stderr, "set multicast query interval failed: %s\n", + strerror(err)); + + return err != 0; +} + +static int br_cmd_setmcqri(int argc, char *const* argv) +{ + struct timeval tv; + int err; + + if (strtotimeval(&tv, argv[2])) { + fprintf(stderr, "bad interval\n"); + return 1; + } + err = br_set_time(argv[1], "multicast_query_response_interval", &tv); + if (err) + fprintf(stderr, "set multicast query response interval " + "failed: %s\n", strerror(err)); + + return err != 0; +} + +static int br_cmd_setmcsqi(int argc, char *const* argv) +{ + struct timeval tv; + int err; + + if (strtotimeval(&tv, argv[2])) { + fprintf(stderr, "bad interval\n"); + return 1; + } + err = br_set_time(argv[1], "multicast_startup_query_interval", &tv); + if (err) + fprintf(stderr, "set multicast startup query interval " + "failed: %s\n", strerror(err)); + + return err != 0; +} + static int br_cmd_setpathcost(int argc, char *const* argv) { int cost, err; @@ -280,6 +483,24 @@ static int br_cmd_setportprio(int argc, return err != 0; } +static int br_cmd_setportmcrouter(int argc, char *const* argv) +{ + int router; + int err; + + if (sscanf(argv[3], "%i", &router) != 1) { + fprintf(stderr, "bad router\n"); + return 1; + } + + err = br_set_port_mcrouter(argv[1], argv[2], router); + if (err) + fprintf(stderr, "set port multicast router failed: %s\n", + strerror(errno)); + + return err != 0; +} + static int br_cmd_stp(int argc, char *const* argv) { int stp, err; @@ -412,10 +633,36 @@ static const struct command commands[] = "<bridge> <time>\t\tset hello time" }, { 2, "setmaxage", br_cmd_setmaxage, "<bridge> <time>\t\tset max message age" }, + { 2, "sethashel", br_cmd_sethashel, + "<bridge> <int>\t\tset hash elasticity" }, + { 2, "sethashmax", br_cmd_sethashmax, + "<bridge> <int>\t\tset hash max" }, + { 2, "setmclmc", br_cmd_setmclmc, + "<bridge> <int>\t\tset multicast last member count" }, + { 2, "setmcrouter", br_cmd_setmcrouter, + "<bridge> <int>\t\tset multicast router" }, + { 2, "setmcsnoop", br_cmd_setmcsnoop, + "<bridge> <int>\t\tset multicast snooping" }, + { 2, "setmcsqc", br_cmd_setmcsqc, + "<bridge> <int>\t\tset multicast startup query count" }, + { 2, "setmclmi", br_cmd_setmclmi, + "<bridge> <time>\t\tset multicast last member interval" }, + { 2, "setmcmi", br_cmd_setmcmi, + "<bridge> <time>\t\tset multicast membership interval" }, + { 2, "setmcqpi", br_cmd_setmcqpi, + "<bridge> <time>\t\tset multicast querier interval" }, + { 2, "setmcqi", br_cmd_setmcqi, + "<bridge> <time>\t\tset multicast query interval" }, + { 2, "setmcqri", br_cmd_setmcqri, + "<bridge> <time>\t\tset multicast query response interval" }, + { 2, "setmcqri", br_cmd_setmcsqi, + "<bridge> <time>\t\tset multicast startup query interval" }, { 3, "setpathcost", br_cmd_setpathcost, "<bridge> <port> <cost>\tset path cost" }, { 3, "setportprio", br_cmd_setportprio, "<bridge> <port> <prio>\tset port priority" }, + { 3, "setportmcrouter", br_cmd_setportmcrouter, + "<bridge> <port> <int>\tset port multicast router" }, { 0, "show", br_cmd_show, "\t\t\tshow a list of bridges" }, { 1, "showmacs", br_cmd_showmacs, "<bridge>\t\tshow a list of mac addrs"}, diff -up bridge-utils-1.1/brctl/brctl_disp.c.igmp-snoping bridge-utils-1.1/brctl/brctl_disp.c --- bridge-utils-1.1/brctl/brctl_disp.c.igmp-snoping 2004-06-08 17:57:46.000000000 +0200 +++ bridge-utils-1.1/brctl/brctl_disp.c 2011-06-01 15:06:12.000000000 +0200 @@ -88,6 +88,7 @@ static int dump_port_info(const char *br printf("\n designated cost\t%4i", pinfo.designated_cost); printf("\t\t\thold timer\t\t"); br_show_timer(&pinfo.hold_timer_value); + printf("\n mc router\t\t%4i", pinfo.multicast_router); printf("\n flags\t\t\t"); if (pinfo.config_pending) printf("CONFIG_PENDING "); @@ -131,6 +132,26 @@ void br_dump_info(const char *br, const br_show_timer(&bri->topology_change_timer_value); printf("\t\t\tgc timer\t\t"); br_show_timer(&bri->gc_timer_value); + printf("\n hash elasticity\t%4i", bri->hash_elasticity); + printf("\t\t\thash max\t\t%4i", bri->hash_max); + printf("\n mc last member count\t%4i", + bri->multicast_last_member_count); + printf("\t\t\tmc init query count\t%4i", + bri->multicast_startup_query_count); + printf("\n mc router\t\t%4i", bri->multicast_router); + printf("\t\t\tmc snooping\t\t%4i", bri->multicast_snooping); + printf("\n mc last member timer\t"); + br_show_timer(&bri->multicast_last_member_interval); + printf("\t\t\tmc membership timer\t"); + br_show_timer(&bri->multicast_membership_interval); + printf("\n mc querier timer\t"); + br_show_timer(&bri->multicast_querier_interval); + printf("\t\t\tmc query interval\t"); + br_show_timer(&bri->multicast_query_interval); + printf("\n mc response interval\t"); + br_show_timer(&bri->multicast_query_response_interval); + printf("\t\t\tmc init query interval\t"); + br_show_timer(&bri->multicast_startup_query_interval); printf("\n flags\t\t\t"); if (bri->topology_change) printf("TOPOLOGY_CHANGE "); diff -up bridge-utils-1.1/libbridge/libbridge_devif.c.igmp-snoping bridge-utils-1.1/libbridge/libbridge_devif.c --- bridge-utils-1.1/libbridge/libbridge_devif.c.igmp-snoping 2011-06-01 15:06:12.000000000 +0200 +++ bridge-utils-1.1/libbridge/libbridge_devif.c 2011-06-01 15:09:39.000000000 +0200 @@ -214,6 +214,28 @@ int br_get_bridge_info(const char *bridg info->topology_change_detected = fetch_int(dev, BRIDGEATTR("topology_change_detected")); + info->hash_elasticity = fetch_int(dev, BRIDGEATTR("hash_elasticity")); + info->hash_max = fetch_int(dev, BRIDGEATTR("hash_max")); + info->multicast_last_member_count = + fetch_int(dev, BRIDGEATTR("multicast_last_member_count")); + info->multicast_router = fetch_int(dev, BRIDGEATTR("multicast_router")); + info->multicast_snooping = fetch_int(dev, BRIDGEATTR("multicast_snooping")); + info->multicast_startup_query_count = + fetch_int(dev, BRIDGEATTR("multicast_startup_query_count")); + + fetch_tv(dev, BRIDGEATTR("multicast_last_member_interval"), + &info->multicast_last_member_interval); + fetch_tv(dev, BRIDGEATTR("multicast_membership_interval"), + &info->multicast_membership_interval); + fetch_tv(dev, BRIDGEATTR("multicast_querier_interval"), + &info->multicast_querier_interval); + fetch_tv(dev, BRIDGEATTR("multicast_query_interval"), + &info->multicast_query_interval); + fetch_tv(dev, BRIDGEATTR("multicast_query_response_interval"), + &info->multicast_query_response_interval); + fetch_tv(dev, BRIDGEATTR("multicast_startup_query_interval"), + &info->multicast_startup_query_interval); + return 0; fallback: @@ -306,6 +328,7 @@ int br_get_port_info(const char *brname, &info->forward_delay_timer_value); fetch_tv(dev, BRPORT("hold_timer"), &info->hold_timer_value); + info->multicast_router = fetch_int(dev, BRIDGEATTR("multicast_router")); return 0; fallback: @@ -314,8 +337,8 @@ fallback: } -static int br_set(const char *bridge, const char *name, - unsigned long value, unsigned long oldcode) +int br_set(const char *bridge, const char *name, + unsigned long value, unsigned long oldcode) { int ret = -1; #ifdef HAVE_LIBSYSFS @@ -337,18 +360,24 @@ static int br_set(const char *bridge, co } } else #endif - { + if (oldcode) { struct ifreq ifr; unsigned long args[4] = { oldcode, value, 0, 0 }; strncpy(ifr.ifr_name, bridge, IFNAMSIZ); ifr.ifr_data = (char *) &args; ret = ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr); - } + } else + return ENOSYS; return ret < 0 ? errno : 0; } +int br_set_time(const char *br, const char *name, struct timeval *tv) +{ + return br_set(br, name, __tv_to_jiffies(tv), 0); +} + int br_set_bridge_forward_delay(const char *br, struct timeval *tv) { return br_set(br, "forward_delay", __tv_to_jiffies(tv), @@ -408,7 +437,7 @@ static int port_set(const char *bridge, } } else #endif - { + if (oldcode) { int index = get_portno(bridge, ifname); if (index < 0) @@ -421,7 +450,8 @@ static int port_set(const char *bridge, ifr.ifr_data = (char *) &args; ret = ioctl(br_socket_fd, SIOCDEVPRIVATE, &ifr); } - } + } else + return ENOSYS; return ret < 0 ? errno : 0; } @@ -431,6 +461,11 @@ int br_set_port_priority(const char *bri return port_set(bridge, port, "priority", priority, BRCTL_SET_PORT_PRIORITY); } +int br_set_port_mcrouter(const char *bridge, const char *port, int value) +{ + return port_set(bridge, port, "multicast_router", value, 0); +} + int br_set_path_cost(const char *bridge, const char *port, int cost) { return port_set(bridge, port, "path_cost", cost, BRCTL_SET_PATH_COST); diff -up bridge-utils-1.1/libbridge/libbridge.h.igmp-snoping bridge-utils-1.1/libbridge/libbridge.h --- bridge-utils-1.1/libbridge/libbridge.h.igmp-snoping 2004-06-08 17:57:49.000000000 +0200 +++ bridge-utils-1.1/libbridge/libbridge.h 2011-06-01 15:06:12.000000000 +0200 @@ -33,6 +33,10 @@ struct bridge_info struct bridge_id designated_root; struct bridge_id bridge_id; unsigned root_path_cost; + unsigned hash_elasticity; + unsigned hash_max; + unsigned multicast_last_member_count; + unsigned multicast_startup_query_count; struct timeval max_age; struct timeval hello_time; struct timeval forward_delay; @@ -43,11 +47,19 @@ struct bridge_info unsigned char stp_enabled; unsigned char topology_change; unsigned char topology_change_detected; + unsigned char multicast_router; + unsigned char multicast_snooping; struct timeval ageing_time; struct timeval hello_timer_value; struct timeval tcn_timer_value; struct timeval topology_change_timer_value; struct timeval gc_timer_value; + struct timeval multicast_last_member_interval; + struct timeval multicast_membership_interval; + struct timeval multicast_querier_interval; + struct timeval multicast_query_interval; + struct timeval multicast_query_response_interval; + struct timeval multicast_startup_query_interval; }; struct fdb_entry @@ -69,6 +81,7 @@ struct port_info unsigned char top_change_ack; unsigned char config_pending; unsigned char state; + unsigned char multicast_router; unsigned path_cost; unsigned designated_cost; struct timeval message_age_timer_value; @@ -95,6 +108,9 @@ extern int br_add_bridge(const char *brn extern int br_del_bridge(const char *brname); extern int br_add_interface(const char *br, const char *dev); extern int br_del_interface(const char *br, const char *dev); +extern int br_set(const char *bridge, const char *name, + unsigned long value, unsigned long oldcode); +extern int br_set_time(const char *br, const char *name, struct timeval *tv); extern int br_set_bridge_forward_delay(const char *br, struct timeval *tv); extern int br_set_bridge_hello_time(const char *br, struct timeval *tv); extern int br_set_bridge_max_age(const char *br, struct timeval *tv); @@ -103,6 +119,8 @@ extern int br_set_stp_state(const char * extern int br_set_bridge_priority(const char *br, int bridge_priority); extern int br_set_port_priority(const char *br, const char *p, int port_priority); +extern int br_set_port_mcrouter(const char *bridge, const char *port, + int value); extern int br_set_path_cost(const char *br, const char *p, int path_cost); extern int br_read_fdb(const char *br, struct fdb_entry *fdbs,