]> git.puffer.fish Git - mirror/frr.git/commitdiff
2005-09-29 Alain Ritoux <alain.ritoux@6wind.com>
authorvincent <vincent>
Thu, 29 Sep 2005 11:25:50 +0000 (11:25 +0000)
committervincent <vincent>
Thu, 29 Sep 2005 11:25:50 +0000 (11:25 +0000)
    * lib/filer.c: show protocol name in filter_show()
    * lib/plist.c: show protocol name in vty_show_prefix_entry()
    * routemap.c: show protocol name in vty_show_route_map_entry()
    * lib/vty.c: in vty_command(), show protocol name if command unknown

    * zebra/zserv.c: Always provide distance fo route add

    * ripd/rip_snmp.c: rip2IfConfReceive() sends values in conformance
      with RFC. Also PeerDomain is now set to a STRING type.
    * ripd/ripd.h: rip_redistribute_add() API includes metric and distance
    * ripd/ripd.c: rip_redistribute_add() API i.e. stores metric and distance
      Now allows a RIP-route to overcome a redistributed route coming
      from a protocol with worse (higher) administrative distance
      Metrics from redistribution are shown in show ip rip
    * ripd/rip_zebra.c: adapt to the rip_redistribute_add() API, i.e.
      provide distance and metric
    * ripd/rip_interface.c: adapt to the rip_redistribute_add() API
    * ripd/rip_routemap.c: no RMAP_COMPILE_ERROR on (metric > 16) usage
      rather a CMD_WARNING, because set metric ius shared with other
      protocols using larger values (such as OSPF)
      The match metric action takes first external metric if present
      (from redistribution) then RIP metric.

14 files changed:
lib/ChangeLog
lib/filter.c
lib/plist.c
lib/routemap.c
lib/vty.c
ripd/ChangeLog
ripd/rip_interface.c
ripd/rip_routemap.c
ripd/rip_snmp.c
ripd/rip_zebra.c
ripd/ripd.c
ripd/ripd.h
zebra/ChangeLog
zebra/zserv.c

index 8a92df3368ca0ae3203deea59e365ae3255ec644..e0605022dda07820442b8fdbebb840116051687c 100644 (file)
@@ -1,3 +1,10 @@
+2005-09-29 Alain Ritoux <alain.ritoux@6wind.com>
+
+       * filer.c: show protocol name in filter_show()
+       * plist.c: show protocol name in vty_show_prefix_entry()
+       * routemap.c: show protocol name in vty_show_route_map_entry()
+       * vty.c: in vty_command(), show protocol name if command unknown
+       
 2005-09-28 Alain Ritoux <alain.ritoux@6wind.com>
 
        * md5-gnu.h: removed
index 55bcdf4bb893b3b5f4813d3f0d27ee1d26a82a81..069919bb718b89fba318aedb4b46a2f87d681605 100644 (file)
@@ -27,6 +27,7 @@
 #include "command.h"
 #include "sockunion.h"
 #include "buffer.h"
