Revision ce1da96e

View differences:

TODO
13 13
- filter-defined internal attributes
14 14
- netlink: realms
15 15

  
16
- bgp: wait on restart
16
- filters: deletion of mandatory attributes?
17 17

  
18
Commands
19
~~~~~~~~
20
- showing of routing table as seen by given protocol
18
- bgp: wait on restart
21 19

  
22 20
Documentation
23 21
~~~~~~~~~~~~~
doc/reply_codes
41 41
8001	Route not found
42 42
8002	Configuration file error
43 43
8003	No protocols match
44
8004	Stopped due to reconfiguration
45
8005	Protocol is down => cannot dump
44 46

  
45 47
9000	Command too long
46 48
9001	Parse error
nest/config.Y
22 22
CF_KEYWORDS(ROUTER, ID, PROTOCOL, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
23 23
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
24 24
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
25
CF_KEYWORDS(PRIMARY)
25 26

  
26 27
CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
27 28
	RIP, OSPF, OSPF_EXT, OSPF_IA, OSPF_BOUNDARY, BGP, PIPE)
......
32 33
%type <p> password_list password_begin
33 34
%type <s> optsym
34 35
%type <ra> r_args
35
%type <i> echo_mask echo_size debug_mask debug_list debug_flag
36
%type <i> echo_mask echo_size debug_mask debug_list debug_flag import_or_proto
36 37
%type <t> proto_patt
37 38

  
38 39
CF_GRAMMAR
......
239 240
CF_CLI(SHOW INTERFACES SUMMARY,,, [[Show summary of network interfaces]])
240 241
{ if_show_summary(); } ;
241 242

  
242
CF_CLI(SHOW ROUTE, r_args, [<prefix>] [table <t>] [filter <f>] [all], [[Show routing table]])
243
CF_CLI(SHOW ROUTE, r_args, [<prefix>] [table <t>] [filter <f>] [all] [primary] [(import|protocol) <p>], [[Show routing table]])
243 244
{ rt_show($3); } ;
244 245

  
245 246
r_args:
......
275 276
     $$ = $1;
276 277
     $$->verbose = 1;
277 278
   }
279
 | r_args PRIMARY {
280
     $$ = $1;
281
     $$->primary_only = 1;
282
   }
283
 | r_args import_or_proto SYM {
284
     struct proto_config *c = (struct proto_config *) $3->def;
285
     $$ = $1;
286
     if ($$->import_mode) cf_error("Protocol specified twice");
287
     if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
288
     $$->import_mode = $2;
289
     $$->primary_only = 1;
290
     $$->import_protocol = c->proto;
291
     $$->running_on_config = c->proto->cf->global;
292
   }
293
 ;
294

  
295
import_or_proto:
296
   IMPORT { $$ = 1; }
297
 | PROTOCOL { $$ = 2; }
278 298
 ;
279 299

  
280 300
CF_CLI(SHOW SYMBOLS, optsym, [<symbol>], [[Show all known symbolic names]])
nest/protocol.h
47 47
  int (*start)(struct proto *);			/* Start the instance */
48 48
  int (*shutdown)(struct proto *);		/* Stop the instance */
49 49
  void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */
50
  void (*get_route_info)(struct rte *, byte *buf); /* Get route information (for `show route' command) */
50
  void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs); /* Get route information (for `show route' command) */
51 51
  int (*get_attr)(struct eattr *, byte *buf);	/* ASCIIfy dynamic attribute (returns GA_*) */
52 52
};
53 53

  
nest/route.h
206 206
  struct filter *filter;
207 207
  int verbose;
208 208
  struct fib_iterator fit;
209
  struct proto *import_protocol;
210
  int import_mode, primary_only;
211
  struct config *running_on_config;
209 212
};
210 213
void rt_show(struct rt_show_data *);
211 214

  
......
326 329
unsigned int ea_hash(ea_list *e);	/* Calculate 16-bit hash value */
327 330
void ea_format(eattr *e, byte *buf);
328 331
#define EA_FORMAT_BUF_SIZE 256
332
ea_list *ea_append(ea_list *to, ea_list *what);
329 333

  
330 334
void rta_init(void);
331 335
rta *rta_lookup(rta *);			/* Get rta equivalent to this one, uc++ */
......
335 339
void rta_dump(rta *);
336 340
void rta_dump_all(void);
337 341
static inline eattr * rta_find(rta *a, unsigned ea) { return ea_find(a->eattrs, ea); }
338
void rta_show(struct cli *, rta *);
342
void rta_show(struct cli *, rta *, ea_list *);
339 343

  
340 344
extern struct protocol *attr_class_to_protocol[EAP_MAX];
341 345

  
nest/rt-attr.c
380 380
  return h;
381 381
}
382 382

  
383
ea_list *
384
ea_append(ea_list *to, ea_list *what)
385
{
386
  ea_list *res;
387

  
388
  if (!to)
389
    return what;
390
  res = to;
391
  while (to->next)
392
    to = to->next;
393
  to->next = what;
394
  return res;
395
}
396

  
383 397
/*
384 398
 *	rta's
385 399
 */
