Revision 4324025f proto/babel/babel.c

View differences:

proto/babel/babel.c
78 78
static inline struct babel_entry *
79 79
babel_find_entry(struct babel_proto *p, const net_addr *n)
80 80
{
81
  return fib_find(&p->rtable, n);
81
  struct fib *rtable = (n->type == NET_IP4) ? &p->ip4_rtable : &p->ip6_rtable;
82
  return fib_find(rtable, n);
82 83
}
83 84

  
84 85
static struct babel_entry *
85 86
babel_get_entry(struct babel_proto *p, const net_addr *n)
86 87
{
87
  struct babel_entry *e = fib_get(&p->rtable, n);
88
  struct fib *rtable = (n->type == NET_IP4) ? &p->ip4_rtable : &p->ip6_rtable;
89
  struct babel_entry *e = fib_get(rtable, n);
88 90
  e->proto = p;
89 91
  return e;
90 92
}
......
224 226
}
225 227

  
226 228
static void
227
babel_expire_routes(struct babel_proto *p)
229
babel_expire_routes_(struct babel_proto *p UNUSED, struct fib *rtable)
228 230
{
229 231
  struct babel_route *r, *rx;
230 232
  struct fib_iterator fit;
231 233

  
232
  FIB_ITERATE_INIT(&fit, &p->rtable);
234
  FIB_ITERATE_INIT(&fit, rtable);
233 235

  
234 236
loop:
235
  FIB_ITERATE_START(&p->rtable, &fit, struct babel_entry, e)
237
  FIB_ITERATE_START(rtable, &fit, struct babel_entry, e)
236 238
  {
237 239
    int changed = 0;
238 240

  
......
253 255
      /*
254 256
       * We have to restart the iteration because there may be a cascade of
255 257
       * synchronous events babel_select_route() -> nest table change ->
256
       * babel_rt_notify() -> p->rtable change, invalidating hidden variables.
258
       * babel_rt_notify() -> rtable change, invalidating hidden variables.
257 259
       */
258 260

  
259 261
      FIB_ITERATE_PUT(&fit);
......
267 269
    if (EMPTY_LIST(e->sources) && EMPTY_LIST(e->routes))
268 270
    {
269 271
      FIB_ITERATE_PUT(&fit);
270
      fib_delete(&p->rtable, e);
272
      fib_delete(rtable, e);
271 273
      goto loop;
272 274
    }
273 275
  }
274 276
  FIB_ITERATE_END;
275 277
}
276 278

  
279
static void
280
babel_expire_routes(struct babel_proto *p)
281
{
282
  babel_expire_routes_(p, &p->ip4_rtable);
283
  babel_expire_routes_(p, &p->ip6_rtable);
284
}
285

  
277 286
static struct babel_neighbor *
278 287
babel_find_neighbor(struct babel_iface *ifa, ip_addr addr)
279 288
{
......
468 477
babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
469 478
{
470 479
  struct babel_route *r = e->selected_in;
480
  struct channel *c = (e->n.addr->type == NET_IP4) ? p->ip4_channel : p->ip6_channel;
471 481

  
472 482
  if (r)
473 483
  {
......
490 500
    rte->u.babel.router_id = r->router_id;
491 501
    rte->pflags = 0;
492 502

  
493
    rte_update(&p->p, e->n.addr, rte);
503
    rte_update2(c, e->n.addr, rte, p->p.main_source);
494 504
  }
495 505
  else
496 506
  {
497 507
    /* Retraction */
498
    rte_update(&p->p, e->n.addr, NULL);
508
    rte_update2(c, e->n.addr, NULL, p->p.main_source);
499 509
  }
500 510
}
501 511

  
......
740 750
 * transmitted entry is updated.
741 751
 */
742 752
static void
743
babel_send_update(struct babel_iface *ifa, bird_clock_t changed)
753
babel_send_update_(struct babel_iface *ifa, bird_clock_t changed, struct fib *rtable)
744 754
{
745 755
  struct babel_proto *p = ifa->proto;
746 756

  
747
  FIB_WALK(&p->rtable, struct babel_entry, e)
757
  FIB_WALK(rtable, struct babel_entry, e)
748 758
  {
749 759
    struct babel_route *r = e->selected_out;
750 760

  
......
774 784
    msg.update.router_id = r->router_id;
775 785
    net_copy(&msg.update.net, e->n.addr);
776 786

  
787
    msg.update.next_hop = ((e->n.addr->type == NET_IP4) ?
788
			   ifa->next_hop_ip4 : ifa->next_hop_ip6);
789

  
777 790
    babel_enqueue(&msg, ifa);
778 791

  
779 792
    /* Update feasibility distance for redistributed routes */
......
794 807
}
795 808

  
796 809
static void
810
babel_send_update(struct babel_iface *ifa, bird_clock_t changed)
811
{
812
  struct babel_proto *p = ifa->proto;
813

  
814
  babel_send_update_(ifa, changed, &p->ip4_rtable);
815
  babel_send_update_(ifa, changed, &p->ip6_rtable);
816
}
817

  
818
static void
797 819
babel_trigger_iface_update(struct babel_iface *ifa)
798 820
{
799 821
  struct babel_proto *p = ifa->proto;
......
1073 1095
    return;
1074 1096
  }
1075 1097

  
1098
  struct channel *c = (msg->net.type == NET_IP4) ? p->ip4_channel : p->ip6_channel;
1099
  if (!c || (c->channel_state != CS_UP))
1100
  {
1101
    DBG("Babel: Ignoring update for inactive address family.\n");
1102
    return;
1103
  }
1104

  
1076 1105
  /*
1077 1106
   * RFC section 3.5.4:
1078 1107
   *
......
1475 1504

  
1476 1505
  add_tail(&p->interfaces, NODE ifa);
1477 1506

  
1507
  ip_addr addr4 = IPA_NONE;
1478 1508
  struct ifa *addr;
1479 1509
  WALK_LIST(addr, new->addrs)
1510
  {
1480 1511
    if (ipa_is_link_local(addr->ip))
1481 1512
      ifa->addr = addr->ip;
1482 1513

  
1514
    if (ipa_zero(addr4) && ipa_is_ip4(addr->ip))
1515
      addr4 = addr->ip;
1516
  }
1517

  
1518
  ifa->next_hop_ip4 = ipa_nonzero(ic->next_hop_ip4) ? ic->next_hop_ip4 : addr4;
1519
  ifa->next_hop_ip6 = ipa_nonzero(ic->next_hop_ip6) ? ic->next_hop_ip6 : ifa->addr;
1520

  
1483 1521
  if (ipa_zero(ifa->addr))
1484 1522
    log(L_WARN "%s: Cannot find link-local addr on %s", p->p.name, new->name);
1485 1523

  
1524
  if (ipa_zero(ifa->next_hop_ip4) && p->ip4_channel)
1525
    log(L_WARN "%s: Cannot find IPv4 next hop addr on %s", p->p.name, new->name);
1526

  
1486 1527
  init_list(&ifa->neigh_list);
1487 1528
  ifa->hello_seqno = 1;
1488 1529

  
......
1574 1615

  
1575 1616
  ifa->cf = new;
1576 1617

  
1618
  if (ipa_nonzero(new->next_hop_ip4))
1619
    ifa->next_hop_ip4 = new->next_hop_ip4;
1620
  else
1621
  {
1622
    ifa->next_hop_ip4 = IPA_NONE;
1623

  
1624
    struct ifa *addr;
1625
    WALK_LIST(addr, ifa->iface->addrs)
1626
      if (ipa_is_ip4(addr->ip))
1627
      {
1628
	ifa->next_hop_ip4 = addr->ip;
1629
	break;
1630
      }
1631
  }
1632

  
1633
  ifa->next_hop_ip6 = ipa_nonzero(new->next_hop_ip6) ? new->next_hop_ip6 : ifa->addr;
1634

  
1635
  if (ipa_zero(ifa->next_hop_ip4) && p->ip4_channel)
1636
    log(L_WARN "%s: Cannot find IPv4 next hop addr on %s", p->p.name, ifa->ifname);
1637

  
1577 1638
  if (ifa->next_hello > (now + new->hello_interval))
1578 1639
    ifa->next_hello = now + (random() % new->hello_interval) + 1;
1579 1640

  
......
1680 1741
{
1681 1742
  struct babel_neighbor *n;
1682 1743

  
1683
  debug("Babel: Interface %s addr %I rxcost %d type %d hello seqno %d intervals %d %d\n",
1744
  debug("Babel: Interface %s addr %I rxcost %d type %d hello seqno %d intervals %d %d",
1684 1745
	ifa->ifname, ifa->addr, ifa->cf->rxcost, ifa->cf->type, ifa->hello_seqno,
1685 1746
	ifa->cf->hello_interval, ifa->cf->update_interval);
1747
  debug(" next hop v4 %I next hop v6 %I\n", ifa->next_hop_ip4, ifa->next_hop_ip6);
1686 1748

  
1687 1749
  WALK_LIST(n, ifa->neigh_list)
1688 1750
  { debug(" "); babel_dump_neighbor(n); }
......
1699 1761
  WALK_LIST(ifa, p->interfaces)
1700 1762
    babel_dump_iface(ifa);
1701 1763

  
1702
  FIB_WALK(&p->rtable, struct babel_entry, e)
1764
  FIB_WALK(&p->ip4_rtable, struct babel_entry, e)
1765
  {
1766
    babel_dump_entry(e);
1767
  }
1768
  FIB_WALK_END;
1769
  FIB_WALK(&p->ip6_rtable, struct babel_entry, e)
1703 1770
  {
1704 1771
    babel_dump_entry(e);
1705 1772
  }
......
1749 1816
  }
1750 1817

  
1751 1818
  cli_msg(-1023, "%s:", p->p.name);
1752
  cli_msg(-1023, "%-10s %-6s %7s %6s %6s",
1753
	  "Interface", "State", "RX cost", "Nbrs", "Timer");
1819
  cli_msg(-1023, "%-10s %-6s %7s %6s %6s %-15s %s",
1820
	  "Interface", "State", "RX cost", "Nbrs", "Timer",
1821
	  "Next hop (v4)", "Next hop (v6)");
1754 1822

  
1755 1823
  WALK_LIST(ifa, p->interfaces)
1756 1824
  {
......
1762 1830
	nbrs++;
1763 1831

  
1764 1832
    int timer = MIN(ifa->next_regular, ifa->next_hello) - now;
1765
    cli_msg(-1023, "%-10s %-6s %7u %6u %6u",
1766
	    ifa->iface->name, (ifa->up ? "Up" : "Down"), ifa->cf->rxcost, nbrs, MAX(timer, 0));
1833
    cli_msg(-1023, "%-10s %-6s %7u %6u %6u %-15I %I",
1834
	    ifa->iface->name, (ifa->up ? "Up" : "Down"),
1835
	    ifa->cf->rxcost, nbrs, MAX(timer, 0),
1836
	    ifa->next_hop_ip4, ifa->next_hop_ip6);
1767 1837
  }
1768 1838

  
1769 1839
  cli_msg(0, "");
......
1808 1878
  cli_msg(0, "");
1809 1879
}
1810 1880

  
1811
void
1812
babel_show_entries(struct proto *P)
1881
static void
1882
babel_show_entries_(struct babel_proto *p, struct fib *rtable)
1813 1883
{
1814
  struct babel_proto *p = (void *) P;
1815 1884
  struct babel_source *s = NULL;
1816 1885
  struct babel_route *r = NULL;
1817 1886

  
1818 1887
  char ridbuf[ROUTER_ID_64_LENGTH+1];
1819 1888

  
1820
  if (p->p.proto_state != PS_UP)
1821
  {
1822
    cli_msg(-1025, "%s: is not up", p->p.name);
1823
    cli_msg(0, "");
1824
    return;
1825
  }
1826

  
1827
  cli_msg(-1025, "%s:", p->p.name);
1828
  cli_msg(-1025, "%-29s %-23s %6s %5s %7s %7s",
1829
	  "Prefix", "Router ID", "Metric", "Seqno", "Expires", "Sources");
1830

  
1831
  FIB_WALK(&p->rtable, struct babel_entry, e)
1889
  FIB_WALK(rtable, struct babel_entry, e)
1832 1890
  {
1833 1891
    r = e->selected_in ? e->selected_in : e->selected_out;
1834 1892

  
......
1853 1911
    }
1854 1912
  }
1855 1913
  FIB_WALK_END;
1914
}
1915

  
1916
void
1917
babel_show_entries(struct proto *P)
1918
{
1919
  struct babel_proto *p = (void *) P;
1920

  
1921
  if (p->p.proto_state != PS_UP)
1922
  {
1923
    cli_msg(-1025, "%s: is not up", p->p.name);
1924
    cli_msg(0, "");
1925
    return;
1926
  }
1927

  
1928
  cli_msg(-1025, "%s:", p->p.name);
1929
  cli_msg(-1025, "%-29s %-23s %6s %5s %7s %7s",
1930
	  "Prefix", "Router ID", "Metric", "Seqno", "Expires", "Sources");
1931

  
1932
  babel_show_entries_(p, &p->ip4_rtable);
1933
  babel_show_entries_(p, &p->ip6_rtable);
1856 1934

  
1857 1935
  cli_msg(0, "");
1858 1936
}
......
2028 2106
babel_init(struct proto_config *CF)
2029 2107
{
2030 2108
  struct proto *P = proto_new(CF);
2109
  struct babel_proto *p = (void *) P;
2031 2110

  
2032
  P->main_channel = proto_add_channel(P, proto_cf_main_channel(CF));
2111
  proto_configure_channel(P, &p->ip4_channel, proto_cf_find_channel(CF, NET_IP4));
2112
  proto_configure_channel(P, &p->ip6_channel, proto_cf_find_channel(CF, NET_IP6));
2033 2113

  
2034 2114
  P->if_notify = babel_if_notify;
2035 2115
  P->rt_notify = babel_rt_notify;
......
2048 2128
  struct babel_proto *p = (void *) P;
2049 2129
  struct babel_config *cf = (void *) P->cf;
2050 2130

  
2051
  fib_init(&p->rtable, P->pool, NET_IP6, sizeof(struct babel_entry),
2131
  fib_init(&p->ip4_rtable, P->pool, NET_IP4, sizeof(struct babel_entry),
2052 2132
	   OFFSETOF(struct babel_entry, n), 0, babel_init_entry);
2133
  fib_init(&p->ip6_rtable, P->pool, NET_IP6, sizeof(struct babel_entry),
2134
	   OFFSETOF(struct babel_entry, n), 0, babel_init_entry);
2135

  
2053 2136
  init_list(&p->interfaces);
2054 2137
  p->timer = tm_new_set(P->pool, babel_timer, p, 0, 1);
2055 2138
  tm_start(p->timer, 2);
......
2099 2182

  
2100 2183
  TRACE(D_EVENTS, "Reconfiguring");
2101 2184

  
2102
  if (!proto_configure_channel(P, &P->main_channel, proto_cf_main_channel(CF)))
2185
  if (!proto_configure_channel(P, &p->ip4_channel, proto_cf_find_channel(CF, NET_IP4)) ||
2186
      !proto_configure_channel(P, &p->ip6_channel, proto_cf_find_channel(CF, NET_IP6)))
2103 2187
    return 0;
2104 2188

  
2105 2189
  p->p.cf = CF;
......
2117 2201
  .template =		"babel%d",
2118 2202
  .attr_class =		EAP_BABEL,
2119 2203
  .preference =		DEF_PREF_BABEL,
2120
  .channel_mask =	NB_IP6,
2204
  .channel_mask =	NB_IP,
2121 2205
  .proto_size =		sizeof(struct babel_proto),
2122 2206
  .config_size =	sizeof(struct babel_config),
2123 2207
  .init =		babel_init,

Also available in: Unified diff