]>
git.proxmox.com Git - mirror_iproute2.git/blob - ip/iplink_vlan.c
2 * iplink_vlan.c VLAN device support
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.
9 * Authors: Patrick McHardy <kaber@trash.net>
15 #include <linux/if_vlan.h>
19 #include "ip_common.h"
21 static void explain(void)
24 "Usage: ... vlan id VLANID [ FLAG-LIST ]\n"
25 " [ ingress-qos-map QOS-MAP ] [ egress-qos-map QOS-MAP ]\n"
28 "FLAG-LIST := [ FLAG-LIST ] FLAG\n"
29 "FLAG := [ reorder_hdr { on | off } ] [ gvrp { on | off } ]\n"
30 " [ loose_binding { on | off } ]\n"
31 "QOS-MAP := [ QOS-MAP ] QOS-MAPPING\n"
32 "QOS-MAPPING := FROM:TO\n"
36 static int on_off(char *msg
)
38 fprintf(stderr
, "Error: argument of \"%s\" must be \"on\" or \"off\"\n", msg
);
42 static int vlan_parse_qos_map(int *argcp
, char ***argvp
, struct nlmsghdr
*n
,
47 struct ifla_vlan_qos_mapping m
;
51 addattr_l(n
, 1024, attrtype
, NULL
, 0);
54 char *colon
= strchr(*argv
, ':');
60 if (get_u32(&m
.from
, *argv
, 0))
62 if (get_u32(&m
.to
, colon
+ 1, 0))
66 addattr_l(n
, 1024, IFLA_VLAN_QOS_MAPPING
, &m
, sizeof(m
));
69 tail
->rta_len
= (void *) NLMSG_TAIL(n
) - (void *)tail
;
76 static int vlan_parse_opt(struct link_util
*lu
, int argc
, char **argv
,
79 struct ifla_vlan_flags flags
= { 0 };
83 if (matches(*argv
, "id") == 0) {
85 if (get_u16(&id
, *argv
, 0))
86 invarg("id is invalid", *argv
);
87 addattr_l(n
, 1024, IFLA_VLAN_ID
, &id
, 2);
88 } else if (matches(*argv
, "reorder_hdr") == 0) {
90 flags
.mask
|= VLAN_FLAG_REORDER_HDR
;
91 if (strcmp(*argv
, "on") == 0)
92 flags
.flags
|= VLAN_FLAG_REORDER_HDR
;
93 else if (strcmp(*argv
, "off") == 0)
94 flags
.flags
&= ~VLAN_FLAG_REORDER_HDR
;
96 return on_off("reorder_hdr");
97 } else if (matches(*argv
, "gvrp") == 0) {
99 flags
.mask
|= VLAN_FLAG_GVRP
;
100 if (strcmp(*argv
, "on") == 0)
101 flags
.flags
|= VLAN_FLAG_GVRP
;
102 else if (strcmp(*argv
, "off") == 0)
103 flags
.flags
&= ~VLAN_FLAG_GVRP
;
105 return on_off("gvrp");
106 } else if (matches(*argv
, "loose_binding") == 0) {
108 flags
.mask
|= VLAN_FLAG_LOOSE_BINDING
;
109 if (strcmp(*argv
, "on") == 0)
110 flags
.flags
|= VLAN_FLAG_LOOSE_BINDING
;
111 else if (strcmp(*argv
, "off") == 0)
112 flags
.flags
&= ~VLAN_FLAG_LOOSE_BINDING
;
114 return on_off("loose_binding");
115 } else if (matches(*argv
, "ingress-qos-map") == 0) {
117 if (vlan_parse_qos_map(&argc
, &argv
, n
,
118 IFLA_VLAN_INGRESS_QOS
))
119 invarg("invalid ingress-qos-map", *argv
);
121 } else if (matches(*argv
, "egress-qos-map") == 0) {
123 if (vlan_parse_qos_map(&argc
, &argv
, n
,
124 IFLA_VLAN_EGRESS_QOS
))
125 invarg("invalid egress-qos-map", *argv
);
127 } else if (matches(*argv
, "help") == 0) {
131 fprintf(stderr
, "vlan: what is \"%s\"?\n", *argv
);
139 addattr_l(n
, 1024, IFLA_VLAN_FLAGS
, &flags
, sizeof(flags
));
144 static void vlan_print_map(FILE *f
, char *name
, struct rtattr
*attr
)
146 struct ifla_vlan_qos_mapping
*m
;
150 fprintf(f
, "\n %s { ", name
);
152 rem
= RTA_PAYLOAD(attr
);
153 for (i
= RTA_DATA(attr
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
)) {
155 fprintf(f
, "%u:%u ", m
->from
, m
->to
);
160 static void vlan_print_flags(FILE *fp
, __u32 flags
)
163 #define _PF(f) if (flags & VLAN_FLAG_##f) { \
164 flags &= ~ VLAN_FLAG_##f; \
165 fprintf(fp, #f "%s", flags ? "," : ""); \
172 fprintf(fp
, "%x", flags
);
176 static void vlan_print_opt(struct link_util
*lu
, FILE *f
, struct rtattr
*tb
[])
178 struct ifla_vlan_flags
*flags
;
182 if (!tb
[IFLA_VLAN_ID
] ||
183 RTA_PAYLOAD(tb
[IFLA_VLAN_ID
]) < sizeof(__u16
))
186 fprintf(f
, "id %u ", *(__u16
*)RTA_DATA(tb
[IFLA_VLAN_ID
]));
188 if (tb
[IFLA_VLAN_FLAGS
]) {
189 if (RTA_PAYLOAD(tb
[IFLA_VLAN_FLAGS
]) < sizeof(*flags
))
191 flags
= RTA_DATA(tb
[IFLA_VLAN_FLAGS
]);
192 vlan_print_flags(f
, flags
->flags
);
194 if (tb
[IFLA_VLAN_INGRESS_QOS
])
195 vlan_print_map(f
, "ingress-qos-map", tb
[IFLA_VLAN_INGRESS_QOS
]);
196 if (tb
[IFLA_VLAN_EGRESS_QOS
])
197 vlan_print_map(f
, "egress-qos-map", tb
[IFLA_VLAN_EGRESS_QOS
]);
200 struct link_util vlan_link_util
= {
202 .maxattr
= IFLA_VLAN_MAX
,
203 .parse_opt
= vlan_parse_opt
,
204 .print_opt
= vlan_print_opt
,