]> git.proxmox.com Git - mirror_iproute2.git/blame - ip/iplink_hsr.c
bridge: fdb: add support for src_vni option
[mirror_iproute2.git] / ip / iplink_hsr.c
CommitLineData
5c0aec93
AB
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
561e650e 24static void print_usage(FILE *f)
5c0aec93 25{
561e650e 26 fprintf(f,
5c0aec93 27"Usage:\tip link add name NAME type hsr slave1 SLAVE1-IF slave2 SLAVE2-IF\n"
4273f100 28"\t[ supervision ADDR-BYTE ] [version VERSION]\n"
5c0aec93
AB
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"
4273f100
PH
36" frames (default = 0)\n"
37"VERSION\n"
38" 0,1; the protocol version to be used. (default = 0)\n");
5c0aec93
AB
39}
40
561e650e 41static void usage(void)
42{
43 print_usage(stderr);
44}
45
5c0aec93
AB
46static 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;
4273f100 51 unsigned char protocol_version;
5c0aec93
AB
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);
4273f100
PH
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);
5c0aec93
AB
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
93static 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
5c0aec93 113 if (tb[IFLA_HSR_SLAVE1])
69ffd273
JF
114 print_string(PRINT_ANY,
115 "slave1",
116 "slave1 %s ",
117 ll_index_to_name(rta_getattr_u32(tb[IFLA_HSR_SLAVE1])));
5c0aec93 118 else
69ffd273 119 print_null(PRINT_ANY, "slave1", "slave1 %s ", "<none>");
5c0aec93 120
5c0aec93 121 if (tb[IFLA_HSR_SLAVE2])
69ffd273
JF
122 print_string(PRINT_ANY,
123 "slave2",
124 "slave2 %s ",
125 ll_index_to_name(rta_getattr_u32(tb[IFLA_HSR_SLAVE2])));
5c0aec93 126 else
69ffd273 127 print_null(PRINT_ANY, "slave2", "slave2 %s ", "<none>");
5c0aec93
AB
128
129 if (tb[IFLA_HSR_SEQ_NR])
69ffd273
JF
130 print_int(PRINT_ANY,
131 "seq_nr",
132 "sequence %d ",
133 rta_getattr_u16(tb[IFLA_HSR_SEQ_NR]));
5c0aec93
AB
134
135 if (tb[IFLA_HSR_SUPERVISION_ADDR])
69ffd273
JF
136 print_string(PRINT_ANY,
137 "supervision_addr",
138 "supervision %s ",
139 ll_addr_n2a(RTA_DATA(tb[IFLA_HSR_SUPERVISION_ADDR]),
140 RTA_PAYLOAD(tb[IFLA_HSR_SUPERVISION_ADDR]),
141 ARPHRD_VOID,
142 b1, sizeof(b1)));
5c0aec93
AB
143}
144
561e650e 145static void hsr_print_help(struct link_util *lu, int argc, char **argv,
146 FILE *f)
147{
148 print_usage(f);
149}
150
5c0aec93
AB
151struct link_util hsr_link_util = {
152 .id = "hsr",
e7867c34 153 .maxattr = IFLA_HSR_MAX,
5c0aec93
AB
154 .parse_opt = hsr_parse_opt,
155 .print_opt = hsr_print_opt,
561e650e 156 .print_help = hsr_print_help,
5c0aec93 157};