]>
Commit | Line | Data |
---|---|---|
c74c0e3c MM |
1 | /* |
2 | * BIRD -- RIP Configuration | |
3 | * | |
8465dccb OZ |
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 | * | |
c74c0e3c MM |
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" | |
2d9290e9 PM |
15 | #include "nest/iface.h" |
16 | ||
2edb31b0 MM |
17 | CF_DEFINES |
18 | ||
8465dccb OZ |
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 | } | |
c74c0e3c | 31 | |
70e212f9 | 32 | |
c74c0e3c MM |
33 | CF_DECLS |
34 | ||
da3cf9ea | 35 | CF_KEYWORDS(RIP, NG, ECMP, LIMIT, WEIGHT, INFINITY, METRIC, UPDATE, TIMEOUT, |
8465dccb OZ |
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, | |
22c3cf95 OZ |
39 | RX, TX, BUFFER, LENGTH, PRIORITY, ONLY, LINK, DEMAND, CIRCUIT, |
40 | RIP_METRIC, RIP_TAG) | |
50e89a6e | 41 | |
23c212e7 | 42 | %type <i> rip_variant rip_auth |
c74c0e3c MM |
43 | |
44 | CF_GRAMMAR | |
45 | ||
f851f0d7 | 46 | proto: rip_proto ; |
c74c0e3c | 47 | |
23c212e7 | 48 | rip_variant: |
da3cf9ea OZ |
49 | RIP { $$ = 1; } |
50 | | RIP NG { $$ = 0; } | |
23c212e7 OZ |
51 | ; |
52 | ||
53 | rip_proto_start: proto_start rip_variant | |
8465dccb OZ |
54 | { |
55 | this_proto = proto_config_new(&proto_rip, $1); | |
f4a60a9b | 56 | this_proto->net_type = $2 ? NET_IP4 : NET_IP6; |
c74c0e3c | 57 | |
f4a60a9b | 58 | init_list(&RIP_CFG->patt_list); |
23c212e7 | 59 | RIP_CFG->rip2 = $2; |
517d05df | 60 | RIP_CFG->ecmp = rt_default_ecmp; |
8465dccb | 61 | RIP_CFG->infinity = RIP_DEFAULT_INFINITY; |
92cc1e74 OZ |
62 | RIP_CFG->min_timeout_time = 60 S_; |
63 | RIP_CFG->max_garbage_time = 60 S_; | |
8465dccb | 64 | }; |
50e89a6e | 65 | |
8465dccb OZ |
66 | rip_proto_item: |
67 | proto_item | |
f4a60a9b | 68 | | proto_channel |
8465dccb | 69 | | ECMP bool { RIP_CFG->ecmp = $2 ? RIP_DEFAULT_ECMP_LIMIT : 0; } |
6aaaa635 | 70 | | ECMP bool LIMIT expr { RIP_CFG->ecmp = $2 ? $4 : 0; } |
8465dccb OZ |
71 | | INFINITY expr { RIP_CFG->infinity = $2; } |
72 | | INTERFACE rip_iface | |
73 | ; | |
20e94fb8 | 74 | |
8465dccb OZ |
75 | rip_proto_opts: |
76 | /* empty */ | |
77 | | rip_proto_opts rip_proto_item ';' | |
50e89a6e PM |
78 | ; |
79 | ||
8465dccb OZ |
80 | rip_proto: |
81 | rip_proto_start proto_name '{' rip_proto_opts '}'; | |
82 | ||
83 | ||
84 | rip_iface_start: | |
85 | { | |
86 | this_ipatt = cfg_allocz(sizeof(struct rip_iface_config)); | |
87 | add_tail(&RIP_CFG->patt_list, NODE this_ipatt); | |
88 | init_list(&this_ipatt->ipn_list); | |
89 | reset_passwords(); | |
90 | ||
91 | RIP_IFACE->metric = 1; | |
92 | RIP_IFACE->port = rip_cfg_is_v2() ? RIP_PORT : RIP_NG_PORT; | |
93 | RIP_IFACE->version = rip_cfg_is_v2() ? RIP_V2 : RIP_V1; | |
94 | RIP_IFACE->split_horizon = 1; | |
95 | RIP_IFACE->poison_reverse = 1; | |
96 | RIP_IFACE->check_zero = 1; | |
517d05df | 97 | RIP_IFACE->check_link = 1; |
8465dccb OZ |
98 | RIP_IFACE->ttl_security = rip_cfg_is_v2() ? 0 : 1; |
99 | RIP_IFACE->rx_buffer = rip_cfg_is_v2() ? RIP_MAX_PKT_LENGTH : 0; | |
100 | RIP_IFACE->tx_length = rip_cfg_is_v2() ? RIP_MAX_PKT_LENGTH : 0; | |
101 | RIP_IFACE->tx_tos = IP_PREC_INTERNET_CONTROL; | |
102 | RIP_IFACE->tx_priority = sk_priority_control; | |
103 | RIP_IFACE->update_time = RIP_DEFAULT_UPDATE_TIME; | |
104 | RIP_IFACE->timeout_time = RIP_DEFAULT_TIMEOUT_TIME; | |
105 | RIP_IFACE->garbage_time = RIP_DEFAULT_GARBAGE_TIME; | |
22c3cf95 | 106 | RIP_IFACE->rxmt_time = RIP_DEFAULT_RXMT_TIME; |
8465dccb OZ |
107 | }; |
108 | ||
109 | rip_iface_finish: | |
110 | { | |
390601f0 OZ |
111 | /* Default mode is broadcast for RIPv1, multicast for RIPv2 and RIPng */ |
112 | if (!RIP_IFACE->mode) | |
113 | RIP_IFACE->mode = (rip_cfg_is_v2() && (RIP_IFACE->version == RIP_V1)) ? | |
114 | RIP_IM_BROADCAST : RIP_IM_MULTICAST; | |
115 | ||
8465dccb OZ |
116 | RIP_IFACE->passwords = get_passwords(); |
117 | ||
118 | if (!RIP_IFACE->auth_type != !RIP_IFACE->passwords) | |
119 | log(L_WARN "Authentication and password options should be used together"); | |
120 | ||
390601f0 OZ |
121 | if (RIP_IFACE->passwords) |
122 | { | |
123 | struct password_item *pass; | |
124 | WALK_LIST(pass, *RIP_IFACE->passwords) | |
125 | { | |
126 | if (pass->alg && (RIP_IFACE->auth_type != RIP_AUTH_CRYPTO)) | |
127 | cf_error("Password algorithm option requires cryptographic authentication"); | |
128 | ||
129 | /* Set default crypto algorithm (MD5) */ | |
130 | if (!pass->alg && (RIP_IFACE->auth_type == RIP_AUTH_CRYPTO)) | |
131 | pass->alg = ALG_MD5; | |
132 | } | |
133 | } | |
8465dccb OZ |
134 | |
135 | RIP_CFG->min_timeout_time = MIN_(RIP_CFG->min_timeout_time, RIP_IFACE->timeout_time); | |
136 | RIP_CFG->max_garbage_time = MAX_(RIP_CFG->max_garbage_time, RIP_IFACE->garbage_time); | |
137 | }; | |
138 | ||
2d9290e9 | 139 | rip_iface_item: |
8465dccb OZ |
140 | METRIC expr { RIP_IFACE->metric = $2; if (($2<1) || ($2>255)) cf_error("Metric must be in range 1-255"); } |
141 | | MODE MULTICAST { RIP_IFACE->mode = RIP_IM_MULTICAST; } | |
142 | | MODE BROADCAST { RIP_IFACE->mode = RIP_IM_BROADCAST; if (rip_cfg_is_ng()) cf_error("Broadcast not supported in RIPng"); } | |
143 | | PASSIVE bool { RIP_IFACE->passive = $2; } | |
08b3a24d | 144 | | ADDRESS ipa { RIP_IFACE->address = $2; if (ipa_is_ip4($2) != rip_cfg_is_v2()) cf_error("IP address version mismatch"); } |
8465dccb OZ |
145 | | PORT expr { RIP_IFACE->port = $2; if (($2<1) || ($2>65535)) cf_error("Invalid port number"); } |
146 | | VERSION expr { RIP_IFACE->version = $2; | |
147 | if (rip_cfg_is_ng()) cf_error("Version not supported in RIPng"); | |
148 | if (($2 != RIP_V1) && ($2 != RIP_V2)) cf_error("Unsupported version"); | |
149 | } | |
150 | | VERSION ONLY bool { RIP_IFACE->version_only = $3; } | |
151 | | SPLIT HORIZON bool { RIP_IFACE->split_horizon = $3; } | |
152 | | POISON REVERSE bool { RIP_IFACE->poison_reverse = $3; } | |
153 | | CHECK ZERO bool { RIP_IFACE->check_zero = $3; } | |
22c3cf95 | 154 | | DEMAND CIRCUIT bool { RIP_IFACE->demand_circuit = $3; } |
ee528fbd OZ |
155 | | UPDATE TIME expr { RIP_IFACE->update_time = $3 S_; if ($3<=0) cf_error("Update time must be positive"); } |
156 | | TIMEOUT TIME expr { RIP_IFACE->timeout_time = $3 S_; if ($3<=0) cf_error("Timeout time must be positive"); } | |
157 | | GARBAGE TIME expr { RIP_IFACE->garbage_time = $3 S_; if ($3<=0) cf_error("Garbage time must be positive"); } | |
22c3cf95 | 158 | | RETRANSMIT TIME expr_us { RIP_IFACE->rxmt_time = $3; if ($3<=0) cf_error("Retransmit time must be positive"); } |
8465dccb | 159 | | ECMP WEIGHT expr { RIP_IFACE->ecmp_weight = $3 - 1; if (($3<1) || ($3>256)) cf_error("ECMP weight must be in range 1-256"); } |
9036bbf2 | 160 | | RX BUFFER expr { RIP_IFACE->rx_buffer = $3; if (($3<256) || ($3>65535)) cf_error("RX length must be in range 256-65535"); } |
8465dccb OZ |
161 | | TX LENGTH expr { RIP_IFACE->tx_length = $3; if (($3<256) || ($3>65535)) cf_error("TX length must be in range 256-65535"); } |
162 | | TX tos { RIP_IFACE->tx_tos = $2; } | |
163 | | TX PRIORITY expr { RIP_IFACE->tx_priority = $3; } | |
164 | | TTL SECURITY bool { RIP_IFACE->ttl_security = $3; } | |
165 | | TTL SECURITY TX ONLY { RIP_IFACE->ttl_security = 2; } | |
166 | | CHECK LINK bool { RIP_IFACE->check_link = $3; } | |
167 | | BFD bool { RIP_IFACE->bfd = $2; cf_check_bfd($2); } | |
168 | | AUTHENTICATION rip_auth { RIP_IFACE->auth_type = $2; if ($2) rip_check_auth(); } | |
169 | | password_list { rip_check_auth(); } | |
170 | ; | |
171 | ||
172 | rip_auth: | |
173 | NONE { $$ = RIP_AUTH_NONE; } | |
174 | | PLAINTEXT { $$ = RIP_AUTH_PLAIN; } | |
175 | | CRYPTOGRAPHIC { $$ = RIP_AUTH_CRYPTO; } | |
56cb3bed | 176 | | MD5 { $$ = RIP_AUTH_CRYPTO; } /* For backward compatibility */ |
2d9290e9 PM |
177 | ; |
178 | ||
8465dccb | 179 | rip_iface_opts: |
20e94fb8 | 180 | /* empty */ |
2d9290e9 PM |
181 | | rip_iface_opts rip_iface_item ';' |
182 | ; | |
183 | ||
20e94fb8 OZ |
184 | rip_iface_opt_list: |
185 | /* empty */ | |
186 | | '{' rip_iface_opts '}' | |
187 | ; | |
2d9290e9 | 188 | |
8465dccb OZ |
189 | rip_iface: |
190 | rip_iface_start iface_patt_list_nopx rip_iface_opt_list rip_iface_finish; | |
c74c0e3c | 191 | |
2d9290e9 | 192 | |
78976974 MM |
193 | dynamic_attr: RIP_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_RIP_METRIC); } ; |
194 | dynamic_attr: RIP_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_RIP_TAG); } ; | |
db1326aa | 195 | |
8465dccb OZ |
196 | CF_CLI_HELP(SHOW RIP, ..., [[Show information about RIP protocol]]); |
197 | ||
c0e958e0 | 198 | CF_CLI(SHOW RIP INTERFACES, optproto opttext, [<name>] [\"<interface>\"], [[Show information about RIP interfaces]]) |
8465dccb OZ |
199 | { rip_show_interfaces(proto_get_named($4, &proto_rip), $5); }; |
200 | ||
c0e958e0 | 201 | CF_CLI(SHOW RIP NEIGHBORS, optproto opttext, [<name>] [\"<interface>\"], [[Show information about RIP neighbors]]) |
8465dccb OZ |
202 | { rip_show_neighbors(proto_get_named($4, &proto_rip), $5); }; |
203 | ||
204 | ||
8edf2361 | 205 | CF_CODE |
2d9290e9 | 206 | |
c74c0e3c | 207 | CF_END |