Revision 4324025f

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,
proto/babel/babel.h
116 116
  u16 tx_length;			/* TX packet length limit (including headers), 0 for MTU */
117 117
  int tx_tos;
118 118
  int tx_priority;
119

  
120
  ip_addr next_hop_ip4;
121
  ip_addr next_hop_ip6;
119 122
};
120 123

  
121 124
struct babel_proto {
122 125
  struct proto p;
123 126
  timer *timer;
124
  struct fib rtable;
127
  struct fib ip4_rtable;
128
  struct fib ip6_rtable;
129

  
130
  struct channel *ip4_channel;
131
  struct channel *ip6_channel;
132

  
125 133
  list interfaces;			/* Interfaces we really know about (struct babel_iface) */
126 134
  u64 router_id;
127 135
  u16 update_seqno;			/* To be increased on request */
......
151 159
  char *ifname;
152 160
  sock *sk;
153 161
  ip_addr addr;
162
  ip_addr next_hop_ip4;
163
  ip_addr next_hop_ip6;
154 164
  int tx_length;
155 165
  list neigh_list;			/* List of neighbors seen on this iface (struct babel_neighbor) */
156 166
  list msg_queue;
proto/babel/config.Y
21 21
CF_DECLS
22 22

  
23 23
CF_KEYWORDS(BABEL, METRIC, RXCOST, HELLO, UPDATE, INTERVAL, PORT, WIRED,
24
WIRELESS, RX, TX, BUFFER, LENGTH, CHECK, LINK, BABEL_METRIC)
24
	WIRELESS, RX, TX, BUFFER, LENGTH, CHECK, LINK, BABEL_METRIC, NEXT, HOP,
25
	IPV4, IPV6)
25 26

  
26 27
CF_GRAMMAR
27 28

  
......
30 31
babel_proto_start: proto_start BABEL
31 32
{
32 33
  this_proto = proto_config_new(&proto_babel, $1);
33
  this_proto->net_type = NET_IP6;
34 34
  init_list(&BABEL_CFG->iface_list);
35 35
};
36 36

  
......
98 98
 | TX tos { BABEL_IFACE->tx_tos = $2; }
99 99
 | TX PRIORITY expr { BABEL_IFACE->tx_priority = $3; }
100 100
 | CHECK LINK bool { BABEL_IFACE->check_link = $3; }
101
 | NEXT HOP IPV4 ipa { BABEL_IFACE->next_hop_ip4 = $4; if (!ipa_is_ip4($4)) cf_error("Must be an IPv4 address"); }
102
 | NEXT HOP IPV6 ipa { BABEL_IFACE->next_hop_ip6 = $4; if (!ipa_is_ip6($4)) cf_error("Must be an IPv6 address"); }
101 103
 ;
102 104

  
103 105
babel_iface_opts:
proto/babel/packets.c
112 112
  struct babel_proto *proto;
113 113
  struct babel_iface *ifa;
114 114
  ip_addr saddr;
115
  ip_addr next_hop;
115
  ip_addr next_hop_ip4;
116
  ip_addr next_hop_ip6;
116 117
  u64 router_id;		/* Router ID used in subsequent updates */
117 118
  u8 def_ip6_prefix[16];	/* Implicit IPv6 prefix in network order */
118 119
  u8 def_ip4_prefix[4];		/* Implicit IPv4 prefix in network order */
