Revision 4116db18

View differences:

doc/bird.sgml
2420 2420
you don't have any specific destination for them and you don't want to send
2421 2421
them out through the default route to prevent routing loops).
2422 2422

  
2423
<p>There are three types of static routes: `classical' routes telling to
2424
forward packets to a neighboring router, device routes specifying forwarding
2425
to hosts on a directly connected network and special routes (sink, blackhole
2426
etc.) which specify a special action to be done instead of forwarding the
2427
packet.
2423
<p>There are five types of static routes: `classical' routes telling
2424
to forward packets to a neighboring router, multipath routes
2425
specifying several (possibly weighted) neighboring routers, device
2426
routes specifying forwarding to hosts on a directly connected network,
2427
recursive routes computing their nexthops by doing route table lookups
2428
for a given IP and special routes (sink, blackhole etc.) which specify
2429
a special action to be done instead of forwarding the packet.
2428 2430

  
2429 2431
<p>When the particular destination is not available (the interface is down or
2430 2432
the next hop of the route is not a neighbor at the moment), Static just
......
2442 2444
 	with their weights.
2443 2445
	<tag>route <m/prefix/ via <m/"interface"/</tag> Static device
2444 2446
	route through an interface to hosts on a directly connected network.
2447
	<tag>route <m/prefix/ recursive <m/ip/</tag> Static recursive route,
2448
	its nexthop depends on a route table lookup for given IP address.
2445 2449
	<tag>route <m/prefix/ drop|reject|prohibit</tag> Special routes
2446 2450
	specifying to drop the packet, return it as unreachable or return
2447 2451
	it as administratively prohibited.
2448 2452

  
2449
	<tag>check link <M>switch</M></tag>
2450
	The only option of the static protocol. If set, hardware link
2451
	states of network interfaces are taken into consideration.
2452
	When link disappears (e.g. ethernet cable is unplugged),
2453
	static routes directing to that interface are removed. It is
2454
	possible that some hardware drivers or platforms do not
2455
	implement this feature. Default: off.
2453
	<tag>check link <m/switch/</tag>
2454
	If set, hardware link states of network interfaces are taken
2455
	into consideration.  When link disappears (e.g. ethernet cable
2456
	is unplugged), static routes directing to that interface are
2457
	removed. It is possible that some hardware drivers or
2458
	platforms do not implement this feature. Default: off.
2459

  
2460
	<tag>igp table <m/name/</tag> Specifies a table that is used
2461
	for route table lookups of recursive routes. Default: the
2462
	same table as the protocol is connected to.
2456 2463
</descrip>
2457 2464

  
2458 2465
<p>Static routes have no specific attributes.
proto/static/config.Y
18 18
CF_DECLS
19 19

  
20 20
CF_KEYWORDS(STATIC, ROUTE, VIA, DROP, REJECT, PROHIBIT, PREFERENCE, CHECK, LINK)
21
CF_KEYWORDS(MULTIPATH, WEIGHT)
21
CF_KEYWORDS(MULTIPATH, WEIGHT, RECURSIVE, IGP, TABLE)
22 22

  
23 23

  
24 24
CF_GRAMMAR
......
35 35
   static_proto_start proto_name '{'
36 36
 | static_proto proto_item ';'
37 37
 | static_proto CHECK LINK bool ';' { STATIC_CFG->check_link = $4; }
38
 | static_proto IGP TABLE rtable ';' { STATIC_CFG->igp_table = $4; }
38 39
 | static_proto stat_route ';'
39 40
 ;
40 41

  
......
79 80
 | stat_route0 MULTIPATH stat_multipath {
80 81
      this_srt->dest = RTD_MULTIPATH;
81 82
   }
83
 | stat_route0 RECURSIVE ipa {
84
      this_srt->dest = RTDX_RECURSIVE;
85
      this_srt->via = $3;
86
   }
82 87
 | stat_route0 DROP { this_srt->dest = RTD_BLACKHOLE; }
83 88
 | stat_route0 REJECT { this_srt->dest = RTD_UNREACHABLE; }
84 89
 | stat_route0 PROHIBIT { this_srt->dest = RTD_PROHIBIT; }
proto/static/static.c
47 47

  
48 48
#include "static.h"
49 49

  
50
static inline rtable *
51
p_igp_table(struct proto *p)
52
{
53
  struct static_config *cf = (void *) p->cf;
54
  return cf->igp_table ? cf->igp_table->table : p->table;
55
}
56

  
57

  
50 58
static void
51 59
static_install(struct proto *p, struct static_route *r, struct iface *ifa)
52 60
{
......
97 105
	a.nexthops = nhs;
98 106
    }
99 107

  
108
  if (r->dest == RTDX_RECURSIVE)
