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>