config.Y 19 KB
Newer Older
1 2 3
/*
 *	BIRD -- OSPF Configuration
 *
4
 *	(c) 1999--2004 Ondrej Filip <feela@network.cz>
5 6 7 8 9 10 11 12
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

CF_HDR

#include "proto/ospf/ospf.h"

13 14 15
CF_DEFINES

#define OSPF_CFG ((struct ospf_config *) this_proto)
Ondřej Filip's avatar
Ondřej Filip committed
16
#define OSPF_PATT ((struct ospf_iface_patt *) this_ipatt)
17 18

static struct ospf_area_config *this_area;
19
static struct nbma_node *this_nbma;
20
static list *this_nets;
Ondřej Filip's avatar
Ondřej Filip committed
21
static struct area_net_config *this_pref;
22
static struct ospf_stubnet_config *this_stubnet;
23

24 25 26
static inline int ospf_cfg_is_v2(void) { return OSPF_CFG->ospf2; }
static inline int ospf_cfg_is_v3(void) { return ! OSPF_CFG->ospf2; }

27
static void
28
ospf_iface_finish(void)
29
{
30 31 32 33 34
  struct ospf_iface_patt *ip = OSPF_PATT;

  if (ip->deadint == 0)
    ip->deadint = ip->deadc * ip->helloint;

35 36 37
  if (ip->waitint == 0)
    ip->waitint = ip->deadc * ip->helloint;

38 39 40 41 42 43 44
  ip->passwords = get_passwords();

  if ((ip->autype == OSPF_AUTH_CRYPT) && (ip->helloint < 5))
    log(L_WARN "Hello or poll interval less that 5 makes cryptographic authenication prone to replay attacks");

  if ((ip->autype == OSPF_AUTH_NONE) && (ip->passwords != NULL))
    log(L_WARN "Password option without authentication option does not make sense");
45 46 47 48 49 50 51 52 53 54 55 56 57 58

  if (ip->passwords)
  {
    struct password_item *pass;
    WALK_LIST(pass, *ip->passwords)
    {
      if (pass->alg && (ip->autype != OSPF_AUTH_CRYPT))
	cf_error("Password algorithm option requires cryptographic authentication");

      /* Set default OSPF crypto algorithms */
      if (!pass->alg && (ip->autype == OSPF_AUTH_CRYPT))
	pass->alg = ospf_cfg_is_v2() ? ALG_MD5 : ALG_HMAC_SHA256;
    }
  }
59 60
}

61 62 63
static void
ospf_area_finish(void)
{
64
  if ((this_area->areaid == 0) && (this_area->type != OPT_E))
65 66 67
    cf_error("Backbone area cannot be stub/NSSA");

  if (this_area->summary && (this_area->type == OPT_E))
68
    cf_error("Only stub/NSSA areas can use summary propagation");
69 70 71 72

  if (this_area->default_nssa && ((this_area->type != OPT_N) || ! this_area->summary))
    cf_error("Only NSSA areas with summary propagation can use NSSA default route");

73
  if ((this_area->default_cost & LSA_EXT3_EBIT) && ! this_area->default_nssa)
74
    cf_error("Only NSSA default route can use type 2 metric");
75 76 77 78 79 80
}

