Home | History | Annotate | Download | only in ip
      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 
     20 static void explain(void)
     21 {
     22 	fprintf(stderr,
     23 		"Usage: ... macvtap mode { private | vepa | bridge | passthru }\n"
     24 	);
     25 }
     26 
     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 
     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 
     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