11a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt/* 21a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt * iplink_vlan.c VLAN device support 31a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt * 41a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt * This program is free software; you can redistribute it and/or 51a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt * modify it under the terms of the GNU General Public License 61a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt * as published by the Free Software Foundation; either version 71a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt * 2 of the License, or (at your option) any later version. 81a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt * 91a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt * Authors: Patrick McHardy <kaber@trash.net> 101a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt * Arnd Bergmann <arnd@arndb.de> 111a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt */ 121a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 131a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt#include <stdio.h> 141a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt#include <stdlib.h> 151a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt#include <string.h> 161a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt#include <sys/socket.h> 171a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt#include <linux/if_link.h> 181a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 191a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt#include "rt_names.h" 201a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt#include "utils.h" 211a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt#include "ip_common.h" 221a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 231a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidtstatic void explain(void) 241a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt{ 251a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(stderr, 261a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt "Usage: ... macvlan mode { private | vepa | bridge }\n" 271a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt ); 281a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt} 291a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 301a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidtstatic int mode_arg(void) 311a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt{ 321a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(stderr, "Error: argument of \"mode\" must be \"private\", " 331a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt "\"vepa\" or \"bridge\"\n"); 341a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt return -1; 351a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt} 361a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 371a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidtstatic int macvlan_parse_opt(struct link_util *lu, int argc, char **argv, 381a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt struct nlmsghdr *n) 391a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt{ 401a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt while (argc > 0) { 411a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (matches(*argv, "mode") == 0) { 421a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt __u32 mode = 0; 431a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt NEXT_ARG(); 441a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 451a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (strcmp(*argv, "private") == 0) 461a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt mode = MACVLAN_MODE_PRIVATE; 471a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt else if (strcmp(*argv, "vepa") == 0) 481a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt mode = MACVLAN_MODE_VEPA; 491a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt else if (strcmp(*argv, "bridge") == 0) 501a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt mode = MACVLAN_MODE_BRIDGE; 511a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt else 521a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt return mode_arg(); 531a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 541a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt addattr32(n, 1024, IFLA_MACVLAN_MODE, mode); 551a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } else if (matches(*argv, "help") == 0) { 561a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt explain(); 571a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt return -1; 581a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } else { 591a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(stderr, "macvlan: what is \"%s\"?\n", *argv); 601a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt explain(); 611a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt return -1; 621a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } 631a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt argc--, argv++; 641a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt } 651a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 661a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt return 0; 671a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt} 681a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 691a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidtstatic void macvlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) 701a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt{ 711a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt __u32 mode; 721a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 731a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (!tb) 741a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt return; 751a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 761a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt if (!tb[IFLA_MACVLAN_MODE] || 771a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt RTA_PAYLOAD(tb[IFLA_MACVLAN_MODE]) < sizeof(__u32)) 781a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt return; 791a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 801a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt mode = *(__u32 *)RTA_DATA(tb[IFLA_VLAN_ID]); 811a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt fprintf(f, " mode %s ", 821a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt mode == MACVLAN_MODE_PRIVATE ? "private" 831a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt : mode == MACVLAN_MODE_VEPA ? "vepa" 841a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt : mode == MACVLAN_MODE_BRIDGE ? "bridge" 851a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt : "unknown"); 861a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt} 871a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt 881a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidtstruct link_util macvlan_link_util = { 891a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt .id = "macvlan", 901a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt .maxattr = IFLA_MACVLAN_MAX, 911a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt .parse_opt = macvlan_parse_opt, 921a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt .print_opt = macvlan_print_opt, 931a441f49ec87ef74b978d7ae17da2a9b2ca6e811Dmitry Shmidt}; 94