......
130 131
struct babel_write_state {
131 132
  u64 router_id;
132 133
  u8 router_id_seen;
133
//  ip_addr next_hop;
134
  ip_addr next_hop_ip4;
135
  ip_addr next_hop_ip6;
134 136
};
135 137

  
136 138

  
......
163 165
}
164 166

  
165 167
static inline void
168
read_ip4_px(net_addr *n, const void *p, uint plen)
169
{
170
  ip4_addr addr = {0};
171
  memcpy(&addr, p, BYTES(plen));
172
  net_fill_ip4(n, ip4_ntoh(addr), plen);
173
}
174

  
175
static inline void
176
put_ip4_px(void *p, net_addr *n)
177
{
178
  ip4_addr addr = ip4_hton(net4_prefix(n));
179
  memcpy(p, &addr, NET_SIZE(n));
180
}
181

  
182
static inline void
166 183
read_ip6_px(net_addr *n, const void *p, uint plen)
167 184
{
168 185
  ip6_addr addr = IPA_NONE;
......
432 449
    return PARSE_ERROR;
433 450

  
434 451
  case BABEL_AE_IP4:
435
    /* TODO */
452
    if (TLV_OPT_LENGTH(tlv) < sizeof(ip4_addr))
453
      return PARSE_ERROR;
454

  
455
    state->next_hop_ip4 = ipa_from_ip4(get_ip4(&tlv->addr));
436 456
    return PARSE_IGNORE;
437 457

  
438 458
  case BABEL_AE_IP6:
439 459
    if (TLV_OPT_LENGTH(tlv) < sizeof(ip6_addr))
440 460
      return PARSE_ERROR;
441 461

  
442
    state->next_hop = ipa_from_ip6(get_ip6(&tlv->addr));
462
    state->next_hop_ip6 = ipa_from_ip6(get_ip6(&tlv->addr));
443 463
    return PARSE_IGNORE;
444 464

  
445 465
  case BABEL_AE_IP6_LL:
446 466
    if (TLV_OPT_LENGTH(tlv) < 8)
447 467
      return PARSE_ERROR;
448 468

  
449
    state->next_hop = ipa_from_ip6(get_ip6_ll(&tlv->addr));
469
    state->next_hop_ip6 = ipa_from_ip6(get_ip6_ll(&tlv->addr));
450 470
    return PARSE_IGNORE;
451 471

  
452 472
  default:
......
456 476
  return PARSE_IGNORE;
457 477
}
458 478

  
479
/* This is called directly from babel_write_update() and returns -1 if a next
480
   hop should be written but there is not enough space. */
481
static int
482
babel_write_next_hop(struct babel_tlv *hdr, ip_addr addr,
483
		     struct babel_write_state *state, uint max_len)
484
{
485
  struct babel_tlv_next_hop *tlv = (void *) hdr;
486

  
487
  if (ipa_zero(addr))
488
  {
489
    /* Should not happen */
490
    return 0;
491
  }
492
  else if (ipa_is_ip4(addr) && !ipa_equal(addr, state->next_hop_ip4))
493
  {
494
    uint len = sizeof(struct babel_tlv_next_hop) + sizeof(ip4_addr);
495
    if (len > max_len)
496
      return -1;
497

  
498
    TLV_HDR(tlv, BABEL_TLV_NEXT_HOP, len);
499

  
500
    tlv->ae = BABEL_AE_IP4;
501
    put_ip4(&tlv->addr, ipa_to_ip4(addr));
502
    state->next_hop_ip4 = addr;
503

  
504
    return len;
505
  }
506
  else if (ipa_is_ip6(addr) && !ipa_equal(addr, state->next_hop_ip6))
507
  {
508
    uint len = sizeof(struct babel_tlv_next_hop) + sizeof(ip6_addr);
509
    if (len > max_len)
510
      return -1;
511

  
512
    TLV_HDR(tlv, BABEL_TLV_NEXT_HOP, len);
513

  
514
    tlv->ae = BABEL_AE_IP6;
515
    put_ip6(&tlv->addr, ipa_to_ip6(addr));
516
    state->next_hop_ip6 = addr;
517

  
518
    return len;
519
  }
520

  
521
  return 0;
522
}
523

  
459 524
static int
460 525
babel_read_update(struct babel_tlv *hdr, union babel_msg *m,
461 526
                  struct babel_parse_state *state)
......
488 553
    break;
489 554

  
490 555
  case BABEL_AE_IP4:
491
    /* TODO */
492
    return PARSE_IGNORE;
556
    if (tlv->plen > IP4_MAX_PREFIX_LENGTH)
557
      return PARSE_ERROR;
558

  
559
    /* Cannot omit data if there is no saved prefix */
560
    if (tlv->omitted && !state->def_ip4_prefix_seen)
561
      return PARSE_ERROR;
562

  
563
    /* Need next hop for v4 routes */
564
    if (ipa_zero(state->next_hop_ip4))
565
      return PARSE_ERROR;
566

  
567
    /* Merge saved prefix and received prefix parts */
568
    memcpy(buf, state->def_ip4_prefix, tlv->omitted);
569
    memcpy(buf + tlv->omitted, tlv->addr, len);
570

  
571
    ip4_addr prefix4 = get_ip4(buf);
