Annotation of embedaddon/bird/nest/rt-dev.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  *     BIRD -- Direct Device Routes
                      3:  *
                      4:  *     (c) 1998--2000 Martin Mares <mj@ucw.cz>
                      5:  *
                      6:  *     Can be freely distributed and used under the terms of the GNU GPL.
                      7:  */
                      8: 
                      9: /**
                     10:  * DOC: Direct
                     11:  *
                     12:  * The Direct protocol works by converting all ifa_notify() events it receives
                     13:  * to rte_update() calls for the corresponding network.
                     14:  */
                     15: 
                     16: #undef LOCAL_DEBUG
                     17: 
                     18: #include "nest/bird.h"
                     19: #include "nest/iface.h"
                     20: #include "nest/protocol.h"
                     21: #include "nest/route.h"
                     22: #include "nest/rt-dev.h"
                     23: #include "conf/conf.h"
                     24: #include "lib/resource.h"
                     25: #include "lib/string.h"
                     26: 
                     27: static void
                     28: dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
                     29: {
                     30:   struct rt_dev_config *P = (void *) p->cf;
                     31: 
                     32:   if (!EMPTY_LIST(P->iface_list) &&
                     33:       !iface_patt_find(&P->iface_list, ad->iface, ad->iface->addr))
                     34:     /* Empty list is automagically treated as "*" */
                     35:     return;
                     36: 
                     37:   if (ad->flags & IA_SECONDARY)
                     38:     return;
                     39: 
                     40:   if (ad->scope <= SCOPE_LINK)
                     41:     return;
                     42: 
                     43:   if (c & IF_CHANGE_DOWN)
                     44:     {
                     45:       net *n;
                     46: 
                     47:       DBG("dev_if_notify: %s:%I going down\n", ad->iface->name, ad->ip);
                     48:       n = net_find(p->table, ad->prefix, ad->pxlen);
                     49:       if (!n)
                     50:        {
                     51:          DBG("dev_if_notify: device shutdown: prefix not found\n");
                     52:          return;
                     53:        }
                     54: 
                     55:       /* Use iface ID as local source ID */
                     56:       struct rte_src *src = rt_get_source(p, ad->iface->index);
                     57:       rte_update2(p->main_ahook, n, NULL, src);
                     58:     }
                     59:   else if (c & IF_CHANGE_UP)
                     60:     {
                     61:       rta *a;
                     62:       net *n;
                     63:       rte *e;
                     64: 
                     65:       DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip);
                     66: 
                     67:       if (P->check_link && !(ad->iface->flags & IF_LINK_UP))
                     68:        return;
                     69: 
                     70:       /* Use iface ID as local source ID */
                     71:       struct rte_src *src = rt_get_source(p, ad->iface->index);
                     72: 
                     73:       rta a0 = {
                     74:        .src = src,
                     75:        .source = RTS_DEVICE,
                     76:        .scope = SCOPE_UNIVERSE,
                     77:        .cast = RTC_UNICAST,
                     78:        .dest = RTD_DEVICE,
                     79:        .iface = ad->iface
                     80:       };
                     81: 
                     82:       a = rta_lookup(&a0);
                     83:       n = net_get(p->table, ad->prefix, ad->pxlen);
                     84:       e = rte_get_temp(a);
                     85:       e->net = n;
                     86:       e->pflags = 0;
                     87:       rte_update2(p->main_ahook, n, e, src);
                     88:     }
                     89: }
                     90: 
                     91: static void
                     92: dev_if_notify(struct proto *p, uint c, struct iface *iface)
                     93: {
                     94:   struct rt_dev_config *cf = (void *) p->cf;
                     95: 
                     96:   if (c & (IF_CHANGE_UP | IF_CHANGE_DOWN))
                     97:     return;
                     98: 
                     99:   if ((c & IF_CHANGE_LINK) && cf->check_link)
                    100:   {
                    101:     uint ac = (iface->flags & IF_LINK_UP) ? IF_CHANGE_UP : IF_CHANGE_DOWN;
                    102: 
                    103:     struct ifa *a;
                    104:     WALK_LIST(a, iface->addrs)
                    105:       dev_ifa_notify(p, ac, a);
                    106:   }
                    107: }
                    108: 
                    109: 
                    110: static struct proto *
                    111: dev_init(struct proto_config *c)
                    112: {
                    113:   struct proto *p = proto_new(c, sizeof(struct proto));
                    114: 
                    115:   p->if_notify = dev_if_notify;
                    116:   p->ifa_notify = dev_ifa_notify;
                    117:   return p;
                    118: }
                    119: 
                    120: static int
                    121: dev_reconfigure(struct proto *p, struct proto_config *new)
                    122: {
                    123:   struct rt_dev_config *o = (struct rt_dev_config *) p->cf;
                    124:   struct rt_dev_config *n = (struct rt_dev_config *) new;
                    125: 
                    126:   return iface_patts_equal(&o->iface_list, &n->iface_list, NULL) &&
                    127:     (o->check_link == n->check_link);
                    128: }
                    129: 
                    130: static void
                    131: dev_copy_config(struct proto_config *dest, struct proto_config *src)
                    132: {
                    133:   struct rt_dev_config *d = (struct rt_dev_config *) dest;
                    134:   struct rt_dev_config *s = (struct rt_dev_config *) src;
                    135: 
                    136:   /*
                    137:    * We copy iface_list as ifaces can be shared by more direct protocols.
                    138:    * Copy suffices to be is shallow, because new nodes can be added, but
                    139:    * old nodes cannot be modified (although they contain internal lists).
                    140:    */
                    141:   cfg_copy_list(&d->iface_list, &s->iface_list, sizeof(struct iface_patt));
                    142: 
                    143:   d->check_link = s->check_link;
                    144: }
                    145: 
                    146: struct protocol proto_device = {
                    147:   .name =              "Direct",
                    148:   .template =          "direct%d",
                    149:   .preference =        DEF_PREF_DIRECT,
                    150:   .config_size =       sizeof(struct rt_dev_config),
                    151:   .init =              dev_init,
                    152:   .reconfigure =       dev_reconfigure,
                    153:   .copy_config =       dev_copy_config
                    154: };

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