Merge RIP part of 6Wind patch.
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index 23c9cb0..8ec96ae 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -43,6 +43,10 @@
void rip_enable_apply (struct interface *);
void rip_passive_interface_apply (struct interface *);
int rip_if_down(struct interface *ifp);
+int rip_enable_if_lookup (char *ifname);
+int rip_enable_network_lookup2 (struct connected *connected);
+void rip_enable_apply_all ();
+
struct message ri_version_msg[] =
{
@@ -122,7 +126,7 @@
Relay or SMDS is enabled, the default value for split-horizon is
off. But currently Zebra does detect Frame Relay or SMDS
interface. So all interface is set to split horizon. */
- ri->split_horizon_default = 1;
+ ri->split_horizon_default = RIP_SPLIT_HORIZON;
ri->split_horizon = ri->split_horizon_default;
return ri;
@@ -226,10 +230,8 @@
to.sin_port = htons (RIP_PORT_DEFAULT);
to.sin_addr = p->prefix;
-#if 0
if (IS_RIP_DEBUG_EVENT)
zlog_info ("SEND request to %s", inet_ntoa (to.sin_addr));
-#endif /* 0 */
rip_request_send (&to, ifp, version);
}
@@ -466,6 +468,9 @@
/* rip_request_neighbor_all (); */
+ /* Check interface routemap. */
+ rip_if_rmap_update_interface (ifp);
+
return 0;
}
@@ -554,8 +559,8 @@
ri->key_chain = NULL;
}
- ri->split_horizon = 0;
- ri->split_horizon_default = 0;
+ ri->split_horizon = RIP_NO_SPLIT_HORIZON;
+ ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
ri->list[RIP_FILTER_IN] = NULL;
ri->list[RIP_FILTER_OUT] = NULL;
@@ -644,6 +649,34 @@
}
}
+static void
+rip_apply_address_add (struct connected *ifc) {
+ struct prefix_ipv4 address;
+ struct prefix *p;
+
+ if (!rip)
+ return;
+
+ if (! if_is_up(ifc->ifp))
+ return;
+
+ p = ifc->address;
+
+ memset (&address, 0, sizeof (address));
+ address.family = p->family;
+ address.prefix = p->u.prefix4;
+ address.prefixlen = p->prefixlen;
+ apply_mask_ipv4(&address);
+
+ /* Check if this interface is RIP enabled or not
+ or Check if this address's prefix is RIP enabled */
+ 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);
+
+}
+
int
rip_interface_address_add (int command, struct zclient *zclient,
zebra_size_t length)
@@ -663,9 +696,9 @@
if (IS_RIP_DEBUG_ZEBRA)
zlog_info ("connected address %s/%d is added",
inet_ntoa (p->u.prefix4), p->prefixlen);
-
- /* Check is this interface is RIP enabled or not.*/
- rip_enable_apply (ifc->ifp);
+
+ /* Check if this prefix needs to be redistributed */
+ rip_apply_address_add(ifc);
#ifdef HAVE_SNMP
rip_ifaddr_add (ifc->ifp, ifc);
@@ -675,6 +708,29 @@
return 0;
}
+static void
+rip_apply_address_del (struct connected *ifc) {
+ struct prefix_ipv4 address;
+ struct prefix *p;
+
+ if (!rip)
+ return;
+
+ if (! if_is_up(ifc->ifp))
+ return;
+
+ p = ifc->address;
+
+ memset (&address, 0, sizeof (address));
+ address.family = p->family;
+ address.prefix = p->u.prefix4;
+ address.prefixlen = p->prefixlen;
+ apply_mask_ipv4(&address);
+
+ rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
+ &address, ifc->ifp->ifindex);
+}
+
int
rip_interface_address_delete (int command, struct zclient *zclient,
zebra_size_t length)
@@ -698,8 +754,9 @@
rip_ifaddr_delete (ifc->ifp, ifc);
#endif /* HAVE_SNMP */
- /* Check if this interface is RIP enabled or not.*/
- rip_enable_apply (ifc->ifp);
+ /* Chech wether this prefix needs to be removed */
+ rip_apply_address_del(ifc);
+
}
connected_free (ifc);
@@ -710,8 +767,10 @@
}
/* Check interface is enabled by network statement. */
+/* Check wether the interface has at least a connected prefix that
+ * is within the ripng_enable_network table. */
int
-rip_enable_network_lookup (struct interface *ifp)
+rip_enable_network_lookup_if (struct interface *ifp)
{
struct listnode *nn;
struct connected *connected;
@@ -743,6 +802,34 @@
return -1;
}
+/* Check wether connected is within the ripng_enable_network table. */
+int
+rip_enable_network_lookup2 (struct connected *connected)
+{
+ struct prefix_ipv4 address;
+ struct prefix *p;
+
+ p = connected->address;
+
+ if (p->family == AF_INET) {
+ struct route_node *node;
+
+ address.family = p->family;
+ address.prefix = p->u.prefix4;
+ address.prefixlen = IPV4_MAX_BITLEN;
+
+ /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
+ node = route_node_match (rip_enable_network,
+ (struct prefix *)&address);
+
+ if (node) {
+ route_unlock_node (node);
+ return 1;
+ }
+ }
+
+ return -1;
+}
/* Add RIP enable network. */
int
rip_enable_network_add (struct prefix *p)
@@ -759,6 +846,9 @@
else
node->info = "enabled";
+ /* XXX: One should find a better solution than a generic one */
+ rip_enable_apply_all();
+
return 1;
}
@@ -779,6 +869,9 @@
/* Unlock lookup lock. */
route_unlock_node (node);
+ /* XXX: One should find a better solution than a generic one */
+ rip_enable_apply_all ();
+
return 1;
}
return -1;
@@ -810,6 +903,8 @@
vector_set (rip_enable_interface, strdup (ifname));
+ rip_enable_apply_all(); /* TODOVJ */
+
return 1;
}
@@ -828,6 +923,8 @@
free (str);
vector_unset (rip_enable_interface, index);
+ rip_enable_apply_all(); /* TODOVJ */
+
return 1;
}
@@ -883,10 +980,13 @@
address.prefixlen = p->prefixlen;
apply_mask_ipv4 (&address);
- if (set)
- rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
- &address, connected->ifp->ifindex, NULL);
- else
+ if (set) {
+ /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
+ 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);
+ } else
{
rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
&address, connected->ifp->ifindex);
@@ -905,16 +1005,13 @@
struct rip_interface *ri = NULL;
/* Check interface. */
- if (if_is_loopback (ifp))
- return;
-
if (! if_is_operative (ifp))
return;
ri = ifp->info;
/* Check network configuration. */
- ret = rip_enable_network_lookup (ifp);
+ ret = rip_enable_network_lookup_if (ifp);
/* If the interface is matched. */
if (ret > 0)
@@ -939,7 +1036,6 @@
/* Update running status of the interface. */
if (ri->enable_network || ri->enable_interface)
{
- if (! ri->running)
{
if (IS_RIP_DEBUG_EVENT)
zlog_info ("turn on %s", ifp->name);
@@ -955,13 +1051,11 @@
{
if (ri->running)
{
- if (IS_RIP_DEBUG_EVENT)
- zlog_info ("turn off %s", ifp->name);
-
- /* Might as well clean up the route table as well */
+ /* Might as well clean up the route table as well
+ * rip_if_down sets to 0 ri->running, and displays "turn off %s"
+ **/
rip_if_down(ifp);
- ri->running = 0;
rip_connect_set (ifp, 0);
}
}
@@ -1181,8 +1275,6 @@
return CMD_WARNING;
}
- rip_enable_apply_all ();
-
return CMD_SUCCESS;
}
@@ -1212,8 +1304,6 @@
return CMD_WARNING;
}
- rip_enable_apply_all ();
-
return CMD_SUCCESS;
}
@@ -1661,10 +1751,15 @@
"Authentication key-chain\n"
"name of key-chain\n")
-DEFUN (rip_split_horizon,
- rip_split_horizon_cmd,
- "ip split-horizon",
+/* CHANGED: ip rip split-horizon
+ Cisco and Zebra's command is
+ ip split-horizon
+ */
+DEFUN (ip_rip_split_horizon,
+ ip_rip_split_horizon_cmd,
+ "ip rip split-horizon",
IP_STR
+ "Routing Information Protocol\n"
"Perform split horizon\n")
{
struct interface *ifp;
@@ -1673,15 +1768,38 @@
ifp = vty->index;
ri = ifp->info;
- ri->split_horizon = 1;
+ ri->split_horizon = RIP_SPLIT_HORIZON;
return CMD_SUCCESS;
}
-DEFUN (no_rip_split_horizon,
- no_rip_split_horizon_cmd,
- "no ip split-horizon",
+DEFUN (ip_rip_split_horizon_poisoned_reverse,
+ ip_rip_split_horizon_poisoned_reverse_cmd,
+ "ip rip split-horizon poisoned-reverse",
+ IP_STR
+ "Routing Information Protocol\n"
+ "Perform split horizon\n"
+ "With poisoned-reverse\n")
+{
+ struct interface *ifp;
+ struct rip_interface *ri;
+
+ ifp = vty->index;
+ ri = ifp->info;
+
+ ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
+ return CMD_SUCCESS;
+}
+
+/* CHANGED: no ip rip split-horizon
+ Cisco and Zebra's command is
+ no ip split-horizon
+ */
+DEFUN (no_ip_rip_split_horizon,
+ no_ip_rip_split_horizon_cmd,
+ "no ip rip split-horizon",
NO_STR
IP_STR
+ "Routing Information Protocol\n"
"Perform split horizon\n")
{
struct interface *ifp;
@@ -1690,10 +1808,19 @@
ifp = vty->index;
ri = ifp->info;
- ri->split_horizon = 0;
+ ri->split_horizon = RIP_NO_SPLIT_HORIZON;
return CMD_SUCCESS;
}
+ALIAS (no_ip_rip_split_horizon,
+ no_ip_rip_split_horizon_poisoned_reverse_cmd,
+ "no ip rip split-horizon poisoned-reverse",
+ NO_STR
+ IP_STR
+ "Routing Information Protocol\n"
+ "Perform split horizon\n"
+ "With poisoned-reverse\n")
+
DEFUN (rip_passive_interface,
rip_passive_interface_cmd,
"passive-interface IFNAME",
@@ -1727,6 +1854,18 @@
ifp = getdata (node);
ri = ifp->info;
+ /* Do not display the interface if there is no
+ * configuration about it.
+ **/
+ if ((!ifp->desc) &&
+ (ri->split_horizon == ri->split_horizon_default) &&
+ (ri->ri_send == RI_RIP_UNSPEC) &&
+ (ri->ri_receive == RI_RIP_UNSPEC) &&
+ (ri->auth_type != RIP_AUTH_MD5) &&
+ (!ri->auth_str) &&
+ (!ri->key_chain) )
+ continue;
+
vty_out (vty, "interface %s%s", ifp->name,
VTY_NEWLINE);
@@ -1737,10 +1876,19 @@
/* Split horizon. */
if (ri->split_horizon != ri->split_horizon_default)
{
- if (ri->split_horizon)
- vty_out (vty, " ip split-horizon%s", VTY_NEWLINE);
- else
- vty_out (vty, " no ip split-horizon%s", VTY_NEWLINE);
+ switch (ri->split_horizon) {
+ case RIP_SPLIT_HORIZON:
+ vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
+ break;
+ case RIP_SPLIT_HORIZON_POISONED_REVERSE:
+ vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
+ VTY_NEWLINE);
+ break;
+ case RIP_NO_SPLIT_HORIZON:
+ default:
+ vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
+ break;
+ }
}
/* RIP version setting. */
@@ -1837,6 +1985,7 @@
rip_interface_delete_hook (struct interface *ifp)
{
XFREE (MTYPE_RIP_INTERFACE, ifp->info);
+ ifp->info = NULL;
return 0;
}
@@ -1897,6 +2046,8 @@
install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
- install_element (INTERFACE_NODE, &rip_split_horizon_cmd);
- install_element (INTERFACE_NODE, &no_rip_split_horizon_cmd);
+ install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
+ install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
+ install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
+ install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
}