void dont_advertise_dcbx_all(char *ifname, bool ad) { int i, is_pfc; pfc_attribs pfc_data; pg_attribs pg_data; app_attribs app_data; llink_attribs llink_data; u32 event_flag = 0; is_pfc = get_pfc(ifname, &pfc_data); if (get_pg(ifname, &pg_data) == cmd_success) { pg_data.protocol.Advertise = ad; put_pg(ifname, &pg_data, &pfc_data); event_flag |= DCB_LOCAL_CHANGE_PG; } if (is_pfc == cmd_success) { pfc_data.protocol.Advertise = ad; put_pfc(ifname, &pfc_data); event_flag |= DCB_LOCAL_CHANGE_PFC; } for (i = 0; i < DCB_MAX_APPTLV ; i++) { if (get_app(ifname, (u32)i, &app_data) == cmd_success) { app_data.protocol.Advertise = ad; put_app(ifname, (u32)i, &app_data); event_flag |= DCB_LOCAL_CHANGE_APPTLV(i); } } for (i = 0; i < DCB_MAX_LLKTLV ; i++) { if (get_llink(ifname, (u32)i, &llink_data) == cmd_success) { llink_data.protocol.Advertise = ad; put_llink(ifname, (u32)i, &llink_data); event_flag |= DCB_LOCAL_CHANGE_LLINK; } } }
int dcbx_clif_cmd(UNUSED void *data, UNUSED struct sockaddr_un *from, UNUSED socklen_t fromlen, char *ibuf, int ilen, char *rbuf, int rlen) { u8 status = cmd_success; u8 cmd; u8 feature; u8 subtype; u8 plen; char port_id[MAX_U8_BUF]; pg_attribs pg_data; pfc_attribs pfc_data; app_attribs app_data; llink_attribs llink_data; struct dcbx_tlvs *dcbx; int dcb_enable; if (hexstr2bin(ibuf+DCB_CMD_OFF, &cmd, sizeof(cmd)) || hexstr2bin(ibuf+DCB_FEATURE_OFF, &feature, sizeof(feature))) return cmd_invalid; if (feature == FEATURE_DCBX) return handle_dcbx_cmd(cmd, feature, ibuf, ilen, rbuf); if (hexstr2bin(ibuf+DCB_SUBTYPE_OFF, &subtype, sizeof(subtype)) || hexstr2bin(ibuf+DCB_PORTLEN_OFF, &plen, sizeof(plen))) return cmd_invalid; if (ilen < DCB_PORT_OFF) return cmd_invalid; if (ibuf[DCB_VER_OFF] < (CLIF_DCBMSG_VERSION | 0x30)) { printf("unsupported client interface message version %x %x\n", ibuf[DCB_VER_OFF], CLIF_DCBMSG_VERSION | 0x30); return cmd_ctrl_vers_not_compatible; } if (ilen < DCB_PORT_OFF+plen) { printf("command too short\n"); return cmd_invalid; } /* append standard dcb command response content */ snprintf(rbuf , rlen, "%*.*s", DCB_PORT_OFF+plen, DCB_PORT_OFF+plen, ibuf); memcpy(port_id, ibuf+DCB_PORT_OFF, plen); port_id[plen] = '\0'; if (get_hw_state(port_id, &dcb_enable) < 0) return cmd_not_capable; dcbx = dcbx_data(port_id); /* OPER and PEER cmd not applicable while in IEEE-DCBX modes */ if ((!dcbx || dcbx->active == 0) && (cmd == CMD_GET_PEER || cmd == CMD_GET_OPER)) return cmd_not_applicable; switch(feature) { case FEATURE_DCB: if (cmd == CMD_SET_CONFIG) status = set_dcb_state(port_id, ibuf, ilen); else if (cmd == CMD_GET_CONFIG) status = get_dcb_state(port_id, rbuf+strlen(rbuf)); else status = cmd_invalid; break; case FEATURE_PG: if (cmd == CMD_GET_PEER) { status = get_peer_pg(port_id, &pg_data); } else { status = get_pg(port_id, &pg_data); } if (status != cmd_success) { printf("error[%d] getting PG data for %s\n", status, port_id); return status; } if (cmd == CMD_SET_CONFIG) { if (ilen < (DCB_PORT_OFF + plen + CFG_LEN)) { printf("set command too short\n"); status = cmd_invalid; } else { set_protocol_data(&pg_data.protocol, port_id, ibuf, plen, NEAREST_BRIDGE); status = set_pg_config(&pg_data, port_id, ibuf, ilen); } } else { status = get_cmd_protocol_data(&pg_data.protocol, cmd, rbuf+strlen(rbuf)); if (status == cmd_success) status = get_pg_data(&pg_data, cmd, port_id, pg_data.protocol.dcbx_st, rbuf+strlen(rbuf)); } break; case FEATURE_PFC: if (cmd == CMD_GET_PEER) { status = get_peer_pfc(port_id, &pfc_data); } else { status = get_pfc(port_id, &pfc_data); } if (status != cmd_success) { printf("error[%d] getting PFC data for %s\n", status, port_id); return status; } if (cmd == CMD_SET_CONFIG) { if (ilen < (DCB_PORT_OFF + plen + CFG_LEN)) { printf("set command too short\n"); status = cmd_failed; } else { set_protocol_data(&pfc_data.protocol, port_id, ibuf, plen, NEAREST_BRIDGE); status = set_pfc_config(&pfc_data, port_id, ibuf, ilen); } } else { status = get_cmd_protocol_data(&pfc_data.protocol, cmd, rbuf+strlen(rbuf)); if (status == cmd_success) status = get_pfc_data(&pfc_data, cmd, port_id, pfc_data.protocol.dcbx_st, rbuf+strlen(rbuf)); } break; case FEATURE_APP: if (cmd == CMD_GET_PEER) { status = get_peer_app(port_id, (u32)subtype, &app_data); } else { status = get_app(port_id, (u32)subtype, &app_data); } if (status != cmd_success) { printf("error[%d] getting APP data for %s\n", status, port_id); return status; } if (cmd == CMD_SET_CONFIG) { if (ilen < (DCB_PORT_OFF + plen + CFG_LEN)) { printf("set command too short\n"); status = cmd_failed; } else { set_app_protocol_data(port_id, ibuf, plen, ilen, subtype, NEAREST_BRIDGE); } } else { status = get_cmd_protocol_data(&app_data.protocol, cmd, rbuf+strlen(rbuf)); if (status == cmd_success) status = get_app_data(&app_data, cmd, port_id, subtype, rbuf + strlen(rbuf)); } break; case FEATURE_LLINK: if (cmd == CMD_GET_PEER) { status = get_peer_llink(port_id, (u32)subtype, &llink_data); } else { status = get_llink(port_id, (u32)subtype, &llink_data); } if (status != cmd_success) { printf("error[%d] getting APP data for %s\n", status, port_id); return status; } if (cmd == CMD_SET_CONFIG) { if (ilen < (DCB_PORT_OFF + plen + CFG_LEN)) { printf("set command too short\n"); status = cmd_failed; } else { set_protocol_data(&llink_data.protocol, port_id, ibuf, plen, NEAREST_BRIDGE); status = set_llink_config(&llink_data, port_id, (u32)subtype, ibuf, ilen); } } else { status = get_cmd_protocol_data(&llink_data.protocol, cmd, rbuf+strlen(rbuf)); if (status == cmd_success) status = get_llink_data(&llink_data, cmd, port_id, subtype, rbuf + strlen(rbuf)); } break; case FEATURE_PG_DESC: if (cmd == CMD_GET_CONFIG) { status = get_bwg_desc(port_id, ibuf, ilen, rbuf+strlen(rbuf)); if (status != cmd_success) { printf("error[%d] getting BWG desc for %s\n", status, port_id); return status; } } else if (cmd == CMD_SET_CONFIG) { status = set_bwg_desc(port_id, ibuf, ilen); } break; default: break; } return status; }
int main(int argc, char *argv[]) { struct tc_config tc[8]; int i, err = 0; int newstate = -1; int read_only = 0; __u8 state; __u8 pfc[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; __u8 bwg[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; __u8 mac[ETH_ALEN], san_mac[ETH_ALEN]; __u8 cap[DCB_CAP_ATTR_MAX+1]; __u8 numtcs; bcn_cfg bcn_set_data, bcn_data; #ifdef DCB_APP_DRV_IF_SUPPORTED appgroup_attribs app_data = {DCB_APP_IDTYPE_ETHTYPE, 0x8906, 0x08}; #endif /* DCB_APP_DRV_IF_SUPPORTED */ int ifindex; int optind = 1; char *ifname; printf("Calling RTNETLINK interface.\n"); if (argc < 2) { fprintf(stderr, "usage: %s [-v] <ifname> [on|off|ro]\n", argv[0]); exit(1); } if (argc > 2) { if (!strcmp(argv[1], "-v")) { hexdump = 1; optind++; } if (argc > optind + 1) { if (!strcmp(argv[optind + 1], "on")) newstate = 1; if (!strcmp(argv[optind + 1], "off")) newstate = 0; if (!strcmp(argv[optind + 1], "ro")) read_only = 1; } } ifname = argv[optind]; ifindex = if_nametoindex(ifname); if (ifindex == 0) { printf("no ifindex for %s\n", ifname); exit(1); } if ((nl_sd = init_socket()) < 0) { fprintf(stderr, "error creating netlink socket\n"); return nl_sd; } #ifdef DO_GETLINK_QUERY printf("DOING A GETLINK COMMAND\n"); nlh = start_msg(RTM_GETLINK, ifindex); if (nlh == NULL) exit(1); if (send_msg(nlh)) exit(1); free(nlh); nlh = get_msg(); #endif printf("GETTING DCB STATE\n"); err = get_state(ifname, &state); if (err) { fprintf(stderr, "Error getting DCB state\n"); goto err_main; } printf("DCB State = %d\n", state); if (newstate >= 0) { printf("\nSETTING DCB STATE TO: %d\n", newstate); err = set_state(ifname, newstate); if (err) goto err_main; err = get_state(ifname, &state); if (err) { fprintf(stderr, "Error getting DCB state\n"); goto err_main; } printf("New DCB State = %d\n", state); } printf("\nGETTING PFC CONFIGURATION\n"); for (i=0; i<8; i++) pfc[i] = 0x0f; get_pfc_cfg(ifname, pfc); printf("PFC config:\n"); for (i=0; i<8; i++) printf("%x ", pfc[i]); printf("\n"); get_pfc_state(ifname, &state); if (err) { fprintf(stderr, "Error getting PFC status\n"); goto err_main; } printf("PFC State = %d\n", state); printf("\nGETTING PG TX CONFIGURATION\n"); get_pg(ifname, tc, bwg, DCB_CMD_PGTX_GCFG); for (i = 0; i < 8; i++) { printf("%d: pr=%d\tbwgid=%d\tbw%%=%d\tu2t=%d\tlk%%=%d\n", i, tc[i].prio_type, tc[i].bwg_id, tc[i].bwg_percent, tc[i].up_to_tc_bitmap, bwg[i]); tc[i].prio_type = 3; tc[i].bwg_id = i; tc[i].bwg_percent = 100; tc[i].up_to_tc_bitmap = i; bwg[i] = 12 + (i & 1); } printf("\nGETTING PG RX CONFIGURATION\n"); memset(bwg, 0, sizeof(bwg)); memset(&tc[0], 0, sizeof(tc)); get_pg(ifname, tc, bwg, DCB_CMD_PGRX_GCFG); for (i = 0; i < 8; i++) { printf("%d: pr=%d\tbwgid=%d\tbw%%=%d\tu2t=%d\tlk%%=%d\n", i, tc[i].prio_type, tc[i].bwg_id, tc[i].bwg_percent, tc[i].up_to_tc_bitmap, bwg[i]); } printf("\nGETTING PERMANENT MAC: "); get_perm_hwaddr(ifname, mac, san_mac); for (i = 0; i < 5; i++) printf("%02x:", mac[i]); printf("%02x\n", mac[i]); printf("\nGETTING SAN MAC: "); for (i = 0; i < 5; i++) printf("%02x:", san_mac[i]); printf("%02x\n", san_mac[i]); printf("\nGETTING DCB CAPABILITIES\n"); get_cap(ifname, &cap[0]); printf("\nGET NUMBER OF PG TCS\n"); if (!get_numtcs(ifname, DCB_NUMTCS_ATTR_PG, &numtcs)) printf("num = %d\n", numtcs); else printf("not found\n"); printf("\nGET NUMBER OF PFC TCS\n"); if (!get_numtcs(ifname, DCB_NUMTCS_ATTR_PFC, &numtcs)) printf("num = %d\n", numtcs); else printf("not found\n"); if (!read_only) { printf("\nTEST SET NUMBER OF PG TCS\n"); if (!set_numtcs(ifname, DCB_NUMTCS_ATTR_PG, numtcs)) printf("set passed\n"); else printf("error\n"); printf("\nTEST SET NUMBER OF PFC TCS\n"); if (!set_numtcs(ifname, DCB_NUMTCS_ATTR_PFC, numtcs)) printf("set passed\n"); else printf("error\n\n"); /* printf("set_pfc_cfg = %d\n", set_pfc_cfg(ifname, pfc)); */ /* printf("set_rx_pg = %d\n", set_pg(ifname, tc, bwg, DCB_CMD_PGRX_SCFG));*/ /* printf("set_hw_all = %d\n", set_hw_all(ifname)); */ err = set_hw_bcn(ifname, &bcn_set_data, 1); printf("set_bcn_cfg result is %d.\n", err); /*set_hw_all(ifname);*/ } printf("\nGETTING BCN:\n"); if (!get_bcn(ifname, &bcn_data)) { for (i = 0; i < 8; i++) { printf("BCN RP %d: %d\n", i, bcn_data.up_settings[i].rp_admin); } printf("\nBCN RP ALPHA: %f\n", bcn_data.rp_alpha); printf("BCN RP BETA : %f\n", bcn_data.rp_beta); printf("BCN RP GD : %f\n", bcn_data.rp_gd); printf("BCN RP GI : %f\n", bcn_data.rp_gi); printf("BCN RP TMAX : %d\n", bcn_data.rp_tmax); printf("BCN RP RI : %d\n", bcn_data.rp_ri); printf("BCN RP TD : %d\n", bcn_data.rp_td); printf("BCN RP RMIN : %d\n", bcn_data.rp_rmin); printf("BCN RP W : %d\n", bcn_data.rp_w); printf("BCN RP RD : %d\n", bcn_data.rp_rd); printf("BCN RP RU : %d\n", bcn_data.rp_ru); printf("BCN RP WRTT : %d\n", bcn_data.rp_wrtt); } else printf("not found\n"); #ifdef DCB_APP_DRV_IF_SUPPORTED if (!read_only) { printf("\nSETTING APP:\n"); if (set_hw_app0(ifname, &app_data)) { printf("Fail to set app data.\n"); goto err_main; } } printf("\nGETTING APP:\n"); if (!get_app_cfg(ifname, &app_data)) { printf("APP ID TYPE: "); if (app_data.dcb_app_idtype) printf(" \t DCB_APP_IDTYPE_ETHTYPE.\n"); else printf(" \t DCB_APP_IDTYPE_PORTNUM.\n"); printf(" APP ID: 0x%0x.\n", app_data.dcb_app_id); printf(" APP PRIORITY: 0x%0x.\n", app_data.dcb_app_priority); } else { printf("GETTING APP FAILED!.\n"); } #endif /* DCB_APP_DRV_IF_SUPPORTED */ if (!read_only) { struct ieee_ets ets = { .willing = 0, .ets_cap = 0x1, .cbs = 0, .tc_tx_bw = {25, 25, 25, 25, 0, 0, 0, 0}, .tc_rx_bw = {0, 0, 0, 0, 25, 25, 25, 25}, .tc_tsa = {1, 2, 3, 4, 1, 2, 3, 4}, .prio_tc = {1, 2, 3, 4, 1, 2, 3, 4} }; struct ieee_pfc pfc = { .pfc_cap = 0xf1, .pfc_en = 0, .mbc = 0, .delay = 0x32 }; struct dcb_app app = { .selector = 0, .priority = 4, .protocol = 0x8906 }; printf("\nSETTING ETS:\n"); set_ieee(ifname, &ets, &pfc, &app); } get_ieee(ifname); err_main: close(nl_sd); return err; }