+#include "log.h"
 
 struct filter_cisco
 {
@@ -1580,6 +1581,11 @@ filter_show (struct vty *vty, const char *name, afi_t afi)
   if (master == NULL)
     return 0;
 
+  /* Print the name of the protocol */
+  if (zlog_default)
+      vty_out (vty, "%s:%s",
+      zlog_proto_names[zlog_default->protocol], VTY_NEWLINE);
+
   for (access = master->num.head; access; access = access->next)
     {
       if (name && strcmp (access->name, name) != 0)
index 97d254f439fa366066abf7fa036bef5c7dd31c38..83c5aa0c7188d255a38e6d648caf3ce230a3cf53 100644 (file)
@@ -28,6 +28,7 @@
 #include "sockunion.h"
 #include "buffer.h"
 #include "stream.h"
+#include "log.h"
 
 /* Each prefix-list's entry. */
 struct prefix_list_entry
@@ -918,6 +919,10 @@ vty_show_prefix_entry (struct vty *vty, afi_t afi, struct prefix_list *plist,
 {
   struct prefix_list_entry *pentry;
 
+  /* Print the name of the protocol */
+  if (zlog_default)
+      vty_out (vty, "%s: ", zlog_proto_names[zlog_default->protocol]);
+                                                                           
   if (dtype == normal_display)
     {
       vty_out (vty, "ip%s prefix-list %s: %d entries%s",
index 0a4eeb994e6e18eee5bf01f1f71a77ff19a9bec0..a9d94f277ab23ee9366f4111527cec4813ebcd51 100644 (file)
@@ -205,6 +205,11 @@ vty_show_route_map_entry (struct vty *vty, struct route_map *map)
   struct route_map_index *index;
   struct route_map_rule *rule;
 
+  /* Print the name of the protocol */
+  if (zlog_default)
+    vty_out (vty, "%s:%s", zlog_proto_names[zlog_default->protocol],
+             VTY_NEWLINE);
+
   for (index = map->head; index; index = index->next)
     {
       vty_out (vty, "route-map %s, %s, sequence %d%s",
index 540f7b9820c1a5b15736fafee58af16ecf2111b5..2f0bd3f659c77c402da91814ec6e78925cb61c0f 100644 (file)
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -388,6 +388,7 @@ vty_command (struct vty *vty, char *buf)
 {
   int ret;
   vector vline;
+  const char *protocolname;
 
   /* Split readline string up into the vector */
   vline = cmd_make_strvec (buf);
@@ -406,6 +407,12 @@ vty_command (struct vty *vty, char *buf)
 
   ret = cmd_execute_command (vline, vty, NULL, 0);
 
+  /* Get the name of the protocol if any */
+  if (zlog_default)
+      protocolname = zlog_proto_names[zlog_default->protocol];
+  else
+      protocolname = zlog_proto_names[ZLOG_NONE];
+                                                                           
 #ifdef CONSUMED_TIME_CHECK
     GETRUSAGE(&after);
     if ((realtime = thread_consumed_time(&after, &before, &cputime)) >
@@ -427,7 +434,7 @@ vty_command (struct vty *vty, char *buf)
        vty_out (vty, "%% Ambiguous command.%s", VTY_NEWLINE);
        break;
       case CMD_ERR_NO_MATCH:
-       vty_out (vty, "%% Unknown command.%s", VTY_NEWLINE);
+       vty_out (vty, "%% [%s] Unknown command: %s%s", protocolname, buf, VTY_NEWLINE);
        break;
       case CMD_ERR_INCOMPLETE:
        vty_out (vty, "%% Command incomplete.%s", VTY_NEWLINE);
index 3a9b5516dc6ae510e9c6150150916930bf535fbd..6aecebd45d7c255ab54bf603cf39c79c58082129 100644 (file)
@@ -1,3 +1,22 @@
+2005-09-29 Alain Ritoux <alain.ritoux@6wind.com>
+
+       * rip_snmp.c: rip2IfConfReceive() sends values in conformance
+         with RFC. Also PeerDomain is now set to a STRING type.
+       * ripd.h: rip_redistribute_add() API includes metric and distance
+         added field external_metric in routes.
+       * ripd.c: rip_redistribute_add() API i.e. stores metric and distance
+      Now allows a RIP-route to overcome a redistributed route coming
+         from a protocol with worse (higher) administrative distance
+         Metrics from redistribution are shown in show ip rip
+       * rip_zebra.c: adapt to the rip_redistribute_add() API, i.e.
+         provide distance and metric
+       * rip_interface.c: adapt to the rip_redistribute_add() API
+       * rip_routemap.c: no RMAP_COMPILE_ERROR on (metric > 16) usage
+         rather a CMD_WARNING, because set metric ius shared with other
+         protocols using larger values (such as OSPF)
+         The match metric action takes first external metric if present
+      (from redistribution) then RIP metric.
+
 2005-09-28 Alain Ritoux <alain.ritoux@6wind.com>
 
        * ripd.c: use new md5 API
index 5fa4b7d328961aa24a39365dc9eed5652c7abc0a..85bf3c5ad011400db489ada99280ed2f674df4df 100644 (file)
@@ -717,7 +717,7 @@ rip_apply_address_add (struct connected *ifc) {
   if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
       (rip_enable_network_lookup2(ifc) >= 0))
     rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
-                         &address, ifc->ifp->ifindex, NULL);
+                         &address, ifc->ifp->ifindex, NULL, 0, 0);
 
 }
 
@@ -1029,14 +1029,16 @@ rip_connect_set (struct interface *ifp, int set)
         if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
             (rip_enable_network_lookup2(connected) >= 0))
           rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
-                                &address, connected->ifp->ifindex, NULL);
+                                &address, connected->ifp->ifindex, 
+                                NULL, 0, 0);
       } else
         {
           rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
                                    &address, connected->ifp->ifindex);
           if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
             rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
-                                  &address, connected->ifp->ifindex, NULL);
+                                  &address, connected->ifp->ifindex,
+                                  NULL, 0, 0);
         }
     }
 }
