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: 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->ecmp = rt_default_ecmp;
60: RIP_CFG->infinity = RIP_DEFAULT_INFINITY;
61: RIP_CFG->min_timeout_time = 60 S_;
62: RIP_CFG->max_garbage_time = 60 S_;
63: };
64:
65: rip_proto_item:
66: proto_item
67: | proto_channel
68: | ECMP bool { RIP_CFG->ecmp = $2 ? RIP_DEFAULT_ECMP_LIMIT : 0; }
69: | ECMP bool LIMIT expr { RIP_CFG->ecmp = $2 ? $4 : 0; }
70: | INFINITY expr { RIP_CFG->infinity = $2; }
71: | INTERFACE rip_iface
72: ;
73:
74: rip_proto_opts:
75: /* empty */
76: | rip_proto_opts rip_proto_item ';'
77: ;
78:
79: rip_proto:
80: rip_proto_start proto_name '{' rip_proto_opts '}';
81:
82:
83: rip_iface_start:
84: {
85: this_ipatt = cfg_allocz(sizeof(struct rip_iface_config));
86: add_tail(&RIP_CFG->patt_list, NODE this_ipatt);
87: init_list(&this_ipatt->ipn_list);
88: reset_passwords();
89:
90: RIP_IFACE->metric = 1;
91: RIP_IFACE->port = rip_cfg_is_v2() ? RIP_PORT : RIP_NG_PORT;
92: RIP_IFACE->version = rip_cfg_is_v2() ? RIP_V2 : RIP_V1;
93: RIP_IFACE->split_horizon = 1;
94: RIP_IFACE->poison_reverse = 1;
95: RIP_IFACE->check_zero = 1;
96: RIP_IFACE->check_link = 1;
97: RIP_IFACE->ttl_security = rip_cfg_is_v2() ? 0 : 1;
98: RIP_IFACE->rx_buffer = rip_cfg_is_v2() ? RIP_MAX_PKT_LENGTH : 0;
99: RIP_IFACE->tx_length = rip_cfg_is_v2() ? RIP_MAX_PKT_LENGTH : 0;
100: RIP_IFACE->tx_tos = IP_PREC_INTERNET_CONTROL;
101: RIP_IFACE->tx_priority = sk_priority_control;
102: RIP_IFACE->update_time = RIP_DEFAULT_UPDATE_TIME;
103: RIP_IFACE->timeout_time = RIP_DEFAULT_TIMEOUT_TIME;
104: RIP_IFACE->garbage_time = RIP_DEFAULT_GARBAGE_TIME;
105: };
106:
107: rip_iface_finish:
108: {
109: /* Default mode is broadcast for RIPv1, multicast for RIPv2 and RIPng */
110: if (!RIP_IFACE->mode)
111: RIP_IFACE->mode = (rip_cfg_is_v2() && (RIP_IFACE->version == RIP_V1)) ?
112: RIP_IM_BROADCAST : RIP_IM_MULTICAST;
113:
114: RIP_IFACE->passwords = get_passwords();
115:
116: if (!RIP_IFACE->auth_type != !RIP_IFACE->passwords)
117: log(L_WARN "Authentication and password options should be used together");
118:
119: if (RIP_IFACE->passwords)
120: {
121: struct password_item *pass;
122: WALK_LIST(pass, *RIP_IFACE->passwords)
123: {
124: if (pass->alg && (RIP_IFACE->auth_type != RIP_AUTH_CRYPTO))
125: cf_error("Password algorithm option requires cryptographic authentication");
126:
127: /* Set default crypto algorithm (MD5) */
128: if (!pass->alg && (RIP_IFACE->auth_type == RIP_AUTH_CRYPTO))
129: pass->alg = ALG_MD5;
130: }
131: }
132:
133: RIP_CFG->min_timeout_time = MIN_(RIP_CFG->min_timeout_time, RIP_IFACE->timeout_time);
134: RIP_CFG->max_garbage_time = MAX_(RIP_CFG->max_garbage_time, RIP_IFACE->garbage_time);
135: };
136:
137: rip_iface_item:
138: METRIC expr { RIP_IFACE->metric = $2; if (($2<1) || ($2>255)) cf_error("Metric must be in range 1-255"); }
139: | MODE MULTICAST { RIP_IFACE->mode = RIP_IM_MULTICAST; }
140: | MODE BROADCAST { RIP_IFACE->mode = RIP_IM_BROADCAST; if (rip_cfg_is_ng()) cf_error("Broadcast not supported in RIPng"); }
141: | PASSIVE bool { RIP_IFACE->passive = $2; }
142: | ADDRESS ipa { RIP_IFACE->address = $2; if (ipa_is_ip4($2) != rip_cfg_is_v2()) cf_error("IP address version mismatch"); }
143: | PORT expr { RIP_IFACE->port = $2; if (($2<1) || ($2>65535)) cf_error("Invalid port number"); }
144: | VERSION expr { RIP_IFACE->version = $2;
145: if (rip_cfg_is_ng()) cf_error("Version not supported in RIPng");
146: if (($2 != RIP_V1) && ($2 != RIP_V2)) cf_error("Unsupported version");
147: }
148: | VERSION ONLY bool { RIP_IFACE->version_only = $3; }
149: | SPLIT HORIZON bool { RIP_IFACE->split_horizon = $3; }
150: | POISON REVERSE bool { RIP_IFACE->poison_reverse = $3; }
151: | CHECK ZERO bool { RIP_IFACE->check_zero = $3; }
152: | UPDATE TIME expr { RIP_IFACE->update_time = $3 S_; if ($3<=0) cf_error("Update time must be positive"); }
153: | TIMEOUT TIME expr { RIP_IFACE->timeout_time = $3 S_; if ($3<=0) cf_error("Timeout time must be positive"); }
154: | GARBAGE TIME expr { RIP_IFACE->garbage_time = $3 S_; if ($3<=0) cf_error("Garbage time must be positive"); }
155: | ECMP WEIGHT expr { RIP_IFACE->ecmp_weight = $3 - 1; if (($3<1) || ($3>256)) cf_error("ECMP weight must be in range 1-256"); }
156: | RX BUFFER expr { RIP_IFACE->rx_buffer = $3; if (($3<256) || ($3>65535)) cf_error("RX length must be in range 256-65535"); }
157: | TX LENGTH expr { RIP_IFACE->tx_length = $3; if (($3<256) || ($3>65535)) cf_error("TX length must be in range 256-65535"); }
158: | TX tos { RIP_IFACE->tx_tos = $2; }
159: | TX PRIORITY expr { RIP_IFACE->tx_priority = $3; }
160: | TTL SECURITY bool { RIP_IFACE->ttl_security = $3; }
161: | TTL SECURITY TX ONLY { RIP_IFACE->ttl_security = 2; }
162: | CHECK LINK bool { RIP_IFACE->check_link = $3; }
163: | BFD bool { RIP_IFACE->bfd = $2; cf_check_bfd($2); }
164: | AUTHENTICATION rip_auth { RIP_IFACE->auth_type = $2; if ($2) rip_check_auth(); }
165: | password_list { rip_check_auth(); }
166: ;
167:
168: rip_auth:
169: NONE { $$ = RIP_AUTH_NONE; }
170: | PLAINTEXT { $$ = RIP_AUTH_PLAIN; }
171: | CRYPTOGRAPHIC { $$ = RIP_AUTH_CRYPTO; }
172: | MD5 { $$ = RIP_AUTH_CRYPTO; } /* For backward compatibility */
173: ;
174:
175: rip_iface_opts:
176: /* empty */
177: | rip_iface_opts rip_iface_item ';'
178: ;
179:
180: rip_iface_opt_list:
181: /* empty */
182: | '{' rip_iface_opts '}'
183: ;
184:
185: rip_iface:
186: rip_iface_start iface_patt_list_nopx rip_iface_opt_list rip_iface_finish;
187:
188:
189: dynamic_attr: RIP_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_RIP_METRIC); } ;
190: dynamic_attr: RIP_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_RIP_TAG); } ;
191:
192: CF_CLI_HELP(SHOW RIP, ..., [[Show information about RIP protocol]]);
193:
194: CF_CLI(SHOW RIP INTERFACES, optproto opttext, [<name>] [\"<interface>\"], [[Show information about RIP interfaces]])
195: { rip_show_interfaces(proto_get_named($4, &proto_rip), $5); };
196:
197: CF_CLI(SHOW RIP NEIGHBORS, optproto opttext, [<name>] [\"<interface>\"], [[Show information about RIP neighbors]])
198: { rip_show_neighbors(proto_get_named($4, &proto_rip), $5); };
199:
200:
201: CF_CODE
202:
203: CF_END
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>