static void
ospf_proto_finish(void)
{
  struct ospf_config *cf = OSPF_CFG;
81 82
  struct ospf_area_config *ac;
  struct ospf_iface_patt *ic;
83

84 85
  /* Define default channel */
  if (EMPTY_LIST(this_proto->channels))
86
  {
87 88
    uint net_type = this_proto->net_type = ospf_cfg_is_v2() ? NET_IP4 : NET_IP6;
    channel_config_new(NULL, net_label[net_type], net_type, this_proto);
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
  }

  /* Propagate global instance ID to interfaces */
  if (cf->instance_id_set)
  {
    WALK_LIST(ac, cf->area_list)
      WALK_LIST(ic, ac->patt_list)
	if (!ic->instance_id_set)
	{ ic->instance_id = cf->instance_id; ic->instance_id_set = 1; }

    WALK_LIST(ic, cf->vlink_list)
      if (!ic->instance_id_set)
      { ic->instance_id = cf->instance_id; ic->instance_id_set = 1; }
  }

  if (ospf_cfg_is_v3())
  {
    uint ipv4 = (this_proto->net_type == NET_IP4);
    uint base = (ipv4 ? 64 : 0) + (cf->af_mc ? 32 : 0);

    /* RFC 5838 - OSPFv3-AF */
    if (cf->af_ext)
    {
      /* RFC 5838 2.1 - instance IDs based on AFs */
      WALK_LIST(ac, cf->area_list)
	WALK_LIST(ic, ac->patt_list)
	{
	  if (!ic->instance_id_set)
	    ic->instance_id = base;
	  else if (ic->instance_id >= 128)
	    log(L_WARN "Instance ID %d from unassigned/private range", ic->instance_id);
	  else if ((ic->instance_id < base) || (ic->instance_id >= (base + 32)))
	    cf_error("Instance ID %d invalid for given channel type", ic->instance_id);
	}

      /* RFC 5838 2.8 - vlinks limited to IPv6 unicast */
      if ((ipv4 || cf->af_mc) && !EMPTY_LIST(cf->vlink_list))
	cf_error("Vlinks not supported in AFs other than IPv6 unicast");
    }
    else
    {
      if (ipv4 || cf->af_mc)
	cf_error("Different channel type");
    }
  }

  if (EMPTY_LIST(cf->area_list))
    cf_error("No configured areas in OSPF");
137

138 139
  int areano = 0;
  int backbone = 0;
140
  int nssa = 0;
141 142 143 144
  WALK_LIST(ac, cf->area_list)
  {
    areano++;
    if (ac->areaid == 0)
145 146 147
      backbone = 1;
    if (ac->type == OPT_N)
      nssa = 1;
148
  }
149

150 151
  cf->abr = areano > 1;

152
  /* Route export or NSSA translation (RFC 3101 3.1) */
153
  cf->asbr = (proto_cf_main_channel(this_proto)->out_filter != FILTER_REJECT) || (nssa && cf->abr);
154

155 156 157
  if (cf->abr && !backbone)
  {
    struct ospf_area_config *ac = cfg_allocz(sizeof(struct ospf_area_config));
158
    ac->type = OPT_E; /* Backbone is non-stub */
159 160 161
    add_head(&cf->area_list, NODE ac);
    init_list(&ac->patt_list);
    init_list(&ac->net_list);
162
    init_list(&ac->enet_list);
163 164 165 166
    init_list(&ac->stubnet_list);
  }

  if (!cf->abr && !EMPTY_LIST(cf->vlink_list))
167 168 169 170
    cf_error("Vlinks cannot be used on single area router");

  if (cf->asbr && (areano == 1) && (this_area->type == 0))
    cf_error("ASBR must be in non-stub area");
171 172
}

173
static inline void
174
ospf_check_defcost(int cost)
175 176
{
  if ((cost <= 0) || (cost >= LSINFINITY))
177
   cf_error("Default cost must be in range 1-%u", LSINFINITY-1);
178 179 180
}

static inline void
181
ospf_check_auth(void)
182
{
183 184
  if (ospf_cfg_is_v3())
    cf_error("Authentication not supported in OSPFv3");
185 186
}

187

188 189
CF_DECLS

190 191
CF_KEYWORDS(OSPF, V2, V3, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG, OSPF_ROUTER_ID)
CF_KEYWORDS(AREA, NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, COST2, RETRANSMIT)
192
CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, TYPE, BROADCAST, BCAST, DEFAULT)
193
CF_KEYWORDS(NONBROADCAST, NBMA, POINTOPOINT, PTP, POINTOMULTIPOINT, PTMP)
194
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC, TTL, SECURITY)
Ondřej Zajíček's avatar
Ondřej Zajíček committed
195
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK, ONLY, BFD)
196
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY, TAG, EXTERNAL)
197
CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA, TRANSLATOR, STABILITY)
198
CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF, INSTANCE, REAL, NETMASK, TX, PRIORITY, LENGTH)
199
CF_KEYWORDS(SECONDARY, MERGE, LSA, SUPPRESSION, MULTICAST, RFC5838)
200

201
%type <ld> lsadb_args
202 203
%type <i> ospf_variant ospf_af_mc nbma_eligible
%type <cc> ospf_channel_start ospf_channel
204

205 206
CF_GRAMMAR

207
CF_ADDTO(proto, ospf_proto '}' { ospf_proto_finish(); } )
208

209
ospf_variant:
210 211 212
   OSPF    { $$ = 1; }
 | OSPF V2 { $$ = 1; }
 | OSPF V3 { $$ = 0; }
213 214
 ;

215 216 217
ospf_proto_start: proto_start ospf_variant
{
  this_proto = proto_config_new(&proto_ospf, $1);
218
  this_proto->net_type = $2 ? NET_IP4 : 0;
219 220 221

  init_list(&OSPF_CFG->area_list);
  init_list(&OSPF_CFG->vlink_list);
222
  OSPF_CFG->ecmp = rt_default_ecmp;
223 224
  OSPF_CFG->tick = OSPF_DEFAULT_TICK;
  OSPF_CFG->ospf2 = $2;
225
  OSPF_CFG->af_ext = !$2;
226
};
227 228 229

ospf_proto:
   ospf_proto_start proto_name '{'
230 231 232
 | ospf_proto ospf_proto_item ';'
 ;

233 234 235 236 237 238 239 240
ospf_af_mc:
             { $$ = 0; }
 | MULTICAST { $$ = 1; }
 ;

/* We redefine proto_channel to add multicast flag */
ospf_channel_start: net_type ospf_af_mc
{
241 242
  /* TODO: change name for multicast channels */
  $$ = this_channel = channel_config_get(NULL, net_label[$1], $1, this_proto);
243 244 245 246 247 248 249 250

  /* Save the multicast flag */
  if (this_channel == proto_cf_main_channel(this_proto))
    OSPF_CFG->af_mc = $2;
};

ospf_channel: ospf_channel_start channel_opt_list channel_end;

251 252
ospf_proto_item:
   proto_item
253
 | ospf_channel { this_proto->net_type = $1->net_type; }
254
 | RFC1583COMPAT bool { OSPF_CFG->rfc1583 = $2; }
255
 | RFC5838 bool { OSPF_CFG->af_ext = $2; if (!ospf_cfg_is_v3()) cf_error("RFC5838 option requires OSPFv3"); }
256
 | STUB ROUTER bool { OSPF_CFG->stub_router = $3; }
257
 | ECMP bool { OSPF_CFG->ecmp = $2 ? OSPF_DEFAULT_ECMP_LIMIT : 0; }
258
 | ECMP bool LIMIT expr { OSPF_CFG->ecmp = $2 ? $4 : 0; }
259
 | MERGE EXTERNAL bool { OSPF_CFG->merge_external = $3; }
260
 | TICK expr { OSPF_CFG->tick = $2; if($2 <= 0) cf_error("Tick must be greater than zero"); }
261
 | INSTANCE ID expr { OSPF_CFG->instance_id = $3; OSPF_CFG->instance_id_set = 1; if ($3 > 255) cf_error("Instance ID must be in range 0-255"); }
262
 | ospf_area
263
 ;
264

265
ospf_area_start: AREA idval {
Ondřej Filip's avatar
Ondřej Filip committed
266 267 268
  this_area = cfg_allocz(sizeof(struct ospf_area_config));
  add_tail(&OSPF_CFG->area_list, NODE this_area);
  this_area->areaid = $2;
269
  this_area->default_cost = OSPF_DEFAULT_STUB_COST;
270
  this_area->type = OPT_E;
271
  this_area->transint = OSPF_DEFAULT_TRANSINT;
272

Ondřej Filip's avatar
Ondřej Filip committed
273
  init_list(&this_area->patt_list);
274
  init_list(&this_area->net_list);
275
  init_list(&this_area->enet_list);
276
  init_list(&this_area->stubnet_list);
277
 }
278
 ;
279

280
ospf_area: ospf_area_start '{' ospf_area_opts '}' { ospf_area_finish(); }
281
 ;
282 283

ospf_area_opts:
284 285 286
   /* empty */
 | ospf_area_opts ospf_area_item ';'
 ;
287

Ondřej Filip's avatar
Ondřej Filip committed
288
ospf_area_item:
289
   STUB bool { this_area->type = $2 ? 0 : OPT_E; /* We should remove the option */ }
290 291
 | NSSA { this_area->type = OPT_N; }
 | SUMMARY bool { this_area->summary = $2; }
292
 | DEFAULT NSSA bool { this_area->default_nssa = $3; }
293 294 295
 | DEFAULT COST expr { this_area->default_cost = $3; ospf_check_defcost($3); }
 | DEFAULT COST2 expr { this_area->default_cost = $3 | LSA_EXT3_EBIT; ospf_check_defcost($3); }
 | STUB COST expr { this_area->default_cost = $3; ospf_check_defcost($3); }
296
 | TRANSLATOR bool { this_area->translator = $2; }
297 298 299
 | TRANSLATOR STABILITY expr { this_area->transint = $3; }
 | NETWORKS { this_nets = &this_area->net_list; } '{' pref_list '}'
 | EXTERNAL { this_nets = &this_area->enet_list; } '{' pref_list '}'
300
 | STUBNET ospf_stubnet
301
 | INTERFACE ospf_iface
302
 | ospf_vlink
303
 ;
Ondřej Filip's avatar
Ondřej Filip committed
304

305 306 307 308 309 310
ospf_stubnet:
   ospf_stubnet_start '{' ospf_stubnet_opts '}'
 | ospf_stubnet_start
 ;

ospf_stubnet_start:
311
   net_ip {
Ondřej Zajíček's avatar
Ondřej Zajíček committed
312
     this_stubnet = cfg_allocz(sizeof(struct ospf_stubnet_config));
313
     add_tail(&this_area->stubnet_list, NODE this_stubnet);
314
     this_stubnet->prefix = $1;
315
     this_stubnet->cost = COST_D;
316
   }
317 318 319 320 321 322 323 324 325 326 327 328 329
 ;

ospf_stubnet_opts:
   /* empty */
 | ospf_stubnet_opts ospf_stubnet_item ';'
 ;

ospf_stubnet_item:
   HIDDEN bool { this_stubnet->hidden = $2; }
 | SUMMARY bool { this_stubnet->summary = $2; }
 | COST expr { this_stubnet->cost = $2; }
 ;

330
ospf_vlink:
331 332
   ospf_vlink_start ospf_instance_id '{' ospf_vlink_opts '}' { ospf_iface_finish(); }
 | ospf_vlink_start ospf_instance_id { ospf_iface_finish(); }
Ondřej Filip's avatar
Ondřej Filip committed
333 334 335 336 337 338 339 340
 ;

ospf_vlink_opts:
   /* empty */
 | ospf_vlink_opts ospf_vlink_item ';'
 ;

ospf_vlink_item:
341
 | HELLO expr { OSPF_PATT->helloint = $2 ; if (($2<=0) || ($2>65535)) cf_error("Hello interval must be in range 1-65535"); }
342
 | RETRANSMIT expr { OSPF_PATT->rxmtint = $2 ; if ($2<=1) cf_error("Retransmit int must be greater than one"); }
Ondřej Filip's avatar
Ondřej Filip committed
343
 | TRANSMIT DELAY expr { OSPF_PATT->inftransdelay = $3 ; if (($3<=0) || ($3>65535)) cf_error("Transmit delay must be in range 1-65535"); }
344
 | WAIT expr { OSPF_PATT->waitint = $2 ; if ($2<=1) cf_error("Wait interval must be greater than one"); }
345
 | DEAD expr { OSPF_PATT->deadint = $2 ; if ($2<=1) cf_error("Dead interval must be greater than one"); }
Ondřej Filip's avatar
Ondřej Filip committed
346
 | DEAD COUNT expr { OSPF_PATT->deadc = $3 ; if ($3<=1) cf_error("Dead count must be greater than one"); }
347 348 349 350
 | AUTHENTICATION NONE { OSPF_PATT->autype = OSPF_AUTH_NONE;  }
 | AUTHENTICATION SIMPLE { OSPF_PATT->autype = OSPF_AUTH_SIMPLE; ospf_check_auth(); }
 | AUTHENTICATION CRYPTOGRAPHIC { OSPF_PATT->autype = OSPF_AUTH_CRYPT; ospf_check_auth(); }
 | password_list { ospf_check_auth(); }
Ondřej Filip's avatar
Ondřej Filip committed
351 352
 ;

353
ospf_vlink_start: VIRTUAL LINK idval
Ondřej Filip's avatar
Ondřej Filip committed
354 355 356
 {
  if (this_area->areaid == 0) cf_error("Virtual link cannot be in backbone");
  this_ipatt = cfg_allocz(sizeof(struct ospf_iface_patt));
357
  add_tail(&OSPF_CFG->vlink_list, NODE this_ipatt);
358
  init_list(&this_ipatt->ipn_list);
359
  OSPF_PATT->voa = this_area->areaid;
360
  OSPF_PATT->vid = $3;
Ondřej Filip's avatar
Ondřej Filip committed
361 362 363 364 365
  OSPF_PATT->helloint = HELLOINT_D;
  OSPF_PATT->rxmtint = RXMTINT_D;
  OSPF_PATT->inftransdelay = INFTRANSDELAY_D;
  OSPF_PATT->deadc = DEADC_D;
  OSPF_PATT->type = OSPF_IT_VLINK;
366
  init_list(&OSPF_PATT->nbma_list);
367
  reset_passwords();
Ondřej Filip's avatar
Ondřej Filip committed
368 369 370
 }
;

Ondřej Filip's avatar
Ondřej Filip committed
371
ospf_iface_item:
372 373 374
   COST expr { OSPF_PATT->cost = $2 ; if (($2<=0) || ($2>65535)) cf_error("Cost must be in range 1-65535"); }
 | HELLO expr { OSPF_PATT->helloint = $2 ; if (($2<=0) || ($2>65535)) cf_error("Hello interval must be in range 1-65535"); }
 | POLL expr { OSPF_PATT->pollint = $2 ; if ($2<=0) cf_error("Poll int must be greater than zero"); }
375 376
 | RETRANSMIT expr { OSPF_PATT->rxmtint = $2 ; if ($2<=1) cf_error("Retransmit int must be greater than one"); }
 | WAIT expr { OSPF_PATT->waitint = $2 ; if ($2<=1) cf_error("Wait interval must be greater than one"); }
377
 | DEAD expr { OSPF_PATT->deadint = $2 ; if ($2<=1) cf_error("Dead interval must be greater than one"); }
378
 | DEAD COUNT expr { OSPF_PATT->deadc = $3 ; if ($3<=1) cf_error("Dead count must be greater than one"); }
379
 | TYPE BROADCAST { OSPF_PATT->type = OSPF_IT_BCAST ; }
380
 | TYPE BCAST { OSPF_PATT->type = OSPF_IT_BCAST ; }
381
 | TYPE NONBROADCAST { OSPF_PATT->type = OSPF_IT_NBMA ; }
382
 | TYPE NBMA { OSPF_PATT->type = OSPF_IT_NBMA ; }
383
 | TYPE POINTOPOINT { OSPF_PATT->type = OSPF_IT_PTP ; }
384 385 386
 | TYPE PTP { OSPF_PATT->type = OSPF_IT_PTP ; }
 | TYPE POINTOMULTIPOINT { OSPF_PATT->type = OSPF_IT_PTMP ; }
 | TYPE PTMP { OSPF_PATT->type = OSPF_IT_PTMP ; }
387 388
 | REAL BROADCAST bool { OSPF_PATT->real_bcast = $3; if (!ospf_cfg_is_v2()) cf_error("Real broadcast option requires OSPFv2"); }
 | PTP NETMASK bool { OSPF_PATT->ptp_netmask = $3; if (!ospf_cfg_is_v2()) cf_error("PtP netmask option requires OSPFv2"); }
389
 | TRANSMIT DELAY expr { OSPF_PATT->inftransdelay = $3 ; if (($3<=0) || ($3>65535)) cf_error("Transmit delay must be in range 1-65535"); }
390
 | PRIORITY expr { OSPF_PATT->priority = $2 ; if ($2>255) cf_error("Priority must be in range 0-255"); }
391
 | STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; }
392
 | STUB bool { OSPF_PATT->stub = $2 ; }
393
 | CHECK LINK bool { OSPF_PATT->check_link = $3; }
394
 | ECMP WEIGHT expr { OSPF_PATT->ecmp_weight = $3 - 1; if (($3<1) || ($3>256)) cf_error("ECMP weight must be in range 1-256"); }
395
 | LINK LSA SUPPRESSION bool { OSPF_PATT->link_lsa_suppression = $4; if (!ospf_cfg_is_v3()) cf_error("Link LSA suppression option requires OSPFv3"); }
396
 | NEIGHBORS '{' nbma_list '}'
397 398 399
 | AUTHENTICATION NONE { OSPF_PATT->autype = OSPF_AUTH_NONE; }
 | AUTHENTICATION SIMPLE { OSPF_PATT->autype = OSPF_AUTH_SIMPLE; ospf_check_auth(); }
 | AUTHENTICATION CRYPTOGRAPHIC { OSPF_PATT->autype = OSPF_AUTH_CRYPT; ospf_check_auth(); }
400 401
 | RX BUFFER NORMAL { OSPF_PATT->rx_buffer = 0; }
 | RX BUFFER LARGE { OSPF_PATT->rx_buffer = OSPF_MAX_PKT_SIZE; }
402
 | RX BUFFER expr { OSPF_PATT->rx_buffer = $3; if (($3 < OSPF_MIN_PKT_SIZE) || ($3 > OSPF_MAX_PKT_SIZE)) cf_error("Buffer size must be in range 256-65535"); }
403 404
 | TX tos { OSPF_PATT->tx_tos = $2; }
 | TX PRIORITY expr { OSPF_PATT->tx_priority = $3; }
405
 | TX LENGTH expr { OSPF_PATT->tx_length = $3; if (($3 < OSPF_MIN_PKT_SIZE) || ($3 > OSPF_MAX_PKT_SIZE)) cf_error("TX length must be in range 256-65535"); }
406 407
 | TTL SECURITY bool { OSPF_PATT->ttl_security = $3; }
 | TTL SECURITY TX ONLY { OSPF_PATT->ttl_security = 2; }
408
 | BFD bool { OSPF_PATT->bfd = $2; cf_check_bfd($2); }
409
 | password_list { ospf_check_auth(); }
410
 ;
411

412 413 414 415 416
pref_list:
 /* empty */
 | pref_list pref_item
 ;

417
pref_item: pref_base pref_opt ';' ;
418

419
pref_base: net_ip
420
 {
Ondřej Filip's avatar
Ondřej Filip committed
421
   this_pref = cfg_allocz(sizeof(struct area_net_config));
422
   add_tail(this_nets, NODE this_pref);
423
   this_pref->prefix = $1;
424 425 426
 }
;

427 428 429 430 431
pref_opt:
 /* empty */
 | HIDDEN { this_pref->hidden = 1; }
 | TAG expr { this_pref->tag = $2; }
 ;
432

433
nbma_list:
434
 /* empty */
435
 | nbma_list nbma_item
436
 ;
437

438 439 440 441
nbma_eligible:
 /* empty */ { $$ = 0; }
 | ELIGIBLE { $$ = 1; }
 ;
442

443
nbma_item: ipa nbma_eligible ';'
444 445 446 447
 {
   this_nbma = cfg_allocz(sizeof(struct nbma_node));
   add_tail(&OSPF_PATT->nbma_list, NODE this_nbma);
   this_nbma->ip=$1;
448
   this_nbma->eligible=$2;
449 450
 }
;
451

452 453 454 455
ospf_iface_start:
 {
  this_ipatt = cfg_allocz(sizeof(struct ospf_iface_patt));
  add_tail(&this_area->patt_list, NODE this_ipatt);
456
  init_list(&this_ipatt->ipn_list);
457 458
  OSPF_PATT->cost = COST_D;
  OSPF_PATT->helloint = HELLOINT_D;
459
  OSPF_PATT->pollint = POLLINT_D;
460 461 462 463 464
  OSPF_PATT->rxmtint = RXMTINT_D;
  OSPF_PATT->inftransdelay = INFTRANSDELAY_D;
  OSPF_PATT->priority = PRIORITY_D;
  OSPF_PATT->deadc = DEADC_D;
  OSPF_PATT->type = OSPF_IT_UNDEF;
465
  init_list(&OSPF_PATT->nbma_list);
466
  OSPF_PATT->check_link = 1;
467
  OSPF_PATT->ptp_netmask = 2; /* not specified */
468 469
  OSPF_PATT->tx_tos = IP_PREC_INTERNET_CONTROL;
  OSPF_PATT->tx_priority = sk_priority_control;
470
  reset_passwords();
471 472 473
 }
;

474 475
ospf_instance_id:
   /* empty */
476
 | INSTANCE expr { OSPF_PATT->instance_id = $2; OSPF_PATT->instance_id_set = 1; if ($2 > 255) cf_error("Instance ID must be in range 0-255"); }
477 478
 ;

479
ospf_iface_patt_list:
480
   iface_patt_list { if (ospf_cfg_is_v3()) iface_patt_check(); } ospf_instance_id
481
 ;
482

Ondřej Filip's avatar
Ondřej Filip committed
483
ospf_iface_opts:
484
   /* empty */
Ondřej Filip's avatar
Ondřej Filip committed
485 486 487
 | ospf_iface_opts ospf_iface_item ';'
 ;

488 489 490 491
ospf_iface_opt_list:
   /* empty */
 | '{' ospf_iface_opts '}'
 ;
Ondřej Filip's avatar
Ondřej Filip committed
492 493

ospf_iface:
494
  ospf_iface_start ospf_iface_patt_list ospf_iface_opt_list { ospf_iface_finish(); }
Ondřej Filip's avatar
Ondřej Filip committed
495 496
 ;

497 498 499
CF_ADDTO(dynamic_attr, OSPF_METRIC1 { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_METRIC1); })
CF_ADDTO(dynamic_attr, OSPF_METRIC2 { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_METRIC2); })
CF_ADDTO(dynamic_attr, OSPF_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_TAG); })
500
CF_ADDTO(dynamic_attr, OSPF_ROUTER_ID { $$ = f_new_dynamic_attr(EAF_TYPE_ROUTER_ID | EAF_TEMP, T_QUAD, EA_OSPF_ROUTER_ID); })
501

502
CF_CLI_HELP(SHOW OSPF, ..., [[Show information about OSPF protocol]]);
Ondřej Zajíček's avatar
Ondřej Zajíček committed
503
CF_CLI(SHOW OSPF, optsym, [<name>], [[Show information about OSPF protocol]])
504
{ ospf_sh(proto_get_named($3, &proto_ospf)); };
Ondřej Filip's avatar
Ondřej Filip committed
505

Martin Mareš's avatar
Martin Mareš committed
506
CF_CLI(SHOW OSPF NEIGHBORS, optsym opttext, [<name>] [\"<interface>\"], [[Show information about OSPF neighbors]])
507
{ ospf_sh_neigh(proto_get_named($4, &proto_ospf), $5); };
508

Martin Mareš's avatar
Martin Mareš committed
509
CF_CLI(SHOW OSPF INTERFACE, optsym opttext, [<name>] [\"<interface>\"], [[Show information about interface]])
510
{ ospf_sh_iface(proto_get_named($4, &proto_ospf), $5); };
511

512
CF_CLI_HELP(SHOW OSPF TOPOLOGY, [all] [<name>], [[Show information about OSPF network topology]])
513

514 515 516 517 518 519 520 521 522 523 524 525 526
CF_CLI(SHOW OSPF TOPOLOGY, optsym opttext, [<name>], [[Show information about reachable OSPF network topology]])
{ ospf_sh_state(proto_get_named($4, &proto_ospf), 0, 1); };

CF_CLI(SHOW OSPF TOPOLOGY ALL, optsym opttext, [<name>], [[Show information about all OSPF network topology]])
{ ospf_sh_state(proto_get_named($5, &proto_ospf), 0, 0); };

CF_CLI_HELP(SHOW OSPF STATE, [all] [<name>], [[Show information about OSPF network state]])

CF_CLI(SHOW OSPF STATE, optsym opttext, [<name>], [[Show information about reachable OSPF network state]])
{ ospf_sh_state(proto_get_named($4, &proto_ospf), 1, 1); };

CF_CLI(SHOW OSPF STATE ALL, optsym opttext, [<name>], [[Show information about all OSPF network state]])
{ ospf_sh_state(proto_get_named($5, &proto_ospf), 1, 0); };
527

528
CF_CLI_HELP(SHOW OSPF LSADB, ..., [[Show content of OSPF LSA database]]);
529 530 531 532 533 534 535 536
CF_CLI(SHOW OSPF LSADB, lsadb_args, [global | area <id> | link] [type <num>] [lsid <id>] [self | router <id>] [<proto>], [[Show content of OSPF LSA database]])
{ ospf_sh_lsadb($4); };

lsadb_args:
   /* empty */ {
     $$ = cfg_allocz(sizeof(struct lsadb_show_data));
   }
 | lsadb_args GLOBAL { $$ = $1; $$->scope = LSA_SCOPE_AS; }
537
 | lsadb_args AREA idval { $$ = $1; $$->scope = LSA_SCOPE_AREA; $$->area = $3; }
538 539 540 541 542 543 544
 | lsadb_args LINK { $$ = $1; $$->scope = 1; /* hack, 0 is no filter */ }
 | lsadb_args TYPE NUM { $$ = $1; $$->type = $3; }
 | lsadb_args LSID idval { $$ = $1; $$->lsid = $3; }
 | lsadb_args SELF { $$ = $1; $$->router = SH_ROUTER_SELF; }
 | lsadb_args ROUTER idval { $$ = $1; $$->router = $3; }
 | lsadb_args SYM { $$ = $1; $$->name = $2; }
 ;
545

546 547 548
CF_CODE

CF_END