15c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy/* 25c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy * iplink_vlan.c VLAN device support 35c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy * 45c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy * This program is free software; you can redistribute it and/or 55c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy * modify it under the terms of the GNU General Public License 65c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy * as published by the Free Software Foundation; either version 75c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy * 2 of the License, or (at your option) any later version. 85c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy * 95c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy * Authors: Patrick McHardy <kaber@trash.net> 105c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy */ 115c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 125c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy#include <stdio.h> 135c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy#include <stdlib.h> 145c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy#include <string.h> 155c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy#include <linux/if_vlan.h> 165c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 175c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy#include "rt_names.h" 185c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy#include "utils.h" 195c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy#include "ip_common.h" 205c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 21561e650eff679296d3f4c12657721ae769cbc187vadimkstatic void print_explain(FILE *f) 225c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy{ 23561e650eff679296d3f4c12657721ae769cbc187vadimk fprintf(f, 248b47135474cde4f0f8c9991741132b930bf3e192Phil Sutter "Usage: ... vlan id VLANID\n" 258b47135474cde4f0f8c9991741132b930bf3e192Phil Sutter " [ protocol VLANPROTO ]\n" 268b47135474cde4f0f8c9991741132b930bf3e192Phil Sutter " [ reorder_hdr { on | off } ]\n" 278b47135474cde4f0f8c9991741132b930bf3e192Phil Sutter " [ gvrp { on | off } ]\n" 288b47135474cde4f0f8c9991741132b930bf3e192Phil Sutter " [ mvrp { on | off } ]\n" 298b47135474cde4f0f8c9991741132b930bf3e192Phil Sutter " [ loose_binding { on | off } ]\n" 308b47135474cde4f0f8c9991741132b930bf3e192Phil Sutter " [ ingress-qos-map QOS-MAP ]\n" 318b47135474cde4f0f8c9991741132b930bf3e192Phil Sutter " [ egress-qos-map QOS-MAP ]\n" 325c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy "\n" 335c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy "VLANID := 0-4095\n" 348b47135474cde4f0f8c9991741132b930bf3e192Phil Sutter "VLANPROTO: [ 802.1Q / 802.1ad ]\n" 355c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy "QOS-MAP := [ QOS-MAP ] QOS-MAPPING\n" 365c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy "QOS-MAPPING := FROM:TO\n" 375c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy ); 385c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy} 395c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 40561e650eff679296d3f4c12657721ae769cbc187vadimkstatic void explain(void) 41561e650eff679296d3f4c12657721ae769cbc187vadimk{ 42561e650eff679296d3f4c12657721ae769cbc187vadimk print_explain(stderr); 43561e650eff679296d3f4c12657721ae769cbc187vadimk} 44561e650eff679296d3f4c12657721ae769cbc187vadimk 4514645ec2310ee7cf6d2f3d5035ac37ec09674e2cKees van Reeuwijkstatic int on_off(const char *msg, const char *arg) 465c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy{ 4714645ec2310ee7cf6d2f3d5035ac37ec09674e2cKees van Reeuwijk fprintf(stderr, "Error: argument of \"%s\" must be \"on\" or \"off\", not \"%s\"\n", msg, arg); 485c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy return -1; 495c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy} 505c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 515c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardystatic int vlan_parse_qos_map(int *argcp, char ***argvp, struct nlmsghdr *n, 525c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy int attrtype) 535c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy{ 545c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy int argc = *argcp; 555c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy char **argv = *argvp; 565c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy struct ifla_vlan_qos_mapping m; 575c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy struct rtattr *tail; 585c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 595c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy tail = NLMSG_TAIL(n); 605c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy addattr_l(n, 1024, attrtype, NULL, 0); 615c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 625c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy while (argc > 0) { 635c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy char *colon = strchr(*argv, ':'); 645c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 655c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy if (!colon) 665c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy break; 675c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy *colon = '\0'; 685c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 695c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy if (get_u32(&m.from, *argv, 0)) 705c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy return 1; 715c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy if (get_u32(&m.to, colon + 1, 0)) 725c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy return 1; 735c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy argc--, argv++; 745c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 755c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy addattr_l(n, 1024, IFLA_VLAN_QOS_MAPPING, &m, sizeof(m)); 765c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy } 775c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 785c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy tail->rta_len = (void *) NLMSG_TAIL(n) - (void *)tail; 795c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 805c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy *argcp = argc; 815c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy *argvp = argv; 825c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy return 0; 835c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy} 845c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 855c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardystatic int vlan_parse_opt(struct link_util *lu, int argc, char **argv, 865c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy struct nlmsghdr *n) 875c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy{ 885c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy struct ifla_vlan_flags flags = { 0 }; 898fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy __u16 id, proto; 905c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 915c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy while (argc > 0) { 928fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy if (matches(*argv, "protocol") == 0) { 938fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy NEXT_ARG(); 948fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy if (ll_proto_a2n(&proto, *argv)) 958fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy invarg("protocol is invalid", *argv); 968fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy addattr_l(n, 1024, IFLA_VLAN_PROTOCOL, &proto, 2); 978fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy } else if (matches(*argv, "id") == 0) { 985c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy NEXT_ARG(); 995c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy if (get_u16(&id, *argv, 0)) 1005c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy invarg("id is invalid", *argv); 1015c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy addattr_l(n, 1024, IFLA_VLAN_ID, &id, 2); 1025c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy } else if (matches(*argv, "reorder_hdr") == 0) { 1035c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy NEXT_ARG(); 1045c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy flags.mask |= VLAN_FLAG_REORDER_HDR; 1055c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy if (strcmp(*argv, "on") == 0) 1065c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy flags.flags |= VLAN_FLAG_REORDER_HDR; 1075c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy else if (strcmp(*argv, "off") == 0) 1085c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy flags.flags &= ~VLAN_FLAG_REORDER_HDR; 1095c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy else 11014645ec2310ee7cf6d2f3d5035ac37ec09674e2cKees van Reeuwijk return on_off("reorder_hdr", *argv); 11147420640687cbd389ddd99d39cf7fb0e0bcb265aPatrick McHardy } else if (matches(*argv, "gvrp") == 0) { 11247420640687cbd389ddd99d39cf7fb0e0bcb265aPatrick McHardy NEXT_ARG(); 11347420640687cbd389ddd99d39cf7fb0e0bcb265aPatrick McHardy flags.mask |= VLAN_FLAG_GVRP; 11447420640687cbd389ddd99d39cf7fb0e0bcb265aPatrick McHardy if (strcmp(*argv, "on") == 0) 11547420640687cbd389ddd99d39cf7fb0e0bcb265aPatrick McHardy flags.flags |= VLAN_FLAG_GVRP; 11647420640687cbd389ddd99d39cf7fb0e0bcb265aPatrick McHardy else if (strcmp(*argv, "off") == 0) 11747420640687cbd389ddd99d39cf7fb0e0bcb265aPatrick McHardy flags.flags &= ~VLAN_FLAG_GVRP; 11847420640687cbd389ddd99d39cf7fb0e0bcb265aPatrick McHardy else 11914645ec2310ee7cf6d2f3d5035ac37ec09674e2cKees van Reeuwijk return on_off("gvrp", *argv); 1204e9a686020b2ff4e391f685a53c91365d04a5e43David Ward } else if (matches(*argv, "mvrp") == 0) { 1214e9a686020b2ff4e391f685a53c91365d04a5e43David Ward NEXT_ARG(); 1224e9a686020b2ff4e391f685a53c91365d04a5e43David Ward flags.mask |= VLAN_FLAG_MVRP; 1234e9a686020b2ff4e391f685a53c91365d04a5e43David Ward if (strcmp(*argv, "on") == 0) 1244e9a686020b2ff4e391f685a53c91365d04a5e43David Ward flags.flags |= VLAN_FLAG_MVRP; 1254e9a686020b2ff4e391f685a53c91365d04a5e43David Ward else if (strcmp(*argv, "off") == 0) 1264e9a686020b2ff4e391f685a53c91365d04a5e43David Ward flags.flags &= ~VLAN_FLAG_MVRP; 1274e9a686020b2ff4e391f685a53c91365d04a5e43David Ward else 1284e9a686020b2ff4e391f685a53c91365d04a5e43David Ward return on_off("mvrp", *argv); 1292180b6b50bdc50e1a7740e5283930088da0bbae7Patrick McHardy } else if (matches(*argv, "loose_binding") == 0) { 1302180b6b50bdc50e1a7740e5283930088da0bbae7Patrick McHardy NEXT_ARG(); 1312180b6b50bdc50e1a7740e5283930088da0bbae7Patrick McHardy flags.mask |= VLAN_FLAG_LOOSE_BINDING; 1322180b6b50bdc50e1a7740e5283930088da0bbae7Patrick McHardy if (strcmp(*argv, "on") == 0) 1332180b6b50bdc50e1a7740e5283930088da0bbae7Patrick McHardy flags.flags |= VLAN_FLAG_LOOSE_BINDING; 1342180b6b50bdc50e1a7740e5283930088da0bbae7Patrick McHardy else if (strcmp(*argv, "off") == 0) 1352180b6b50bdc50e1a7740e5283930088da0bbae7Patrick McHardy flags.flags &= ~VLAN_FLAG_LOOSE_BINDING; 1362180b6b50bdc50e1a7740e5283930088da0bbae7Patrick McHardy else 13714645ec2310ee7cf6d2f3d5035ac37ec09674e2cKees van Reeuwijk return on_off("loose_binding", *argv); 1385c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy } else if (matches(*argv, "ingress-qos-map") == 0) { 1395c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy NEXT_ARG(); 1405c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy if (vlan_parse_qos_map(&argc, &argv, n, 1415c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy IFLA_VLAN_INGRESS_QOS)) 1425c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy invarg("invalid ingress-qos-map", *argv); 1435c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy continue; 1445c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy } else if (matches(*argv, "egress-qos-map") == 0) { 1455c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy NEXT_ARG(); 1465c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy if (vlan_parse_qos_map(&argc, &argv, n, 1475c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy IFLA_VLAN_EGRESS_QOS)) 1485c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy invarg("invalid egress-qos-map", *argv); 1495c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy continue; 1505c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy } else if (matches(*argv, "help") == 0) { 1515c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy explain(); 1525c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy return -1; 1535c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy } else { 15414645ec2310ee7cf6d2f3d5035ac37ec09674e2cKees van Reeuwijk fprintf(stderr, "vlan: unknown command \"%s\"?\n", *argv); 1555c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy explain(); 1565c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy return -1; 1575c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy } 1585c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy argc--, argv++; 1595c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy } 1605c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 1615c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy if (flags.mask) 1625c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy addattr_l(n, 1024, IFLA_VLAN_FLAGS, &flags, sizeof(flags)); 1635c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 1645c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy return 0; 1655c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy} 1665c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 16743bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortinstatic void vlan_print_map(FILE *f, 16843bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin const char *name_json, 16943bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin const char *name_fp, 17043bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin struct rtattr *attr) 1715c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy{ 1725c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy struct ifla_vlan_qos_mapping *m; 1735c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy struct rtattr *i; 1745c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy int rem; 1755c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 17643bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin open_json_array(PRINT_JSON, name_json); 17743bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin print_string(PRINT_FP, NULL, "\n %s { ", name_fp); 1785c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 1795c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy rem = RTA_PAYLOAD(attr); 1805c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy for (i = RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) { 1815c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy m = RTA_DATA(i); 18243bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin 18343bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin if (is_json_context()) { 18443bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin open_json_object(NULL); 18543bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin print_uint(PRINT_JSON, "from", NULL, m->from); 18643bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin print_uint(PRINT_JSON, "to", NULL, m->to); 18743bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin close_json_object(); 18843bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin } else { 18943bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin fprintf(f, "%u:%u ", m->from, m->to); 19043bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin } 1915c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy } 19243bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin 19343bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin close_json_array(PRINT_JSON, NULL); 19443bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin print_string(PRINT_FP, NULL, "%s ", "}"); 1955c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy} 1965c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 1975c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardystatic void vlan_print_flags(FILE *fp, __u32 flags) 1985c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy{ 19943bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin open_json_array(PRINT_ANY, is_json_context() ? "flags" : "<"); 20043bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin#define _PF(f) if (flags & VLAN_FLAG_##f) { \ 20143bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin flags &= ~VLAN_FLAG_##f; \ 20243bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin print_string(PRINT_ANY, NULL, flags ? "%s," : "%s", #f); \ 20343bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin } 2045c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy _PF(REORDER_HDR); 20547420640687cbd389ddd99d39cf7fb0e0bcb265aPatrick McHardy _PF(GVRP); 2064e9a686020b2ff4e391f685a53c91365d04a5e43David Ward _PF(MVRP); 2072180b6b50bdc50e1a7740e5283930088da0bbae7Patrick McHardy _PF(LOOSE_BINDING); 2085c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy#undef _PF 2095c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy if (flags) 21043bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin print_hex(PRINT_ANY, NULL, "%x", flags); 21143bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin close_json_array(PRINT_ANY, "> "); 2125c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy} 2135c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 2145c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardystatic void vlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) 2155c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy{ 2165c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy struct ifla_vlan_flags *flags; 21756f5daac98da0c405fdbc52f04afd5de82404bceStephen Hemminger 2188fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy SPRINT_BUF(b1); 2198fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy 2205c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy if (!tb) 2215c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy return; 2225c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 2238fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy if (tb[IFLA_VLAN_PROTOCOL] && 2248fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy RTA_PAYLOAD(tb[IFLA_VLAN_PROTOCOL]) < sizeof(__u16)) 2258fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy return; 2265c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy if (!tb[IFLA_VLAN_ID] || 2275c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy RTA_PAYLOAD(tb[IFLA_VLAN_ID]) < sizeof(__u16)) 2285c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy return; 2295c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 2308fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy if (tb[IFLA_VLAN_PROTOCOL]) 23143bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin print_string(PRINT_ANY, 23243bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin "protocol", 23343bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin "protocol %s ", 23443bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin ll_proto_n2a( 23543bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin rta_getattr_u16(tb[IFLA_VLAN_PROTOCOL]), 2368fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy b1, sizeof(b1))); 2378fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy else 23843bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin print_string(PRINT_ANY, "protocol", "protocol %s ", "802.1q"); 2398fd8f6ed715aaa6d87e99675e0dfe13ed6c782bdPatric McHardy 24043bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin print_uint(PRINT_ANY, 24143bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin "id", 24243bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin "id %u ", 24343bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin rta_getattr_u16(tb[IFLA_VLAN_ID])); 2445c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 2455c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy if (tb[IFLA_VLAN_FLAGS]) { 2465c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy if (RTA_PAYLOAD(tb[IFLA_VLAN_FLAGS]) < sizeof(*flags)) 2475c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy return; 2485c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy flags = RTA_DATA(tb[IFLA_VLAN_FLAGS]); 2495c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy vlan_print_flags(f, flags->flags); 2505c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy } 2515c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy if (tb[IFLA_VLAN_INGRESS_QOS]) 25243bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin vlan_print_map(f, 25343bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin "ingress_qos", 25443bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin "ingress-qos-map", 25543bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin tb[IFLA_VLAN_INGRESS_QOS]); 2565c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy if (tb[IFLA_VLAN_EGRESS_QOS]) 25743bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin vlan_print_map(f, 25843bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin "egress_qos", 25943bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin "egress-qos-map", 26043bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin tb[IFLA_VLAN_EGRESS_QOS]); 2615c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy} 2625c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy 263561e650eff679296d3f4c12657721ae769cbc187vadimkstatic void vlan_print_help(struct link_util *lu, int argc, char **argv, 26443bc20ae736c943a7202fef07104eb1b5800b7f8Julien Fortin FILE *f) 265561e650eff679296d3f4c12657721ae769cbc187vadimk{ 266561e650eff679296d3f4c12657721ae769cbc187vadimk print_explain(f); 267561e650eff679296d3f4c12657721ae769cbc187vadimk} 268561e650eff679296d3f4c12657721ae769cbc187vadimk 2695c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardystruct link_util vlan_link_util = { 2705c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy .id = "vlan", 2715c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy .maxattr = IFLA_VLAN_MAX, 2725c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy .parse_opt = vlan_parse_opt, 2735c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy .print_opt = vlan_print_opt, 274561e650eff679296d3f4c12657721ae769cbc187vadimk .print_help = vlan_print_help, 2755c302d518f10e67ddab9e44207a0c878214ed389Patrick McHardy}; 276