mirror of
				https://git.proxmox.com/git/mirror_iproute2
				synced 2025-10-31 14:01:31 +00:00 
			
		
		
		
	 561e650eff
			
		
	
	
		561e650eff
		
	
	
	
	
		
			
			Allow to print particular link type usage by:
    ip link help [TYPE]
Currently to print usage for some link type it is needed
to use the following way:
    ip link { add | del | set } type TYPE help
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
		
	
			
		
			
				
	
	
		
			106 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * iplink_macvtap.c	macvtap device support
 | |
|  *
 | |
|  *              This program is free software; you can redistribute it and/or
 | |
|  *              modify it under the terms of the GNU General Public License
 | |
|  *              as published by the Free Software Foundation; either version
 | |
|  *              2 of the License, or (at your option) any later version.
 | |
|  */
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <sys/socket.h>
 | |
| #include <linux/if_link.h>
 | |
| 
 | |
| #include "rt_names.h"
 | |
| #include "utils.h"
 | |
| #include "ip_common.h"
 | |
| 
 | |
| static void print_explain(FILE *f)
 | |
| {
 | |
| 	fprintf(stderr,
 | |
| 		"Usage: ... macvtap mode { private | vepa | bridge | passthru }\n"
 | |
| 	);
 | |
| }
 | |
| 
 | |
| static void explain(void)
 | |
| {
 | |
| 	print_explain(stderr);
 | |
| }
 | |
| 
 | |
| static int mode_arg(const char *arg)
 | |
| {
 | |
|         fprintf(stderr, "Error: argument of \"mode\" must be \"private\", "
 | |
| 		"\"vepa\", \"bridge\" or \"passthru\", not \"%s\"\n", arg);
 | |
|         return -1;
 | |
| }
 | |
| 
 | |
| static int macvtap_parse_opt(struct link_util *lu, int argc, char **argv,
 | |
| 			  struct nlmsghdr *n)
 | |
| {
 | |
| 	while (argc > 0) {
 | |
| 		if (matches(*argv, "mode") == 0) {
 | |
| 			__u32 mode = 0;
 | |
| 			NEXT_ARG();
 | |
| 
 | |
| 			if (strcmp(*argv, "private") == 0)
 | |
| 				mode = MACVLAN_MODE_PRIVATE;
 | |
| 			else if (strcmp(*argv, "vepa") == 0)
 | |
| 				mode = MACVLAN_MODE_VEPA;
 | |
| 			else if (strcmp(*argv, "bridge") == 0)
 | |
| 				mode = MACVLAN_MODE_BRIDGE;
 | |
| 			else if (strcmp(*argv, "passthru") == 0)
 | |
| 				mode = MACVLAN_MODE_PASSTHRU;
 | |
| 			else
 | |
| 				return mode_arg(*argv);
 | |
| 
 | |
| 			addattr32(n, 1024, IFLA_MACVLAN_MODE, mode);
 | |
| 		} else if (matches(*argv, "help") == 0) {
 | |
| 			explain();
 | |
| 			return -1;
 | |
| 		} else {
 | |
| 			fprintf(stderr, "macvtap: unknown command \"%s\"?\n", *argv);
 | |
| 			explain();
 | |
| 			return -1;
 | |
| 		}
 | |
| 		argc--, argv++;
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static void macvtap_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
 | |
| {
 | |
| 	__u32 mode;
 | |
| 
 | |
| 	if (!tb)
 | |
| 		return;
 | |
| 
 | |
| 	if (!tb[IFLA_MACVLAN_MODE] ||
 | |
| 	    RTA_PAYLOAD(tb[IFLA_MACVLAN_MODE]) < sizeof(__u32))
 | |
| 		return;
 | |
| 
 | |
| 	mode = rta_getattr_u32(tb[IFLA_VLAN_ID]);
 | |
| 	fprintf(f, " mode %s ",
 | |
| 		  mode == MACVLAN_MODE_PRIVATE ? "private"
 | |
| 		: mode == MACVLAN_MODE_VEPA    ? "vepa"
 | |
| 		: mode == MACVLAN_MODE_BRIDGE  ? "bridge"
 | |
| 		: mode == MACVLAN_MODE_PASSTHRU  ? "passthru"
 | |
| 		:				 "unknown");
 | |
| }
 | |
| 
 | |
| static void macvtap_print_help(struct link_util *lu, int argc, char **argv,
 | |
| 	FILE *f)
 | |
| {
 | |
| 	print_explain(f);
 | |
| }
 | |
| 
 | |
| struct link_util macvtap_link_util = {
 | |
| 	.id		= "macvtap",
 | |
| 	.maxattr	= IFLA_MACVLAN_MAX,
 | |
| 	.parse_opt	= macvtap_parse_opt,
 | |
| 	.print_opt	= macvtap_print_opt,
 | |
| 	.print_help	= macvtap_print_help,
 | |
| };
 |