Annotation of embedaddon/bird/nest/rt-dev.c, revision 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>