Annotation of embedaddon/bird/proto/babel/babel.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:  *     BIRD -- The Babel protocol
                      3:  *
                      4:  *     Copyright (c) 2015--2016 Toke Hoiland-Jorgensen
                      5:  *
                      6:  *     Can be freely distributed and used under the terms of the GNU GPL.
                      7:  *
                      8:  *     This file contains the main routines for handling and sending TLVs, as
                      9:  *     well as timers and interaction with the nest.
                     10:  */
                     11: 
                     12: /**
                     13:  * DOC: The Babel protocol
                     14:  *
                     15:  * Babel (RFC6126) is a loop-avoiding distance-vector routing protocol that is
                     16:  * robust and efficient both in ordinary wired networks and in wireless mesh
                     17:  * networks.
                     18:  *
                     19:  * The Babel protocol keeps state for each neighbour in a &babel_neighbor
                     20:  * struct, tracking received Hello and I Heard You (IHU) messages. A
                     21:  * &babel_interface struct keeps hello and update times for each interface, and
                     22:  * a separate hello seqno is maintained for each interface.
                     23:  *
                     24:  * For each prefix, Babel keeps track of both the possible routes (with next hop
                     25:  * and router IDs), as well as the feasibility distance for each prefix and
                     26:  * router id. The prefix itself is tracked in a &babel_entry struct, while the
                     27:  * possible routes for the prefix are tracked as &babel_route entries and the
                     28:  * feasibility distance is maintained through &babel_source structures.
                     29:  *
                     30:  * The main route selection is done in babel_select_route(). This is called when
                     31:  * an entry is updated by receiving updates from the network or when modified by
                     32:  * internal timers. It performs feasibility checks on the available routes for
                     33:  * the prefix and selects the one with the lowest metric to be announced to the
                     34:  * core.
                     35:  */
                     36: 
                     37: #include <stdlib.h>
                     38: #include "babel.h"
                     39: 
                     40: 
                     41: #define OUR_ROUTE(r) (r->neigh == NULL)
                     42: 
                     43: /*
                     44:  * Is one number greater or equal than another mod 2^16? This is based on the
                     45:  * definition of serial number space in RFC 1982. Note that arguments are of
                     46:  * uint type to avoid integer promotion to signed integer.
                     47:  */
                     48: static inline int ge_mod64k(uint a, uint b)
                     49: { return (u16)(a - b) < 0x8000; }
                     50: 
                     51: static void babel_dump_entry(struct babel_entry *e);
                     52: static void babel_dump_route(struct babel_route *r);
                     53: static void babel_select_route(struct babel_entry *e);
                     54: static void babel_send_route_request(struct babel_entry *e, struct babel_neighbor *n);
                     55: static void babel_send_wildcard_request(struct babel_iface *ifa);
                     56: static int  babel_cache_seqno_request(struct babel_proto *p, ip_addr prefix, u8 plen,
                     57:                               u64 router_id, u16 seqno);
                     58: static void babel_trigger_iface_update(struct babel_iface *ifa);
                     59: static void babel_trigger_update(struct babel_proto *p);
                     60: static void babel_send_seqno_request(struct babel_entry *e);
                     61: static inline void babel_kick_timer(struct babel_proto *p);
                     62: static inline void babel_iface_kick_timer(struct babel_iface *ifa);
                     63: 
                     64: 
                     65: /*
                     66:  *     Functions to maintain data structures
                     67:  */
                     68: 
                     69: static void
                     70: babel_init_entry(struct fib_node *n)
                     71: {
                     72:   struct babel_entry *e = (void *) n;
                     73:   e->proto = NULL;
                     74:   e->selected_in = NULL;
                     75:   e->selected_out = NULL;
                     76:   e->updated = now;
                     77:   init_list(&e->sources);
                     78:   init_list(&e->routes);
                     79: }
                     80: 
                     81: static inline struct babel_entry *
                     82: babel_find_entry(struct babel_proto *p, ip_addr prefix, u8 plen)
                     83: {
                     84:   return fib_find(&p->rtable, &prefix, plen);
                     85: }
                     86: 
                     87: static struct babel_entry *
                     88: babel_get_entry(struct babel_proto *p, ip_addr prefix, u8 plen)
                     89: {
                     90:   struct babel_entry *e = fib_get(&p->rtable, &prefix, plen);
                     91:   e->proto = p;
                     92:   return e;
                     93: }
                     94: 
                     95: static struct babel_source *
                     96: babel_find_source(struct babel_entry *e, u64 router_id)
                     97: {
                     98:   struct babel_source *s;
                     99: 
                    100:   WALK_LIST(s, e->sources)
                    101:     if (s->router_id == router_id)
                    102:       return s;
                    103: 
                    104:   return NULL;
                    105: }
                    106: 
                    107: static struct babel_source *
                    108: babel_get_source(struct babel_entry *e, u64 router_id)
                    109: {
                    110:   struct babel_proto *p = e->proto;
                    111:   struct babel_source *s = babel_find_source(e, router_id);
                    112: 
                    113:   if (s)
                    114:     return s;
                    115: 
                    116:   s = sl_alloc(p->source_slab);
                    117:   s->router_id = router_id;
                    118:   s->expires = now + BABEL_GARBAGE_INTERVAL;
                    119:   s->seqno = 0;
                    120:   s->metric = BABEL_INFINITY;
                    121:   add_tail(&e->sources, NODE s);
                    122: 
                    123:   return s;
                    124: }
                    125: 
                    126: static void
                    127: babel_expire_sources(struct babel_entry *e)
                    128: {
                    129:   struct babel_proto *p = e->proto;
                    130:   struct babel_source *n, *nx;
                    131: 
                    132:   WALK_LIST_DELSAFE(n, nx, e->sources)
                    133:   {
                    134:     if (n->expires && n->expires <= now)
                    135:     {
                    136:       rem_node(NODE n);
                    137:       sl_free(p->source_slab, n);
                    138:     }
                    139:   }
                    140: }
                    141: 
                    142: static struct babel_route *
                    143: babel_find_route(struct babel_entry *e, struct babel_neighbor *n)
                    144: {
                    145:   struct babel_route *r;
                    146: 
                    147:   WALK_LIST(r, e->routes)
                    148:     if (r->neigh == n)
                    149:       return r;
                    150: 
                    151:   return NULL;
                    152: }
                    153: 
                    154: static struct babel_route *
                    155: babel_get_route(struct babel_entry *e, struct babel_neighbor *nbr)
                    156: {
                    157:   struct babel_proto *p = e->proto;
                    158:   struct babel_route *r = babel_find_route(e, nbr);
                    159: 
                    160:   if (r)
                    161:     return r;
                    162: 
                    163:   r = sl_alloc(p->route_slab);
                    164:   memset(r, 0, sizeof(*r));
                    165:   r->e = e;
                    166:   add_tail(&e->routes, NODE r);
                    167: 
                    168:   if (nbr)
                    169:   {
                    170:     r->neigh = nbr;
                    171:     r->expires = now + BABEL_GARBAGE_INTERVAL;
                    172:     add_tail(&nbr->routes, NODE &r->neigh_route);
                    173:   }
                    174: 
                    175:   return r;
                    176: }
                    177: 
                    178: static void
                    179: babel_flush_route(struct babel_route *r)
                    180: {
                    181:   struct babel_proto *p = r->e->proto;
                    182: 
                    183:   DBG("Babel: Flush route %I/%d router_id %lR neigh %I\n",
                    184:       r->e->n.prefix, r->e->n.pxlen, r->router_id, r->neigh ? r->neigh->addr : IPA_NONE);
                    185: 
                    186:   rem_node(NODE r);
                    187: 
                    188:   if (r->neigh)
                    189:     rem_node(&r->neigh_route);
                    190: 
                    191:   if (r->e->selected_in == r)
                    192:     r->e->selected_in = NULL;
                    193: 
                    194:   if (r->e->selected_out == r)
                    195:     r->e->selected_out = NULL;
                    196: 
                    197:   sl_free(p->route_slab, r);
                    198: }
                    199: 
                    200: static void
                    201: babel_expire_route(struct babel_route *r)
                    202: {
                    203:   struct babel_proto *p = r->e->proto;
                    204:   struct babel_entry *e = r->e;
                    205: 
                    206:   TRACE(D_EVENTS, "Route expiry timer for %I/%d router-id %lR fired",
                    207:        e->n.prefix, e->n.pxlen, r->router_id);
                    208: 
                    209:   if (r->metric < BABEL_INFINITY)
                    210:   {
                    211:     r->metric = BABEL_INFINITY;
                    212:     r->expires = now + r->expiry_interval;
                    213:   }
                    214:   else
                    215:   {
                    216:     babel_flush_route(r);
                    217:   }
                    218: }
                    219: 
                    220: static void
                    221: babel_refresh_route(struct babel_route *r)
                    222: {
                    223:   if (!OUR_ROUTE(r) && (r == r->e->selected_in))
                    224:     babel_send_route_request(r->e, r->neigh);
                    225: 
                    226:   r->refresh_time = 0;
                    227: }
                    228: 
                    229: static void
                    230: babel_expire_routes(struct babel_proto *p)
                    231: {
                    232:   struct babel_entry *e;
                    233:   struct babel_route *r, *rx;
                    234:   struct fib_iterator fit;
                    235: 
                    236:   FIB_ITERATE_INIT(&fit, &p->rtable);
                    237: 
                    238: loop:
                    239:   FIB_ITERATE_START(&p->rtable, &fit, n)
                    240:   {
                    241:     e = (struct babel_entry *) n;
                    242:     int changed = 0;
                    243: 
                    244:     WALK_LIST_DELSAFE(r, rx, e->routes)
                    245:     {
                    246:       if (r->refresh_time && r->refresh_time <= now)
                    247:        babel_refresh_route(r);
                    248: 
                    249:       if (r->expires && r->expires <= now)
                    250:       {
                    251:        babel_expire_route(r);
                    252:        changed = 1;
                    253:       }
                    254:     }
                    255: 
                    256:     if (changed)
                    257:     {
                    258:       /*
                    259:        * We have to restart the iteration because there may be a cascade of
                    260:        * synchronous events babel_select_route() -> nest table change ->
                    261:        * babel_rt_notify() -> p->rtable change, invalidating hidden variables.
                    262:        */
                    263: 
                    264:       FIB_ITERATE_PUT(&fit, n);
                    265:       babel_select_route(e);
                    266:       goto loop;
                    267:     }
                    268: 
                    269:     babel_expire_sources(e);
                    270: 
                    271:     /* Remove empty entries */
                    272:     if (EMPTY_LIST(e->sources) && EMPTY_LIST(e->routes))
                    273:     {
                    274:       FIB_ITERATE_PUT(&fit, n);
                    275:       fib_delete(&p->rtable, e);
                    276:       goto loop;
                    277:     }
                    278:   }
                    279:   FIB_ITERATE_END(n);
                    280: }
                    281: 
                    282: static struct babel_neighbor *
                    283: babel_find_neighbor(struct babel_iface *ifa, ip_addr addr)
                    284: {
                    285:   struct babel_neighbor *nbr;
                    286: 
                    287:   WALK_LIST(nbr, ifa->neigh_list)
                    288:     if (ipa_equal(nbr->addr, addr))
                    289:       return nbr;
                    290: 
                    291:   return NULL;
                    292: }
                    293: 
                    294: static struct babel_neighbor *
                    295: babel_get_neighbor(struct babel_iface *ifa, ip_addr addr)
                    296: {
                    297:   struct babel_neighbor *nbr = babel_find_neighbor(ifa, addr);
                    298: 
                    299:   if (nbr)
                    300:     return nbr;
                    301: 
                    302:   nbr = mb_allocz(ifa->pool, sizeof(struct babel_neighbor));
                    303:   nbr->ifa = ifa;
                    304:   nbr->addr = addr;
                    305:   nbr->txcost = BABEL_INFINITY;
                    306:   init_list(&nbr->routes);
                    307:   add_tail(&ifa->neigh_list, NODE nbr);
                    308: 
                    309:   return nbr;
                    310: }
                    311: 
                    312: static void
                    313: babel_flush_neighbor(struct babel_neighbor *nbr)
                    314: {
                    315:   struct babel_proto *p = nbr->ifa->proto;
                    316:   node *n;
                    317: 
                    318:   TRACE(D_EVENTS, "Flushing neighbor %I", nbr->addr);
                    319: 
                    320:   WALK_LIST_FIRST(n, nbr->routes)
                    321:   {
                    322:     struct babel_route *r = SKIP_BACK(struct babel_route, neigh_route, n);
                    323:     struct babel_entry *e = r->e;
                    324:     int selected = (r == e->selected_in);
                    325: 
                    326:     babel_flush_route(r);
                    327: 
                    328:     if (selected)
                    329:       babel_select_route(e);
                    330:   }
                    331: 
                    332:   rem_node(NODE nbr);
                    333:   mb_free(nbr);
                    334: }
                    335: 
                    336: static void
                    337: babel_expire_ihu(struct babel_neighbor *nbr)
                    338: {
                    339:   nbr->txcost = BABEL_INFINITY;
                    340: }
                    341: 
                    342: static void
                    343: babel_expire_hello(struct babel_neighbor *nbr)
                    344: {
                    345:   nbr->hello_map <<= 1;
                    346: 
                    347:   if (nbr->hello_cnt < 16)
                    348:     nbr->hello_cnt++;
                    349: 
                    350:   if (!nbr->hello_map)
                    351:     babel_flush_neighbor(nbr);
                    352: }
                    353: 
                    354: static void
                    355: babel_expire_neighbors(struct babel_proto *p)
                    356: {
                    357:   struct babel_iface *ifa;
                    358:   struct babel_neighbor *nbr, *nbx;
                    359: 
                    360:   WALK_LIST(ifa, p->interfaces)
                    361:   {
                    362:     WALK_LIST_DELSAFE(nbr, nbx, ifa->neigh_list)
                    363:     {
                    364:       if (nbr->ihu_expiry && nbr->ihu_expiry <= now)
                    365:         babel_expire_ihu(nbr);
                    366: 
                    367:       if (nbr->hello_expiry && nbr->hello_expiry <= now)
                    368:         babel_expire_hello(nbr);
                    369:     }
                    370:   }
                    371: }
                    372: 
                    373: 
                    374: /*
                    375:  *     Best route selection
                    376:  */
                    377: 
                    378: /*
                    379:  * From the RFC (section 3.5.1):
                    380:  *
                    381:  * a route advertisement carrying the quintuple (prefix, plen, router-id, seqno,
                    382:  * metric) is feasible if one of the following conditions holds:
                    383:  *
                    384:  * - metric is infinite; or
                    385:  *
                    386:  * - no entry exists in the source table indexed by (id, prefix, plen); or
                    387:  *
                    388:  * - an entry (prefix, plen, router-id, seqno', metric') exists in the source
                    389:  *   table, and either
                    390:  *   - seqno' < seqno or
                    391:  *   - seqno = seqno' and metric < metric'.
                    392:  */
                    393: static inline int
                    394: babel_is_feasible(struct babel_source *s, u16 seqno, u16 metric)
                    395: {
                    396:   return !s ||
                    397:     (metric == BABEL_INFINITY) ||
                    398:     (seqno > s->seqno) ||
                    399:     ((seqno == s->seqno) && (metric < s->metric));
                    400: }
                    401: 
                    402: static u16
                    403: babel_compute_rxcost(struct babel_neighbor *n)
                    404: {
                    405:   struct babel_iface *ifa = n->ifa;
                    406:   u8 cnt, missed;
                    407:   u16 map=n->hello_map;
                    408: 
                    409:   if (!map) return BABEL_INFINITY;
                    410:   cnt = u32_popcount(map); // number of bits set
                    411:   missed = n->hello_cnt-cnt;
                    412: 
                    413:   if (ifa->cf->type == BABEL_IFACE_TYPE_WIRELESS)
                    414:   {
                    415:     /* ETX - Appendix 2.2 in the RFC.
                    416: 
                    417:        beta = prob. of successful transmission.
                    418:        rxcost = BABEL_RXCOST_WIRELESS/beta
                    419: 
                    420:        Since: beta = 1-missed/n->hello_cnt = cnt/n->hello_cnt
                    421:        Then: rxcost = BABEL_RXCOST_WIRELESS * n->hello_cnt / cnt
                    422:    */
                    423:     if (!cnt) return BABEL_INFINITY;
                    424:     return BABEL_RXCOST_WIRELESS * n->hello_cnt / cnt;
                    425:   }
                    426:   else
                    427:   {
                    428:     /* k-out-of-j selection - Appendix 2.1 in the RFC. */
                    429:     DBG("Babel: Missed %d hellos from %I\n", missed, n->addr);
                    430:     /* Link is bad if more than half the expected hellos were lost */
                    431:     return (missed > n->hello_cnt/2) ? BABEL_INFINITY : ifa->cf->rxcost;
                    432:   }
                    433: }
                    434: 
                    435: 
                    436: static u16
                    437: babel_compute_cost(struct babel_neighbor *n)
                    438: {
                    439:   struct babel_iface *ifa = n->ifa;
                    440:   u16 rxcost = babel_compute_rxcost(n);
                    441:   if (rxcost == BABEL_INFINITY) return rxcost;
                    442:   else if (ifa->cf->type == BABEL_IFACE_TYPE_WIRELESS)
                    443:   {
                    444:     /* ETX - Appendix 2.2 in the RFC */
                    445:     return (MAX(n->txcost, BABEL_RXCOST_WIRELESS) * rxcost)/BABEL_RXCOST_WIRELESS;
                    446:   }
                    447:   else
                    448:   {
                    449:     /* k-out-of-j selection - Appendix 2.1 in the RFC. */
                    450:     return n->txcost;
                    451:   }
                    452: }
                    453: 
                    454: /* Simple additive metric - Appendix 3.1 in the RFC */
                    455: static u16
                    456: babel_compute_metric(struct babel_neighbor *n, uint metric)
                    457: {
                    458:   metric += babel_compute_cost(n);
                    459:   return MIN(metric, BABEL_INFINITY);
                    460: }
                    461: 
                    462: 
                    463: /**
                    464:  * babel_announce_rte - announce selected route to the core
                    465:  * @p: Babel protocol instance
                    466:  * @e: Babel route entry to announce
                    467:  *
                    468:  * This function announces a Babel entry to the core if it has a selected
                    469:  * incoming path, and retracts it otherwise. If the selected entry has infinite
                    470:  * metric, the route is announced as unreachable.
                    471:  */
                    472: static void
                    473: babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
                    474: {
                    475:   struct babel_route *r = e->selected_in;
                    476: 
                    477:   if (r)
                    478:   {
                    479:     net *n = net_get(p->p.table, e->n.prefix, e->n.pxlen);
                    480:     rta A = {
                    481:       .src = p->p.main_source,
                    482:       .source = RTS_BABEL,
                    483:       .scope = SCOPE_UNIVERSE,
                    484:       .cast = RTC_UNICAST,
                    485:       .dest = r->metric == BABEL_INFINITY ? RTD_UNREACHABLE : RTD_ROUTER,
                    486:       .flags = 0,
                    487:       .from = r->neigh->addr,
                    488:       .iface = r->neigh->ifa->iface,
                    489:     };
                    490: 
                    491:     if (r->metric < BABEL_INFINITY)
                    492:       A.gw = r->next_hop;
                    493: 
                    494:     rta *a = rta_lookup(&A);
                    495:     rte *rte = rte_get_temp(a);
                    496:     rte->u.babel.metric = r->metric;
                    497:     rte->u.babel.router_id = r->router_id;
                    498:     rte->net = n;
                    499:     rte->pflags = 0;
                    500: 
                    501:     rte_update(&p->p, n, rte);
                    502:   }
                    503:   else
                    504:   {
                    505:     /* Retraction */
                    506:     net *n = net_find(p->p.table, e->n.prefix, e->n.pxlen);
                    507:     rte_update(&p->p, n, NULL);
                    508:   }
                    509: }
                    510: 
                    511: /**
                    512:  * babel_select_route - select best route for given route entry
                    513:  * @e: Babel entry to select the best route for
                    514:  *
                    515:  * Select the best feasible route for a given prefix among the routes received
                    516:  * from peers, and propagate it to the nest. This just selects the feasible
                    517:  * route with the lowest metric.
                    518:  *
                    519:  * If no feasible route is available for a prefix that previously had a route
                    520:  * selected, a seqno request is sent to try to get a valid route. In the
                    521:  * meantime, the route is marked as infeasible in the nest (to blackhole packets
                    522:  * going to it, as per the RFC).
                    523:  *
                    524:  * If no feasible route is available, and no previous route is selected, the
                    525:  * route is removed from the nest entirely.
                    526:  */
                    527: static void
                    528: babel_select_route(struct babel_entry *e)
                    529: {
                    530:   struct babel_proto *p = e->proto;
                    531:   struct babel_route *r, *cur = e->selected_in;
                    532: 
                    533:   /* try to find the best feasible route */
                    534:   WALK_LIST(r, e->routes)
                    535:     if (!OUR_ROUTE(r) && /* prevent propagating our own routes back to core */
                    536:        (!cur || r->metric < cur->metric) &&
                    537:         babel_is_feasible(babel_find_source(e, r->router_id), r->seqno, r->advert_metric))
                    538:       cur = r;
                    539: 
                    540:   if (cur && !OUR_ROUTE(cur) &&
                    541:       ((!e->selected_in && cur->metric < BABEL_INFINITY) ||
                    542:        (e->selected_in && cur->metric < e->selected_in->metric)))
                    543:   {
                    544:     TRACE(D_EVENTS, "Picked new route for prefix %I/%d: router id %lR metric %d",
                    545:          e->n.prefix, e->n.pxlen, cur->router_id, cur->metric);
                    546: 
                    547:     e->selected_in = cur;
                    548:     e->updated = now;
                    549:     babel_announce_rte(p, e);
                    550:   }
                    551:   else if (!cur || cur->metric == BABEL_INFINITY)
                    552:   {
                    553:     /* Couldn't find a feasible route. If we have a selected route, that means
                    554:        it just became infeasible; so set it's metric to infinite and install it
                    555:        (as unreachable), then send a seqno request.
                    556: 
                    557:        babel_build_rte() will set the unreachable flag if the metric is BABEL_INFINITY.*/
                    558:     if (e->selected_in)
                    559:     {
                    560:       TRACE(D_EVENTS, "Lost feasible route for prefix %I/%d",
                    561:            e->n.prefix, e->n.pxlen);
                    562: 
                    563:       e->selected_in->metric = BABEL_INFINITY;
                    564:       e->updated = now;
                    565: 
                    566:       babel_send_seqno_request(e);
                    567:       babel_announce_rte(p, e);
                    568: 
                    569:       /* Section 3.6 of the RFC forbids an infeasible from being selected. This
                    570:         is cleared after announcing the route to the core to make sure an
                    571:         unreachable route is propagated first. */
                    572:       e->selected_in = NULL;
                    573:     }
                    574:     else
                    575:     {
                    576:       /* No route currently selected, and no new one selected; this means we
                    577:         don't have a route to this destination anymore (and were probably
                    578:         called from an expiry timer). Remove the route from the nest. */
                    579:       TRACE(D_EVENTS, "Flushing route for prefix %I/%d", e->n.prefix, e->n.pxlen);
                    580: 
                    581:       e->selected_in = NULL;
                    582:       e->updated = now;
                    583:       babel_announce_rte(p, e);
                    584:     }
                    585:   }
                    586: }
                    587: 
                    588: /*
                    589:  *     Functions to send replies
                    590:  */
                    591: 
                    592: static void
                    593: babel_send_ack(struct babel_iface *ifa, ip_addr dest, u16 nonce)
                    594: {
                    595:   struct babel_proto *p = ifa->proto;
                    596:   union babel_msg msg = {};
                    597: 
                    598:   TRACE(D_PACKETS, "Sending ACK to %I with nonce %d", dest, nonce);
                    599: 
                    600:   msg.type = BABEL_TLV_ACK;
                    601:   msg.ack.nonce = nonce;
                    602: 
                    603:   babel_send_unicast(&msg, ifa, dest);
                    604: }
                    605: 
                    606: static void
                    607: babel_build_ihu(union babel_msg *msg, struct babel_iface *ifa, struct babel_neighbor *n)
                    608: {
                    609:   struct babel_proto *p = ifa->proto;
                    610: 
                    611:   msg->type = BABEL_TLV_IHU;
                    612:   msg->ihu.addr = n->addr;
                    613:   msg->ihu.rxcost = babel_compute_rxcost(n);
                    614:   msg->ihu.interval = ifa->cf->ihu_interval;
                    615: 
                    616:   TRACE(D_PACKETS, "Sending IHU for %I with rxcost %d interval %d",
                    617:         msg->ihu.addr, msg->ihu.rxcost, msg->ihu.interval);
                    618: }
                    619: 
                    620: static void
                    621: babel_send_ihu(struct babel_iface *ifa, struct babel_neighbor *n)
                    622: {
                    623:   union babel_msg msg = {};
                    624:   babel_build_ihu(&msg, ifa, n);
                    625:   babel_send_unicast(&msg, ifa, n->addr);
                    626: }
                    627: 
                    628: static void
                    629: babel_send_ihus(struct babel_iface *ifa)
                    630: {
                    631:   struct babel_neighbor *n;
                    632:   WALK_LIST(n, ifa->neigh_list)
                    633:   {
                    634:     union babel_msg msg = {};
                    635:     babel_build_ihu(&msg, ifa, n);
                    636:     babel_enqueue(&msg, ifa);
                    637:   }
                    638: }
                    639: 
                    640: static void
                    641: babel_send_hello(struct babel_iface *ifa, u8 send_ihu)
                    642: {
                    643:   struct babel_proto *p = ifa->proto;
                    644:   union babel_msg msg = {};
                    645: 
                    646:   msg.type = BABEL_TLV_HELLO;
                    647:   msg.hello.seqno = ifa->hello_seqno++;
                    648:   msg.hello.interval = ifa->cf->hello_interval;
                    649: 
                    650:   TRACE(D_PACKETS, "Sending hello on %s with seqno %d interval %d",
                    651:        ifa->ifname, msg.hello.seqno, msg.hello.interval);
                    652: 
                    653:   babel_enqueue(&msg, ifa);
                    654: 
                    655:   if (send_ihu)
                    656:     babel_send_ihus(ifa);
                    657: }
                    658: 
                    659: static void
                    660: babel_send_route_request(struct babel_entry *e, struct babel_neighbor *n)
                    661: {
                    662:   struct babel_proto *p = e->proto;
                    663:   struct babel_iface *ifa = n->ifa;
                    664:   union babel_msg msg = {};
                    665: 
                    666:   TRACE(D_PACKETS, "Sending route request for %I/%d to %I",
                    667:         e->n.prefix, e->n.pxlen, n->addr);
                    668: 
                    669:   msg.type = BABEL_TLV_ROUTE_REQUEST;
                    670:   msg.route_request.prefix = e->n.prefix;
                    671:   msg.route_request.plen = e->n.pxlen;
                    672: 
                    673:   babel_send_unicast(&msg, ifa, n->addr);
                    674: }
                    675: 
                    676: static void
                    677: babel_send_wildcard_request(struct babel_iface *ifa)
                    678: {
                    679:   struct babel_proto *p = ifa->proto;
                    680:   union babel_msg msg = {};
                    681: 
                    682:   TRACE(D_PACKETS, "Sending wildcard route request on %s",
                    683:        ifa->ifname);
                    684: 
                    685:   msg.type = BABEL_TLV_ROUTE_REQUEST;
                    686:   msg.route_request.full = 1;
                    687: 
                    688:   babel_enqueue(&msg, ifa);
                    689: }
                    690: 
                    691: static void
                    692: babel_send_seqno_request(struct babel_entry *e)
                    693: {
                    694:   struct babel_proto *p = e->proto;
                    695:   struct babel_route *r = e->selected_in;
                    696:   struct babel_iface *ifa = NULL;
                    697:   struct babel_source *s = NULL;
                    698:   union babel_msg msg = {};
                    699: 
                    700:   s = babel_find_source(e, r->router_id);
                    701:   if (!s || !babel_cache_seqno_request(p, e->n.prefix, e->n.pxlen, r->router_id, s->seqno + 1))
                    702:     return;
                    703: 
                    704:   TRACE(D_PACKETS, "Sending seqno request for %I/%d router-id %lR seqno %d",
                    705:        e->n.prefix, e->n.pxlen, r->router_id, s->seqno + 1);
                    706: 
                    707:   msg.type = BABEL_TLV_SEQNO_REQUEST;
                    708:   msg.seqno_request.plen = e->n.pxlen;
                    709:   msg.seqno_request.seqno = s->seqno + 1;
                    710:   msg.seqno_request.hop_count = BABEL_INITIAL_HOP_COUNT;
                    711:   msg.seqno_request.router_id = r->router_id;
                    712:   msg.seqno_request.prefix = e->n.prefix;
                    713: 
                    714:   WALK_LIST(ifa, p->interfaces)
                    715:     babel_enqueue(&msg, ifa);
                    716: }
                    717: 
                    718: static void
                    719: babel_unicast_seqno_request(struct babel_route *r)
                    720: {
                    721:   struct babel_entry *e = r->e;
                    722:   struct babel_proto *p = e->proto;
                    723:   struct babel_iface *ifa = r->neigh->ifa;
                    724:   struct babel_source *s = NULL;
                    725:   union babel_msg msg = {};
                    726: 
                    727:   s = babel_find_source(e, r->router_id);
                    728:   if (!s || !babel_cache_seqno_request(p, e->n.prefix, e->n.pxlen, r->router_id, s->seqno + 1))
                    729:     return;
                    730: 
                    731:   TRACE(D_PACKETS, "Sending seqno request for %I/%d router-id %lR seqno %d",
                    732:        e->n.prefix, e->n.pxlen, r->router_id, s->seqno + 1);
                    733: 
                    734:   msg.type = BABEL_TLV_SEQNO_REQUEST;
                    735:   msg.seqno_request.plen = e->n.pxlen;
                    736:   msg.seqno_request.seqno = s->seqno + 1;
                    737:   msg.seqno_request.hop_count = BABEL_INITIAL_HOP_COUNT;
                    738:   msg.seqno_request.router_id = r->router_id;
                    739:   msg.seqno_request.prefix = e->n.prefix;
                    740: 
                    741:   babel_send_unicast(&msg, ifa, r->neigh->addr);
                    742: }
                    743: 
                    744: /**
                    745:  * babel_send_update - send route table updates
                    746:  * @ifa: Interface to transmit on
                    747:  * @changed: Only send entries changed since this time
                    748:  *
                    749:  * This function produces update TLVs for all entries changed since the time
                    750:  * indicated by the &changed parameter and queues them for transmission on the
                    751:  * selected interface. During the process, the feasibility distance for each
                    752:  * transmitted entry is updated.
                    753:  */
                    754: static void
                    755: babel_send_update(struct babel_iface *ifa, bird_clock_t changed)
                    756: {
                    757:   struct babel_proto *p = ifa->proto;
                    758: 
                    759:   FIB_WALK(&p->rtable, n)
                    760:   {
                    761:     struct babel_entry *e = (void *) n;
                    762:     struct babel_route *r = e->selected_out;
                    763: 
                    764:     if (!r)
                    765:       continue;
                    766: 
                    767:     /* Our own seqno might have changed, in which case we update the routes we
                    768:        originate. */
                    769:     if ((r->router_id == p->router_id) && (r->seqno < p->update_seqno))
                    770:     {
                    771:       r->seqno = p->update_seqno;
                    772:       e->updated = now;
                    773:     }
                    774: 
                    775:     /* Skip routes that weren't updated since 'changed' time */
                    776:     if (e->updated < changed)
                    777:       continue;
                    778: 
                    779:     TRACE(D_PACKETS, "Sending update for %I/%d router-id %lR seqno %d metric %d",
                    780:          e->n.prefix, e->n.pxlen, r->router_id, r->seqno, r->metric);
                    781: 
                    782:     union babel_msg msg = {};
                    783:     msg.type = BABEL_TLV_UPDATE;
                    784:     msg.update.plen = e->n.pxlen;
                    785:     msg.update.interval = ifa->cf->update_interval;
                    786:     msg.update.seqno = r->seqno;
                    787:     msg.update.metric = r->metric;
                    788:     msg.update.prefix = e->n.prefix;
                    789:     msg.update.router_id = r->router_id;
                    790: 
                    791:     babel_enqueue(&msg, ifa);
                    792: 
                    793:     /* Update feasibility distance for redistributed routes */
                    794:     if (!OUR_ROUTE(r))
                    795:     {
                    796:       struct babel_source *s = babel_get_source(e, r->router_id);
                    797:       s->expires = now + BABEL_GARBAGE_INTERVAL;
                    798: 
                    799:       if ((msg.update.seqno > s->seqno) ||
                    800:          ((msg.update.seqno == s->seqno) && (msg.update.metric < s->metric)))
                    801:       {
                    802:        s->seqno = msg.update.seqno;
                    803:        s->metric = msg.update.metric;
                    804:       }
                    805:     }
                    806:   }
                    807:   FIB_WALK_END;
                    808: }
                    809: 
                    810: static void
                    811: babel_trigger_iface_update(struct babel_iface *ifa)
                    812: {
                    813:   struct babel_proto *p = ifa->proto;
                    814: 
                    815:   /* Interface not active or already scheduled */
                    816:   if (!ifa->up || ifa->want_triggered)
                    817:     return;
                    818: 
                    819:   TRACE(D_EVENTS, "Scheduling triggered updates for %s seqno %d",
                    820:        ifa->iface->name, p->update_seqno);
                    821: 
                    822:   ifa->want_triggered = now;
                    823:   babel_iface_kick_timer(ifa);
                    824: }
                    825: 
                    826: /* Sends and update on all interfaces. */
                    827: static void
                    828: babel_trigger_update(struct babel_proto *p)
                    829: {
                    830:   if (p->triggered)
                    831:     return;
                    832: 
                    833:   struct babel_iface *ifa;
                    834:   WALK_LIST(ifa, p->interfaces)
                    835:     babel_trigger_iface_update(ifa);
                    836: 
                    837:   p->triggered = 1;
                    838: }
                    839: 
                    840: /* A retraction is an update with an infinite metric */
                    841: static void
                    842: babel_send_retraction(struct babel_iface *ifa, ip_addr prefix, int plen)
                    843: {
                    844:   struct babel_proto *p = ifa->proto;
                    845:   union babel_msg msg = {};
                    846: 
                    847:   TRACE(D_PACKETS, "Sending retraction for %I/%d seqno %d",
                    848:        prefix, plen, p->update_seqno);
                    849: 
                    850:   msg.type = BABEL_TLV_UPDATE;
                    851:   msg.update.plen = plen;
                    852:   msg.update.interval = ifa->cf->update_interval;
                    853:   msg.update.seqno = p->update_seqno;
                    854:   msg.update.metric = BABEL_INFINITY;
                    855:   msg.update.prefix = prefix;
                    856: 
                    857:   babel_enqueue(&msg, ifa);
                    858: }
                    859: 
                    860: static void
                    861: babel_send_wildcard_retraction(struct babel_iface *ifa)
                    862: {
                    863:   struct babel_proto *p = ifa->proto;
                    864:   union babel_msg msg = {};
                    865: 
                    866:   TRACE(D_PACKETS, "Sending wildcard retraction on %s", ifa->ifname);
                    867: 
                    868:   msg.type = BABEL_TLV_UPDATE;
                    869:   msg.update.wildcard = 1;
                    870:   msg.update.interval = ifa->cf->update_interval;
                    871:   msg.update.seqno = p->update_seqno;
                    872:   msg.update.metric = BABEL_INFINITY;
                    873: 
                    874:   babel_enqueue(&msg, ifa);
                    875: }
                    876: 
                    877: 
                    878: /*
                    879:  *     TLV handler helpers
                    880:  */
                    881: 
                    882: /* Update hello history according to Appendix A1 of the RFC */
                    883: static void
                    884: babel_update_hello_history(struct babel_neighbor *n, u16 seqno, u16 interval)
                    885: {
                    886:   /*
                    887:    * Compute the difference between expected and received seqno (modulo 2^16).
                    888:    * If the expected and received seqnos are within 16 of each other, the modular
                    889:    * difference is going to be less than 16 for one of the directions. Otherwise,
                    890:    * the values differ too much, so just reset the state.
                    891:    */
                    892: 
                    893:   u16 delta = ((uint) seqno - (uint) n->next_hello_seqno);
                    894: 
                    895:   if (delta == 0)
                    896:   {
                    897:     /* Do nothing */
                    898:   }
                    899:   else if (delta <= 16)
                    900:   {
                    901:     /* Sending node decreased interval; fast-forward */
                    902:     n->hello_map <<= delta;
                    903:     n->hello_cnt = MIN(n->hello_cnt + delta, 16);
                    904:   }
                    905:   else if (delta >= 0xfff0)
                    906:   {
                    907:     u8 diff = (0xffff - delta);
                    908:     /* Sending node increased interval; undo history */
                    909:     n->hello_map >>= diff;
                    910:     n->hello_cnt = (diff < n->hello_cnt) ? n->hello_cnt - diff : 0;
                    911:   }
                    912:   else
                    913:   {
                    914:     /* Note state reset - flush entries */
                    915:     n->hello_map = n->hello_cnt = 0;
                    916:   }
                    917: 
                    918:   /* Current entry */
                    919:   n->hello_map = (n->hello_map << 1) | 1;
                    920:   n->next_hello_seqno = seqno+1;
                    921:   if (n->hello_cnt < 16) n->hello_cnt++;
                    922:   n->hello_expiry = now + BABEL_HELLO_EXPIRY_FACTOR(interval);
                    923: }
                    924: 
                    925: static void
                    926: babel_expire_seqno_requests(struct babel_proto *p)
                    927: {
                    928:   struct babel_seqno_request *n, *nx;
                    929:   WALK_LIST_DELSAFE(n, nx, p->seqno_cache)
                    930:   {
                    931:     if ((n->updated + BABEL_SEQNO_REQUEST_EXPIRY) <= now)
                    932:     {
                    933:       rem_node(NODE n);
                    934:       sl_free(p->seqno_slab, n);
                    935:     }
                    936:   }
                    937: }
                    938: 
                    939: /*
                    940:  * Checks the seqno request cache for a matching request and returns failure if
                    941:  * found. Otherwise, a new entry is stored in the cache.
                    942:  */
                    943: static int
                    944: babel_cache_seqno_request(struct babel_proto *p, ip_addr prefix, u8 plen,
                    945:                           u64 router_id, u16 seqno)
                    946: {
                    947:   struct babel_seqno_request *r;
                    948: 
                    949:   WALK_LIST(r, p->seqno_cache)
                    950:   {
                    951:     if (ipa_equal(r->prefix, prefix) && (r->plen == plen) &&
                    952:        (r->router_id == router_id) && (r->seqno == seqno))
                    953:       return 0;
                    954:   }
                    955: 
                    956:   /* no entries found */
                    957:   r = sl_alloc(p->seqno_slab);
                    958:   r->prefix = prefix;
                    959:   r->plen = plen;
                    960:   r->router_id = router_id;
                    961:   r->seqno = seqno;
                    962:   r->updated = now;
                    963:   add_tail(&p->seqno_cache, NODE r);
                    964: 
                    965:   return 1;
                    966: }
                    967: 
                    968: static void
                    969: babel_forward_seqno_request(struct babel_entry *e,
                    970:                             struct babel_msg_seqno_request *in,
                    971:                             ip_addr sender)
                    972: {
                    973:   struct babel_proto *p = e->proto;
                    974:   struct babel_route *r;
                    975: 
                    976:   TRACE(D_PACKETS, "Forwarding seqno request for %I/%d router-id %lR seqno %d",
                    977:        e->n.prefix, e->n.pxlen, in->router_id, in->seqno);
                    978: 
                    979:   WALK_LIST(r, e->routes)
                    980:   {
                    981:     if ((r->router_id == in->router_id) &&
                    982:        !OUR_ROUTE(r) &&
                    983:        !ipa_equal(r->neigh->addr, sender))
                    984:     {
                    985:       if (!babel_cache_seqno_request(p, e->n.prefix, e->n.pxlen, in->router_id, in->seqno))
                    986:        return;
                    987: 
                    988:       union babel_msg msg = {};
                    989:       msg.type = BABEL_TLV_SEQNO_REQUEST;
                    990:       msg.seqno_request.plen = in->plen;
                    991:       msg.seqno_request.seqno = in->seqno;
                    992:       msg.seqno_request.hop_count = in->hop_count-1;
                    993:       msg.seqno_request.router_id = in->router_id;
                    994:       msg.seqno_request.prefix = e->n.prefix;
                    995: 
                    996:       babel_send_unicast(&msg, r->neigh->ifa, r->neigh->addr);
                    997:       return;
                    998:     }
                    999:   }
                   1000: }
                   1001: 
                   1002: 
                   1003: /*
                   1004:  *     TLV handlers
                   1005:  */
                   1006: 
                   1007: void
                   1008: babel_handle_ack_req(union babel_msg *m, struct babel_iface *ifa)
                   1009: {
                   1010:   struct babel_proto *p = ifa->proto;
                   1011:   struct babel_msg_ack_req *msg = &m->ack_req;
                   1012: 
                   1013:   TRACE(D_PACKETS, "Handling ACK request nonce %d interval %d",
                   1014:        msg->nonce, msg->interval);
                   1015: 
                   1016:   babel_send_ack(ifa, msg->sender, msg->nonce);
                   1017: }
                   1018: 
                   1019: void
                   1020: babel_handle_hello(union babel_msg *m, struct babel_iface *ifa)
                   1021: {
                   1022:   struct babel_proto *p = ifa->proto;
                   1023:   struct babel_msg_hello *msg = &m->hello;
                   1024: 
                   1025:   TRACE(D_PACKETS, "Handling hello seqno %d interval %d",
                   1026:        msg->seqno, msg->interval);
                   1027: 
                   1028:   struct babel_neighbor *n = babel_get_neighbor(ifa, msg->sender);
                   1029:   babel_update_hello_history(n, msg->seqno, msg->interval);
                   1030:   if (ifa->cf->type == BABEL_IFACE_TYPE_WIRELESS)
                   1031:     babel_send_ihu(ifa, n);
                   1032: }
                   1033: 
                   1034: void
                   1035: babel_handle_ihu(union babel_msg *m, struct babel_iface *ifa)
                   1036: {
                   1037:   struct babel_proto *p = ifa->proto;
                   1038:   struct babel_msg_ihu *msg = &m->ihu;
                   1039: 
                   1040:   /* Ignore IHUs that are not about us */
                   1041:   if ((msg->ae != BABEL_AE_WILDCARD) && !ipa_equal(msg->addr, ifa->addr))
                   1042:     return;
                   1043: 
                   1044:   TRACE(D_PACKETS, "Handling IHU rxcost %d interval %d",
                   1045:        msg->rxcost, msg->interval);
                   1046: 
                   1047:   struct babel_neighbor *n = babel_get_neighbor(ifa, msg->sender);
                   1048:   n->txcost = msg->rxcost;
                   1049:   n->ihu_expiry = now + BABEL_IHU_EXPIRY_FACTOR(msg->interval);
                   1050: }
                   1051: 
                   1052: /**
                   1053:  * babel_handle_update - handle incoming route updates
                   1054:  * @m: Incoming update TLV
                   1055:  * @ifa: Interface the update was received on
                   1056:  *
                   1057:  * This function is called as a handler for update TLVs and handles the updating
                   1058:  * and maintenance of route entries in Babel's internal routing cache. The
                   1059:  * handling follows the actions described in the Babel RFC, and at the end of
                   1060:  * each update handling, babel_select_route() is called on the affected entry to
                   1061:  * optionally update the selected routes and propagate them to the core.
                   1062:  */
                   1063: void
                   1064: babel_handle_update(union babel_msg *m, struct babel_iface *ifa)
                   1065: {
                   1066:   struct babel_proto *p = ifa->proto;
                   1067:   struct babel_msg_update *msg = &m->update;
                   1068: 
                   1069:   struct babel_neighbor *nbr;
                   1070:   struct babel_entry *e;
                   1071:   struct babel_source *s;
                   1072:   struct babel_route *r;
                   1073:   node *n;
                   1074:   int feasible;
                   1075: 
                   1076:   TRACE(D_PACKETS, "Handling update for %I/%d with seqno %d metric %d",
                   1077:        msg->prefix, msg->plen, msg->seqno, msg->metric);
                   1078: 
                   1079:   nbr = babel_find_neighbor(ifa, msg->sender);
                   1080:   if (!nbr)
                   1081:   {
                   1082:     DBG("Babel: Haven't heard from neighbor %I; ignoring update.\n", msg->sender);
                   1083:     return;
                   1084:   }
                   1085: 
                   1086:   if (msg->router_id == p->router_id)
                   1087:   {
                   1088:     DBG("Babel: Ignoring update for our own router ID.\n");
                   1089:     return;
                   1090:   }
                   1091: 
                   1092:   /*
                   1093:    * RFC section 3.5.4:
                   1094:    *
                   1095:    * When a Babel node receives an update (id, prefix, seqno, metric) from a
                   1096:    * neighbour neigh with a link cost value equal to cost, it checks whether it
                   1097:    * already has a routing table entry indexed by (neigh, id, prefix).
                   1098:    *
                   1099:    * If no such entry exists:
                   1100:    *
                   1101:    * o if the update is unfeasible, it is ignored;
                   1102:    *
                   1103:    * o if the metric is infinite (the update is a retraction), the update is
                   1104:    *   ignored;
                   1105:    *
                   1106:    * o otherwise, a new route table entry is created, indexed by (neigh, id,
                   1107:    *   prefix), with seqno equal to seqno and an advertised metric equal to the
                   1108:    *   metric carried by the update.
                   1109:    *
                   1110:    * If such an entry exists:
                   1111:    *
                   1112:    * o if the entry is currently installed and the update is unfeasible, then
                   1113:    *   the behaviour depends on whether the router-ids of the two entries match.
                   1114:    *   If the router-ids are different, the update is treated as though it were
                   1115:    *   a retraction (i.e., as though the metric were FFFF hexadecimal). If the
                   1116:    *   router-ids are equal, the update is ignored;
                   1117:    *
                   1118:    * o otherwise (i.e., if either the update is feasible or the entry is not
                   1119:    *   currently installed), then the entry's sequence number, advertised
                   1120:    *   metric, metric, and router-id are updated and, unless the advertised
                   1121:    *   metric is infinite, the route's expiry timer is reset to a small multiple
                   1122:    *   of the Interval value included in the update.
                   1123:    */
                   1124: 
                   1125:   /* Retraction */
                   1126:   if (msg->metric == BABEL_INFINITY)
                   1127:   {
                   1128:     if (msg->wildcard)
                   1129:     {
                   1130:       /*
                   1131:        * Special case: This is a retraction of all prefixes announced by this
                   1132:        * neighbour (see second-to-last paragraph of section 4.4.9 in the RFC).
                   1133:        */
                   1134:       WALK_LIST(n, nbr->routes)
                   1135:       {
                   1136:        r = SKIP_BACK(struct babel_route, neigh_route, n);
                   1137:        r->metric = BABEL_INFINITY;
                   1138:        babel_select_route(r->e);
                   1139:       }
                   1140:     }
                   1141:     else
                   1142:     {
                   1143:       e = babel_find_entry(p, msg->prefix, msg->plen);
                   1144: 
                   1145:       if (!e)
                   1146:        return;
                   1147: 
                   1148:       /* The route entry indexed by neighbour */
                   1149:       r = babel_find_route(e, nbr);
                   1150: 
                   1151:       if (!r)
                   1152:        return;
                   1153: 
                   1154:       r->metric = BABEL_INFINITY;
                   1155:       babel_select_route(e);
                   1156:     }
                   1157: 
                   1158:     /* Done with retractions */
                   1159:     return;
                   1160:   }
                   1161: 
                   1162:   e = babel_get_entry(p, msg->prefix, msg->plen);
                   1163:   r = babel_find_route(e, nbr); /* the route entry indexed by neighbour */
                   1164:   s = babel_find_source(e, msg->router_id); /* for feasibility */
                   1165:   feasible = babel_is_feasible(s, msg->seqno, msg->metric);
                   1166: 
                   1167:   if (!r)
                   1168:   {
                   1169:     if (!feasible)
                   1170:       return;
                   1171: 
                   1172:     r = babel_get_route(e, nbr);
                   1173:     r->advert_metric = msg->metric;
                   1174:     r->router_id = msg->router_id;
                   1175:     r->metric = babel_compute_metric(nbr, msg->metric);
                   1176:     r->next_hop = msg->next_hop;
                   1177:     r->seqno = msg->seqno;
                   1178:   }
                   1179:   else if (r == r->e->selected_in && !feasible)
                   1180:   {
                   1181:     /*
                   1182:      * Route is installed and update is infeasible - we may lose the route,
                   1183:      * so send a unicast seqno request (section 3.8.2.2 second paragraph).
                   1184:      */
                   1185:     babel_unicast_seqno_request(r);
                   1186: 
                   1187:     if (msg->router_id == r->router_id)
                   1188:       return;
                   1189: 
                   1190:     /* Treat as retraction */
                   1191:     r->metric = BABEL_INFINITY;
                   1192:   }
                   1193:   else
                   1194:   {
                   1195:     /* Last paragraph above - update the entry */
                   1196:     r->advert_metric = msg->metric;
                   1197:     r->metric = babel_compute_metric(nbr, msg->metric);
                   1198:     r->next_hop = msg->next_hop;
                   1199: 
                   1200:     r->router_id = msg->router_id;
                   1201:     r->seqno = msg->seqno;
                   1202: 
                   1203:     r->expiry_interval = BABEL_ROUTE_EXPIRY_FACTOR(msg->interval);
                   1204:     r->expires = now + r->expiry_interval;
                   1205:     if (r->expiry_interval > BABEL_ROUTE_REFRESH_INTERVAL)
                   1206:       r->refresh_time = now + r->expiry_interval - BABEL_ROUTE_REFRESH_INTERVAL;
                   1207: 
                   1208:     /* If the route is not feasible at this point, it means it is from another
                   1209:        neighbour than the one currently selected; so send a unicast seqno
                   1210:        request to try to get a better route (section 3.8.2.2 last paragraph). */
                   1211:     if (!feasible)
                   1212:       babel_unicast_seqno_request(r);
                   1213:   }
                   1214: 
                   1215:   babel_select_route(e);
                   1216: }
                   1217: 
                   1218: void
                   1219: babel_handle_route_request(union babel_msg *m, struct babel_iface *ifa)
                   1220: {
                   1221:   struct babel_proto *p = ifa->proto;
                   1222:   struct babel_msg_route_request *msg = &m->route_request;
                   1223: 
                   1224:   /* RFC 6126 3.8.1.1 */
                   1225: 
                   1226:   /* Wildcard request - full update on the interface */
                   1227:   if (msg->full)
                   1228:   {
                   1229:     TRACE(D_PACKETS, "Handling wildcard route request");
                   1230:     ifa->want_triggered = 1;
                   1231:     return;
                   1232:   }
                   1233: 
                   1234:   TRACE(D_PACKETS, "Handling route request for %I/%d", msg->prefix, msg->plen);
                   1235: 
                   1236:   /* Non-wildcard request - see if we have an entry for the route.
                   1237:      If not, send a retraction, otherwise send an update. */
                   1238:   struct babel_entry *e = babel_find_entry(p, msg->prefix, msg->plen);
                   1239:   if (!e)
                   1240:   {
                   1241:     babel_send_retraction(ifa, msg->prefix, msg->plen);
                   1242:   }
                   1243:   else
                   1244:   {
                   1245:     babel_trigger_iface_update(ifa);
                   1246:     e->updated = now;
                   1247:   }
                   1248: }
                   1249: 
                   1250: 
                   1251: void
                   1252: babel_handle_seqno_request(union babel_msg *m, struct babel_iface *ifa)
                   1253: {
                   1254:   struct babel_proto *p = ifa->proto;
                   1255:   struct babel_msg_seqno_request *msg = &m->seqno_request;
                   1256: 
                   1257:   /* RFC 6126 3.8.1.2 */
                   1258: 
                   1259:   TRACE(D_PACKETS, "Handling seqno request for %I/%d router-id %lR seqno %d hop count %d",
                   1260:        msg->prefix, msg->plen, msg->router_id, msg->seqno, msg->hop_count);
                   1261: 
                   1262:   /* Ignore if we have no such entry or entry has infinite metric */
                   1263:   struct babel_entry *e = babel_find_entry(p, msg->prefix, msg->plen);
                   1264:   if (!e || !e->selected_out || (e->selected_out->metric == BABEL_INFINITY))
                   1265:     return;
                   1266: 
                   1267:   /* Trigger update on incoming interface if we have a selected route with
                   1268:      different router id or seqno no smaller than requested */
                   1269:   struct babel_route *r = e->selected_out;
                   1270:   if ((r->router_id != msg->router_id) || ge_mod64k(r->seqno, msg->seqno))
                   1271:   {
                   1272:     babel_trigger_iface_update(ifa);
                   1273:     e->updated = now;
                   1274:     return;
                   1275:   }
                   1276: 
                   1277:   /* Seqno is larger; check if we own the router id */
                   1278:   if (msg->router_id == p->router_id)
                   1279:   {
                   1280:     /* Ours; update seqno and trigger global update */
                   1281:     p->update_seqno++;
                   1282:     babel_trigger_update(p);
                   1283:   }
                   1284:   else
                   1285:   {
                   1286:     /* Not ours; forward if TTL allows it */
                   1287:     if (msg->hop_count > 1)
                   1288:       babel_forward_seqno_request(e, msg, msg->sender);
                   1289:   }
                   1290: }
                   1291: 
                   1292: 
                   1293: /*
                   1294:  *     Babel interfaces
                   1295:  */
                   1296: 
                   1297: /**
                   1298:  * babel_iface_timer - Babel interface timer handler
                   1299:  * @t: Timer
                   1300:  *
                   1301:  * This function is called by the per-interface timer and triggers sending of
                   1302:  * periodic Hello's and both triggered and periodic updates. Periodic Hello's
                   1303:  * and updates are simply handled by setting the next_{hello,regular} variables
                   1304:  * on the interface, and triggering an update (and resetting the variable)
                   1305:  * whenever 'now' exceeds that value.
                   1306:  *
                   1307:  * For triggered updates, babel_trigger_iface_update() will set the
                   1308:  * want_triggered field on the interface to a timestamp value. If this is set
                   1309:  * (and the next_triggered time has passed; this is a rate limiting mechanism),
                   1310:  * babel_send_update() will be called with this timestamp as the second
                   1311:  * parameter. This causes updates to be send consisting of only the routes that
                   1312:  * have changed since the time saved in want_triggered.
                   1313:  *
                   1314:  * Mostly when an update is triggered, the route being modified will be set to
                   1315:  * the value of 'now' at the time of the trigger; the >= comparison for
                   1316:  * selecting which routes to send in the update will make sure this is included.
                   1317:  */
                   1318: static void
                   1319: babel_iface_timer(timer *t)
                   1320: {
                   1321:   struct babel_iface *ifa = t->data;
                   1322:   struct babel_proto *p = ifa->proto;
                   1323:   bird_clock_t hello_period = ifa->cf->hello_interval;
                   1324:   bird_clock_t update_period = ifa->cf->update_interval;
                   1325: 
                   1326:   if (now >= ifa->next_hello)
                   1327:   {
                   1328:     babel_send_hello(ifa, (ifa->cf->type == BABEL_IFACE_TYPE_WIRELESS ||
                   1329:                            ifa->hello_seqno % BABEL_IHU_INTERVAL_FACTOR == 0));
                   1330:     ifa->next_hello +=  hello_period * (1 + (now - ifa->next_hello) / hello_period);
                   1331:   }
                   1332: 
                   1333:   if (now >= ifa->next_regular)
                   1334:   {
                   1335:     TRACE(D_EVENTS, "Sending regular updates on %s", ifa->ifname);
                   1336:     babel_send_update(ifa, 0);
                   1337:     ifa->next_regular += update_period * (1 + (now - ifa->next_regular) / update_period);
                   1338:     ifa->want_triggered = 0;
                   1339:     p->triggered = 0;
                   1340:   }
                   1341:   else if (ifa->want_triggered && (now >= ifa->next_triggered))
                   1342:   {
                   1343:     TRACE(D_EVENTS, "Sending triggered updates on %s", ifa->ifname);
                   1344:     babel_send_update(ifa, ifa->want_triggered);
                   1345:     ifa->next_triggered = now + MIN(5, update_period / 2 + 1);
                   1346:     ifa->want_triggered = 0;
                   1347:     p->triggered = 0;
                   1348:   }
                   1349: 
                   1350:   bird_clock_t next_event = MIN(ifa->next_hello, ifa->next_regular);
                   1351:   tm_start(ifa->timer, ifa->want_triggered ? 1 : (next_event - now));
                   1352: }
                   1353: 
                   1354: static inline void
                   1355: babel_iface_kick_timer(struct babel_iface *ifa)
                   1356: {
                   1357:   if (ifa->timer->expires > (now + 1))
                   1358:     tm_start(ifa->timer, 1);
                   1359: }
                   1360: 
                   1361: static void
                   1362: babel_iface_start(struct babel_iface *ifa)
                   1363: {
                   1364:   struct babel_proto *p = ifa->proto;
                   1365: 
                   1366:   TRACE(D_EVENTS, "Starting interface %s", ifa->ifname);
                   1367: 
                   1368:   ifa->next_hello = now + (random() % ifa->cf->hello_interval) + 1;
                   1369:   ifa->next_regular = now + (random() % ifa->cf->update_interval) + 1;
                   1370:   ifa->next_triggered = now + MIN(5, ifa->cf->update_interval / 2 + 1);
                   1371:   ifa->want_triggered = 0;     /* We send an immediate update (below) */
                   1372:   tm_start(ifa->timer, 1);
                   1373:   ifa->up = 1;
                   1374: 
                   1375:   babel_send_hello(ifa, 0);
                   1376:   babel_send_wildcard_retraction(ifa);
                   1377:   babel_send_wildcard_request(ifa);
                   1378:   babel_send_update(ifa, 0);   /* Full update */
                   1379: }
                   1380: 
                   1381: static void
                   1382: babel_iface_stop(struct babel_iface *ifa)
                   1383: {
                   1384:   struct babel_proto *p = ifa->proto;
                   1385:   struct babel_neighbor *nbr;
                   1386:   struct babel_route *r;
                   1387:   node *n;
                   1388: 
                   1389:   TRACE(D_EVENTS, "Stopping interface %s", ifa->ifname);
                   1390: 
                   1391:   /*
                   1392:    * Rather than just flushing the neighbours, we set the metric of their routes
                   1393:    * to infinity. This allows us to keep the neighbour hello state for when the
                   1394:    * interface comes back up. The routes will also be kept until they expire.
                   1395:    */
                   1396:   WALK_LIST(nbr, ifa->neigh_list)
                   1397:   {
                   1398:     WALK_LIST(n, nbr->routes)
                   1399:     {
                   1400:       r = SKIP_BACK(struct babel_route, neigh_route, n);
                   1401:       r->metric = BABEL_INFINITY;
                   1402:       r->expires = now + r->expiry_interval;
                   1403:       babel_select_route(r->e);
                   1404:     }
                   1405:   }
                   1406: 
                   1407:   tm_stop(ifa->timer);
                   1408:   ifa->up = 0;
                   1409: }
                   1410: 
                   1411: static inline int
                   1412: babel_iface_link_up(struct babel_iface *ifa)
                   1413: {
                   1414:   return !ifa->cf->check_link || (ifa->iface->flags & IF_LINK_UP);
                   1415: }
                   1416: 
                   1417: static void
                   1418: babel_iface_update_state(struct babel_iface *ifa)
                   1419: {
                   1420:   int up = ifa->sk && babel_iface_link_up(ifa);
                   1421: 
                   1422:   if (up == ifa->up)
                   1423:     return;
                   1424: 
                   1425:   if (up)
                   1426:     babel_iface_start(ifa);
                   1427:   else
                   1428:     babel_iface_stop(ifa);
                   1429: }
                   1430: 
                   1431: static void
                   1432: babel_iface_update_buffers(struct babel_iface *ifa)
                   1433: {
                   1434:   if (!ifa->sk)
                   1435:     return;
                   1436: 
                   1437:   uint mtu = MAX(BABEL_MIN_MTU, ifa->iface->mtu);
                   1438:   uint rbsize = ifa->cf->rx_buffer ?: mtu;
                   1439:   uint tbsize = ifa->cf->tx_length ?: mtu;
                   1440:   rbsize = MAX(rbsize, tbsize);
                   1441: 
                   1442:   sk_set_rbsize(ifa->sk, rbsize);
                   1443:   sk_set_tbsize(ifa->sk, tbsize);
                   1444: 
                   1445:   ifa->tx_length = tbsize - BABEL_OVERHEAD;
                   1446: }
                   1447: 
                   1448: static struct babel_iface*
                   1449: babel_find_iface(struct babel_proto *p, struct iface *what)
                   1450: {
                   1451:   struct babel_iface *ifa;
                   1452: 
                   1453:   WALK_LIST (ifa, p->interfaces)
                   1454:     if (ifa->iface == what)
                   1455:       return ifa;
                   1456: 
                   1457:   return NULL;
                   1458: }
                   1459: 
                   1460: static void
                   1461: babel_iface_locked(struct object_lock *lock)
                   1462: {
                   1463:   struct babel_iface *ifa = lock->data;
                   1464:   struct babel_proto *p = ifa->proto;
                   1465: 
                   1466:   if (!babel_open_socket(ifa))
                   1467:   {
                   1468:     log(L_ERR "%s: Cannot open socket for %s", p->p.name, ifa->iface->name);
                   1469:     return;
                   1470:   }
                   1471: 
                   1472:   babel_iface_update_buffers(ifa);
                   1473:   babel_iface_update_state(ifa);
                   1474: }
                   1475: 
                   1476: static void
                   1477: babel_add_iface(struct babel_proto *p, struct iface *new, struct babel_iface_config *ic)
                   1478: {
                   1479:   struct babel_iface *ifa;
                   1480: 
                   1481:   TRACE(D_EVENTS, "Adding interface %s", new->name);
                   1482: 
                   1483:   pool *pool = rp_new(p->p.pool, new->name);
                   1484: 
                   1485:   ifa = mb_allocz(pool, sizeof(struct babel_iface));
                   1486:   ifa->proto = p;
                   1487:   ifa->iface = new;
                   1488:   ifa->cf = ic;
                   1489:   ifa->pool = pool;
                   1490:   ifa->ifname = new->name;
1.1.1.2 ! misho    1491:   ifa->addr = new->llv6->ip;
1.1       misho    1492: 
                   1493:   add_tail(&p->interfaces, NODE ifa);
                   1494: 
                   1495:   init_list(&ifa->neigh_list);
                   1496:   ifa->hello_seqno = 1;
                   1497: 
                   1498:   ifa->timer = tm_new_set(ifa->pool, babel_iface_timer, ifa, 0, 0);
                   1499: 
                   1500:   init_list(&ifa->msg_queue);
                   1501:   ifa->send_event = ev_new(ifa->pool);
                   1502:   ifa->send_event->hook = babel_send_queue;
                   1503:   ifa->send_event->data = ifa;
                   1504: 
                   1505:   struct object_lock *lock = olock_new(ifa->pool);
                   1506:   lock->type = OBJLOCK_UDP;
                   1507:   lock->addr = IP6_BABEL_ROUTERS;
                   1508:   lock->port = ifa->cf->port;
                   1509:   lock->iface = ifa->iface;
                   1510:   lock->hook = babel_iface_locked;
                   1511:   lock->data = ifa;
                   1512: 
                   1513:   olock_acquire(lock);
                   1514: }
                   1515: 
                   1516: static void
                   1517: babel_remove_iface(struct babel_proto *p, struct babel_iface *ifa)
                   1518: {
                   1519:   TRACE(D_EVENTS, "Removing interface %s", ifa->iface->name);
                   1520: 
                   1521:   struct babel_neighbor *n;
                   1522:   WALK_LIST_FIRST(n, ifa->neigh_list)
                   1523:     babel_flush_neighbor(n);
                   1524: 
                   1525:   rem_node(NODE ifa);
                   1526: 
                   1527:   rfree(ifa->pool); /* contains ifa itself, locks, socket, etc */
                   1528: }
                   1529: 
                   1530: static void
                   1531: babel_if_notify(struct proto *P, unsigned flags, struct iface *iface)
                   1532: {
                   1533:   struct babel_proto *p = (void *) P;
                   1534:   struct babel_config *cf = (void *) P->cf;
                   1535: 
                   1536:   if (iface->flags & IF_IGNORE)
                   1537:     return;
                   1538: 
                   1539:   if (flags & IF_CHANGE_UP)
                   1540:   {
                   1541:     struct babel_iface_config *ic = (void *) iface_patt_find(&cf->iface_list, iface, iface->addr);
                   1542: 
                   1543:     /* we only speak multicast */
                   1544:     if (!(iface->flags & IF_MULTICAST))
                   1545:       return;
                   1546: 
1.1.1.2 ! misho    1547:     /* Ignore ifaces without link-local address */
        !          1548:     if (!iface->llv6)
        !          1549:       return;
        !          1550: 
1.1       misho    1551:     if (ic)
                   1552:       babel_add_iface(p, iface, ic);
                   1553: 
                   1554:     return;
                   1555:   }
                   1556: 
                   1557:   struct babel_iface *ifa = babel_find_iface(p, iface);
                   1558: 
                   1559:   if (!ifa)
                   1560:     return;
                   1561: 
                   1562:   if (flags & IF_CHANGE_DOWN)
                   1563:   {
                   1564:     babel_remove_iface(p, ifa);
                   1565:     return;
                   1566:   }
                   1567: 
                   1568:   if (flags & IF_CHANGE_MTU)
                   1569:     babel_iface_update_buffers(ifa);
                   1570: 
                   1571:   if (flags & IF_CHANGE_LINK)
                   1572:     babel_iface_update_state(ifa);
                   1573: }
                   1574: 
                   1575: static int
                   1576: babel_reconfigure_iface(struct babel_proto *p, struct babel_iface *ifa, struct babel_iface_config *new)
                   1577: {
                   1578:   struct babel_iface_config *old = ifa->cf;
                   1579: 
                   1580:   /* Change of these options would require to reset the iface socket */
                   1581:   if ((new->port != old->port) ||
                   1582:       (new->tx_tos != old->tx_tos) ||
                   1583:       (new->tx_priority != old->tx_priority))
                   1584:     return 0;
                   1585: 
                   1586:   TRACE(D_EVENTS, "Reconfiguring interface %s", ifa->iface->name);
                   1587: 
                   1588:   ifa->cf = new;
                   1589: 
                   1590:   if (ifa->next_hello > (now + new->hello_interval))
                   1591:     ifa->next_hello = now + (random() % new->hello_interval) + 1;
                   1592: 
                   1593:   if (ifa->next_regular > (now + new->update_interval))
                   1594:     ifa->next_regular = now + (random() % new->update_interval) + 1;
                   1595: 
                   1596:   if ((new->tx_length != old->tx_length) || (new->rx_buffer != old->rx_buffer))
                   1597:     babel_iface_update_buffers(ifa);
                   1598: 
                   1599:   if (new->check_link != old->check_link)
                   1600:     babel_iface_update_state(ifa);
                   1601: 
                   1602:   if (ifa->up)
                   1603:     babel_iface_kick_timer(ifa);
                   1604: 
                   1605:   return 1;
                   1606: }
                   1607: 
                   1608: static void
                   1609: babel_reconfigure_ifaces(struct babel_proto *p, struct babel_config *cf)
                   1610: {
                   1611:   struct iface *iface;
                   1612: 
                   1613:   WALK_LIST(iface, iface_list)
                   1614:   {
                   1615:     if (! (iface->flags & IF_UP))
                   1616:       continue;
                   1617: 
                   1618:     struct babel_iface *ifa = babel_find_iface(p, iface);
                   1619:     struct babel_iface_config *ic = (void *) iface_patt_find(&cf->iface_list, iface, NULL);
                   1620: 
                   1621:     if (ifa && ic)
                   1622:     {
                   1623:       if (babel_reconfigure_iface(p, ifa, ic))
                   1624:        continue;
                   1625: 
                   1626:       /* Hard restart */
                   1627:       log(L_INFO "%s: Restarting interface %s", p->p.name, ifa->iface->name);
                   1628:       babel_remove_iface(p, ifa);
                   1629:       babel_add_iface(p, iface, ic);
                   1630:     }
                   1631: 
                   1632:     if (ifa && !ic)
                   1633:       babel_remove_iface(p, ifa);
                   1634: 
                   1635:     if (!ifa && ic)
                   1636:       babel_add_iface(p, iface, ic);
                   1637:   }
                   1638: }
                   1639: 
                   1640: 
                   1641: /*
                   1642:  *     Debugging and info output functions
                   1643:  */
                   1644: 
                   1645: static void
                   1646: babel_dump_source(struct babel_source *s)
                   1647: {
                   1648:   debug("Source router_id %lR seqno %d metric %d expires %d\n",
                   1649:        s->router_id, s->seqno, s->metric, s->expires ? s->expires-now : 0);
                   1650: }
                   1651: 
                   1652: static void
                   1653: babel_dump_route(struct babel_route *r)
                   1654: {
                   1655:   debug("Route neigh %I if %s seqno %d metric %d/%d router_id %lR expires %d\n",
                   1656:        r->neigh ? r->neigh->addr : IPA_NONE,
                   1657:         r->neigh ? r->neigh->ifa->ifname : "(none)",
                   1658:         r->seqno, r->advert_metric, r->metric,
                   1659:        r->router_id, r->expires ? r->expires-now : 0);
                   1660: }
                   1661: 
                   1662: static void
                   1663: babel_dump_entry(struct babel_entry *e)
                   1664: {
                   1665:   struct babel_source *s;
                   1666:   struct babel_route *r;
                   1667: 
                   1668:   debug("Babel: Entry %I/%d:\n", e->n.prefix, e->n.pxlen);
                   1669: 
                   1670:   WALK_LIST(s,e->sources)
                   1671:   { debug(" "); babel_dump_source(s); }
                   1672: 
                   1673:   WALK_LIST(r,e->routes)
                   1674:   {
                   1675:     debug(" ");
                   1676:     if (r == e->selected_out) debug("*");
                   1677:     if (r == e->selected_in) debug("+");
                   1678:     babel_dump_route(r);
                   1679:   }
                   1680: }
                   1681: 
                   1682: static void
                   1683: babel_dump_neighbor(struct babel_neighbor *n)
                   1684: {
                   1685:   debug("Neighbor %I txcost %d hello_map %x next seqno %d expires %d/%d\n",
                   1686:        n->addr, n->txcost, n->hello_map, n->next_hello_seqno,
                   1687:         n->hello_expiry ? n->hello_expiry - now : 0,
                   1688:         n->ihu_expiry ? n->ihu_expiry - now : 0);
                   1689: }
                   1690: 
                   1691: static void
                   1692: babel_dump_iface(struct babel_iface *ifa)
                   1693: {
                   1694:   struct babel_neighbor *n;
                   1695: 
                   1696:   debug("Babel: Interface %s addr %I rxcost %d type %d hello seqno %d intervals %d %d\n",
                   1697:        ifa->ifname, ifa->addr, ifa->cf->rxcost, ifa->cf->type, ifa->hello_seqno,
                   1698:        ifa->cf->hello_interval, ifa->cf->update_interval);
                   1699: 
                   1700:   WALK_LIST(n, ifa->neigh_list)
                   1701:   { debug(" "); babel_dump_neighbor(n); }
                   1702: }
                   1703: 
                   1704: static void
                   1705: babel_dump(struct proto *P)
                   1706: {
                   1707:   struct babel_proto *p = (struct babel_proto *) P;
                   1708:   struct babel_iface *ifa;
                   1709: 
                   1710:   debug("Babel: router id %lR update seqno %d\n", p->router_id, p->update_seqno);
                   1711: 
                   1712:   WALK_LIST(ifa, p->interfaces)
                   1713:     babel_dump_iface(ifa);
                   1714: 
                   1715:   FIB_WALK(&p->rtable, n)
                   1716:   {
                   1717:     babel_dump_entry((struct babel_entry *) n);
                   1718:   }
                   1719:   FIB_WALK_END;
                   1720: }
                   1721: 
                   1722: static void
                   1723: babel_get_route_info(rte *rte, byte *buf, ea_list *attrs UNUSED)
                   1724: {
                   1725:   buf += bsprintf(buf, " (%d/%d) [%lR]", rte->pref, rte->u.babel.metric, rte->u.babel.router_id);
                   1726: }
                   1727: 
                   1728: static int
                   1729: babel_get_attr(eattr *a, byte *buf, int buflen UNUSED)
                   1730: {
                   1731:   switch (a->id)
                   1732:   {
                   1733:   case EA_BABEL_METRIC:
                   1734:     bsprintf(buf, "metric: %d", a->u.data);
                   1735:     return GA_FULL;
                   1736: 
                   1737:   case EA_BABEL_ROUTER_ID:
                   1738:   {
                   1739:     u64 rid = 0;
                   1740:     memcpy(&rid, a->u.ptr->data, sizeof(u64));
                   1741:     bsprintf(buf, "router_id: %lR", rid);
                   1742:     return GA_FULL;
                   1743:   }
                   1744: 
                   1745:   default:
                   1746:     return GA_UNKNOWN;
                   1747:   }
                   1748: }
                   1749: 
                   1750: void
                   1751: babel_show_interfaces(struct proto *P, char *iff)
                   1752: {
                   1753:   struct babel_proto *p = (void *) P;
                   1754:   struct babel_iface *ifa = NULL;
                   1755:   struct babel_neighbor *nbr = NULL;
                   1756: 
                   1757:   if (p->p.proto_state != PS_UP)
                   1758:   {
                   1759:     cli_msg(-1023, "%s: is not up", p->p.name);
                   1760:     cli_msg(0, "");
                   1761:     return;
                   1762:   }
                   1763: 
                   1764:   cli_msg(-1023, "%s:", p->p.name);
                   1765:   cli_msg(-1023, "%-10s %-6s %7s %6s %6s",
                   1766:          "Interface", "State", "RX cost", "Nbrs", "Timer");
                   1767: 
                   1768:   WALK_LIST(ifa, p->interfaces)
                   1769:   {
                   1770:     if (iff && !patmatch(iff, ifa->iface->name))
                   1771:       continue;
                   1772: 
                   1773:     int nbrs = 0;
                   1774:     WALK_LIST(nbr, ifa->neigh_list)
                   1775:        nbrs++;
                   1776: 
                   1777:     int timer = MIN(ifa->next_regular, ifa->next_hello) - now;
                   1778:     cli_msg(-1023, "%-10s %-6s %7u %6u %6u",
                   1779:            ifa->iface->name, (ifa->up ? "Up" : "Down"), ifa->cf->rxcost, nbrs, MAX(timer, 0));
                   1780:   }
                   1781: 
                   1782:   cli_msg(0, "");
                   1783: }
                   1784: 
                   1785: void
                   1786: babel_show_neighbors(struct proto *P, char *iff)
                   1787: {
                   1788:   struct babel_proto *p = (void *) P;
                   1789:   struct babel_iface *ifa = NULL;
                   1790:   struct babel_neighbor *n = NULL;
                   1791:   struct babel_route *r = NULL;
                   1792: 
                   1793:   if (p->p.proto_state != PS_UP)
                   1794:   {
                   1795:     cli_msg(-1024, "%s: is not up", p->p.name);
                   1796:     cli_msg(0, "");
                   1797:     return;
                   1798:   }
                   1799: 
                   1800:   cli_msg(-1024, "%s:", p->p.name);
                   1801:   cli_msg(-1024, "%-25s %-10s %6s %6s %10s",
                   1802:          "IP address", "Interface", "Metric", "Routes", "Next hello");
                   1803: 
                   1804:   WALK_LIST(ifa, p->interfaces)
                   1805:   {
                   1806:     if (iff && !patmatch(iff, ifa->iface->name))
                   1807:       continue;
                   1808: 
                   1809:     WALK_LIST(n, ifa->neigh_list)
                   1810:     {
                   1811:       int rts = 0;
                   1812:       WALK_LIST(r, n->routes)
                   1813:         rts++;
                   1814: 
                   1815:       int timer = n->hello_expiry - now;
                   1816:       cli_msg(-1024, "%-25I %-10s %6u %6u %10u",
                   1817:              n->addr, ifa->iface->name, n->txcost, rts, MAX(timer, 0));
                   1818:     }
                   1819:   }
                   1820: 
                   1821:   cli_msg(0, "");
                   1822: }
                   1823: 
                   1824: void
                   1825: babel_show_entries(struct proto *P)
                   1826: {
                   1827:   struct babel_proto *p = (void *) P;
                   1828:   struct babel_entry *e = NULL;
                   1829:   struct babel_source *s = NULL;
                   1830:   struct babel_route *r = NULL;
                   1831: 
                   1832:   char ipbuf[STD_ADDRESS_P_LENGTH+5];
                   1833:   char ridbuf[ROUTER_ID_64_LENGTH+1];
                   1834: 
                   1835:   if (p->p.proto_state != PS_UP)
                   1836:   {
                   1837:     cli_msg(-1025, "%s: is not up", p->p.name);
                   1838:     cli_msg(0, "");
                   1839:     return;
                   1840:   }
                   1841: 
                   1842:   cli_msg(-1025, "%s:", p->p.name);
                   1843:   cli_msg(-1025, "%-29s %-23s %6s %5s %7s %7s",
                   1844:          "Prefix", "Router ID", "Metric", "Seqno", "Expires", "Sources");
                   1845: 
                   1846:   FIB_WALK(&p->rtable, n)
                   1847:   {
                   1848:     e = (struct babel_entry *) n;
                   1849:     r = e->selected_in ? e->selected_in : e->selected_out;
                   1850: 
                   1851:     int srcs = 0;
                   1852:     WALK_LIST(s, e->sources)
                   1853:       srcs++;
                   1854: 
                   1855:     bsprintf(ipbuf, "%I/%u", e->n.prefix, e->n.pxlen);
                   1856: 
                   1857:     if (r)
                   1858:     {
                   1859:       if (r->router_id == p->router_id)
                   1860:         bsprintf(ridbuf, "%s", "<self>");
                   1861:       else
                   1862:         bsprintf(ridbuf, "%lR", r->router_id);
                   1863: 
                   1864:       int time = r->expires ? r->expires - now : 0;
                   1865:       cli_msg(-1025, "%-29s %-23s %6u %5u %7u %7u",
                   1866:              ipbuf, ridbuf, r->metric, r->seqno, MAX(time, 0), srcs);
                   1867:     }
                   1868:     else
                   1869:     {
                   1870:       cli_msg(-1025, "%-29s %-44s %7u", ipbuf, "<pending>", srcs);
                   1871:     }
                   1872:   }
                   1873:   FIB_WALK_END;
                   1874: 
                   1875:   cli_msg(0, "");
                   1876: }
                   1877: 
                   1878: 
                   1879: /*
                   1880:  *     Babel protocol glue
                   1881:  */
                   1882: 
                   1883: /**
                   1884:  * babel_timer - global timer hook
                   1885:  * @t: Timer
                   1886:  *
                   1887:  * This function is called by the global protocol instance timer and handles
                   1888:  * expiration of routes and neighbours as well as pruning of the seqno request
                   1889:  * cache.
                   1890:  */
                   1891: static void
                   1892: babel_timer(timer *t)
                   1893: {
                   1894:   struct babel_proto *p = t->data;
                   1895: 
                   1896:   babel_expire_routes(p);
                   1897:   babel_expire_seqno_requests(p);
                   1898:   babel_expire_neighbors(p);
                   1899: }
                   1900: 
                   1901: static inline void
                   1902: babel_kick_timer(struct babel_proto *p)
                   1903: {
                   1904:   if (p->timer->expires > (now + 1))
                   1905:     tm_start(p->timer, 1);
                   1906: }
                   1907: 
                   1908: 
                   1909: static struct ea_list *
                   1910: babel_prepare_attrs(struct linpool *pool, ea_list *next, uint metric, u64 router_id)
                   1911: {
                   1912:   struct ea_list *l = lp_alloc(pool, sizeof(struct ea_list) + 2*sizeof(eattr));
                   1913:   struct adata *rid = lp_alloc(pool, sizeof(struct adata) + sizeof(u64));
                   1914:   rid->length = sizeof(u64);
                   1915:   memcpy(&rid->data, &router_id, sizeof(u64));
                   1916: 
                   1917:   l->next = next;
                   1918:   l->flags = EALF_SORTED;
                   1919:   l->count = 2;
                   1920: 
                   1921:   l->attrs[0].id = EA_BABEL_METRIC;
                   1922:   l->attrs[0].flags = 0;
                   1923:   l->attrs[0].type = EAF_TYPE_INT | EAF_TEMP;
                   1924:   l->attrs[0].u.data = metric;
                   1925: 
                   1926:   l->attrs[1].id = EA_BABEL_ROUTER_ID;
                   1927:   l->attrs[1].flags = 0;
                   1928:   l->attrs[1].type = EAF_TYPE_OPAQUE | EAF_TEMP;
                   1929:   l->attrs[1].u.ptr = rid;
                   1930: 
                   1931:   return l;
                   1932: }
                   1933: 
                   1934: 
                   1935: static int
                   1936: babel_import_control(struct proto *P, struct rte **rt, struct ea_list **attrs, struct linpool *pool)
                   1937: {
                   1938:   struct babel_proto *p = (void *) P;
                   1939: 
                   1940:   /* Prepare attributes with initial values */
                   1941:   if ((*rt)->attrs->source != RTS_BABEL)
                   1942:     *attrs = babel_prepare_attrs(pool, NULL, 0, p->router_id);
                   1943: 
                   1944:   return 0;
                   1945: }
                   1946: 
                   1947: static struct ea_list *
                   1948: babel_make_tmp_attrs(struct rte *rt, struct linpool *pool)
                   1949: {
                   1950:   return babel_prepare_attrs(pool, NULL, rt->u.babel.metric, rt->u.babel.router_id);
                   1951: }
                   1952: 
                   1953: static void
                   1954: babel_store_tmp_attrs(struct rte *rt, struct ea_list *attrs)
                   1955: {
                   1956:   rt->u.babel.metric = ea_get_int(attrs, EA_BABEL_METRIC, 0);
                   1957: }
                   1958: 
                   1959: /*
                   1960:  * babel_rt_notify - core tells us about new route (possibly our own),
                   1961:  * so store it into our data structures.
                   1962:  */
                   1963: static void
                   1964: babel_rt_notify(struct proto *P, struct rtable *table UNUSED, struct network *net,
                   1965:                struct rte *new, struct rte *old UNUSED, struct ea_list *attrs UNUSED)
                   1966: {
                   1967:   struct babel_proto *p = (void *) P;
                   1968:   struct babel_entry *e;
                   1969:   struct babel_route *r;
                   1970: 
                   1971:   if (new)
                   1972:   {
                   1973:     /* Update */
                   1974:     e = babel_get_entry(p, net->n.prefix, net->n.pxlen);
                   1975: 
                   1976:     if (new->attrs->src->proto != P)
                   1977:     {
                   1978:       r = babel_get_route(e, NULL);
                   1979:       r->seqno = p->update_seqno;
                   1980:       r->router_id = p->router_id;
                   1981:       r->metric = 0;   /* FIXME: should be selectable */
                   1982:     }
                   1983:     else
                   1984:       r = e->selected_in;
                   1985: 
                   1986:     if (r != e->selected_out)
                   1987:     {
                   1988:       e->selected_out = r;
                   1989:       e->updated = now;
                   1990:       babel_trigger_update(p);
                   1991:     }
                   1992:   }
                   1993:   else
                   1994:   {
                   1995:     /* Withdraw */
                   1996:     e = babel_find_entry(p, net->n.prefix, net->n.pxlen);
                   1997:     if (!e || !e->selected_out)
                   1998:       return;
                   1999: 
                   2000:     if (OUR_ROUTE(e->selected_out))
                   2001:     {
                   2002:       /*
                   2003:        * We originate this route, so set its metric to infinity and set an
                   2004:        * expiry time. This causes a retraction to be sent, and later the route
                   2005:        * to be flushed once the hold time has passed.
                   2006:        */
                   2007:       e->selected_out->metric = BABEL_INFINITY;
                   2008:       e->selected_out->expires = now + BABEL_HOLD_TIME;
                   2009:       e->updated = now;
                   2010:       babel_trigger_update(p);
                   2011:     }
                   2012:     else
                   2013:     {
                   2014:       /*
                   2015:        * This is a route originating from someone else that was lost; presumably
                   2016:        * because an export filter was updated to filter it. This means we can't
                   2017:        * set the metric to infinity (it would be overridden on subsequent
                   2018:        * updates from the peer originating the route), so just clear the
                   2019:        * exported route.
                   2020:        *
                   2021:        * This causes peers to expire the route after a while (like if we just
                   2022:        * shut down), but it's the best we can do in these circumstances; and
                   2023:        * since export filters presumably aren't updated that often this is
                   2024:        * acceptable.
                   2025:        */
                   2026:       e->selected_out = NULL;
                   2027:     }
                   2028:   }
                   2029: }
                   2030: 
                   2031: static int
                   2032: babel_rte_better(struct rte *new, struct rte *old)
                   2033: {
                   2034:   return new->u.babel.metric < old->u.babel.metric;
                   2035: }
                   2036: 
                   2037: static int
                   2038: babel_rte_same(struct rte *new, struct rte *old)
                   2039: {
                   2040:   return ((new->u.babel.router_id == old->u.babel.router_id) &&
                   2041:           (new->u.babel.metric == old->u.babel.metric));
                   2042: }
                   2043: 
                   2044: 
                   2045: static struct proto *
                   2046: babel_init(struct proto_config *cfg)
                   2047: {
                   2048:   struct proto *P = proto_new(cfg, sizeof(struct babel_proto));
                   2049: 
                   2050:   P->accept_ra_types = RA_OPTIMAL;
                   2051:   P->if_notify = babel_if_notify;
                   2052:   P->rt_notify = babel_rt_notify;
                   2053:   P->import_control = babel_import_control;
                   2054:   P->make_tmp_attrs = babel_make_tmp_attrs;
                   2055:   P->store_tmp_attrs = babel_store_tmp_attrs;
                   2056:   P->rte_better = babel_rte_better;
                   2057:   P->rte_same = babel_rte_same;
                   2058: 
                   2059:   return P;
                   2060: }
                   2061: 
                   2062: static int
                   2063: babel_start(struct proto *P)
                   2064: {
                   2065:   struct babel_proto *p = (void *) P;
                   2066:   struct babel_config *cf = (void *) P->cf;
                   2067: 
                   2068:   fib_init(&p->rtable, P->pool, sizeof(struct babel_entry), 0, babel_init_entry);
                   2069:   init_list(&p->interfaces);
                   2070:   p->timer = tm_new_set(P->pool, babel_timer, p, 0, 1);
                   2071:   tm_start(p->timer, 2);
                   2072:   p->update_seqno = 1;
                   2073:   p->router_id = proto_get_router_id(&cf->c);
                   2074: 
                   2075:   p->route_slab = sl_new(P->pool, sizeof(struct babel_route));
                   2076:   p->source_slab = sl_new(P->pool, sizeof(struct babel_source));
                   2077:   p->msg_slab = sl_new(P->pool, sizeof(struct babel_msg_node));
                   2078:   p->seqno_slab = sl_new(P->pool, sizeof(struct babel_seqno_request));
                   2079:   init_list(&p->seqno_cache);
                   2080: 
                   2081:   p->log_pkt_tbf = (struct tbf){ .rate = 1, .burst = 5 };
                   2082: 
                   2083:   return PS_UP;
                   2084: }
                   2085: 
                   2086: static inline void
                   2087: babel_iface_shutdown(struct babel_iface *ifa)
                   2088: {
                   2089:   if (ifa->sk)
                   2090:   {
                   2091:     babel_send_wildcard_retraction(ifa);
                   2092:     babel_send_queue(ifa);
                   2093:   }
                   2094: }
                   2095: 
                   2096: static int
                   2097: babel_shutdown(struct proto *P)
                   2098: {
                   2099:   struct babel_proto *p = (void *) P;
                   2100:   struct babel_iface *ifa;
                   2101: 
                   2102:   TRACE(D_EVENTS, "Shutdown requested");
                   2103: 
                   2104:   WALK_LIST(ifa, p->interfaces)
                   2105:     babel_iface_shutdown(ifa);
                   2106: 
                   2107:   return PS_DOWN;
                   2108: }
                   2109: 
                   2110: static int
                   2111: babel_reconfigure(struct proto *P, struct proto_config *c)
                   2112: {
                   2113:   struct babel_proto *p = (void *) P;
                   2114:   struct babel_config *new = (void *) c;
                   2115: 
                   2116:   TRACE(D_EVENTS, "Reconfiguring");
                   2117: 
                   2118:   p->p.cf = c;
                   2119:   babel_reconfigure_ifaces(p, new);
                   2120: 
                   2121:   babel_trigger_update(p);
                   2122:   babel_kick_timer(p);
                   2123: 
                   2124:   return 1;
                   2125: }
                   2126: 
                   2127: 
                   2128: struct protocol proto_babel = {
                   2129:   .name =              "Babel",
                   2130:   .template =          "babel%d",
                   2131:   .attr_class =                EAP_BABEL,
                   2132:   .preference =                DEF_PREF_BABEL,
                   2133:   .config_size =       sizeof(struct babel_config),
                   2134:   .init =              babel_init,
                   2135:   .dump =              babel_dump,
                   2136:   .start =             babel_start,
                   2137:   .shutdown =          babel_shutdown,
                   2138:   .reconfigure =       babel_reconfigure,
                   2139:   .get_route_info =    babel_get_route_info,
                   2140:   .get_attr =          babel_get_attr
                   2141: };

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>