index e7692be0458fce16735f77f9dc2b200197908f1a..2a2f264f31bf6d6ebf978f3c58fae9bee66a0f8e 100644 (file)
@@ -1,4 +1,5 @@
 /* RIPv2 routemap.
+ * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
  * Copyright (C) 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
  *
  * This file is part of GNU Zebra.
@@ -106,8 +107,14 @@ rip_route_set_add (struct vty *vty, struct route_map_index *index,
          vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
          return CMD_WARNING;
        case RMAP_COMPILE_ERROR:
-         vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
-         return CMD_WARNING;
+         /* rip, ripng and other protocols share the set metric command
+            but only values from 0 to 16 are valid for rip and ripng
+            if metric is out of range for rip and ripng, it is not for
+            other protocols. Do not return an error */
+         if (strcmp(command, "metric")) {
+            vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
+            return CMD_WARNING;
+         }
        }
     }
   return CMD_SUCCESS;
@@ -161,6 +168,7 @@ route_match_metric (void *rule, struct prefix *prefix,
                    route_map_object_t type, void *object)
 {
   u_int32_t *metric;
+  u_int32_t  check;
   struct rip_info *rinfo;
 
   if (type == RMAP_RIP)
@@ -168,7 +176,11 @@ route_match_metric (void *rule, struct prefix *prefix,
       metric = rule;
       rinfo = object;
     
-      if (rinfo->metric == *metric)
+      /* If external metric is available, the route-map should
+         work on this one (for redistribute purpose)  */
+      check = (rinfo->external_metric) ? rinfo->external_metric :
+                                         rinfo->metric;
+      if (check == *metric)
        return RMAP_MATCH;
       else
        return RMAP_NOMATCH;
index 93773bc58d9f17b82d77209424fd1e301e949d48..c1bec762b90b873fbf2544ddf29909f9fde3bb64 100644 (file)
@@ -136,7 +136,7 @@ struct variable rip_variables[] =
   {RIP2PEERADDRESS,           IPADDRESS, RONLY, rip2PeerTable,
    /* RIP Peer Table. */
    3, {4, 1, 1}},
-  {RIP2PEERDOMAIN,            INTEGER, RONLY, rip2PeerTable,
+  {RIP2PEERDOMAIN,            STRING, RONLY, rip2PeerTable,
    3, {4, 1, 2}},
   {RIP2PEERLASTUPDATE,        TIMETICKS, RONLY, rip2PeerTable,
    3, {4, 1, 3}},
@@ -419,15 +419,19 @@ rip2IfConfReceive (struct rip_interface *ri)
 #define rip1OrRip2      3
 #define doNotReceive    4
 
+  int recvv;
+
   if (! ri->running)
     return doNotReceive;
 
-  if (ri->ri_receive == RI_RIP_VERSION_1_AND_2)
+  recvv = (ri->ri_receive == RI_RIP_UNSPEC) ?  rip->version_recv :
+                                               ri->ri_receive;
+  if (recvv == RI_RIP_VERSION_1_AND_2)
     return rip1OrRip2;
-  else if (ri->ri_receive & RIPv2)
-    return ripVersion2;
-  else if (ri->ri_receive & RIPv1)
-    return ripVersion1;
+  else if (recvv & RIPv2)
+    return rip2;
+  else if (recvv & RIPv1)
+    return rip1;
   else
     return doNotReceive;
 }
@@ -508,6 +512,7 @@ rip2PeerTable (struct variable *v, oid name[], size_t *length,
               int exact, size_t *val_len, WriteMethod **write_method)
 {
   static struct in_addr addr;
+  static int domain = 0;
   static int version;
   /* static time_t uptime; */
 
@@ -527,8 +532,8 @@ rip2PeerTable (struct variable *v, oid name[], size_t *length,
       return (u_char *) &peer->addr;
 
     case RIP2PEERDOMAIN:
-      *val_len = sizeof (int);
-      return (u_char *) &peer->domain;
+      *val_len = 2;
+      return (u_char *) &domain;
 
     case RIP2PEERLASTUPDATE:
 #if 0 
index 734555b765da11670a003a395aa1c38a92ee5212..570b5281082c94ff600292dbce1d862b2a59ea9c 100644 (file)
@@ -134,12 +134,17 @@ rip_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
     }
   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
     api.distance = stream_getc (s);
+  else
+    api.distance = 255;
   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
     api.metric = stream_getl (s);
+  else
+    api.metric = 0;
 
   /* Then fetch IPv4 prefixes. */
   if (command == ZEBRA_IPV4_ROUTE_ADD)
-    rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex, &nexthop);
+    rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex, 
+                          &nexthop, api.metric, api.distance);
   else 
     rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex);
 
