iproute2/ip/iplink_hsr.c
<<
>>
Prefs
   1/*
   2 * iplink_hsr.c HSR 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:     Arvid Brodin <arvid.brodin@alten.se>
  10 *
  11 *              Based on iplink_vlan.c by Patrick McHardy <kaber@trash.net>
  12 */
  13
  14#include <stdio.h>
  15#include <stdlib.h>
  16#include <string.h>
  17#include <sys/socket.h>  /* Needed by linux/if.h for some reason */
  18#include <linux/if.h>
  19#include <linux/if_arp.h>
  20#include "rt_names.h"
  21#include "utils.h"
  22#include "ip_common.h"
  23
  24static void print_usage(FILE *f)
  25{
  26        fprintf(f,
  27                "Usage:\tip link add name NAME type hsr slave1 SLAVE1-IF slave2 SLAVE2-IF\n"
  28                "\t[ supervision ADDR-BYTE ] [version VERSION] [proto PROTOCOL]\n"
  29                "\n"
  30                "NAME\n"
  31                "       name of new hsr device (e.g. hsr0)\n"
  32                "SLAVE1-IF, SLAVE2-IF\n"
  33                "       the two slave devices bound to the HSR device\n"
  34                "ADDR-BYTE\n"
  35                "       0-255; the last byte of the multicast address used for HSR supervision\n"
  36                "       frames (default = 0)\n"
  37                "VERSION\n"
  38                "       0,1; the protocol version to be used. (default = 0)\n"
  39                "PROTOCOL\n"
  40                "       0 - HSR, 1 - PRP. (default = 0 - HSR)\n");
  41}
  42
  43static void usage(void)
  44{
  45        print_usage(stderr);
  46}
  47
  48static int hsr_parse_opt(struct link_util *lu, int argc, char **argv,
  49                         struct nlmsghdr *n)
  50{
  51        int ifindex;
  52        unsigned char multicast_spec;
  53        unsigned char protocol_version;
  54        unsigned char protocol = HSR_PROTOCOL_HSR;
  55
  56        while (argc > 0) {
  57                if (matches(*argv, "supervision") == 0) {
  58                        NEXT_ARG();
  59                        if (get_u8(&multicast_spec, *argv, 0))
  60                                invarg("ADDR-BYTE is invalid", *argv);
  61                        addattr_l(n, 1024, IFLA_HSR_MULTICAST_SPEC,
  62                                  &multicast_spec, 1);
  63                } else if (matches(*argv, "version") == 0) {
  64                        NEXT_ARG();
  65                        if (!(get_u8(&protocol_version, *argv, 0) == 0 ||
  66                              get_u8(&protocol_version, *argv, 0) == 1))
  67                                invarg("version is invalid", *argv);
  68                        addattr_l(n, 1024, IFLA_HSR_VERSION,
  69                                  &protocol_version, 1);
  70                } else if (matches(*argv, "proto") == 0) {
  71                        NEXT_ARG();
  72                        if (!(get_u8(&protocol, *argv, 0) == HSR_PROTOCOL_HSR ||
  73                              get_u8(&protocol, *argv, 0) == HSR_PROTOCOL_PRP))
  74                                invarg("protocol is invalid", *argv);
  75                        addattr_l(n, 1024, IFLA_HSR_PROTOCOL,
  76                                  &protocol, 1);
  77                } else if (matches(*argv, "slave1") == 0) {
  78                        NEXT_ARG();
  79                        ifindex = ll_name_to_index(*argv);
  80                        if (ifindex == 0)
  81                                invarg("No such interface", *argv);
  82                        addattr_l(n, 1024, IFLA_HSR_SLAVE1, &ifindex, 4);
  83                } else if (matches(*argv, "slave2") == 0) {
  84                        NEXT_ARG();
  85                        ifindex = ll_name_to_index(*argv);
  86                        if (ifindex == 0)
  87                                invarg("No such interface", *argv);
  88                        addattr_l(n, 1024, IFLA_HSR_SLAVE2, &ifindex, 4);
  89                } else if (matches(*argv, "help") == 0) {
  90                        usage();
  91                        return -1;
  92                } else {
  93                        fprintf(stderr, "hsr: what is \"%s\"?\n", *argv);
  94                        usage();
  95                        return -1;
  96                }
  97                argc--, argv++;
  98        }
  99
 100        return 0;
 101}
 102
 103static void hsr_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
 104{
 105        SPRINT_BUF(b1);
 106
 107        if (!tb)
 108                return;
 109
 110        if (tb[IFLA_HSR_SLAVE1] &&
 111            RTA_PAYLOAD(tb[IFLA_HSR_SLAVE1]) < sizeof(__u32))
 112                return;
 113        if (tb[IFLA_HSR_SLAVE2] &&
 114            RTA_PAYLOAD(tb[IFLA_HSR_SLAVE2]) < sizeof(__u32))
 115                return;
 116        if (tb[IFLA_HSR_SEQ_NR] &&
 117            RTA_PAYLOAD(tb[IFLA_HSR_SEQ_NR]) < sizeof(__u16))
 118                return;
 119        if (tb[IFLA_HSR_SUPERVISION_ADDR] &&
 120            RTA_PAYLOAD(tb[IFLA_HSR_SUPERVISION_ADDR]) < ETH_ALEN)
 121                return;
 122
 123        if (tb[IFLA_HSR_SLAVE1])
 124                print_string(PRINT_ANY,
 125                             "slave1",
 126                             "slave1 %s ",
 127                             ll_index_to_name(rta_getattr_u32(tb[IFLA_HSR_SLAVE1])));
 128        else
 129                print_null(PRINT_ANY, "slave1", "slave1 %s ", "<none>");
 130
 131        if (tb[IFLA_HSR_SLAVE2])
 132                print_string(PRINT_ANY,
 133                             "slave2",
 134                             "slave2 %s ",
 135                             ll_index_to_name(rta_getattr_u32(tb[IFLA_HSR_SLAVE2])));
 136        else
 137                print_null(PRINT_ANY, "slave2", "slave2 %s ", "<none>");
 138
 139        if (tb[IFLA_HSR_SEQ_NR])
 140                print_int(PRINT_ANY,
 141                          "seq_nr",
 142                          "sequence %d ",
 143                          rta_getattr_u16(tb[IFLA_HSR_SEQ_NR]));
 144
 145        if (tb[IFLA_HSR_SUPERVISION_ADDR])
 146                print_string(PRINT_ANY,
 147                             "supervision_addr",
 148                             "supervision %s ",
 149                             ll_addr_n2a(RTA_DATA(tb[IFLA_HSR_SUPERVISION_ADDR]),
 150                                         RTA_PAYLOAD(tb[IFLA_HSR_SUPERVISION_ADDR]),
 151                                         ARPHRD_VOID,
 152                                         b1, sizeof(b1)));
 153        if (tb[IFLA_HSR_PROTOCOL])
 154                print_hhu(PRINT_ANY, "proto", "proto %hhu ",
 155                          rta_getattr_u8(tb[IFLA_HSR_PROTOCOL]));
 156}
 157
 158static void hsr_print_help(struct link_util *lu, int argc, char **argv,
 159        FILE *f)
 160{
 161        print_usage(f);
 162}
 163
 164struct link_util hsr_link_util = {
 165        .id             = "hsr",
 166        .maxattr        = IFLA_HSR_MAX,
 167        .parse_opt      = hsr_parse_opt,
 168        .print_opt      = hsr_print_opt,
 169        .print_help     = hsr_print_help,
 170};
 171