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