1d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann/* 2d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann * iplink_vlan.c VLAN device support 3d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann * 4d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann * This program is free software; you can redistribute it and/or 5d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann * modify it under the terms of the GNU General Public License 6d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann * as published by the Free Software Foundation; either version 7d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann * 2 of the License, or (at your option) any later version. 8d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann * 9d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann * Authors: Patrick McHardy <kaber@trash.net> 10d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann * Arnd Bergmann <arnd@arndb.de> 11d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann */ 12d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann 13d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann#include <stdio.h> 14d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann#include <stdlib.h> 15d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann#include <string.h> 16d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann#include <sys/socket.h> 17d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann#include <linux/if_link.h> 18d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann 19d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann#include "rt_names.h" 20d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann#include "utils.h" 21d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann#include "ip_common.h" 22d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann 23d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmannstatic void explain(void) 24d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann{ 25d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann fprintf(stderr, 26f0612d566b8bb76866fa772076412d290ed4cf5eSridhar Samudrala "Usage: ... macvlan mode { private | vepa | bridge | passthru }\n" 27d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann ); 28d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann} 29d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann 30d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmannstatic int mode_arg(void) 31d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann{ 32d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann fprintf(stderr, "Error: argument of \"mode\" must be \"private\", " 33f0612d566b8bb76866fa772076412d290ed4cf5eSridhar Samudrala "\"vepa\", \"bridge\" or \"passthru\" \n"); 34d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann return -1; 35d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann} 36d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann 37d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmannstatic int macvlan_parse_opt(struct link_util *lu, int argc, char **argv, 38d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann struct nlmsghdr *n) 39d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann{ 40d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann while (argc > 0) { 41d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann if (matches(*argv, "mode") == 0) { 42d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann __u32 mode = 0; 43d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann NEXT_ARG(); 44d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann 45d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann if (strcmp(*argv, "private") == 0) 46d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann mode = MACVLAN_MODE_PRIVATE; 47d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann else if (strcmp(*argv, "vepa") == 0) 48d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann mode = MACVLAN_MODE_VEPA; 49d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann else if (strcmp(*argv, "bridge") == 0) 50d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann mode = MACVLAN_MODE_BRIDGE; 51f0612d566b8bb76866fa772076412d290ed4cf5eSridhar Samudrala else if (strcmp(*argv, "passthru") == 0) 52f0612d566b8bb76866fa772076412d290ed4cf5eSridhar Samudrala mode = MACVLAN_MODE_PASSTHRU; 53d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann else 54d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann return mode_arg(); 55d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann 56d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann addattr32(n, 1024, IFLA_MACVLAN_MODE, mode); 57d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann } else if (matches(*argv, "help") == 0) { 58d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann explain(); 59d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann return -1; 60d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann } else { 61d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann fprintf(stderr, "macvlan: what is \"%s\"?\n", *argv); 62d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann explain(); 63d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann return -1; 64d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann } 65d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann argc--, argv++; 66d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann } 67d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann 68d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann return 0; 69d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann} 70d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann 71d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmannstatic void macvlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) 72d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann{ 73d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann __u32 mode; 74d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann 75d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann if (!tb) 76d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann return; 77d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann 78d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann if (!tb[IFLA_MACVLAN_MODE] || 79d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann RTA_PAYLOAD(tb[IFLA_MACVLAN_MODE]) < sizeof(__u32)) 80d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann return; 81d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann 82ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger mode = rta_getattr_u32(tb[IFLA_VLAN_ID]); 83d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann fprintf(f, " mode %s ", 84d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann mode == MACVLAN_MODE_PRIVATE ? "private" 85d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann : mode == MACVLAN_MODE_VEPA ? "vepa" 86d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann : mode == MACVLAN_MODE_BRIDGE ? "bridge" 87f0612d566b8bb76866fa772076412d290ed4cf5eSridhar Samudrala : mode == MACVLAN_MODE_PASSTHRU ? "passthru" 88d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann : "unknown"); 89d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann} 90d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann 91d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmannstruct link_util macvlan_link_util = { 92d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann .id = "macvlan", 93d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann .maxattr = IFLA_MACVLAN_MAX, 94d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann .parse_opt = macvlan_parse_opt, 95d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann .print_opt = macvlan_print_opt, 96d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7Arnd Bergmann}; 97