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 ]\n"
     26 		"                 [ mode {datagram | connected} ]\n"
     27 		"                 [ umcast {0|1} ]\n"
     28 		"\n"
     29 		"PKEY  := 0x8001-0xffff\n"
     30 	);
     31 }
     32 
     33 static void explain(void)
     34 {
     35 	print_explain(stderr);
     36 }
     37 
     38 static int mode_arg(void)
     39 {
     40 	fprintf(stderr, "Error: argument of \"mode\" must be \"datagram\"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 	__u16 pkey = rta_getattr_u16(tb[IFLA_IPOIB_PKEY]);
     95 
     96 	if (is_json_context()) {
     97 		SPRINT_BUF(b1);
     98 
     99 		snprintf(b1, sizeof(b1), "%#.4x", pkey);
    100 		print_string(PRINT_JSON, "key", NULL, b1);
    101 	} else {
    102 		fprintf(f, "pkey  %#.4x ", pkey);
    103 	}
    104 
    105 	if (!tb[IFLA_IPOIB_MODE] ||
    106 	    RTA_PAYLOAD(tb[IFLA_IPOIB_MODE]) < sizeof(__u16))
    107 		return;
    108 
    109 	mode = rta_getattr_u16(tb[IFLA_IPOIB_MODE]);
    110 
    111 	const char *mode_str =
    112 		mode == IPOIB_MODE_DATAGRAM ? "datagram" :
    113 		mode == IPOIB_MODE_CONNECTED ? "connected" : "unknown";
    114 
    115 	print_string(PRINT_ANY, "mode", "mode  %s ", mode_str);
    116 
    117 	if (!tb[IFLA_IPOIB_UMCAST] ||
    118 	    RTA_PAYLOAD(tb[IFLA_IPOIB_UMCAST]) < sizeof(__u16))
    119 		return;
    120 
    121 	__u16 umcast = rta_getattr_u16(tb[IFLA_IPOIB_UMCAST]);
    122 
    123 	if (is_json_context()) {
    124 		SPRINT_BUF(b1);
    125 
    126 		snprintf(b1, sizeof(b1), "%.4x", umcast);
    127 		print_string(PRINT_JSON, "umcast", NULL, b1);
    128 	} else {
    129 		fprintf(f, "umcast  %.4x ", umcast);
    130 	}
    131 }
    132 
    133 static void ipoib_print_help(struct link_util *lu, int argc, char **argv,
    134 	FILE *f)
    135 {
    136 	print_explain(f);
    137 }
    138 
    139 struct link_util ipoib_link_util = {
    140 	.id		= "ipoib",
    141 	.maxattr	= IFLA_IPOIB_MAX,
    142 	.parse_opt	= ipoib_parse_opt,
    143 	.print_opt	= ipoib_print_opt,
    144 	.print_help	= ipoib_print_help,
    145 };
    146