1 /* 2 * iplink_bond_slave.c Bonding slave device support 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 * 9 * Authors: Jiri Pirko <jiri (at) resnulli.us> 10 */ 11 12 #include <stdio.h> 13 #include <sys/socket.h> 14 #include <linux/if_bonding.h> 15 16 #include "rt_names.h" 17 #include "utils.h" 18 #include "ip_common.h" 19 20 static void print_explain(FILE *f) 21 { 22 fprintf(f, "Usage: ... bond_slave [ queue_id ID ]\n"); 23 } 24 25 static void explain(void) 26 { 27 print_explain(stderr); 28 } 29 30 static const char *slave_states[] = { 31 [BOND_STATE_ACTIVE] = "ACTIVE", 32 [BOND_STATE_BACKUP] = "BACKUP", 33 }; 34 35 static void print_slave_state(FILE *f, struct rtattr *tb) 36 { 37 unsigned int state = rta_getattr_u8(tb); 38 39 if (state >= ARRAY_SIZE(slave_states)) 40 print_int(PRINT_ANY, "state_index", "state %d ", state); 41 else 42 print_string(PRINT_ANY, 43 "state", 44 "state %s ", 45 slave_states[state]); 46 } 47 48 static const char *slave_mii_status[] = { 49 [BOND_LINK_UP] = "UP", 50 [BOND_LINK_FAIL] = "GOING_DOWN", 51 [BOND_LINK_DOWN] = "DOWN", 52 [BOND_LINK_BACK] = "GOING_BACK", 53 }; 54 55 static void print_slave_mii_status(FILE *f, struct rtattr *tb) 56 { 57 unsigned int status = rta_getattr_u8(tb); 58 59 if (status >= ARRAY_SIZE(slave_mii_status)) 60 print_int(PRINT_ANY, 61 "mii_status_index", 62 "mii_status %d ", 63 status); 64 else 65 print_string(PRINT_ANY, 66 "mii_status", 67 "mii_status %s ", 68 slave_mii_status[status]); 69 } 70 71 static void bond_slave_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) 72 { 73 SPRINT_BUF(b1); 74 if (!tb) 75 return; 76 77 if (tb[IFLA_BOND_SLAVE_STATE]) 78 print_slave_state(f, tb[IFLA_BOND_SLAVE_STATE]); 79 80 if (tb[IFLA_BOND_SLAVE_MII_STATUS]) 81 print_slave_mii_status(f, tb[IFLA_BOND_SLAVE_MII_STATUS]); 82 83 if (tb[IFLA_BOND_SLAVE_LINK_FAILURE_COUNT]) 84 print_int(PRINT_ANY, 85 "link_failure_count", 86 "link_failure_count %d ", 87 rta_getattr_u32(tb[IFLA_BOND_SLAVE_LINK_FAILURE_COUNT])); 88 89 if (tb[IFLA_BOND_SLAVE_PERM_HWADDR]) 90 print_string(PRINT_ANY, 91 "perm_hwaddr", 92 "perm_hwaddr %s ", 93 ll_addr_n2a(RTA_DATA(tb[IFLA_BOND_SLAVE_PERM_HWADDR]), 94 RTA_PAYLOAD(tb[IFLA_BOND_SLAVE_PERM_HWADDR]), 95 0, b1, sizeof(b1))); 96 97 if (tb[IFLA_BOND_SLAVE_QUEUE_ID]) 98 print_int(PRINT_ANY, 99 "queue_id", 100 "queue_id %d ", 101 rta_getattr_u16(tb[IFLA_BOND_SLAVE_QUEUE_ID])); 102 103 if (tb[IFLA_BOND_SLAVE_AD_AGGREGATOR_ID]) 104 print_int(PRINT_ANY, 105 "ad_aggregator_id", 106 "ad_aggregator_id %d ", 107 rta_getattr_u16(tb[IFLA_BOND_SLAVE_AD_AGGREGATOR_ID])); 108 109 if (tb[IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE]) 110 print_int(PRINT_ANY, 111 "ad_actor_oper_port_state", 112 "ad_actor_oper_port_state %d ", 113 rta_getattr_u8(tb[IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE])); 114 115 if (tb[IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE]) 116 print_int(PRINT_ANY, 117 "ad_partner_oper_port_state", 118 "ad_partner_oper_port_state %d ", 119 rta_getattr_u16(tb[IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE])); 120 } 121 122 static int bond_slave_parse_opt(struct link_util *lu, int argc, char **argv, 123 struct nlmsghdr *n) 124 { 125 __u16 queue_id; 126 127 while (argc > 0) { 128 if (matches(*argv, "queue_id") == 0) { 129 NEXT_ARG(); 130 if (get_u16(&queue_id, *argv, 0)) 131 invarg("queue_id is invalid", *argv); 132 addattr16(n, 1024, IFLA_BOND_SLAVE_QUEUE_ID, queue_id); 133 } else { 134 if (matches(*argv, "help") != 0) 135 fprintf(stderr, 136 "bond_slave: unknown option \"%s\"?\n", 137 *argv); 138 explain(); 139 return -1; 140 } 141 argc--, argv++; 142 } 143 144 return 0; 145 } 146 147 static void bond_slave_print_help(struct link_util *lu, int argc, char **argv, 148 FILE *f) 149 { 150 print_explain(f); 151 } 152 153 struct link_util bond_slave_link_util = { 154 .id = "bond_slave", 155 .maxattr = IFLA_BOND_SLAVE_MAX, 156 .print_opt = bond_slave_print_opt, 157 .parse_opt = bond_slave_parse_opt, 158 .print_help = bond_slave_print_help, 159 }; 160