13f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala/* 23f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala * iplink_macvtap.c macvtap device support 33f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala * 43f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala * This program is free software; you can redistribute it and/or 53f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala * modify it under the terms of the GNU General Public License 63f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala * as published by the Free Software Foundation; either version 73f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala * 2 of the License, or (at your option) any later version. 83f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala */ 93f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala 103f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala#include <stdio.h> 113f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala#include <stdlib.h> 123f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala#include <string.h> 133f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala#include <sys/socket.h> 143f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala#include <linux/if_link.h> 153f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala 163f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala#include "rt_names.h" 173f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala#include "utils.h" 183f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala#include "ip_common.h" 193f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala 203f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudralastatic void explain(void) 213f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala{ 223f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala fprintf(stderr, 23f0612d566b8bb76866fa772076412d290ed4cf5eSridhar Samudrala "Usage: ... macvtap mode { private | vepa | bridge | passthru }\n" 243f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala ); 253f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala} 263f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala 273f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudralastatic int mode_arg(void) 283f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala{ 293f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala fprintf(stderr, "Error: argument of \"mode\" must be \"private\", " 30f0612d566b8bb76866fa772076412d290ed4cf5eSridhar Samudrala "\"vepa\", \"bridge\" or \"passthru\" \n"); 313f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala return -1; 323f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala} 333f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala 343f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudralastatic int macvtap_parse_opt(struct link_util *lu, int argc, char **argv, 353f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala struct nlmsghdr *n) 363f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala{ 373f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala while (argc > 0) { 383f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala if (matches(*argv, "mode") == 0) { 393f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala __u32 mode = 0; 403f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala NEXT_ARG(); 413f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala 423f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala if (strcmp(*argv, "private") == 0) 433f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala mode = MACVLAN_MODE_PRIVATE; 443f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala else if (strcmp(*argv, "vepa") == 0) 453f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala mode = MACVLAN_MODE_VEPA; 463f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala else if (strcmp(*argv, "bridge") == 0) 473f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala mode = MACVLAN_MODE_BRIDGE; 48f0612d566b8bb76866fa772076412d290ed4cf5eSridhar Samudrala else if (strcmp(*argv, "passthru") == 0) 49f0612d566b8bb76866fa772076412d290ed4cf5eSridhar Samudrala mode = MACVLAN_MODE_PASSTHRU; 503f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala else 513f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala return mode_arg(); 523f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala 533f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala addattr32(n, 1024, IFLA_MACVLAN_MODE, mode); 543f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala } else if (matches(*argv, "help") == 0) { 553f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala explain(); 563f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala return -1; 573f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala } else { 583f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala fprintf(stderr, "macvtap: what is \"%s\"?\n", *argv); 593f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala explain(); 603f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala return -1; 613f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala } 623f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala argc--, argv++; 633f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala } 643f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala 653f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala return 0; 663f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala} 673f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala 683f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudralastatic void macvtap_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) 693f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala{ 703f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala __u32 mode; 713f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala 723f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala if (!tb) 733f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala return; 743f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala 753f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala if (!tb[IFLA_MACVLAN_MODE] || 763f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala RTA_PAYLOAD(tb[IFLA_MACVLAN_MODE]) < sizeof(__u32)) 773f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala return; 783f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala 79ff24746cca1ef0c92d46614158e6672acd6b63d3Stephen Hemminger mode = rta_getattr_u32(tb[IFLA_VLAN_ID]); 803f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala fprintf(f, " mode %s ", 813f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala mode == MACVLAN_MODE_PRIVATE ? "private" 823f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala : mode == MACVLAN_MODE_VEPA ? "vepa" 833f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala : mode == MACVLAN_MODE_BRIDGE ? "bridge" 84f0612d566b8bb76866fa772076412d290ed4cf5eSridhar Samudrala : mode == MACVLAN_MODE_PASSTHRU ? "passthru" 853f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala : "unknown"); 863f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala} 873f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala 883f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudralastruct link_util macvtap_link_util = { 893f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala .id = "macvtap", 903f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala .maxattr = IFLA_MACVLAN_MAX, 913f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala .parse_opt = macvtap_parse_opt, 923f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala .print_opt = macvtap_print_opt, 933f0a7b4c4f0a6c5462ad55b7fa4445c2d485f435Sridhar Samudrala}; 94