• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * iplink_macvtap.c	macvtap 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 
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <sys/socket.h>
14 #include <linux/if_link.h>
15 
16 #include "rt_names.h"
17 #include "utils.h"
18 #include "ip_common.h"
19 
explain(void)20 static void explain(void)
21 {
22 	fprintf(stderr,
23 		"Usage: ... macvtap mode { private | vepa | bridge | passthru }\n"
24 	);
25 }
26 
mode_arg(void)27 static int mode_arg(void)
28 {
29         fprintf(stderr, "Error: argument of \"mode\" must be \"private\", "
30 		"\"vepa\", \"bridge\" or \"passthru\" \n");
31         return -1;
32 }
33 
macvtap_parse_opt(struct link_util * lu,int argc,char ** argv,struct nlmsghdr * n)34 static int macvtap_parse_opt(struct link_util *lu, int argc, char **argv,
35 			  struct nlmsghdr *n)
36 {
37 	while (argc > 0) {
38 		if (matches(*argv, "mode") == 0) {
39 			__u32 mode = 0;
40 			NEXT_ARG();
41 
42 			if (strcmp(*argv, "private") == 0)
43 				mode = MACVLAN_MODE_PRIVATE;
44 			else if (strcmp(*argv, "vepa") == 0)
45 				mode = MACVLAN_MODE_VEPA;
46 			else if (strcmp(*argv, "bridge") == 0)
47 				mode = MACVLAN_MODE_BRIDGE;
48 			else if (strcmp(*argv, "passthru") == 0)
49 				mode = MACVLAN_MODE_PASSTHRU;
50 			else
51 				return mode_arg();
52 
53 			addattr32(n, 1024, IFLA_MACVLAN_MODE, mode);
54 		} else if (matches(*argv, "help") == 0) {
55 			explain();
56 			return -1;
57 		} else {
58 			fprintf(stderr, "macvtap: what is \"%s\"?\n", *argv);
59 			explain();
60 			return -1;
61 		}
62 		argc--, argv++;
63 	}
64 
65 	return 0;
66 }
67 
macvtap_print_opt(struct link_util * lu,FILE * f,struct rtattr * tb[])68 static void macvtap_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
69 {
70 	__u32 mode;
71 
72 	if (!tb)
73 		return;
74 
75 	if (!tb[IFLA_MACVLAN_MODE] ||
76 	    RTA_PAYLOAD(tb[IFLA_MACVLAN_MODE]) < sizeof(__u32))
77 		return;
78 
79 	mode = rta_getattr_u32(tb[IFLA_VLAN_ID]);
80 	fprintf(f, " mode %s ",
81 		  mode == MACVLAN_MODE_PRIVATE ? "private"
82 		: mode == MACVLAN_MODE_VEPA    ? "vepa"
83 		: mode == MACVLAN_MODE_BRIDGE  ? "bridge"
84 		: mode == MACVLAN_MODE_PASSTHRU  ? "passthru"
85 		:				 "unknown");
86 }
87 
88 struct link_util macvtap_link_util = {
89 	.id		= "macvtap",
90 	.maxattr	= IFLA_MACVLAN_MAX,
91 	.parse_opt	= macvtap_parse_opt,
92 	.print_opt	= macvtap_print_opt,
93 };
94