]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
o The if_change_too_big_p change was too high-spirited. Fixed.
authorMartin Mares <mj@ucw.cz>
Tue, 2 Mar 1999 18:36:09 +0000 (18:36 +0000)
committerMartin Mares <mj@ucw.cz>
Tue, 2 Mar 1999 18:36:09 +0000 (18:36 +0000)
o  Introduced if_find_by_index()
o  Recognizing two types of interface updates: full update (starting with
   if_start_update(), ending with if_end_update(), guaranteed to see
   all existing interfaces) and a partial update (only if_update(),
   usually due to asynchronous interface notifications).

nest/iface.c
nest/iface.h
sysdep/unix/sync-if.c

index 4d1b68566ce9cb2c97795d356915b9021928ea3b..9a02a3f64fd5655d9bb6dcb9cad6ec922ca1a3c6 100644 (file)
@@ -231,8 +231,6 @@ if_dump_all(void)
 static inline int
 if_change_too_big_p(struct iface *i, struct iface *j)
 {
-  if ((i->flags ^ j->flags) & IF_UP)   /* Going up/down is always OK */
-    return 0;
   if (!ipa_equal(i->ip, j->ip) ||      /* Address change isn't */
       !ipa_equal(i->prefix, j->prefix) ||
       i->pxlen != j->pxlen ||
@@ -310,16 +308,19 @@ if_update(struct iface *new)
        if (if_change_too_big_p(i, new)) /* Changed a lot, convert it to down/up */
          {
            DBG("Interface %s changed too much -- forcing down/up transition\n", i->name);
-           i->flags &= ~IF_UP;
-           if_notify_change(IF_CHANGE_DOWN | IF_CHANGE_FLAGS, i, NULL);
+           if (i->flags & IF_UP)
+             {
+               i->flags &= ~IF_UP;
+               if_notify_change(IF_CHANGE_DOWN | IF_CHANGE_FLAGS, i, NULL);
+             }
            rem_node(&i->n);
            goto newif;
          }
        c = if_changed(i, new);
-       if_copy(i, new);                /* Even if c==0 as we might need to update i->index et al. */
-       i->flags |= IF_UPDATED;
        if (c)
          if_notify_change(c, i, new);
+       if_copy(i, new);                /* Even if c==0 as we might need to update i->index et al. */
+       i->flags |= IF_UPDATED;
        return;
       }
 
@@ -332,6 +333,15 @@ newif:
                   | IF_CHANGE_FLAGS | IF_CHANGE_MTU, NULL, i);
 }
 
+void
+if_start_update(void)
+{
+  struct iface *i;
+
+  WALK_LIST(i, iface_list)
+    i->flags &= ~IF_UPDATED;
+}
+
 void
 if_end_update(void)
 {
@@ -341,9 +351,7 @@ if_end_update(void)
     auto_router_id();
 
   WALK_LIST(i, iface_list)
-    if (i->flags & IF_UPDATED)
-      i->flags &= ~IF_UPDATED;
-    else
+    if (!(i->flags & IF_UPDATED))
       {
        memcpy(&j, i, sizeof(struct iface));
        i->flags = (i->flags & ~(IF_LINK_UP | IF_UP)) | IF_ADMIN_DOWN;
@@ -364,6 +372,17 @@ if_feed_baby(struct proto *p)
     p->if_notify(p, IF_CHANGE_CREATE | ((i->flags & IF_UP) ? IF_CHANGE_UP : 0), i, NULL);
 }
 
+struct iface *
+if_find_by_index(unsigned idx)
+{
+  struct iface *i;
+
+  WALK_LIST(i, iface_list)
+    if (i->index == idx)
+      return i;
+  return NULL;
+}
+
 static void
 auto_router_id(void)                   /* FIXME: What if we run IPv6??? */
 {
index fcad71879b9a23f02e6f3ad796050f533599ecee..8677be0d8b5c9b92367360a7ae5872f334416adc 100644 (file)
@@ -53,8 +53,10 @@ void if_init(void);
 void if_dump(struct iface *);
 void if_dump_all(void);
 void if_update(struct iface *);
+void if_start_update(void);
 void if_end_update(void);
 void if_feed_baby(struct proto *);
+struct iface *if_find_by_index(unsigned);
 
 /*
  *     Neighbor Cache. We hold (direct neighbor, protocol) pairs we've seen
index ce54fc77d0d4b2145a79d042d9bb10a9e7cb8b94..3dfa4f01d20dc273020bd43e9572a16bc3c2bbce 100644 (file)
@@ -37,6 +37,7 @@ scan_ifs(struct ifreq *r, int cnt)
   ip_addr netmask;
   int l;
 
+  if_start_update();
   for (cnt /= sizeof(struct ifreq); cnt; cnt--, r++)
     {
       bzero(&i, sizeof(i));