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 }\n"
     27 	);
     28 }
     29 
     30 static int mode_arg(void)
     31 {
     32         fprintf(stderr, "Error: argument of \"mode\" must be \"private\", "
     33 		"\"vepa\" or \"bridge\"\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
     52 				return mode_arg();
     53 
     54 			addattr32(n, 1024, IFLA_MACVLAN_MODE, mode);
     55 		} else if (matches(*argv, "help") == 0) {
     56 			explain();
     57 			return -1;
     58 		} else {
     59 			fprintf(stderr, "macvlan: what is \"%s\"?\n", *argv);
     60 			explain();
     61 			return -1;
     62 		}
     63 		argc--, argv++;
     64 	}
     65 
     66 	return 0;
     67 }
     68 
     69 static void macvlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
     70 {
     71 	__u32 mode;
     72 
     73 	if (!tb)
     74 		return;
     75 
     76 	if (!tb[IFLA_MACVLAN_MODE] ||
     77 	    RTA_PAYLOAD(tb[IFLA_MACVLAN_MODE]) < sizeof(__u32))
     78 		return;
     79 
     80 	mode = *(__u32 *)RTA_DATA(tb[IFLA_VLAN_ID]);
     81 	fprintf(f, " mode %s ",
     82 		  mode == MACVLAN_MODE_PRIVATE ? "private"
     83 		: mode == MACVLAN_MODE_VEPA    ? "vepa"
     84 		: mode == MACVLAN_MODE_BRIDGE  ? "bridge"
     85 		:				 "unknown");
     86 }
     87 
     88 struct link_util macvlan_link_util = {
     89 	.id		= "macvlan",
     90 	.maxattr	= IFLA_MACVLAN_MAX,
     91 	.parse_opt	= macvlan_parse_opt,
     92 	.print_opt	= macvlan_print_opt,
     93 };
     94