]> git.proxmox.com Git - mirror_iproute2.git/blob - ip/iplink_hsr.c
iproute_lwtunnel: Argument to strerror must be positive
[mirror_iproute2.git] / ip / iplink_hsr.c
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
24 static 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]\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 }
40
41 static void usage(void)
42 {
43 print_usage(stderr);
44 }
45
46 static int hsr_parse_opt(struct link_util *lu, int argc, char **argv,
47 struct nlmsghdr *n)
48 {
49 int ifindex;
50 unsigned char multicast_spec;
51 unsigned char protocol_version;
52
53 while (argc > 0) {
54 if (matches(*argv, "supervision") == 0) {
55 NEXT_ARG();
56 if (get_u8(&multicast_spec, *argv, 0))
57 invarg("ADDR-BYTE is invalid", *argv);
58 addattr_l(n, 1024, IFLA_HSR_MULTICAST_SPEC,
59 &multicast_spec, 1);
60 } else if (matches(*argv, "version") == 0) {
61 NEXT_ARG();
62 if (!(get_u8(&protocol_version, *argv, 0) == 0 ||
63 get_u8(&protocol_version, *argv, 0) == 1))
64 invarg("version is invalid", *argv);
65 addattr_l(n, 1024, IFLA_HSR_VERSION,
66 &protocol_version, 1);
67 } else if (matches(*argv, "slave1") == 0) {
68 NEXT_ARG();
69 ifindex = ll_name_to_index(*argv);
70 if (ifindex == 0)
71 invarg("No such interface", *argv);
72 addattr_l(n, 1024, IFLA_HSR_SLAVE1, &ifindex, 4);
73 } else if (matches(*argv, "slave2") == 0) {
74 NEXT_ARG();
75 ifindex = ll_name_to_index(*argv);
76 if (ifindex == 0)
77 invarg("No such interface", *argv);
78 addattr_l(n, 1024, IFLA_HSR_SLAVE2, &ifindex, 4);
79 } else if (matches(*argv, "help") == 0) {
80 usage();
81 return -1;
82 } else {
83 fprintf(stderr, "hsr: what is \"%s\"?\n", *argv);
84 usage();
85 return -1;
86 }
87 argc--, argv++;
88 }
89
90 return 0;
91 }
92
93 static void hsr_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
94 {
95 SPRINT_BUF(b1);
96
97 if (!tb)
98 return;
99
100 if (tb[IFLA_HSR_SLAVE1] &&
101 RTA_PAYLOAD(tb[IFLA_HSR_SLAVE1]) < sizeof(__u32))
102 return;
103 if (tb[IFLA_HSR_SLAVE2] &&
104 RTA_PAYLOAD(tb[IFLA_HSR_SLAVE2]) < sizeof(__u32))
105 return;
106 if (tb[IFLA_HSR_SEQ_NR] &&
107 RTA_PAYLOAD(tb[IFLA_HSR_SEQ_NR]) < sizeof(__u16))
108 return;
109 if (tb[IFLA_HSR_SUPERVISION_ADDR] &&
110 RTA_PAYLOAD(tb[IFLA_HSR_SUPERVISION_ADDR]) < ETH_ALEN)
111 return;
112
113 fprintf(f, "slave1 ");
114 if (tb[IFLA_HSR_SLAVE1])
115 fprintf(f, "%s ",
116 ll_index_to_name(rta_getattr_u32(tb[IFLA_HSR_SLAVE1])));
117 else
118 fprintf(f, "<none> ");
119
120 fprintf(f, "slave2 ");
121 if (tb[IFLA_HSR_SLAVE2])
122 fprintf(f, "%s ",
123 ll_index_to_name(rta_getattr_u32(tb[IFLA_HSR_SLAVE2])));
124 else
125 fprintf(f, "<none> ");
126
127 if (tb[IFLA_HSR_SEQ_NR])
128 fprintf(f, "sequence %d ",
129 rta_getattr_u16(tb[IFLA_HSR_SEQ_NR]));
130
131 if (tb[IFLA_HSR_SUPERVISION_ADDR])
132 fprintf(f, "supervision %s ",
133 ll_addr_n2a(RTA_DATA(tb[IFLA_HSR_SUPERVISION_ADDR]),
134 RTA_PAYLOAD(tb[IFLA_HSR_SUPERVISION_ADDR]),
135 ARPHRD_VOID,
136 b1, sizeof(b1)));
137 }
138
139 static void hsr_print_help(struct link_util *lu, int argc, char **argv,
140 FILE *f)
141 {
142 print_usage(f);
143 }
144
145 struct link_util hsr_link_util = {
146 .id = "hsr",
147 .maxattr = IFLA_HSR_MAX,
148 .parse_opt = hsr_parse_opt,
149 .print_opt = hsr_print_opt,
150 .print_help = hsr_print_help,
151 };