......
551 565
}
552 566

  
553 567
void
554
rta_show(struct cli *c, rta *a)
568
rta_show(struct cli *c, rta *a, ea_list *eal)
555 569
{
556 570
  static char *src_names[] = { "dummy", "static", "inherit", "device", "static-device", "redirect",
557 571
			       "RIP", "RIP-ext", "OSPF", "OSPF-ext", "OSPF-IA", "OSPF-boundary",
558 572
			       "BGP" };
559 573
  static char *cast_names[] = { "unicast", "broadcast", "multicast", "anycast" };
560
  ea_list *eal;
561 574
  int i;
562 575
  byte buf[EA_FORMAT_BUF_SIZE];
563 576

  
564 577
  cli_printf(c, -1008, "\tType: %s %s %s", src_names[a->source], cast_names[a->cast], ip_scope_text(a->scope));
565
  for(eal=a->eattrs; eal; eal=eal->next)
578
  if (!eal)
579
    eal = a->eattrs;
580
  for(; eal; eal=eal->next)
566 581
    for(i=0; i<eal->count; i++)
567 582
      {
568 583
	ea_format(&eal->attrs[i], buf);
nest/rt-table.c
683 683
}
684 684

  
685 685
static void
686
rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d)
686
rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tmpa)
687 687
{
688 688
  byte via[STD_ADDRESS_P_LENGTH+32], from[STD_ADDRESS_P_LENGTH+6];
689 689
  byte tm[TM_RELTIME_BUFFER_SIZE], info[256];
......
695 695
    bsprintf(from, " from %I", a->from);
696 696
  else
697 697
    from[0] = 0;
698
  if (a->proto->proto->get_route_info || d->verbose)
699
    {
700
      /* Need to normalize the extended attributes */
701
      ea_list *t = tmpa;
702
      t = ea_append(t, a->eattrs);
703
      tmpa = alloca(ea_scan(t));
704
      ea_merge(t, tmpa);
705
    }
698 706
  if (a->proto->proto->get_route_info)
699
    a->proto->proto->get_route_info(e, info);
707
    a->proto->proto->get_route_info(e, info, tmpa);
700 708
  else
701 709
    bsprintf(info, " (%d)", e->pref);
702 710
  cli_printf(c, -1007, "%-18s %s [%s %s%s]%s", ia, via, a->proto->name, tm, from, info);
703 711
  if (d->verbose)
704
    rta_show(c, a);
712
    rta_show(c, a, tmpa);
705 713
}
706 714

  
707 715
static void
......
709 717
{
710 718
  rte *e, *ee;
711 719
  byte ia[STD_ADDRESS_P_LENGTH+8];
720
  int ok;
712 721

  
713 722
  bsprintf(ia, "%I/%d", n->n.prefix, n->n.pxlen);
714 723
  for(e=n->routes; e; e=e->next)
715 724
    {
716
      struct ea_list *tmpa = NULL;
725
      struct ea_list *tmpa, *old_tmpa;
726
      struct proto *p0 = e->attrs->proto;
727
      struct proto *p1 = d->import_protocol;
717 728
      ee = e;
718 729
      rte_update_lock();		/* We use the update buffer for filtering */
719
      if (d->filter == FILTER_ACCEPT || f_run(d->filter, &ee, &tmpa, rte_update_pool, 0) <= F_ACCEPT)
730
      old_tmpa = tmpa = p0->make_tmp_attrs ? p0->make_tmp_attrs(e, rte_update_pool) : NULL;
731
      ok = (d->filter == FILTER_ACCEPT || f_run(d->filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) <= F_ACCEPT);
732
      if (ok && d->import_mode)
733
	{
734
	  int ic = (p1->import_control ? p1->import_control(p1, &e, &tmpa, rte_update_pool) : 0);
735
	  if (ic < 0)
736
	    ok = 0;
737
	  else if (!ic && d->import_mode > 1)
738
	    {
739
	      if (p1->out_filter == FILTER_REJECT ||
740
		  p1->out_filter && f_run(p1->out_filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT)
741
		ok = 0;
742
	    }
743
	}
744
      if (ok)
720 745
	{
721
	  rt_show_rte(c, ia, e, d);
746
	  rt_show_rte(c, ia, e, d, tmpa);
722 747
	  ia[0] = 0;
723 748
	}
724 749
      if (e != ee)
725 750
	rte_free(ee);
726 751
      rte_update_unlock();
752
      if (d->import_mode)		/* In import mode, accept only the primary route */
753
	break;
727 754
    }
728 755
}
729 756

  
......
742 769
  FIB_ITERATE_START(fib, it, f)
743 770
    {
744 771
      net *n = (net *) f;
772
      if (d->running_on_config && d->running_on_config != config)
773
	{
774
	  cli_printf(c, 8004, "Stopped due to reconfiguration");
775
	  goto done;
776
	}
777
      if (d->import_protocol &&
778
	  d->import_protocol->core_state != FS_HAPPY &&
779
	  d->import_protocol->core_state != FS_FEEDING)
780
	{
781
	  cli_printf(c, 8005, "Protocol is down");
782
	  goto done;
783
	}
745 784
      if (!max--)
746 785
	{
747 786
	  FIB_ITERATE_PUT(it, f);
......
751 790
    }
752 791
  FIB_ITERATE_END(f);
753 792
  cli_printf(c, 0, "");
793
done:
754 794
  c->cont = c->cleanup = NULL;
755 795
}
756 796

  
proto/rip/rip.c
535 535
}
536 536

  
537 537
static void
538
rip_get_route_info(rte *rte, byte *buf)
538
rip_get_route_info(rte *rte, byte *buf, ea_list *attrs)
539 539
{
540
  buf += bsprintf(buf, " (%d/%d)", rte->pref, rte->u.rip.metric );
541
  bsprintf(buf, " t%04x", rte->u.rip.tag );
540
  eattr *metric = ea_find(attrs, EA_RIP_METRIC);
541
  eattr *tag = ea_find(attrs, EA_RIP_TAG);
542

  
543
  buf += bsprintf(buf, " (%d/%d)", rte->pref, metric ? metric->u.data : 0);
544
  if (tag && tag->u.data)
545
    bsprintf(buf, " t%04x", tag->u.data);
542 546
}
543 547

  
544 548
static int

Also available in: Unified diff