Return to config.Y CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird2 / proto / radv |
1.1 ! misho 1: /* ! 2: * BIRD -- Router Advertisement Configuration ! 3: * ! 4: * (c) 2011--2019 Ondrej Zajicek <santiago@crfreenet.org> ! 5: * (c) 2011--2019 CZ.NIC z.s.p.o. ! 6: * ! 7: * Can be freely distributed and used under the terms of the GNU GPL. ! 8: */ ! 9: ! 10: CF_HDR ! 11: ! 12: #include "proto/radv/radv.h" ! 13: ! 14: CF_DEFINES ! 15: ! 16: #define RADV_CFG ((struct radv_config *) this_proto) ! 17: #define RADV_IFACE ((struct radv_iface_config *) this_ipatt) ! 18: #define RADV_PREFIX this_radv_prefix ! 19: #define RADV_RDNSS (&this_radv_rdnss) ! 20: #define RADV_DNSSL (&this_radv_dnssl) ! 21: ! 22: static struct radv_prefix_config *this_radv_prefix; ! 23: static struct radv_rdnss_config this_radv_rdnss; ! 24: static struct radv_dnssl_config this_radv_dnssl; ! 25: static list radv_dns_list; /* Used by radv_rdnss and radv_dnssl */ ! 26: static u8 radv_mult_val; /* Used by radv_mult for second return value */ ! 27: ! 28: ! 29: CF_DECLS ! 30: ! 31: CF_KEYWORDS(RADV, PREFIX, INTERFACE, MIN, MAX, RA, DELAY, INTERVAL, SOLICITED, ! 32: UNICAST, MANAGED, OTHER, CONFIG, LINGER, LINK, MTU, REACHABLE, TIME, ! 33: RETRANS, TIMER, CURRENT, HOP, LIMIT, DEFAULT, VALID, PREFERRED, MULT, ! 34: LIFETIME, SKIP, ONLINK, AUTONOMOUS, RDNSS, DNSSL, NS, DOMAIN, LOCAL, ! 35: TRIGGER, SENSITIVE, PREFERENCE, LOW, MEDIUM, HIGH, PROPAGATE, ROUTE, ! 36: ROUTES, RA_PREFERENCE, RA_LIFETIME) ! 37: ! 38: CF_ENUM(T_ENUM_RA_PREFERENCE, RA_PREF_, LOW, MEDIUM, HIGH) ! 39: ! 40: %type<i> radv_mult radv_sensitive radv_preference ! 41: ! 42: CF_GRAMMAR ! 43: ! 44: proto: radv_proto ; ! 45: ! 46: radv_proto_start: proto_start RADV ! 47: { ! 48: this_proto = proto_config_new(&proto_radv, $1); ! 49: ! 50: init_list(&RADV_CFG->patt_list); ! 51: init_list(&RADV_CFG->pref_list); ! 52: init_list(&RADV_CFG->rdnss_list); ! 53: init_list(&RADV_CFG->dnssl_list); ! 54: }; ! 55: ! 56: radv_proto_item: ! 57: proto_item ! 58: | proto_channel ! 59: | INTERFACE radv_iface ! 60: | PREFIX radv_prefix { add_tail(&RADV_CFG->pref_list, NODE this_radv_prefix); } ! 61: | RDNSS { init_list(&radv_dns_list); } radv_rdnss { add_tail_list(&RADV_CFG->rdnss_list, &radv_dns_list); } ! 62: | DNSSL { init_list(&radv_dns_list); } radv_dnssl { add_tail_list(&RADV_CFG->dnssl_list, &radv_dns_list); } ! 63: | TRIGGER net_ip6 { RADV_CFG->trigger = $2; } ! 64: | PROPAGATE ROUTES bool { RADV_CFG->propagate_routes = $3; } ! 65: ; ! 66: ! 67: radv_proto_opts: ! 68: /* empty */ ! 69: | radv_proto_opts radv_proto_item ';' ! 70: ; ! 71: ! 72: radv_proto: ! 73: radv_proto_start proto_name '{' radv_proto_opts '}'; ! 74: ! 75: ! 76: radv_iface_start: ! 77: { ! 78: this_ipatt = cfg_allocz(sizeof(struct radv_iface_config)); ! 79: add_tail(&RADV_CFG->patt_list, NODE this_ipatt); ! 80: init_list(&this_ipatt->ipn_list); ! 81: init_list(&RADV_IFACE->pref_list); ! 82: init_list(&RADV_IFACE->rdnss_list); ! 83: init_list(&RADV_IFACE->dnssl_list); ! 84: ! 85: RADV_IFACE->min_ra_int = (u32) -1; /* undefined */ ! 86: RADV_IFACE->max_ra_int = DEFAULT_MAX_RA_INT; ! 87: RADV_IFACE->min_delay = DEFAULT_MIN_DELAY; ! 88: RADV_IFACE->prefix_linger_time = (u32) -1; ! 89: RADV_IFACE->route_linger_time = (u32) -1; ! 90: RADV_IFACE->current_hop_limit = DEFAULT_CURRENT_HOP_LIMIT; ! 91: RADV_IFACE->default_lifetime = (u32) -1; ! 92: RADV_IFACE->default_lifetime_sensitive = 1; ! 93: RADV_IFACE->default_preference = RA_PREF_MEDIUM; ! 94: RADV_IFACE->route_lifetime = (u32) -1; ! 95: RADV_IFACE->route_lifetime_sensitive = 0; ! 96: RADV_IFACE->route_preference = RA_PREF_MEDIUM; ! 97: }; ! 98: ! 99: radv_iface_item: ! 100: MIN RA INTERVAL expr { RADV_IFACE->min_ra_int = $4; if ($4 < 3) cf_error("Min RA interval must be at least 3"); } ! 101: | MAX RA INTERVAL expr { RADV_IFACE->max_ra_int = $4; if (($4 < 4) || ($4 > 1800)) cf_error("Max RA interval must be in range 4-1800"); } ! 102: | MIN DELAY expr { RADV_IFACE->min_delay = $3; if ($3 <= 0) cf_error("Min delay must be positive"); } ! 103: | SOLICITED RA UNICAST bool { RADV_IFACE->solicited_ra_unicast = $4; } ! 104: | MANAGED bool { RADV_IFACE->managed = $2; } ! 105: | OTHER CONFIG bool { RADV_IFACE->other_config = $3; } ! 106: | LINK MTU expr { RADV_IFACE->link_mtu = $3; } ! 107: | REACHABLE TIME expr { RADV_IFACE->reachable_time = $3; if ($3 > 3600000) cf_error("Reachable time must be in range 0-3600000"); } ! 108: | RETRANS TIMER expr { RADV_IFACE->retrans_timer = $3; } ! 109: | CURRENT HOP LIMIT expr { RADV_IFACE->current_hop_limit = $4; if ($4 > 255) cf_error("Current hop limit must be in range 0-255"); } ! 110: | DEFAULT LIFETIME expr radv_sensitive { ! 111: RADV_IFACE->default_lifetime = $3; ! 112: if ($3 > 9000) cf_error("Default lifetime must be in range 0-9000"); ! 113: if ($4 != (uint) -1) RADV_IFACE->default_lifetime_sensitive = $4; ! 114: } ! 115: | ROUTE LIFETIME expr radv_sensitive { ! 116: RADV_IFACE->route_lifetime = $3; ! 117: if ($4 != (uint) -1) RADV_IFACE->route_lifetime_sensitive = $4; ! 118: } ! 119: | DEFAULT PREFERENCE radv_preference { RADV_IFACE->default_preference = $3; } ! 120: | ROUTE PREFERENCE radv_preference { RADV_IFACE->route_preference = $3; } ! 121: | PREFIX LINGER TIME expr { RADV_IFACE->prefix_linger_time = $4; } ! 122: | ROUTE LINGER TIME expr { RADV_IFACE->route_linger_time = $4; } ! 123: | PREFIX radv_prefix { add_tail(&RADV_IFACE->pref_list, NODE this_radv_prefix); } ! 124: | RDNSS { init_list(&radv_dns_list); } radv_rdnss { add_tail_list(&RADV_IFACE->rdnss_list, &radv_dns_list); } ! 125: | DNSSL { init_list(&radv_dns_list); } radv_dnssl { add_tail_list(&RADV_IFACE->dnssl_list, &radv_dns_list); } ! 126: | RDNSS LOCAL bool { RADV_IFACE->rdnss_local = $3; } ! 127: | DNSSL LOCAL bool { RADV_IFACE->dnssl_local = $3; } ! 128: ; ! 129: ! 130: radv_preference: ! 131: LOW { $$ = RA_PREF_LOW; } ! 132: | MEDIUM { $$ = RA_PREF_MEDIUM; } ! 133: | HIGH { $$ = RA_PREF_HIGH; } ! 134: ! 135: radv_iface_finish: ! 136: { ! 137: struct radv_iface_config *ic = RADV_IFACE; ! 138: ! 139: if (ic->min_ra_int == (u32) -1) ! 140: ic->min_ra_int = MAX_(ic->max_ra_int / 3, 3); ! 141: ! 142: if (ic->default_lifetime == (u32) -1) ! 143: ic->default_lifetime = 3 * ic->max_ra_int; ! 144: ! 145: if (ic->route_lifetime == (u32) -1) ! 146: ic->route_lifetime = 3 * ic->max_ra_int; ! 147: ! 148: if (ic->prefix_linger_time == (u32) -1) ! 149: ic->prefix_linger_time = 3 * ic->max_ra_int; ! 150: ! 151: if (ic->route_linger_time == (u32) -1) ! 152: ic->route_linger_time = 3 * ic->max_ra_int; ! 153: ! 154: if ((ic->min_ra_int > 3) && ! 155: (ic->min_ra_int > (ic->max_ra_int * 3 / 4))) ! 156: cf_error("Min RA interval must be at most 3/4 * Max RA interval"); ! 157: ! 158: if ((ic->default_lifetime > 0) && (ic->default_lifetime < ic->max_ra_int)) ! 159: cf_error("Default lifetime must be either 0 or at least Max RA interval"); ! 160: ! 161: if ((ic->route_lifetime > 0) && (ic->route_lifetime < ic->max_ra_int)) ! 162: cf_error("Route lifetime must be either 0 or at least Max RA interval"); ! 163: ! 164: if ((ic->prefix_linger_time > 0) && (ic->prefix_linger_time < ic->max_ra_int)) ! 165: cf_error("Prefix linger time must be either 0 or at least Max RA interval"); ! 166: ! 167: if ((ic->route_linger_time > 0) && (ic->route_linger_time < ic->max_ra_int)) ! 168: cf_error("Route linger time must be either 0 or at least Max RA interval"); ! 169: ! 170: RADV_CFG->max_linger_time = MAX_(RADV_CFG->max_linger_time, ic->route_linger_time); ! 171: }; ! 172: ! 173: ! 174: radv_iface_opts: ! 175: /* empty */ ! 176: | radv_iface_opts radv_iface_item ';' ! 177: ; ! 178: ! 179: radv_iface_opt_list: ! 180: /* empty */ ! 181: | '{' radv_iface_opts '}' ! 182: ; ! 183: ! 184: radv_iface: ! 185: radv_iface_start iface_patt_list_nopx radv_iface_opt_list radv_iface_finish; ! 186: ! 187: ! 188: radv_prefix_start: net_ip6 ! 189: { ! 190: this_radv_prefix = cfg_allocz(sizeof(struct radv_prefix_config)); ! 191: RADV_PREFIX->prefix = *(net_addr_ip6 *) &($1); ! 192: ! 193: RADV_PREFIX->onlink = 1; ! 194: RADV_PREFIX->autonomous = 1; ! 195: RADV_PREFIX->valid_lifetime = DEFAULT_VALID_LIFETIME; ! 196: RADV_PREFIX->preferred_lifetime = DEFAULT_PREFERRED_LIFETIME; ! 197: }; ! 198: ! 199: radv_prefix_item: ! 200: SKIP bool { RADV_PREFIX->skip = $2; } ! 201: | ONLINK bool { RADV_PREFIX->onlink = $2; } ! 202: | AUTONOMOUS bool { RADV_PREFIX->autonomous = $2; } ! 203: | VALID LIFETIME expr radv_sensitive { ! 204: RADV_PREFIX->valid_lifetime = $3; ! 205: if ($4 != (uint) -1) RADV_PREFIX->valid_lifetime_sensitive = $4; ! 206: } ! 207: | PREFERRED LIFETIME expr radv_sensitive { ! 208: RADV_PREFIX->preferred_lifetime = $3; ! 209: if ($4 != (uint) -1) RADV_PREFIX->preferred_lifetime_sensitive = $4; ! 210: } ! 211: ; ! 212: ! 213: radv_prefix_finish: ! 214: { ! 215: if (RADV_PREFIX->preferred_lifetime > RADV_PREFIX->valid_lifetime) ! 216: cf_error("Preferred lifetime must be at most Valid lifetime"); ! 217: ! 218: if (RADV_PREFIX->valid_lifetime_sensitive > RADV_PREFIX->preferred_lifetime_sensitive) ! 219: cf_error("Valid lifetime sensitive requires that Preferred lifetime is sensitive too"); ! 220: }; ! 221: ! 222: radv_prefix_opts: ! 223: /* empty */ ! 224: | radv_prefix_opts radv_prefix_item ';' ! 225: ; ! 226: ! 227: radv_prefix_opt_list: ! 228: /* empty */ ! 229: | '{' radv_prefix_opts '}' ! 230: ; ! 231: ! 232: radv_prefix: ! 233: radv_prefix_start radv_prefix_opt_list radv_prefix_finish; ! 234: ! 235: ! 236: ! 237: radv_rdnss_node: ipa ! 238: { ! 239: struct radv_rdnss_config *cf = cfg_allocz(sizeof(struct radv_rdnss_config)); ! 240: add_tail(&radv_dns_list, NODE cf); ! 241: ! 242: cf->server = $1; ! 243: cf->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT; ! 244: }; ! 245: ! 246: radv_rdnss_start: ! 247: { ! 248: RADV_RDNSS->lifetime = 0; ! 249: RADV_RDNSS->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT; ! 250: }; ! 251: ! 252: radv_rdnss_item: ! 253: | NS radv_rdnss_node ! 254: | LIFETIME radv_mult { RADV_RDNSS->lifetime = $2; RADV_RDNSS->lifetime_mult = radv_mult_val; } ! 255: ; ! 256: ! 257: radv_rdnss_finish: ! 258: { ! 259: if (EMPTY_LIST(radv_dns_list)) ! 260: cf_error("No nameserver in RDNSS section"); ! 261: ! 262: struct radv_rdnss_config *cf; ! 263: WALK_LIST(cf, radv_dns_list) ! 264: { ! 265: cf->lifetime = RADV_RDNSS->lifetime; ! 266: cf->lifetime_mult = RADV_RDNSS->lifetime_mult; ! 267: } ! 268: }; ! 269: ! 270: radv_rdnss_opts: ! 271: /* empty */ ! 272: | radv_rdnss_opts radv_rdnss_item ';' ! 273: ; ! 274: ! 275: radv_rdnss: ! 276: radv_rdnss_node ! 277: | '{' radv_rdnss_start radv_rdnss_opts '}' radv_rdnss_finish ! 278: ; ! 279: ! 280: ! 281: radv_dnssl_node: TEXT ! 282: { ! 283: struct radv_dnssl_config *cf = cfg_allocz(sizeof(struct radv_dnssl_config)); ! 284: add_tail(&radv_dns_list, NODE cf); ! 285: ! 286: cf->domain = $1; ! 287: cf->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT; ! 288: ! 289: if (radv_process_domain(cf) < 0) ! 290: cf_error("Invalid domain dame"); ! 291: }; ! 292: ! 293: radv_dnssl_start: ! 294: { ! 295: RADV_DNSSL->lifetime = 0; ! 296: RADV_DNSSL->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT; ! 297: }; ! 298: ! 299: radv_dnssl_item: ! 300: | DOMAIN radv_dnssl_node ! 301: | LIFETIME radv_mult { RADV_DNSSL->lifetime = $2; RADV_DNSSL->lifetime_mult = radv_mult_val; } ! 302: ; ! 303: ! 304: radv_dnssl_finish: ! 305: { ! 306: if (EMPTY_LIST(radv_dns_list)) ! 307: cf_error("No domain in DNSSL section"); ! 308: ! 309: struct radv_dnssl_config *cf; ! 310: WALK_LIST(cf, radv_dns_list) ! 311: { ! 312: cf->lifetime = RADV_DNSSL->lifetime; ! 313: cf->lifetime_mult = RADV_DNSSL->lifetime_mult; ! 314: } ! 315: }; ! 316: ! 317: radv_dnssl_opts: ! 318: /* empty */ ! 319: | radv_dnssl_opts radv_dnssl_item ';' ! 320: ; ! 321: ! 322: radv_dnssl: ! 323: radv_dnssl_node ! 324: | '{' radv_dnssl_start radv_dnssl_opts '}' radv_dnssl_finish ! 325: ; ! 326: ! 327: ! 328: radv_mult: ! 329: expr { $$ = $1; radv_mult_val = 0; } ! 330: | MULT expr { $$ = 0; radv_mult_val = $2; if (($2 < 1) || ($2 > 254)) cf_error("Multiplier must be in range 1-254"); } ! 331: ; ! 332: ! 333: radv_sensitive: ! 334: /* empty */ { $$ = (uint) -1; } ! 335: | SENSITIVE bool { $$ = $2; } ! 336: ; ! 337: ! 338: dynamic_attr: RA_PREFERENCE { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_ENUM_RA_PREFERENCE, EA_RA_PREFERENCE); } ; ! 339: dynamic_attr: RA_LIFETIME { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_RA_LIFETIME); } ; ! 340: ! 341: CF_CODE ! 342: ! 343: CF_END