572
    net_fill_ip4(&msg->net, prefix4, tlv->plen);
573

  
574
    if (tlv->flags & BABEL_FLAG_DEF_PREFIX)
575
    {
576
      put_ip4(state->def_ip4_prefix, prefix4);
577
      state->def_ip4_prefix_seen = 1;
578
    }
579

  
580
    msg->next_hop = state->next_hop_ip4;
581

  
582
    break;
493 583

  
494 584
  case BABEL_AE_IP6:
495 585
    if (tlv->plen > IP6_MAX_PREFIX_LENGTH)
......
503 593
    memcpy(buf, state->def_ip6_prefix, tlv->omitted);
504 594
    memcpy(buf + tlv->omitted, tlv->addr, len);
505 595

  
506
    ip6_addr prefix = get_ip6(buf);
507
    net_fill_ip6(&msg->net, prefix, tlv->plen);
596
    ip6_addr prefix6 = get_ip6(buf);
597
    net_fill_ip6(&msg->net, prefix6, tlv->plen);
508 598

  
509 599
    if (tlv->flags & BABEL_FLAG_DEF_PREFIX)
510 600
    {
511
      put_ip6(state->def_ip6_prefix, prefix);
601
      put_ip6(state->def_ip6_prefix, prefix6);
512 602
      state->def_ip6_prefix_seen = 1;
513 603
    }
514 604

  
515 605
    if (tlv->flags & BABEL_FLAG_ROUTER_ID)
516 606
    {
517
      state->router_id = ((u64) _I2(prefix)) << 32 | _I3(prefix);
607
      state->router_id = ((u64) _I2(prefix6)) << 32 | _I3(prefix6);
518 608
      state->router_id_seen = 1;
519 609
    }
610

  
611
    msg->next_hop = state->next_hop_ip6;
612

  
520 613
    break;
521 614

  
522 615
  case BABEL_AE_IP6_LL:
......
535 628
  }
536 629

  
537 630
  msg->router_id = state->router_id;
538
  msg->next_hop = state->next_hop;
539 631
  msg->sender = state->saddr;
540 632

  
541 633
  return PARSE_SUCCESS;
......
545 637
babel_write_update(struct babel_tlv *hdr, union babel_msg *m,
546 638
                   struct babel_write_state *state, uint max_len)
547 639
{
548
  struct babel_tlv_update *tlv = (void *) hdr;
549 640
  struct babel_msg_update *msg = &m->update;
550 641
  uint len0 = 0;
551 642

  
......
554 645
   * both of them. There is enough space for the Router-ID TLV, because
555 646
   * sizeof(struct babel_tlv_router_id) == sizeof(struct babel_tlv_update).
556 647
   *
557
   * Router ID is not used for retractions, so do not us it in such case.
648
   * Router ID is not used for retractions, so do not use it in such case.
558 649
   */
559 650
  if ((msg->metric < BABEL_INFINITY) &&
560 651
      (!state->router_id_seen || (msg->router_id != state->router_id)))
561 652
  {
562 653
    len0 = babel_write_router_id(hdr, msg->router_id, state, max_len);
563
    tlv = (struct babel_tlv_update *) NEXT_TLV(tlv);
654
    hdr = NEXT_TLV(hdr);
564 655
  }
565 656

  
657
  /*
658
   * We also may add Next Hop TLV for regular updates. It may fail for not
659
   * enough space or it may be unnecessary as the next hop is the same as the
660
   * last one already announced. So we handle all three cases.
661
   */
662
  if (msg->metric < BABEL_INFINITY)
663
  {
664
    int l = babel_write_next_hop(hdr, msg->next_hop, state, max_len - len0);
665
    if (l < 0)
666
      return 0;
667

  
668
    if (l)
669
    {
670
      len0 += l;
671
      hdr = NEXT_TLV(hdr);
672
    }
673
  }
674

  
675
  struct babel_tlv_update *tlv = (void *) hdr;
566 676
  uint len = sizeof(struct babel_tlv_update) + NET_SIZE(&msg->net);
567 677

  
568 678
  if (len0 + len > max_len)
......
576 686
    tlv->ae = BABEL_AE_WILDCARD;
577 687
    tlv->plen = 0;
578 688
  }
689
  else if (msg->net.type == NET_IP4)
