Home | History | Annotate | Download | only in ip
      1 /*
      2  * iplink_ipoib.c	IPoIB device support
      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:     Or Gerlitz <ogerlitz (at) mellanox.com>
     10  *		copied iflink_vlan.c authored by Patrick McHardy <kaber (at) trash.net>
     11  */
     12 
     13 #include <stdio.h>
     14 #include <stdlib.h>
     15 #include <string.h>
     16 #include <linux/if_link.h>
     17 
     18 #include "rt_names.h"
     19 #include "utils.h"
     20 #include "ip_common.h"
     21 
     22 static void print_explain(FILE *f)
     23 {
     24 	fprintf(f,
     25 		"Usage: ... ipoib [pkey PKEY] [mode {datagram | connected}]"
     26 		"[umcast {0|1}]\n"
     27 		"\n"
     28 		"PKEY  := 0x8001-0xffff\n"
     29 	);
     30 }
     31 
     32 static void explain(void)
     33 {
     34 	print_explain(stderr);
     35 }
     36 
     37 static int mode_arg(void)
     38 {
     39 	fprintf(stderr, "Error: argument of \"mode\" must be \"datagram\""
     40 		"or \"connected\"\n");
     41 	return -1;
     42 }
     43 
     44 static int ipoib_parse_opt(struct link_util *lu, int argc, char **argv,
     45 			  struct nlmsghdr *n)
     46 {
     47 	__u16 pkey, mode, umcast;
     48 
     49 	while (argc > 0) {
     50 		if (matches(*argv, "pkey") == 0) {
     51 			NEXT_ARG();
     52 			if (get_u16(&pkey, *argv, 0))
     53 				invarg("pkey is invalid", *argv);
     54 			addattr_l(n, 1024, IFLA_IPOIB_PKEY, &pkey, 2);
     55 		} else if (matches(*argv, "mode") == 0) {
     56 			NEXT_ARG();
     57 			if (strcmp(*argv, "datagram") == 0)
     58 				mode = IPOIB_MODE_DATAGRAM;
     59 			else if (strcmp(*argv, "connected") == 0)
     60 				mode = IPOIB_MODE_CONNECTED;
     61 			else
     62 				return mode_arg();
     63 			addattr_l(n, 1024, IFLA_IPOIB_MODE, &mode, 2);
     64 		} else if (matches(*argv, "umcast") == 0) {
     65 			NEXT_ARG();
     66 			if (get_u16(&umcast, *argv, 0))
     67 				invarg("umcast is invalid", *argv);
     68 			addattr_l(n, 1024, IFLA_IPOIB_UMCAST, &umcast, 2);
     69 		} else if (matches(*argv, "help") == 0) {
     70 			explain();
     71 			return -1;
     72 		} else {
     73 			fprintf(stderr, "ipoib: unknown option \"%s\"?\n", *argv);
     74 			explain();
     75 			return -1;
     76 		}
     77 		argc--, argv++;
     78 	}
     79 
     80 	return 0;
     81 }
     82 
     83 static void ipoib_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
     84 {
     85 	__u16 mode;
     86 
     87 	if (!tb)
     88 		return;
     89 
     90 	if (!tb[IFLA_IPOIB_PKEY] ||
     91 	    RTA_PAYLOAD(tb[IFLA_IPOIB_PKEY]) < sizeof(__u16))
     92 		return;
     93 
     94 	fprintf(f, "pkey  %#.4x ", rta_getattr_u16(tb[IFLA_IPOIB_PKEY]));
     95 
     96 	if (!tb[IFLA_IPOIB_MODE] ||
     97 	    RTA_PAYLOAD(tb[IFLA_IPOIB_MODE]) < sizeof(__u16))
     98 		return;
     99 
    100 	mode = rta_getattr_u16(tb[IFLA_IPOIB_MODE]);
    101 	fprintf(f, "mode  %s ",
    102 		mode == IPOIB_MODE_DATAGRAM ? "datagram" :
    103 		mode == IPOIB_MODE_CONNECTED ? "connected" :
    104 		"unknown");
    105 
    106 	if (!tb[IFLA_IPOIB_UMCAST] ||
    107 	    RTA_PAYLOAD(tb[IFLA_IPOIB_UMCAST]) < sizeof(__u16))
    108 		return;
    109 
    110 	fprintf(f, "umcast  %.4x ", rta_getattr_u16(tb[IFLA_IPOIB_UMCAST]));
    111 }
    112 
    113 static void ipoib_print_help(struct link_util *lu, int argc, char **argv,
    114 	FILE *f)
    115 {
    116 	print_explain(f);
    117 }
    118 
    119 struct link_util ipoib_link_util = {
    120 	.id		= "ipoib",
    121 	.maxattr	= IFLA_IPOIB_MAX,
    122 	.parse_opt	= ipoib_parse_opt,
    123 	.print_opt	= ipoib_print_opt,
    124 	.print_help	= ipoib_print_help,
    125 };
    126