@@ -597,7 +602,8 @@ DEFUN (rip_default_information_originate,
 
       rip->default_information = 1;
   
-      rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0, NULL);
+      rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0, 
+                            NULL, 0, 0);
     }
 
   return CMD_SUCCESS;
index b75e018b81614af1c3f24754d1c93f53e2f39ae7..13cf9b9bdde7ee2795fb7772b7237e2de32420af 100644 (file)
@@ -1,4 +1,5 @@
 /* RIP version 1 and 2.
+ * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
  * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro <kunihiro@zebra.org>
  *
  * This file is part of GNU Zebra.
@@ -392,6 +393,8 @@ rip_rte_process (struct rte *rte, struct sockaddr_in *from,
   struct in_addr *nexthop;
   u_char oldmetric;
   int same = 0;
+  int route_reuse = 0;
+  unsigned char old_dist, new_dist;
 
   /* Make prefix structure. */
   memset (&p, 0, sizeof (struct prefix_ipv4));
@@ -480,17 +483,51 @@ rip_rte_process (struct rte *rte, struct sockaddr_in *from,
 
   if (rinfo)
     {
-      /* Redistributed route check. */
-      if (rinfo->type != ZEBRA_ROUTE_RIP
-          && rinfo->metric != RIP_METRIC_INFINITY)
-        return;
-
       /* Local static route. */
       if (rinfo->type == ZEBRA_ROUTE_RIP
           && ((rinfo->sub_type == RIP_ROUTE_STATIC) ||
               (rinfo->sub_type == RIP_ROUTE_DEFAULT))
           && rinfo->metric != RIP_METRIC_INFINITY)
-        return;
+        {
+          route_unlock_node (rp);
+          return;
+        }
+
+      /* Redistributed route check. */
+      if (rinfo->type != ZEBRA_ROUTE_RIP
+          && rinfo->metric != RIP_METRIC_INFINITY)
+        {
+          /* Fill in a minimaly temporary rip_info structure, for a future
+             rip_distance_apply() use) */
+          memset (&rinfotmp, 0, sizeof (rinfotmp));
+          IPV4_ADDR_COPY (&rinfotmp.from, &from->sin_addr);
+          rinfotmp.rp = rinfo->rp;
+          new_dist = rip_distance_apply (&rinfotmp);
+          new_dist = new_dist ? new_dist : ZEBRA_RIP_DISTANCE_DEFAULT;
+          old_dist = rinfo->distance;
+          old_dist = old_dist ? old_dist : ZEBRA_RIP_DISTANCE_DEFAULT;
+          /* If imported route does not have STRICT precedence, 
+             mark it as a ghost */
+          if (new_dist > old_dist 
+              || rte->metric == RIP_METRIC_INFINITY)
+            {
+              route_unlock_node (rp);
+              return;
+            }
+          else
+            {
+              RIP_TIMER_OFF (rinfo->t_timeout);
+              RIP_TIMER_OFF (rinfo->t_garbage_collect);
+                                                                                
+              rp->info = NULL;
+              if (rip_route_rte (rinfo))
+                rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p, 
+                                        &rinfo->nexthop, rinfo->metric);
+              rip_info_free (rinfo);
+              rinfo = NULL;
+              route_reuse = 1;
+            }
+        }
     }
 
   if (!rinfo)
