]> git.ipfire.org Git - thirdparty/bird.git/blob - proto/rip/config.Y
Merge branch 'master' into int-new
[thirdparty/bird.git] / proto / rip / config.Y
1 /*
2 * BIRD -- RIP Configuration
3 *
4 * (c) 1998--1999 Pavel Machek <pavel@ucw.cz>
5 * (c) 2004--2013 Ondrej Filip <feela@network.cz>
6 * (c) 2009--2015 Ondrej Zajicek <santiago@crfreenet.org>
7 * (c) 2009--2015 CZ.NIC z.s.p.o.
8 *
9 * Can be freely distributed and used under the terms of the GNU GPL.
10 */
11
12 CF_HDR
13
14 #include "proto/rip/rip.h"
15 #include "nest/iface.h"
16
17 CF_DEFINES
18
19 #define RIP_CFG ((struct rip_config *) this_proto)
20 #define RIP_IFACE ((struct rip_iface_config *) this_ipatt)
21
22 static inline int rip_cfg_is_v2(void) { return RIP_CFG->rip2; }
23 static inline int rip_cfg_is_ng(void) { return ! RIP_CFG->rip2; }
24
25 static inline void
26 rip_check_auth(void)
27 {
28 if (rip_cfg_is_ng())
29 cf_error("Authentication not supported in RIPng");
30 }
31
32
33 CF_DECLS
34
35 CF_KEYWORDS(RIP, NG, ECMP, LIMIT, WEIGHT, INFINITY, METRIC, UPDATE, TIMEOUT,
36 GARBAGE, PORT, ADDRESS, MODE, BROADCAST, MULTICAST, PASSIVE,
37 VERSION, SPLIT, HORIZON, POISON, REVERSE, CHECK, ZERO, TIME, BFD,
38 AUTHENTICATION, NONE, PLAINTEXT, CRYPTOGRAPHIC, MD5, TTL, SECURITY,
39 RX, TX, BUFFER, LENGTH, PRIORITY, ONLY, LINK, RIP_METRIC, RIP_TAG)
40
41 %type <i> rip_variant rip_auth
42
43 CF_GRAMMAR
44
45 CF_ADDTO(proto, rip_proto)
46
47 rip_variant:
48 RIP { $$ = 1; }
49 | RIP NG { $$ = 0; }
50 ;
51
52 rip_proto_start: proto_start rip_variant
53 {
54 this_proto = proto_config_new(&proto_rip, $1);
55 this_proto->net_type = $2 ? NET_IP4 : NET_IP6;
56
57 init_list(&RIP_CFG->patt_list);
58 RIP_CFG->rip2 = $2;
59 RIP_CFG->infinity = RIP_DEFAULT_INFINITY;
60 RIP_CFG->min_timeout_time = 60;
61 RIP_CFG->max_garbage_time = 60;
62 };
63
64 rip_proto_item:
65 proto_item
66 | proto_channel
67 | ECMP bool { RIP_CFG->ecmp = $2 ? RIP_DEFAULT_ECMP_LIMIT : 0; }
68 | ECMP bool LIMIT expr { RIP_CFG->ecmp = $2 ? $4 : 0; }
69 | INFINITY expr { RIP_CFG->infinity = $2; }
70 | INTERFACE rip_iface
71 ;
72
73 rip_proto_opts:
74 /* empty */
75 | rip_proto_opts rip_proto_item ';'
76 ;
77
78 rip_proto:
79 rip_proto_start proto_name '{' rip_proto_opts '}';
80
81
82 rip_iface_start:
83 {
84 this_ipatt = cfg_allocz(sizeof(struct rip_iface_config));
85 add_tail(&RIP_CFG->patt_list, NODE this_ipatt);
86 init_list(&this_ipatt->ipn_list);
87 reset_passwords();
88
89 RIP_IFACE->metric = 1;
90 RIP_IFACE->port = rip_cfg_is_v2() ? RIP_PORT : RIP_NG_PORT;
91 RIP_IFACE->version = rip_cfg_is_v2() ? RIP_V2 : RIP_V1;
92 RIP_IFACE->split_horizon = 1;
93 RIP_IFACE->poison_reverse = 1;
94 RIP_IFACE->check_zero = 1;
95 RIP_IFACE->ttl_security = rip_cfg_is_v2() ? 0 : 1;
96 RIP_IFACE->rx_buffer = rip_cfg_is_v2() ? RIP_MAX_PKT_LENGTH : 0;
97 RIP_IFACE->tx_length = rip_cfg_is_v2() ? RIP_MAX_PKT_LENGTH : 0;
98 RIP_IFACE->tx_tos = IP_PREC_INTERNET_CONTROL;
99 RIP_IFACE->tx_priority = sk_priority_control;
100 RIP_IFACE->update_time = RIP_DEFAULT_UPDATE_TIME;
101 RIP_IFACE->timeout_time = RIP_DEFAULT_TIMEOUT_TIME;
102 RIP_IFACE->garbage_time = RIP_DEFAULT_GARBAGE_TIME;
103 };
104
105 rip_iface_finish:
106 {
107 /* Default mode is broadcast for RIPv1, multicast for RIPv2 and RIPng */
108 if (!RIP_IFACE->mode)
109 RIP_IFACE->mode = (rip_cfg_is_v2() && (RIP_IFACE->version == RIP_V1)) ?
110 RIP_IM_BROADCAST : RIP_IM_MULTICAST;
111
112 RIP_IFACE->passwords = get_passwords();
113
114 if (!RIP_IFACE->auth_type != !RIP_IFACE->passwords)
115 log(L_WARN "Authentication and password options should be used together");
116
117 if (RIP_IFACE->passwords)
118 {
119 struct password_item *pass;
120 WALK_LIST(pass, *RIP_IFACE->passwords)
121 {
122 if (pass->alg && (RIP_IFACE->auth_type != RIP_AUTH_CRYPTO))
123 cf_error("Password algorithm option requires cryptographic authentication");
124
125 /* Set default crypto algorithm (MD5) */
126 if (!pass->alg && (RIP_IFACE->auth_type == RIP_AUTH_CRYPTO))
127 pass->alg = ALG_MD5;
128 }
129 }
130
131 RIP_CFG->min_timeout_time = MIN_(RIP_CFG->min_timeout_time, RIP_IFACE->timeout_time);
132 RIP_CFG->max_garbage_time = MAX_(RIP_CFG->max_garbage_time, RIP_IFACE->garbage_time);
133 };
134
135 rip_iface_item:
136 METRIC expr { RIP_IFACE->metric = $2; if (($2<1) || ($2>255)) cf_error("Metric must be in range 1-255"); }
137 | MODE MULTICAST { RIP_IFACE->mode = RIP_IM_MULTICAST; }
138 | MODE BROADCAST { RIP_IFACE->mode = RIP_IM_BROADCAST; if (rip_cfg_is_ng()) cf_error("Broadcast not supported in RIPng"); }
139 | PASSIVE bool { RIP_IFACE->passive = $2; }
140 | ADDRESS ipa { RIP_IFACE->address = $2; if (ipa_is_ip4($2) != rip_cfg_is_v2()) cf_error("IP address version mismatch"); }
141 | PORT expr { RIP_IFACE->port = $2; if (($2<1) || ($2>65535)) cf_error("Invalid port number"); }
142 | VERSION expr { RIP_IFACE->version = $2;
143 if (rip_cfg_is_ng()) cf_error("Version not supported in RIPng");
144 if (($2 != RIP_V1) && ($2 != RIP_V2)) cf_error("Unsupported version");
145 }
146 | VERSION ONLY bool { RIP_IFACE->version_only = $3; }
147 | SPLIT HORIZON bool { RIP_IFACE->split_horizon = $3; }
148 | POISON REVERSE bool { RIP_IFACE->poison_reverse = $3; }
149 | CHECK ZERO bool { RIP_IFACE->check_zero = $3; }
150 | UPDATE TIME expr { RIP_IFACE->update_time = $3; if ($3<=0) cf_error("Update time must be positive"); }
151 | TIMEOUT TIME expr { RIP_IFACE->timeout_time = $3; if ($3<=0) cf_error("Timeout time must be positive"); }
152 | GARBAGE TIME expr { RIP_IFACE->garbage_time = $3; if ($3<=0) cf_error("Garbage time must be positive"); }
153 | ECMP WEIGHT expr { RIP_IFACE->ecmp_weight = $3 - 1; if (($3<1) || ($3>256)) cf_error("ECMP weight must be in range 1-256"); }
154 | RX BUFFER expr { RIP_IFACE->rx_buffer = $3; if (($3<256) || ($3>65535)) cf_error("RX length must be in range 256-65535"); }
155 | TX LENGTH expr { RIP_IFACE->tx_length = $3; if (($3<256) || ($3>65535)) cf_error("TX length must be in range 256-65535"); }
156 | TX tos { RIP_IFACE->tx_tos = $2; }
157 | TX PRIORITY expr { RIP_IFACE->tx_priority = $3; }
158 | TTL SECURITY bool { RIP_IFACE->ttl_security = $3; }
159 | TTL SECURITY TX ONLY { RIP_IFACE->ttl_security = 2; }
160 | CHECK LINK bool { RIP_IFACE->check_link = $3; }
161 | BFD bool { RIP_IFACE->bfd = $2; cf_check_bfd($2); }
162 | AUTHENTICATION rip_auth { RIP_IFACE->auth_type = $2; if ($2) rip_check_auth(); }
163 | password_list { rip_check_auth(); }
164 ;
165
166 rip_auth:
167 NONE { $$ = RIP_AUTH_NONE; }
168 | PLAINTEXT { $$ = RIP_AUTH_PLAIN; }
169 | CRYPTOGRAPHIC { $$ = RIP_AUTH_CRYPTO; }
170 | MD5 { $$ = RIP_AUTH_CRYPTO; } /* For backward compatibility */
171 ;
172
173 rip_iface_opts:
174 /* empty */
175 | rip_iface_opts rip_iface_item ';'
176 ;
177
178 rip_iface_opt_list:
179 /* empty */
180 | '{' rip_iface_opts '}'
181 ;
182
183 rip_iface:
184 rip_iface_start iface_patt_list_nopx rip_iface_opt_list rip_iface_finish;
185
186
187 CF_ADDTO(dynamic_attr, RIP_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_RIP_METRIC); })
188 CF_ADDTO(dynamic_attr, RIP_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_RIP_TAG); })
189
190 CF_CLI_HELP(SHOW RIP, ..., [[Show information about RIP protocol]]);
191
192 CF_CLI(SHOW RIP INTERFACES, optsym opttext, [<name>] [\"<interface>\"], [[Show information about RIP interfaces]])
193 { rip_show_interfaces(proto_get_named($4, &proto_rip), $5); };
194
195 CF_CLI(SHOW RIP NEIGHBORS, optsym opttext, [<name>] [\"<interface>\"], [[Show information about RIP neighbors]])
196 { rip_show_neighbors(proto_get_named($4, &proto_rip), $5); };
197
198
199 CF_CODE
200
201 CF_END