Home | History | Annotate | Download | only in ip
      1 /*
      2  * link_veth.c	veth driver module
      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:	Pavel Emelianov <xemul (at) openvz.org>
     10  *
     11  */
     12 
     13 #include <string.h>
     14 #include <net/if.h>
     15 #include <linux/veth.h>
     16 
     17 #include "utils.h"
     18 #include "ip_common.h"
     19 
     20 static void print_usage(FILE *f)
     21 {
     22 	printf("Usage: ip link <options> type veth [peer <options>]\n"
     23 	       "To get <options> type 'ip link add help'\n");
     24 }
     25 
     26 static void usage(void)
     27 {
     28 	print_usage(stderr);
     29 }
     30 
     31 static int veth_parse_opt(struct link_util *lu, int argc, char **argv,
     32 			  struct nlmsghdr *hdr)
     33 {
     34 	char *dev = NULL;
     35 	char *name = NULL;
     36 	char *link = NULL;
     37 	char *type = NULL;
     38 	int index = 0;
     39 	int err, len;
     40 	struct rtattr * data;
     41 	int group;
     42 	struct ifinfomsg *ifm, *peer_ifm;
     43 	unsigned int ifi_flags, ifi_change;
     44 
     45 	if (strcmp(argv[0], "peer") != 0) {
     46 		usage();
     47 		return -1;
     48 	}
     49 
     50 	ifm = NLMSG_DATA(hdr);
     51 	ifi_flags = ifm->ifi_flags;
     52 	ifi_change = ifm->ifi_change;
     53 	ifm->ifi_flags = 0;
     54 	ifm->ifi_change = 0;
     55 
     56 	data = NLMSG_TAIL(hdr);
     57 	addattr_l(hdr, 1024, VETH_INFO_PEER, NULL, 0);
     58 
     59 	hdr->nlmsg_len += sizeof(struct ifinfomsg);
     60 
     61 	err = iplink_parse(argc - 1, argv + 1, (struct iplink_req *)hdr,
     62 			   &name, &type, &link, &dev, &group, &index);
     63 	if (err < 0)
     64 		return err;
     65 
     66 	if (name) {
     67 		len = strlen(name) + 1;
     68 		if (len > IFNAMSIZ)
     69 			invarg("\"name\" too long\n", *argv);
     70 		addattr_l(hdr, 1024, IFLA_IFNAME, name, len);
     71 	}
     72 
     73 	peer_ifm = RTA_DATA(data);
     74 	peer_ifm->ifi_index = index;
     75 	peer_ifm->ifi_flags = ifm->ifi_flags;
     76 	peer_ifm->ifi_change = ifm->ifi_change;
     77 	ifm->ifi_flags = ifi_flags;
     78 	ifm->ifi_change = ifi_change;
     79 
     80 	if (group != -1)
     81 		addattr32(hdr, 1024, IFLA_GROUP, group);
     82 
     83 	data->rta_len = (void *)NLMSG_TAIL(hdr) - (void *)data;
     84 	return argc - 1 - err;
     85 }
     86 
     87 static void veth_print_help(struct link_util *lu, int argc, char **argv,
     88 	FILE *f)
     89 {
     90 	print_usage(f);
     91 }
     92 
     93 struct link_util veth_link_util = {
     94 	.id = "veth",
     95 	.parse_opt = veth_parse_opt,
     96 	.print_help = veth_print_help,
     97 };
     98