Revision 4116db18 proto/static/static.c

View differences:

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

Also available in: Unified diff