File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird / nest / rt-dev.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Aug 22 12:33:54 2017 UTC (6 years, 10 months ago) by misho
Branches: bird, MAIN
CVS tags: v1_6_8p3, v1_6_3p0, v1_6_3, HEAD
bird 1.6.3

    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>