@@ -544,6 +581,10 @@ rip_rte_process (struct rte *rte, struct sockaddr_in *from,
                               rinfo->distance);
           rinfo->flags |= RIP_RTF_FIB;
         }
+
+      /* Unlock temporary lock, i.e. same behaviour */
+      if (route_reuse)
+        route_unlock_node (rp);
     }
   else
     {
@@ -1495,7 +1536,8 @@ rip_send_packet (u_char * buf, int size, struct sockaddr_in *to,
 /* Add redistributed route to RIP table. */
 void
 rip_redistribute_add (int type, int sub_type, struct prefix_ipv4 *p, 
-                     unsigned int ifindex, struct in_addr *nexthop)
+                     unsigned int ifindex, struct in_addr *nexthop,
+                      unsigned int metric, unsigned char distance)
 {
   int ret;
   struct route_node *rp;
@@ -1551,6 +1593,8 @@ rip_redistribute_add (int type, int sub_type, struct prefix_ipv4 *p,
   rinfo->sub_type = sub_type;
   rinfo->ifindex = ifindex;
   rinfo->metric = 1;
+  rinfo->external_metric = metric;
+  rinfo->distance = distance;
   rinfo->rp = rp;
 
   if (nexthop)
@@ -2922,7 +2966,7 @@ DEFUN (rip_route,
 
   node->info = (char *)"static";
 
-  rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0, NULL);
+  rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0, NULL, 0, 0);
 
   return CMD_SUCCESS;
 }
@@ -3467,7 +3511,17 @@ DEFUN (show_ip_rip,
          }
        else
          {
-           vty_out (vty, "self            ");
+           if (rinfo->external_metric)
+             {
+               len = vty_out (vty, "self (%s:%d)", 
+                              route_info[rinfo->type].str_long,
+                              rinfo->external_metric);
+               len = 16 - len;
+               if (len > 0)
+                 vty_out (vty, "%*s", len, " ");
+             }
+           else
+             vty_out (vty, "self            ");
            vty_out (vty, "%3d", rinfo->tag);
          }
 
index 7874871e6e30c5230b8248bd91b4d344e7b67bc6..6ddd52d513dbf948bf1962188475d8855c7a3876 100644 (file)
@@ -200,6 +200,10 @@ struct rip_info
   /* Metric of this route. */
   u_int32_t metric;
 
+  /* External metric of this route. 
+     if learnt from an externalm proto */
+  u_int32_t external_metric;
+
   /* Tag information of this route. */
   u_int16_t tag;
 
@@ -393,7 +397,7 @@ int rip_request_send (struct sockaddr_in *, struct interface *, u_char,
                       struct connected *);
 int rip_neighbor_lookup (struct sockaddr_in *);
 void rip_redistribute_add (int, int, struct prefix_ipv4 *, unsigned int, 
-                          struct in_addr *);
+                          struct in_addr *, unsigned int, unsigned char);
 void rip_redistribute_delete (int, int, struct prefix_ipv4 *, unsigned int);
 void rip_redistribute_withdraw (int);
 void rip_zebra_ipv4_add (struct prefix_ipv4 *, struct in_addr *, u_int32_t, u_char);
index 1e453ae888a7d6883b645d6f881096acc9b5ef5b..c3c88e85d1042bd575f90dc3d7f97353b306dd08 100644 (file)
@@ -1,4 +1,8 @@
 
+2005-09-28 Alain Ritoux <alain.ritoux@6wind.com>
+
+       * zserv.c: Always provied distance for route add
+
 2005-09-28 Alain Ritoux <alain.ritoux@6wind.com>
 
        * connected.c: flag connected_up_ipv6() and connected_down_ipv6()
index 872ddb85ee3f54540db968d263871d4019fecf1c..abd99cdc381f0c61508135b37853352f431ed3c0 100644 (file)
@@ -486,6 +486,8 @@ zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
   /* Metric */
   if (cmd == ZEBRA_IPV4_ROUTE_ADD || ZEBRA_IPV6_ROUTE_ADD)
     {
+      SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
+      stream_putc (s, rib->distance);
       SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
       stream_putl (s, rib->metric);
     }