690
  {
691
    tlv->ae = BABEL_AE_IP4;
692
    tlv->plen = net4_pxlen(&msg->net);
693
    put_ip4_px(tlv->addr, &msg->net);
694
  }
579 695
  else
580 696
  {
581 697
    tlv->ae = BABEL_AE_IP6;
......
610 726
    return PARSE_SUCCESS;
611 727

  
612 728
  case BABEL_AE_IP4:
613
    /* TODO */
614
    return PARSE_IGNORE;
729
    if (tlv->plen > IP4_MAX_PREFIX_LENGTH)
730
      return PARSE_ERROR;
731

  
732
    if (TLV_OPT_LENGTH(tlv) < BYTES(tlv->plen))
733
      return PARSE_ERROR;
734

  
735
    read_ip4_px(&msg->net, tlv->addr, tlv->plen);
736
    return PARSE_SUCCESS;
615 737

  
616 738
  case BABEL_AE_IP6:
617 739
    if (tlv->plen > IP6_MAX_PREFIX_LENGTH)
......
652 774
    tlv->ae = BABEL_AE_WILDCARD;
653 775
    tlv->plen = 0;
654 776
  }
777
  else if (msg->net.type == NET_IP4)
778
  {
779
    tlv->ae = BABEL_AE_IP4;
780
    tlv->plen = net4_pxlen(&msg->net);
781
    put_ip4_px(tlv->addr, &msg->net);
782
  }
655 783
  else
656 784
  {
657 785
    tlv->ae = BABEL_AE_IP6;
......
684 812
    return PARSE_ERROR;
685 813

  
686 814
  case BABEL_AE_IP4:
687
    /* TODO */
688
    return PARSE_IGNORE;
815
    if (tlv->plen > IP4_MAX_PREFIX_LENGTH)
816
      return PARSE_ERROR;
817

  
818
    if (TLV_OPT_LENGTH(tlv) < BYTES(tlv->plen))
819
      return PARSE_ERROR;
820

  
821
    read_ip4_px(&msg->net, tlv->addr, tlv->plen);
822
    return PARSE_SUCCESS;
689 823

  
690 824
  case BABEL_AE_IP6:
691 825
    if (tlv->plen > IP6_MAX_PREFIX_LENGTH)
......
720 854
    return 0;
721 855

  
722 856
  TLV_HDR(tlv, BABEL_TLV_SEQNO_REQUEST, len);
723
  tlv->ae = BABEL_AE_IP6;
724
  tlv->plen = net6_pxlen(&msg->net);
857

  
858
  if (msg->net.type == NET_IP4)
859
  {
860
    tlv->ae = BABEL_AE_IP4;
861
    tlv->plen = net4_pxlen(&msg->net);
862
    put_ip4_px(tlv->addr, &msg->net);
863
  }
864
  else
865
  {
866
    tlv->ae = BABEL_AE_IP6;
867
    tlv->plen = net6_pxlen(&msg->net);
868
    put_ip6_px(tlv->addr, &msg->net);
869
  }
870

  
725 871
  put_u16(&tlv->seqno, msg->seqno);
726 872
  tlv->hop_count = msg->hop_count;
727 873
  put_u64(&tlv->router_id, msg->router_id);
728
  put_ip6_px(tlv->addr, &msg->net);
729 874

  
730 875
  return len;
731 876
}
......
799 944
babel_write_queue(struct babel_iface *ifa, list *queue)
800 945
{
801 946
  struct babel_proto *p = ifa->proto;
802
  struct babel_write_state state = {};
947
  struct babel_write_state state = { .next_hop_ip6 = ifa->addr };
803 948

  
804 949
  if (EMPTY_LIST(*queue))
805 950
    return 0;
......
935 1080
  byte *end = (byte *)pkt + plen;
936 1081

  
937 1082
  struct babel_parse_state state = {
938
    .proto	= p,
939
    .ifa	= ifa,
940
    .saddr	= saddr,
941
    .next_hop	= saddr,
1083
    .proto	  = p,
1084
    .ifa	  = ifa,
1085
    .saddr	  = saddr,
1086
    .next_hop_ip6 = saddr,
942 1087
  };
943 1088

  
944 1089
  if ((pkt->magic != BABEL_MAGIC) || (pkt->version != BABEL_VERSION))

Also available in: Unified diff