]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
RIP: Improvements to demand circuit mode
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Sat, 14 Mar 2020 16:04:49 +0000 (17:04 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Sat, 14 Mar 2020 16:08:29 +0000 (17:08 +0100)
Restart iface after changing demand circuit mode during reconfiguration.
Fix next_regular interval reset during reconfiguration. Send flushing
response when iface goes down.

proto/rip/packets.c
proto/rip/rip.c
proto/rip/rip.h

index d8b04317df955ab0240a01ef2900620f81b39787..da6ff2c81cc63f5a7feba5a004a2a8b19c21af1c 100644 (file)
@@ -780,6 +780,25 @@ rip_receive_response(struct rip_proto *p, struct rip_iface *ifa, struct rip_pack
   }
 }
 
+int
+rip_send_flush(struct rip_proto *p, struct rip_iface *ifa)
+{
+  /* Caller should handle cleanup of pending response */
+  if (ifa->tx_pending)
+    return 0;
+
+  struct rip_packet *pkt = rip_tx_buffer(ifa);
+
+  rip_fill_header(ifa, pkt, RIP_CMD_UPDATE_RESPONSE);
+  rip_fill_update_hdr(pkt, 1, ifa->tx_seqnum);
+
+  /* We suppose that iface is going down, so we do not expect ACK */
+  ifa->tx_seqnum++;
+
+  TRACE(D_PACKETS, "Sending response via %s", ifa->iface->name);
+  return rip_send_to(p, ifa, pkt, rip_pkt_hdrlen(ifa), ifa->tx_addr);
+}
+
 
 static int
 rip_send_ack(struct rip_proto *p, struct rip_iface *ifa, uint flush, uint seqnum)
index 0f7f77ac0c39d8c9c1bea69b2f6f16e7bdf84f71..fb212a9b5af49af70daebbc76a6d977514999c32 100644 (file)
@@ -550,9 +550,15 @@ rip_iface_stop(struct rip_iface *ifa)
   ifa->next_triggered = 0;
   ifa->want_triggered = 0;
 
+  if (ifa->tx_pending)
+    ifa->tx_seqnum++;
+
   ifa->tx_pending = 0;
   ifa->req_pending = 0;
 
+  if (ifa->cf->demand_circuit)
+    rip_send_flush(p, ifa);
+
   WALK_LIST_FIRST(n, ifa->neigh_list)
     rip_remove_neighbor(p, n);
 
@@ -710,7 +716,8 @@ rip_reconfigure_iface(struct rip_proto *p, struct rip_iface *ifa, struct rip_ifa
       (new->port != old->port) ||
       (new->tx_tos != old->tx_tos) ||
       (new->tx_priority != old->tx_priority) ||
-      (new->ttl_security != old->ttl_security))
+      (new->ttl_security != old->ttl_security) ||
+      (new->demand_circuit != old->demand_circuit))
     return 0;
 
   TRACE(D_EVENTS, "Reconfiguring interface %s", ifa->iface->name);
@@ -719,7 +726,8 @@ rip_reconfigure_iface(struct rip_proto *p, struct rip_iface *ifa, struct rip_ifa
 
   rip_iface_update_buffers(ifa);
 
-  if (ifa->next_regular > (current_time() + new->update_time))
+  if ((! ifa->cf->demand_circuit) &&
+      (ifa->next_regular > (current_time() + new->update_time)))
     ifa->next_regular = current_time() + (random() % new->update_time) + 100 MS;
 
   if (new->check_link != old->check_link)
@@ -1161,6 +1169,20 @@ rip_start(struct proto *P)
   return PS_UP;
 }
 
+static int
+rip_shutdown(struct proto *P)
+{
+  struct rip_proto *p = (void *) P;
+
+  TRACE(D_EVENTS, "Shutdown requested");
+
+  struct rip_iface *ifa;
+  WALK_LIST(ifa, p->iface_list)
+    rip_iface_stop(ifa);
+
+  return PS_DOWN;
+}
+
 static int
 rip_reconfigure(struct proto *P, struct proto_config *CF)
 {
@@ -1302,8 +1324,12 @@ rip_dump(struct proto *P)
   FIB_WALK(&p->rtable, struct rip_entry, en)
   {
     debug("RIP: entry #%d: %N via %I dev %s valid %d metric %d age %t\n",
-         i++, en->n.addr, en->next_hop, en->iface->name,
+         i++, en->n.addr, en->next_hop, en->iface ? en->iface->name : "(null)",
          en->valid, en->metric, current_time() - en->changed);
+
+    for (struct rip_rte *e = en->routes; e; e = e->next)
+      debug("RIP:   via %I metric %d expires %t\n",
+           e->next_hop, e->metric, e->expires - current_time());
   }
   FIB_WALK_END;
 
@@ -1329,6 +1355,7 @@ struct protocol proto_rip = {
   .init =              rip_init,
   .dump =              rip_dump,
   .start =             rip_start,
+  .shutdown =          rip_shutdown,
   .reconfigure =       rip_reconfigure,
   .get_route_info =    rip_get_route_info,
   .get_attr =          rip_get_attr
index d7ed7033f6b4f3d7ba283284960546977c8494e0..24d4e025b2ee873953d76b744dd65c37ef9d72ad 100644 (file)
@@ -162,7 +162,7 @@ struct rip_entry
   u8 valid;                            /* Entry validity state (RIP_ENTRY_*) */
   u8 metric;                           /* Outgoing route metric */
   u16 tag;                             /* Outgoing route tag */
-  struct iface *from;                  /* Outgoing route from, NULL if from  proto */
+  struct iface *from;                  /* Outgoing route from, NULL if from proto */
   struct iface *iface;                 /* Outgoing route iface (for next hop) */
   ip_addr next_hop;                    /* Outgoing route next hop */
 
@@ -227,6 +227,7 @@ void rip_show_neighbors(struct proto *P, char *iff);
 /* packets.c */
 void rip_send_request(struct rip_proto *p, struct rip_iface *ifa);
 void rip_send_table(struct rip_proto *p, struct rip_iface *ifa, ip_addr addr, btime changed);
+int rip_send_flush(struct rip_proto *p, struct rip_iface *ifa);
 void rip_rxmt_timeout(timer *t);
 int rip_open_socket(struct rip_iface *ifa);