diff --git a/ip/ip_common.h b/ip/ip_common.h index 9a846df3..815487a0 100644 --- a/ip/ip_common.h +++ b/ip/ip_common.h @@ -87,6 +87,8 @@ struct link_util struct link_util *get_link_kind(const char *kind); struct link_util *get_link_slave_kind(const char *slave_kind); +void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len); + #ifndef INFINITY_LIFE_TIME #define INFINITY_LIFE_TIME 0xFFFFFFFFU #endif diff --git a/ip/iplink_bridge.c b/ip/iplink_bridge.c index 1b666f0a..79f15eff 100644 --- a/ip/iplink_bridge.c +++ b/ip/iplink_bridge.c @@ -60,8 +60,7 @@ static void explain(void) print_explain(stderr); } -static void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, - size_t len) +void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len) { char eaddr[32]; diff --git a/ip/iplink_bridge_slave.c b/ip/iplink_bridge_slave.c index 4593872e..3ec2bba7 100644 --- a/ip/iplink_bridge_slave.c +++ b/ip/iplink_bridge_slave.c @@ -29,6 +29,10 @@ static void print_explain(FILE *f) " [ root_block {on | off} ]\n" " [ learning {on | off} ]\n" " [ flood {on | off} ]\n" + " [ proxy_arp {on | off} ]\n" + " [ proxy_arp_wifi {on | off} ]\n" + " [ mcast_router MULTICAST_ROUTER ]\n" + " [ mcast_fast_leave {on | off} ]\n" ); } @@ -98,6 +102,91 @@ static void bridge_slave_print_opt(struct link_util *lu, FILE *f, if (tb[IFLA_BRPORT_UNICAST_FLOOD]) print_onoff(f, "flood", rta_getattr_u8(tb[IFLA_BRPORT_UNICAST_FLOOD])); + + if (tb[IFLA_BRPORT_ID]) + fprintf(f, "port_id 0x%x ", + rta_getattr_u16(tb[IFLA_BRPORT_ID])); + + if (tb[IFLA_BRPORT_NO]) + fprintf(f, "port_no 0x%x ", + rta_getattr_u16(tb[IFLA_BRPORT_NO])); + + if (tb[IFLA_BRPORT_DESIGNATED_PORT]) + fprintf(f, "designated_port %u ", + rta_getattr_u16(tb[IFLA_BRPORT_DESIGNATED_PORT])); + + if (tb[IFLA_BRPORT_DESIGNATED_COST]) + fprintf(f, "designated_cost %u ", + rta_getattr_u16(tb[IFLA_BRPORT_DESIGNATED_COST])); + + if (tb[IFLA_BRPORT_BRIDGE_ID]) { + char bridge_id[32]; + + br_dump_bridge_id(RTA_DATA(tb[IFLA_BRPORT_BRIDGE_ID]), + bridge_id, sizeof(bridge_id)); + fprintf(f, "designated_bridge %s ", bridge_id); + } + + if (tb[IFLA_BRPORT_ROOT_ID]) { + char root_id[32]; + + br_dump_bridge_id(RTA_DATA(tb[IFLA_BRPORT_ROOT_ID]), + root_id, sizeof(root_id)); + fprintf(f, "designated_root %s ", root_id); + } + + if (tb[IFLA_BRPORT_HOLD_TIMER]) { + struct timeval tv; + __u64 htimer; + + htimer = rta_getattr_u64(tb[IFLA_BRPORT_HOLD_TIMER]); + __jiffies_to_tv(&tv, htimer); + fprintf(f, "hold_timer %4i.%.2i ", (int)tv.tv_sec, + (int)tv.tv_usec/10000); + } + + if (tb[IFLA_BRPORT_MESSAGE_AGE_TIMER]) { + struct timeval tv; + __u64 agetimer; + + agetimer = rta_getattr_u64(tb[IFLA_BRPORT_MESSAGE_AGE_TIMER]); + __jiffies_to_tv(&tv, agetimer); + fprintf(f, "message_age_timer %4i.%.2i ", (int)tv.tv_sec, + (int)tv.tv_usec/10000); + } + + if (tb[IFLA_BRPORT_FORWARD_DELAY_TIMER]) { + struct timeval tv; + __u64 fwdtimer; + + fwdtimer = rta_getattr_u64(tb[IFLA_BRPORT_FORWARD_DELAY_TIMER]); + __jiffies_to_tv(&tv, fwdtimer); + fprintf(f, "forward_delay_timer %4i.%.2i ", (int)tv.tv_sec, + (int)tv.tv_usec/10000); + } + + if (tb[IFLA_BRPORT_TOPOLOGY_CHANGE_ACK]) + fprintf(f, "topology_change_ack %u ", + rta_getattr_u8(tb[IFLA_BRPORT_TOPOLOGY_CHANGE_ACK])); + + if (tb[IFLA_BRPORT_CONFIG_PENDING]) + fprintf(f, "config_pending %u ", + rta_getattr_u8(tb[IFLA_BRPORT_CONFIG_PENDING])); + if (tb[IFLA_BRPORT_PROXYARP]) + print_onoff(f, "proxy_arp", + rta_getattr_u8(tb[IFLA_BRPORT_PROXYARP])); + + if (tb[IFLA_BRPORT_PROXYARP_WIFI]) + print_onoff(f, "proxy_arp_wifi", + rta_getattr_u8(tb[IFLA_BRPORT_PROXYARP_WIFI])); + + if (tb[IFLA_BRPORT_MULTICAST_ROUTER]) + fprintf(f, "mcast_router %u ", + rta_getattr_u8(tb[IFLA_BRPORT_MULTICAST_ROUTER])); + + if (tb[IFLA_BRPORT_FAST_LEAVE]) + print_onoff(f, "mcast_fast_leave", + rta_getattr_u8(tb[IFLA_BRPORT_FAST_LEAVE])); } static void bridge_slave_parse_on_off(char *arg_name, char *arg_val, @@ -162,6 +251,26 @@ static int bridge_slave_parse_opt(struct link_util *lu, int argc, char **argv, NEXT_ARG(); bridge_slave_parse_on_off("flood", *argv, n, IFLA_BRPORT_UNICAST_FLOOD); + } else if (matches(*argv, "proxy_arp") == 0) { + NEXT_ARG(); + bridge_slave_parse_on_off("proxy_arp", *argv, n, + IFLA_BRPORT_PROXYARP); + } else if (matches(*argv, "proxy_arp_wifi") == 0) { + NEXT_ARG(); + bridge_slave_parse_on_off("proxy_arp_wifi", *argv, n, + IFLA_BRPORT_PROXYARP_WIFI); + } else if (matches(*argv, "mcast_router") == 0) { + __u8 mcast_router; + + NEXT_ARG(); + if (get_u8(&mcast_router, *argv, 0)) + invarg("invalid mcast_router", *argv); + addattr8(n, 1024, IFLA_BRPORT_MULTICAST_ROUTER, + mcast_router); + } else if (matches(*argv, "mcast_fast_leave") == 0) { + NEXT_ARG(); + bridge_slave_parse_on_off("mcast_fast_leave", *argv, n, + IFLA_BRPORT_FAST_LEAVE); } else if (matches(*argv, "help") == 0) { explain(); return -1; diff --git a/tc/q_htb.c b/tc/q_htb.c index 7075a4c0..7d540908 100644 --- a/tc/q_htb.c +++ b/tc/q_htb.c @@ -274,7 +274,6 @@ static int htb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) SPRINT_BUF(b1); SPRINT_BUF(b2); SPRINT_BUF(b3); - SPRINT_BUF(b4); if (opt == NULL) return 0; @@ -311,18 +310,16 @@ static int htb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) cbuffer = tc_calc_xmitsize(ceil64, hopt->cbuffer); linklayer = (hopt->rate.linklayer & TC_LINKLAYER_MASK); if (linklayer > TC_LINKLAYER_ETHERNET || show_details) - fprintf(f, "linklayer %s ", sprint_linklayer(linklayer, b4)); + fprintf(f, "linklayer %s ", sprint_linklayer(linklayer, b3)); if (show_details) { - fprintf(f, "burst %s/%u mpu %s overhead %s ", + fprintf(f, "burst %s/%u mpu %s ", sprint_size(buffer, b1), 1<rate.cell_log, - sprint_size(hopt->rate.mpu&0xFF, b2), - sprint_size((hopt->rate.mpu>>8)&0xFF, b3)); - fprintf(f, "cburst %s/%u mpu %s overhead %s ", + sprint_size(hopt->rate.mpu, b2)); + fprintf(f, "cburst %s/%u mpu %s ", sprint_size(cbuffer, b1), 1<ceil.cell_log, - sprint_size(hopt->ceil.mpu&0xFF, b2), - sprint_size((hopt->ceil.mpu>>8)&0xFF, b3)); + sprint_size(hopt->ceil.mpu, b2)); fprintf(f, "level %d ", (int)hopt->level); } else { fprintf(f, "burst %s ", sprint_size(buffer, b1));