From 16705130a1c842f7de252779514e4e7f92d967e2 Mon Sep 17 00:00:00 2001 From: hasso Date: Sun, 25 May 2003 14:49:19 +0000 Subject: Merge RIP part of 6Wind patch. --- ripd/rip_interface.c | 237 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 194 insertions(+), 43 deletions(-) (limited to 'ripd/rip_interface.c') diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 23c9cb0b..8ec96ae1 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 @@ rip_interface_new () 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 @@ rip_request_interface_send (struct interface *ifp, u_char version) 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_interface_add (int command, struct zclient *zclient, zebra_size_t length) /* rip_request_neighbor_all (); */ + /* Check interface routemap. */ + rip_if_rmap_update_interface (ifp); + return 0; } @@ -554,8 +559,8 @@ rip_interface_reset () 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 @@ rip_if_down_all () } } +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 @@ rip_interface_address_add (int command, struct zclient *zclient, 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 @@ rip_interface_address_add (int command, struct zclient *zclient, 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_interface_address_delete (int command, struct zclient *zclient, 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 @@ rip_interface_address_delete (int command, struct zclient *zclient, } /* 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 @@ rip_enable_network_lookup (struct interface *ifp) 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 @@ rip_enable_network_add (struct prefix *p) 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 @@ rip_enable_network_delete (struct prefix *p) /* 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 @@ rip_enable_if_add (char *ifname) vector_set (rip_enable_interface, strdup (ifname)); + rip_enable_apply_all(); /* TODOVJ */ + return 1; } @@ -828,6 +923,8 @@ rip_enable_if_delete (char *ifname) free (str); vector_unset (rip_enable_interface, index); + rip_enable_apply_all(); /* TODOVJ */ + return 1; } @@ -883,10 +980,13 @@ rip_connect_set (struct interface *ifp, int set) 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 @@ rip_enable_apply (struct interface *ifp) 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 @@ rip_enable_apply (struct interface *ifp) /* 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 @@ rip_enable_apply (struct interface *ifp) { 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 @@ DEFUN (rip_network, return CMD_WARNING; } - rip_enable_apply_all (); - return CMD_SUCCESS; } @@ -1212,8 +1304,6 @@ DEFUN (no_rip_network, return CMD_WARNING; } - rip_enable_apply_all (); - return CMD_SUCCESS; } @@ -1661,10 +1751,15 @@ ALIAS (no_ip_rip_authentication_key_chain, "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 @@ DEFUN (rip_split_horizon, 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 @@ DEFUN (no_rip_split_horizon, 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 @@ rip_interface_config_write (struct vty *vty) 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 @@ rip_interface_config_write (struct vty *vty) /* 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 @@ int rip_interface_delete_hook (struct interface *ifp) { XFREE (MTYPE_RIP_INTERFACE, ifp->info); + ifp->info = NULL; return 0; } @@ -1897,6 +2046,8 @@ rip_if_init () 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); } -- cgit v1.2.1