iproute2/ip/iplink_ipoib.c
<<
>>
Prefs
   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@mellanox.com>
  10 *              copied iflink_vlan.c authored by Patrick McHardy <kaber@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
  22static 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
  33static void explain(void)
  34{
  35        print_explain(stderr);
  36}
  37
  38static int mode_arg(void)
  39{
  40        fprintf(stderr, "Error: argument of \"mode\" must be \"datagram\"or \"connected\"\n");
  41        return -1;
  42}
  43
  44static 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
  83static 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
 133static void ipoib_print_help(struct link_util *lu, int argc, char **argv,
 134        FILE *f)
 135{
 136        print_explain(f);
 137}
 138
 139struct 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