📄 rip_interface.c
字号:
ri->t_wakeup = NULL; } ri->recv_badpackets = 0; ri->recv_badroutes = 0; ri->sent_updates = 0; ri->passive = 0; }}intrip_if_down(struct interface *ifp){ struct route_node *rp; struct rip_info *rinfo; struct rip_interface *ri = NULL; if (rip) { for (rp = route_top (rip->table); rp; rp = route_next (rp)) if ((rinfo = rp->info) != NULL) { /* Routes got through this interface. */ if (rinfo->ifindex == ifp->ifindex && rinfo->type == ZEBRA_ROUTE_RIP && rinfo->sub_type == RIP_ROUTE_RTE) { rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p, &rinfo->nexthop, rinfo->ifindex); rip_redistribute_delete (rinfo->type,rinfo->sub_type, (struct prefix_ipv4 *)&rp->p, rinfo->ifindex); } else { /* All redistributed routes but static and system */ if ((rinfo->ifindex == ifp->ifindex) && (rinfo->type != ZEBRA_ROUTE_STATIC) && (rinfo->type != ZEBRA_ROUTE_SYSTEM)) rip_redistribute_delete (rinfo->type,rinfo->sub_type, (struct prefix_ipv4 *)&rp->p, rinfo->ifindex); } } } ri = ifp->info; if (ri->running) { if (IS_RIP_DEBUG_EVENT) zlog_info ("turn off %s", ifp->name); /* Leave from multicast group. */ rip_multicast_leave (ifp, rip->sock); ri->running = 0; } return 0;}/* Needed for stop RIP process. */voidrip_if_down_all (){ struct interface *ifp; listnode node; for (node = listhead (iflist); node; nextnode (node)) { ifp = getdata (node); rip_if_down (ifp); }}intrip_interface_address_add (int command, struct zclient *zclient, zebra_size_t length){ struct connected *ifc; struct prefix *p; ifc = zebra_interface_address_add_read (zclient->ibuf); if (ifc == NULL) return 0; p = ifc->address; if (p->family == AF_INET) { 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);#ifdef HAVE_SNMP rip_ifaddr_add (ifc->ifp, ifc);#endif /* HAVE_SNMP */ } return 0;}intrip_interface_address_delete (int command, struct zclient *zclient, zebra_size_t length){ struct connected *ifc; struct prefix *p; ifc = zebra_interface_address_delete_read (zclient->ibuf); if (ifc) { p = ifc->address; if (p->family == AF_INET) { if (IS_RIP_DEBUG_ZEBRA) zlog_info ("connected address %s/%d is deleted", inet_ntoa (p->u.prefix4), p->prefixlen);#ifdef HAVE_SNMP rip_ifaddr_delete (ifc->ifp, ifc);#endif /* HAVE_SNMP */ /* Check if this interface is RIP enabled or not.*/ rip_enable_apply (ifc->ifp); } connected_free (ifc); } return 0;}/* Check interface is enabled by network statement. */intrip_enable_network_lookup (struct interface *ifp){ struct listnode *nn; struct connected *connected; struct prefix_ipv4 address; for (nn = listhead (ifp->connected); nn; nextnode (nn)) if ((connected = getdata (nn)) != NULL) { struct prefix *p; struct route_node *node; p = connected->address; if (p->family == AF_INET) { address.family = AF_INET; address.prefix = p->u.prefix4; address.prefixlen = IPV4_MAX_BITLEN; node = route_node_match (rip_enable_network, (struct prefix *)&address); if (node) { route_unlock_node (node); return 1; } } } return -1;}/* Add RIP enable network. */intrip_enable_network_add (struct prefix *p){ struct route_node *node; node = route_node_get (rip_enable_network, p); if (node->info) { route_unlock_node (node); return -1; } else node->info = "enabled"; return 1;}/* Delete RIP enable network. */intrip_enable_network_delete (struct prefix *p){ struct route_node *node; node = route_node_lookup (rip_enable_network, p); if (node) { node->info = NULL; /* Unlock info lock. */ route_unlock_node (node); /* Unlock lookup lock. */ route_unlock_node (node); return 1; } return -1;}/* Check interface is enabled by ifname statement. */intrip_enable_if_lookup (char *ifname){ int i; char *str; for (i = 0; i < vector_max (rip_enable_interface); i++) if ((str = vector_slot (rip_enable_interface, i)) != NULL) if (strcmp (str, ifname) == 0) return i; return -1;}/* Add interface to rip_enable_if. */intrip_enable_if_add (char *ifname){ int ret; ret = rip_enable_if_lookup (ifname); if (ret >= 0) return -1; vector_set (rip_enable_interface, strdup (ifname)); return 1;}/* Delete interface from rip_enable_if. */intrip_enable_if_delete (char *ifname){ int index; char *str; index = rip_enable_if_lookup (ifname); if (index < 0) return -1; str = vector_slot (rip_enable_interface, index); free (str); vector_unset (rip_enable_interface, index); return 1;}/* Join to multicast group and send request to the interface. */intrip_interface_wakeup (struct thread *t){ struct interface *ifp; struct rip_interface *ri; /* Get interface. */ ifp = THREAD_ARG (t); ri = ifp->info; ri->t_wakeup = NULL; /* Join to multicast group. */ if (rip_multicast_join (ifp, rip->sock) < 0) { zlog_err ("multicast join failed, interface %s not running", ifp->name); return 0; } /* Set running flag. */ ri->running = 1; /* Send RIP request to the interface. */ rip_request_interface (ifp); return 0;}int rip_redistribute_check (int);voidrip_connect_set (struct interface *ifp, int set){ struct listnode *nn; struct connected *connected; struct prefix_ipv4 address; for (nn = listhead (ifp->connected); nn; nextnode (nn)) if ((connected = getdata (nn)) != NULL) { struct prefix *p; p = connected->address; if (p->family != AF_INET) continue; address.family = AF_INET; address.prefix = p->u.prefix4; 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 { 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); } }}/* Update interface status. */voidrip_enable_apply (struct interface *ifp){ int ret; struct rip_interface *ri = NULL; /* Check interface. */ if (if_is_loopback (ifp)) return; if (! if_is_up (ifp)) return; ri = ifp->info; /* Check network configuration. */ ret = rip_enable_network_lookup (ifp); /* If the interface is matched. */ if (ret > 0) ri->enable_network = 1; else ri->enable_network = 0; /* Check interface name configuration. */ ret = rip_enable_if_lookup (ifp->name); if (ret >= 0) ri->enable_interface = 1; else ri->enable_interface = 0; /* any interface MUST have an IPv4 address */ if ( ! rip_if_ipv4_address_check (ifp) ) { ri->enable_network = 0; ri->enable_interface = 0; } /* 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); /* Add interface wake up thread. */ if (! ri->t_wakeup) ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup, ifp, 1); rip_connect_set (ifp, 1); } } else { 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 */ rip_if_down(ifp); ri->running = 0; rip_connect_set (ifp, 0); } }}/* Apply network configuration to all interface. */voidrip_enable_apply_all (){ struct interface *ifp; listnode node; /* Check each interface. */ for (node = listhead (iflist); node; nextnode (node)) { ifp = getdata (node); rip_enable_apply (ifp); }}intrip_neighbor_lookup (struct sockaddr_in *from){ struct prefix_ipv4 p; struct route_node *node; memset (&p, 0, sizeof (struct prefix_ipv4)); p.family = AF_INET; p.prefix = from->sin_addr; p.prefixlen = IPV4_MAX_BITLEN; node = route_node_lookup (rip->neighbor, (struct prefix *) &p); if (node) { route_unlock_node (node); return 1; } return 0;}/* Add new RIP neighbor to the neighbor tree. */intrip_neighbor_add (struct prefix_ipv4 *p){ struct route_node *node; node = route_node_get (rip->neighbor, (struct prefix *) p); if (node->info) return -1; node->info = rip->neighbor; return 0;}/* Delete RIP neighbor from the neighbor tree. */intrip_neighbor_delete (struct prefix_ipv4 *p){ struct route_node *node; /* Lock for look up. */ node = route_node_lookup (rip->neighbor, (struct prefix *) p); if (! node) return -1; node->info = NULL; /* Unlock lookup lock. */ route_unlock_node (node); /* Unlock real neighbor information lock. */ route_unlock_node (node); return 0;}/* Clear all network and neighbor configuration. */voidrip_clean_network (){ int i; char *str; struct route_node *rn; /* rip_enable_network. */ for (rn = route_top (rip_enable_network); rn; rn = route_next (rn)) if (rn->info) { rn->info = NULL; route_unlock_node (rn); } /* rip_enable_interface. */ for (i = 0; i < vector_max (rip_enable_interface); i++) if ((str = vector_slot (rip_enable_interface, i)) != NULL) { free (str); vector_slot (rip_enable_interface, i) = NULL; }}/* Utility function for looking up passive interface settings. */intrip_passive_interface_lookup (char *ifname){ int i; char *str; for (i = 0; i < vector_max (Vrip_passive_interface); i++) if ((str = vector_slot (Vrip_passive_interface, i)) != NULL) if (strcmp (str, ifname) == 0) return i; return -1;}voidrip_passive_interface_apply (struct interface *ifp){ int ret; struct rip_interface *ri; ri = ifp->info; ret = rip_passive_interface_lookup (ifp->name); if (ret < 0) ri->passive = 0; else ri->passive = 1;}voidrip_passive_interface_apply_all (){ struct interface *ifp; listnode node; for (node = listhead (iflist); node; nextnode (node)) { ifp = getdata (node); rip_passive_interface_apply (ifp); }}/* Passive interface. */intrip_passive_interface_set (struct vty *vty, char *ifname){ if (rip_passive_interface_lookup (ifname) >= 0) return CMD_WARNING; vector_set (Vrip_passive_interface, strdup (ifname)); rip_passive_interface_apply_all (); return CMD_SUCCESS;}intrip_passive_interface_unset (struct vty *vty, char *ifname){ int i; char *str; i = rip_passive_interface_lookup (ifname); if (i < 0) return CMD_WARNING; str = vector_slot (Vrip_passive_interface, i); free (str); vector_unset (Vrip_passive_interface, i); rip_passive_interface_apply_all (); return CMD_SUCCESS;}/* Free all configured RIP passive-interface settings. */voidrip_passive_interface_clean (){ int i; char *str; for (i = 0; i < vector_max (Vrip_passive_interface); i++) if ((str = vector_slot (Vrip_passive_interface, i)) != NULL) { free (str); vector_slot (Vrip_passive_interface, i) = NULL; } rip_passive_interface_apply_all ();}/* RIP enable network or interface configuration. */DEFUN (rip_network, rip_network_cmd, "network (A.B.C.D/M|WORD)", "Enable routing on an IP network\n" "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n" "Interface name\n"){ int ret; struct prefix_ipv4 p; ret = str2prefix_ipv4 (argv[0], &p); if (ret) ret = rip_enable_network_add ((struct prefix *) &p); else ret = rip_enable_if_add (argv[0]); if (ret < 0) { vty_out (vty, "There is a same network configuration %s%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } rip_enable_apply_all (); return CMD_SUCCESS;}/* RIP enable network or interface configuration. */DEFUN (no_rip_network, no_rip_network_cmd, "no network (A.B.C.D/M|WORD)", NO_STR "Enable routing on an IP network\n" "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n" "Interface name\n"){ int ret; struct prefix_ipv4 p; ret = str2prefix_ipv4 (argv[0], &p); if (ret) ret = rip_enable_network_delete ((struct prefix *) &p); else ret = rip_enable_if_delete (argv[0]); if (ret < 0) { vty_out (vty, "Can't find network configuration %s%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } rip_enable_apply_all (); return CMD_SUCCESS;}/* RIP neighbor configuration set. */DEFUN (rip_neighbor, rip_neighbor_cmd, "neighbor A.B.C.D", "Specify a neighbor router\n" "Neighbor address\n"){ int ret; struct prefix_ipv4 p; ret = str2prefix_ipv4 (argv[0], &p); if (ret <= 0) { vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE); return CMD_WARNING; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -