?? ripng_interface.c
字號:
/* * Interface related function for RIPng. * Copyright (C) 1998 Kunihiro Ishiguro * * This file is part of GNU Zebra. * * GNU Zebra is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * GNU Zebra is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Zebra; see the file COPYING. If not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */#include <zebra.h>#include "linklist.h"#include "if.h"#include "prefix.h"#include "memory.h"#include "network.h"#include "filter.h"#include "log.h"#include "stream.h"#include "zclient.h"#include "command.h"#include "table.h"#include "thread.h"#include "ripngd/ripngd.h"#include "ripngd/ripng_debug.h"/* If RFC2133 definition is used. */#ifndef IPV6_JOIN_GROUP#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP #endif#ifndef IPV6_LEAVE_GROUP#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP #endif/* Static utility function. */static void ripng_enable_apply (struct interface *);static void ripng_passive_interface_apply (struct interface *);/* Join to the all rip routers multicast group. */intripng_multicast_join (struct interface *ifp){ int ret; struct ipv6_mreq mreq; memset (&mreq, 0, sizeof (mreq)); inet_pton(AF_INET6, RIPNG_GROUP, &mreq.ipv6mr_multiaddr); mreq.ipv6mr_interface = ifp->ifindex; ret = setsockopt (ripng->sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *) &mreq, sizeof (mreq)); if (ret < 0) zlog_warn ("can't setsockopt IPV6_JOIN_GROUP: %s", strerror (errno)); if (IS_RIPNG_DEBUG_EVENT) zlog_info ("RIPng %s join to all-rip-routers multicast group", ifp->name); return ret;}/* Leave from the all rip routers multicast group. */intripng_multicast_leave (struct interface *ifp){ int ret; struct ipv6_mreq mreq; memset (&mreq, 0, sizeof (mreq)); inet_pton(AF_INET6, RIPNG_GROUP, &mreq.ipv6mr_multiaddr); mreq.ipv6mr_interface = ifp->ifindex; ret = setsockopt (ripng->sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP, (char *) &mreq, sizeof (mreq)); if (ret < 0) zlog_warn ("can't setsockopt IPV6_LEAVE_GROUP: %s\n", strerror (errno)); if (IS_RIPNG_DEBUG_EVENT) zlog_info ("RIPng %s leave from all-rip-routers multicast group", ifp->name); return ret;}/* Check max mtu size. */intripng_check_max_mtu (){ listnode node; struct interface *ifp; int mtu; mtu = 0; for (node = listhead (iflist); node; nextnode (node)) { ifp = getdata (node); if (mtu < ifp->mtu) mtu = ifp->mtu; } return mtu;}intripng_if_down (struct interface *ifp){ struct route_node *rp; struct ripng_info *rinfo; struct ripng_interface *ri; if (ripng) { for (rp = route_top (ripng->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_RIPNG && rinfo->sub_type == RIPNG_ROUTE_RTE) { ripng_zebra_ipv6_delete ((struct prefix_ipv6 *) &rp->p, &rinfo->nexthop, rinfo->ifindex); RIPNG_TIMER_OFF (rinfo->t_timeout); RIPNG_TIMER_OFF (rinfo->t_garbage_collect); rp->info = NULL; route_unlock_node (rp); ripng_info_free (rinfo); } else { /* All redistributed routes got through this interface. */ if (rinfo->ifindex == ifp->ifindex) ripng_redistribute_delete (rinfo->type, rinfo->sub_type, (struct prefix_ipv6 *) &rp->p, rinfo->ifindex); } } } ri = ifp->info; if (ripng && ri->running) { if (IS_RIPNG_DEBUG_EVENT) zlog_info ("turn off %s", ifp->name); /* Leave from multicast group. */ ripng_multicast_leave (ifp); ri->running = 0; } return 0;}/* Inteface link up message processing. */intripng_interface_up (int command, struct zclient *zclient, zebra_size_t length){ struct stream *s; struct interface *ifp; /* zebra_interface_state_read() updates interface structure in iflist. */ s = zclient->ibuf; ifp = zebra_interface_state_read (s); if (ifp == NULL) return 0; if (IS_RIPNG_DEBUG_ZEBRA) zlog_info ("interface up %s index %d flags %ld metric %d mtu %d", ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu); /* Check if this interface is RIPng enabled or not. */ ripng_enable_apply (ifp); /* Check for a passive interface. */ ripng_passive_interface_apply (ifp); /* Apply distribute list to the all interface. */ ripng_distribute_update_interface (ifp); return 0;}/* Inteface link down message processing. */intripng_interface_down (int command, struct zclient *zclient, zebra_size_t length){ struct stream *s; struct interface *ifp; /* zebra_interface_state_read() updates interface structure in iflist. */ s = zclient->ibuf; ifp = zebra_interface_state_read (s); if (ifp == NULL) return 0; ripng_if_down (ifp); if (IS_RIPNG_DEBUG_ZEBRA) zlog_info ("interface down %s index %d flags %ld metric %d mtu %d", ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu); return 0;}/* Inteface addition message from zebra. */intripng_interface_add (int command, struct zclient *zclient, zebra_size_t length){ struct interface *ifp; ifp = zebra_interface_add_read (zclient->ibuf); if (IS_RIPNG_DEBUG_ZEBRA) zlog_info ("RIPng interface add %s index %d flags %ld metric %d mtu %d", ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu); /* Check is this interface is RIP enabled or not.*/ ripng_enable_apply (ifp); /* Apply distribute list to the interface. */ ripng_distribute_update_interface (ifp); /* Check interface routemap. */ ripng_if_rmap_update_interface (ifp); return 0;}intripng_interface_delete (int command, struct zclient *zclient, zebra_size_t length){ return 0;}intripng_interface_address_add (int command, struct zclient *zclient, zebra_size_t length){ struct connected *c; struct prefix *p; char buf[INET6_ADDRSTRLEN]; c = zebra_interface_address_add_read (zclient->ibuf); if (c == NULL) return 0; p = c->address; if (p->family == AF_INET6) { if (IS_RIPNG_DEBUG_ZEBRA) zlog_info ("RIPng connected address %s/%d add", inet_ntop (AF_INET6, &p->u.prefix6, buf, INET6_ADDRSTRLEN), p->prefixlen); /* Check is this interface is RIP enabled or not.*/ ripng_enable_apply (c->ifp); } return 0;}intripng_interface_address_delete (int command, struct zclient *zclient, zebra_size_t length){ struct connected *ifc; struct prefix *p; char buf[INET6_ADDRSTRLEN]; ifc = zebra_interface_address_delete_read (zclient->ibuf); if (ifc) { p = ifc->address; if (p->family == AF_INET6) { if (IS_RIPNG_DEBUG_ZEBRA) zlog_info ("RIPng connected address %s/%d delete", inet_ntop (AF_INET6, &p->u.prefix6, buf, INET6_ADDRSTRLEN), p->prefixlen); /* Check is this interface is RIP enabled or not.*/ ripng_enable_apply (ifc->ifp); } connected_free (ifc); } return 0;}/* RIPng enable interface vector. */vector ripng_enable_if;/* RIPng enable network table. */struct route_table *ripng_enable_network;/* Lookup RIPng enable network. */intripng_enable_network_lookup (struct interface *ifp){ listnode listnode; struct connected *connected; for (listnode = listhead (ifp->connected); listnode; nextnode (listnode)) if ((connected = getdata (listnode)) != NULL) { struct prefix *p; struct route_node *node; p = connected->address; if (p->family == AF_INET6) { node = route_node_match (ripng_enable_network, p); if (node) { route_unlock_node (node); return 1; } } } return -1;}/* Add RIPng enable network. */intripng_enable_network_add (struct prefix *p){ struct route_node *node; node = route_node_get (ripng_enable_network, p); if (node->info) { route_unlock_node (node); return -1; } else node->info = "enabled"; return 1;}/* Delete RIPng enable network. */intripng_enable_network_delete (struct prefix *p){ struct route_node *node; node = route_node_lookup (ripng_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;}/* Lookup function. */intripng_enable_if_lookup (char *ifname){ int i; char *str; for (i = 0; i < vector_max (ripng_enable_if); i++) if ((str = vector_slot (ripng_enable_if, i)) != NULL) if (strcmp (str, ifname) == 0) return i; return -1;}/* Add interface to ripng_enable_if. */intripng_enable_if_add (char *ifname){ int ret; ret = ripng_enable_if_lookup (ifname); if (ret >= 0) return -1; vector_set (ripng_enable_if, strdup (ifname)); return 1;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -