config.Y 19.1 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
  ip->passwords = get_passwords();

40
  if (ospf_cfg_is_v2() && (ip->autype == OSPF_AUTH_CRYPT) && (ip->helloint < 5))
41 42 43 44
    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

  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;
57 58 59

      if (ospf_cfg_is_v3() && ip->autype && (pass->alg < ALG_HMAC))
	cf_error("Keyed hash algorithms are not allowed, use HMAC algorithms");
60 61
    }
  }
62 63
}

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

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

  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");

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

static void
ospf_proto_finish(void)
{
  struct ospf_config *cf = OSPF_CFG;
84 85
  struct ospf_area_config *ac;
  struct ospf_iface_patt *ic;
86

87 88
  /* Define default channel */
  if (EMPTY_LIST(this_proto->channels))
89
  {
90 91
    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);
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 137 138 139
  }

  /* 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");
140

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

153 154
  cf->abr = areano > 1;

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

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

  if (!cf->abr && !EMPTY_LIST(cf->vlink_list))
170 171 172 173
    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");
174 175
}

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

static inline void
184
ospf_check_auth(void)
185
{
186
  if (ospf_cfg_is_v3())
187
    cf_error("Plaintext authentication not supported in OSPFv3");
188 189
}

190

191 192
CF_DECLS

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

204
%type <ld> lsadb_args
205 206
%type <i> ospf_variant ospf_af_mc nbma_eligible
%type <cc> ospf_channel_start ospf_channel
207

208 209
CF_GRAMMAR

210
CF_ADDTO(proto, ospf_proto '}' { ospf_proto_finish(); } )
211

212
ospf_variant:
213 214 215
   OSPF    { $$ = 1; }
 | OSPF V2 { $$ = 1; }
 | OSPF V3 { $$ = 0; }
216 217
 ;

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

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

ospf_proto:
   ospf_proto_start proto_name '{'
233 234 235
 | ospf_proto ospf_proto_item ';'
 ;

236 237 238 239 240 241 242 243
ospf_af_mc:
             { $$ = 0; }
 | MULTICAST { $$ = 1; }
 ;

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

  /* 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;

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

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

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

283
ospf_area: ospf_area_start '{' ospf_area_opts '}' { ospf_area_finish(); }
284
 ;
285 286

ospf_area_opts:
287 288 289
   /* empty */
 | ospf_area_opts ospf_area_item ';'
 ;
290

Ondřej Filip's avatar
Ondřej Filip committed
291
ospf_area_item:
292
   STUB bool { this_area->type = $2 ? 0 : OPT_E; /* We should remove the option */ }
293 294
 | NSSA { this_area->type = OPT_N; }
 | SUMMARY bool { this_area->summary = $2; }
295
 | DEFAULT NSSA bool { this_area->default_nssa = $3; }
296 297 298
 | 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); }
299
 | TRANSLATOR bool { this_area->translator = $2; }
300 301 302
 | 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 '}'
303
 | STUBNET ospf_stubnet
304
 | INTERFACE ospf_iface
305
 | ospf_vlink
306
 ;
Ondřej Filip's avatar
Ondřej Filip committed
307

308 309 310 311 312 313
ospf_stubnet:
   ospf_stubnet_start '{' ospf_stubnet_opts '}'
 | ospf_stubnet_start
 ;

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

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; }
 ;

333
ospf_vlink:
334 335
   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
336 337 338 339 340 341 342 343
 ;

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

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

356
ospf_vlink_start: VIRTUAL LINK idval
Ondřej Filip's avatar
Ondřej Filip committed
357 358 359
 {
  if (this_area->areaid == 0) cf_error("Virtual link cannot be in backbone");
  this_ipatt = cfg_allocz(sizeof(struct ospf_iface_patt));
360
  add_tail(&OSPF_CFG->vlink_list, NODE this_ipatt);
361
  init_list(&this_ipatt->ipn_list);
362
  OSPF_PATT->voa = this_area->areaid;
363
  OSPF_PATT->vid = $3;
Ondřej Filip's avatar
Ondřej Filip committed
364 365 366 367 368
  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;
369
  init_list(&OSPF_PATT->nbma_list);
370
  reset_passwords();
Ondřej Filip's avatar
Ondřej Filip committed
371 372 373
 }
;

Ondřej Filip's avatar
Ondřej Filip committed
374
ospf_iface_item:
375 376 377
   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"); }
378 379
 | 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"); }
380
 | DEAD expr { OSPF_PATT->deadint = $2 ; if ($2<=1) cf_error("Dead interval must be greater than one"); }
381
 | DEAD COUNT expr { OSPF_PATT->deadc = $3 ; if ($3<=1) cf_error("Dead count must be greater than one"); }
382
 | TYPE BROADCAST { OSPF_PATT->type = OSPF_IT_BCAST ; }
383
 | TYPE BCAST { OSPF_PATT->type = OSPF_IT_BCAST ; }
384
 | TYPE NONBROADCAST { OSPF_PATT->type = OSPF_IT_NBMA ; }
385
 | TYPE NBMA { OSPF_PATT->type = OSPF_IT_NBMA ; }
386
 | TYPE POINTOPOINT { OSPF_PATT->type = OSPF_IT_PTP ; }
387 388 389
 | TYPE PTP { OSPF_PATT->type = OSPF_IT_PTP ; }
 | TYPE POINTOMULTIPOINT { OSPF_PATT->type = OSPF_IT_PTMP ; }
 | TYPE PTMP { OSPF_PATT->type = OSPF_IT_PTMP ; }
390 391
 | 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"); }
392
 | TRANSMIT DELAY expr { OSPF_PATT->inftransdelay = $3 ; if (($3<=0) || ($3>65535)) cf_error("Transmit delay must be in range 1-65535"); }
393
 | PRIORITY expr { OSPF_PATT->priority = $2 ; if ($2>255) cf_error("Priority must be in range 0-255"); }
394
 | STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; }
395
 | STUB bool { OSPF_PATT->stub = $2 ; }
396
 | CHECK LINK bool { OSPF_PATT->check_link = $3; }
397
 | ECMP WEIGHT expr { OSPF_PATT->ecmp_weight = $3 - 1; if (($3<1) || ($3>256)) cf_error("ECMP weight must be in range 1-256"); }
398
 | LINK LSA SUPPRESSION bool { OSPF_PATT->link_lsa_suppression = $4; if (!ospf_cfg_is_v3()) cf_error("Link LSA suppression option requires OSPFv3"); }
399
 | NEIGHBORS '{' nbma_list '}'
400 401
 | AUTHENTICATION NONE { OSPF_PATT->autype = OSPF_AUTH_NONE; }
 | AUTHENTICATION SIMPLE { OSPF_PATT->autype = OSPF_AUTH_SIMPLE; ospf_check_auth(); }
402
 | AUTHENTICATION CRYPTOGRAPHIC { OSPF_PATT->autype = OSPF_AUTH_CRYPT; }
403 404
 | RX BUFFER NORMAL { OSPF_PATT->rx_buffer = 0; }
 | RX BUFFER LARGE { OSPF_PATT->rx_buffer = OSPF_MAX_PKT_SIZE; }
405
 | 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"); }
406 407
 | TX tos { OSPF_PATT->tx_tos = $2; }
 | TX PRIORITY expr { OSPF_PATT->tx_priority = $3; }
408
 | 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"); }
409 410
 | TTL SECURITY bool { OSPF_PATT->ttl_security = $3; }
 | TTL SECURITY TX ONLY { OSPF_PATT->ttl_security = 2; }
411
 | BFD bool { OSPF_PATT->bfd = $2; cf_check_bfd($2); }
412
 | password_list
413
 ;
414

415 416 417 418 419
pref_list:
 /* empty */
 | pref_list pref_item
 ;

420
pref_item: pref_base pref_opt ';' ;
421

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

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

436
nbma_list:
437
 /* empty */
438
 | nbma_list nbma_item
439
 ;
440

441 442 443 444
nbma_eligible:
 /* empty */ { $$ = 0; }
 | ELIGIBLE { $$ = 1; }
 ;
445

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

455 456 457 458
ospf_iface_start:
 {
  this_ipatt = cfg_allocz(sizeof(struct ospf_iface_patt));
  add_tail(&this_area->patt_list, NODE this_ipatt);
459
  init_list(&this_ipatt->ipn_list);
460 461
  OSPF_PATT->cost = COST_D;
  OSPF_PATT->helloint = HELLOINT_D;
462
  OSPF_PATT->pollint = POLLINT_D;
463 464 465 466 467
  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;
468
  init_list(&OSPF_PATT->nbma_list);
469
  OSPF_PATT->check_link = 1;
470
  OSPF_PATT->ptp_netmask = 2; /* not specified */
471 472
  OSPF_PATT->tx_tos = IP_PREC_INTERNET_CONTROL;
  OSPF_PATT->tx_priority = sk_priority_control;
473
  reset_passwords();
474 475 476
 }
;

477 478
ospf_instance_id:
   /* empty */
479
 | 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"); }
480 481
 ;

482
ospf_iface_patt_list:
483
   iface_patt_list { if (ospf_cfg_is_v3()) iface_patt_check(); } ospf_instance_id
484
 ;
485

Ondřej Filip's avatar
Ondřej Filip committed
486
ospf_iface_opts:
487
   /* empty */
Ondřej Filip's avatar
Ondřej Filip committed
488 489 490
 | ospf_iface_opts ospf_iface_item ';'
 ;

491 492 493 494
ospf_iface_opt_list:
   /* empty */
 | '{' ospf_iface_opts '}'
 ;
Ondřej Filip's avatar
Ondřej Filip committed
495 496

ospf_iface:
497
  ospf_iface_start ospf_iface_patt_list ospf_iface_opt_list { ospf_iface_finish(); }
Ondřej Filip's avatar
Ondřej Filip committed
498 499
 ;

500 501 502
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); })
503
CF_ADDTO(dynamic_attr, OSPF_ROUTER_ID { $$ = f_new_dynamic_attr(EAF_TYPE_ROUTER_ID | EAF_TEMP, T_QUAD, EA_OSPF_ROUTER_ID); })
504

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

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

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

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

517 518 519 520 521 522 523 524 525 526 527 528 529
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); };
530

531
CF_CLI_HELP(SHOW OSPF LSADB, ..., [[Show content of OSPF LSA database]]);
532 533 534 535 536 537 538 539
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; }
540
 | lsadb_args AREA idval { $$ = $1; $$->scope = LSA_SCOPE_AREA; $$->area = $3; }
541 542 543 544 545 546 547
 | 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; }
 ;
548

549 550 551
CF_CODE

CF_END