109
    rta_set_recursive_next_hop(p->table, &a, p_igp_table(p), &r->via, &r->via);
110

  
100 111
  aa = rta_lookup(&a);
101 112
  n = net_get(p->table, r->net, r->masklen);
102 113
  e = rte_get_temp(aa);
......
207 218
static int
208 219
static_start(struct proto *p)
209 220
{
210
  struct static_config *c = (void *) p->cf;
221
  struct static_config *cf = (void *) p->cf;
211 222
  struct static_route *r;
212 223

  
213 224
  DBG("Static: take off!\n");
214
  WALK_LIST(r, c->other_routes)
215
    static_add(p, c, r);
225

  
226
  if (cf->igp_table)
227
    rt_lock_table(cf->igp_table->table);
228

  
229
  WALK_LIST(r, cf->other_routes)
230
    static_add(p, cf, r);
216 231
  return PS_UP;
217 232
}
218 233

  
219 234
static int
220 235
static_shutdown(struct proto *p)
221 236
{
222
  struct static_config *c = (void *) p->cf;
237
  struct static_config *cf = (void *) p->cf;
223 238
  struct static_route *r;
224 239

  
225 240
  /* Just reset the flag, the routes will be flushed by the nest */
226
  WALK_LIST(r, c->iface_routes)
241
  WALK_LIST(r, cf->iface_routes)
227 242
    r->installed = 0;
228
  WALK_LIST(r, c->other_routes)
243
  WALK_LIST(r, cf->other_routes)
229 244
    r->installed = 0;
230 245

  
231 246
  return PS_DOWN;
232 247
}
233 248

  
234 249
static void
250
static_cleanup(struct proto *p)
251
{
252
  struct static_config *cf = (void *) p->cf;
253

  
254
  if (cf->igp_table)
255
    rt_unlock_table(cf->igp_table->table);
256
}
257

  
258

  
259
static void
235 260
static_neigh_notify(struct neighbor *n)
236 261
{
237 262
  struct proto *p = n->proto;
......
373 398
	  return 0;
374 399
      return !x && !y;
375 400

  
401
    case RTDX_RECURSIVE:
402
      return ipa_equal(x->via, y->via);
403

  
376 404
    default:
377 405
      return 1;
378 406
    }
......
407 435
  static_remove(p, r);
408 436
}
409 437

  
438
static inline rtable *
439
cf_igp_table(struct static_config *cf)
440
{
441
  return cf->igp_table ? cf->igp_table->table : NULL;
442
}
443

  
410 444
static int
411 445
static_reconfigure(struct proto *p, struct proto_config *new)
412 446
{
......
414 448
  struct static_config *n = (void *) new;
415 449
  struct static_route *r;
416 450

  
451
  if (cf_igp_table(o) != cf_igp_table(n))
452
    return 0;
453

  
417 454
  /* Delete all obsolete routes and reset neighbor entries */
418 455
  WALK_LIST(r, o->iface_routes)
419 456
    static_match(p, r, n);
......
440 477
  dump:		static_dump,
441 478
  start:	static_start,
442 479
  shutdown:	static_shutdown,
480
  cleanup:	static_cleanup,
443 481
  reconfigure:	static_reconfigure,
444 482
};
445 483

  
......
456 494
    case RTD_UNREACHABLE: bsprintf(via, "unreachable"); break;
457 495
    case RTD_PROHIBIT:	bsprintf(via, "prohibited"); break;
458 496
    case RTD_MULTIPATH:	bsprintf(via, "multipath"); break;
497
    case RTDX_RECURSIVE: bsprintf(via, "recursive %I", r->via); break;
459 498
    default:		bsprintf(via, "???");
460 499
    }
461 500
  cli_msg(-1009, "%I/%d %s%s", r->net, r->masklen, via, r->installed ? "" : " (dormant)");
proto/static/static.h
13 13
  struct proto_config c;
14 14
  list iface_routes;		/* Routes to search on interface events */
15 15
  list other_routes;		/* Routes hooked to neighbor cache and reject routes */
16
  int check_link;		/* Whether iface link state is used */
16
  int check_link;			/* Whether iface link state is used */
17
  struct rtable_config *igp_table;	/* Table used for recursive next hop lookups */
17 18
};
18 19

  
19 20

  
......
35 36
/* Dummy nodes (parts of multipath route) abuses masklen field for weight
36 37
   and if_name field for a ptr to the master (RTD_MULTIPATH) node. */
37 38

  
39

  
40
#define RTDX_RECURSIVE 0x7f		/* Phony dest value for recursive routes */
41

  
38 42
void static_show(struct proto *);
39 43

  
40 44
#endif

Also available in: Unified diff