2002-12-13 21:15:29 +01:00
|
|
|
/* Interface related function for RIP.
|
|
|
|
* Copyright (C) 1997, 98 Kunihiro Ishiguro <kunihiro@zebra.org>
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
2017-05-13 10:25:29 +02:00
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; see the file COPYING; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
2002-12-13 21:15:29 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "command.h"
|
|
|
|
#include "if.h"
|
|
|
|
#include "sockunion.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "network.h"
|
|
|
|
#include "table.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "stream.h"
|
|
|
|
#include "thread.h"
|
|
|
|
#include "zclient.h"
|
|
|
|
#include "filter.h"
|
|
|
|
#include "sockopt.h"
|
2003-06-04 15:59:38 +02:00
|
|
|
#include "privs.h"
|
2018-06-18 15:50:29 +02:00
|
|
|
#include "lib_errors.h"
|
2018-05-09 06:34:59 +02:00
|
|
|
#include "northbound_cli.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
#include "zebra/connected.h"
|
|
|
|
|
|
|
|
#include "ripd/ripd.h"
|
|
|
|
#include "ripd/rip_debug.h"
|
2005-10-26 01:31:05 +02:00
|
|
|
#include "ripd/rip_interface.h"
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2019-06-21 08:39:33 +02:00
|
|
|
DEFINE_MTYPE_STATIC(RIPD, RIP_INTERFACE, "RIP interface")
|
|
|
|
DEFINE_MTYPE(RIPD, RIP_INTERFACE_STRING, "RIP Interface String")
|
2016-06-12 17:32:23 +02:00
|
|
|
DEFINE_HOOK(rip_ifaddr_add, (struct connected * ifc), (ifc))
|
|
|
|
DEFINE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc))
|
|
|
|
|
2005-10-26 01:31:05 +02:00
|
|
|
/* static prototypes */
|
|
|
|
static void rip_enable_apply(struct interface *);
|
|
|
|
static void rip_passive_interface_apply(struct interface *);
|
|
|
|
static int rip_if_down(struct interface *ifp);
|
2019-01-04 22:08:10 +01:00
|
|
|
static int rip_enable_if_lookup(struct rip *rip, const char *ifname);
|
2005-10-26 01:31:05 +02:00
|
|
|
static int rip_enable_network_lookup2(struct connected *connected);
|
2019-01-04 22:08:10 +01:00
|
|
|
static void rip_enable_apply_all(struct rip *rip);
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2014-11-03 02:20:09 +01:00
|
|
|
const struct message ri_version_msg[] = {{RI_RIP_VERSION_1, "1"},
|
2002-12-13 21:15:29 +01:00
|
|
|
{RI_RIP_VERSION_2, "2"},
|
|
|
|
{RI_RIP_VERSION_1_AND_2, "1 2"},
|
2016-11-10 16:15:43 +01:00
|
|
|
{RI_RIP_VERSION_NONE, "none"},
|
2002-12-13 21:15:29 +01:00
|
|
|
{0}};
|
|
|
|
|
|
|
|
/* Join to the RIP version 2 multicast group. */
|
|
|
|
static int ipv4_multicast_join(int sock, struct in_addr group,
|
|
|
|
struct in_addr ifa, ifindex_t ifindex)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2011-08-18 18:22:17 +02:00
|
|
|
ret = setsockopt_ipv4_multicast(sock, IP_ADD_MEMBERSHIP, ifa,
|
2002-12-13 21:15:29 +01:00
|
|
|
group.s_addr, ifindex);
|
|
|
|
|
|
|
|
if (ret < 0)
|
*: get rid of zlog(*, LOG_LEVEL, ...)
Result of running the following Coccinelle patch + fixups:
<<EOF
/* long-forms: zlog(NULL, <level>, ...)
* => zlog_level(...)
*/
@@
expression list args;
@@
- zlog(NULL, LOG_DEBUG, args)
+ zlog_debug(args)
@@
expression list args;
@@
- zlog(NULL, LOG_NOTICE, args)
+ zlog_notice(args)
@@
expression list args;
@@
- zlog(NULL, LOG_INFO, args)
+ zlog_info(args)
@@
expression list args;
@@
- zlog(NULL, LOG_WARNING, args)
+ zlog_warn(args)
@@
expression list args;
@@
- zlog(NULL, LOG_ERR, args)
+ zlog_err(args)
/* long-forms: zlog(base->log, <level>, ...)
* => zlog_level(...)
*/
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_DEBUG, args)
+ zlog_debug(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_NOTICE, args)
+ zlog_notice(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_INFO, args)
+ zlog_info(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_WARNING, args)
+ zlog_warn(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_ERR, args)
+ zlog_err(args)
EOF
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2016-11-13 04:19:14 +01:00
|
|
|
zlog_info("can't setsockopt IP_ADD_MEMBERSHIP %s",
|
|
|
|
safe_strerror(errno));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Leave from the RIP version 2 multicast group. */
|
|
|
|
static int ipv4_multicast_leave(int sock, struct in_addr group,
|
|
|
|
struct in_addr ifa, ifindex_t ifindex)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2011-08-18 18:22:17 +02:00
|
|
|
ret = setsockopt_ipv4_multicast(sock, IP_DROP_MEMBERSHIP, ifa,
|
2002-12-13 21:15:29 +01:00
|
|
|
group.s_addr, ifindex);
|
|
|
|
|
|
|
|
if (ret < 0)
|
*: get rid of zlog(*, LOG_LEVEL, ...)
Result of running the following Coccinelle patch + fixups:
<<EOF
/* long-forms: zlog(NULL, <level>, ...)
* => zlog_level(...)
*/
@@
expression list args;
@@
- zlog(NULL, LOG_DEBUG, args)
+ zlog_debug(args)
@@
expression list args;
@@
- zlog(NULL, LOG_NOTICE, args)
+ zlog_notice(args)
@@
expression list args;
@@
- zlog(NULL, LOG_INFO, args)
+ zlog_info(args)
@@
expression list args;
@@
- zlog(NULL, LOG_WARNING, args)
+ zlog_warn(args)
@@
expression list args;
@@
- zlog(NULL, LOG_ERR, args)
+ zlog_err(args)
/* long-forms: zlog(base->log, <level>, ...)
* => zlog_level(...)
*/
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_DEBUG, args)
+ zlog_debug(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_NOTICE, args)
+ zlog_notice(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_INFO, args)
+ zlog_info(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_WARNING, args)
+ zlog_warn(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_ERR, args)
+ zlog_err(args)
EOF
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2016-11-13 04:19:14 +01:00
|
|
|
zlog_info("can't setsockopt IP_DROP_MEMBERSHIP");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
ripd: split-horizon default differed between rip_interface_new and _reset
* rip_interface.c: Default for split_horizon_default differed between
rip_interface_new and rip_interface_reset, causing at least some issues
after interface events. See patchwork #604. Fix, and consolidate code.
(rip_interface_{reset,clean}) rename these to 'interface', as that's more
appropriate. Spin the ri specific bodies of these functions out to
rip_interface_{reset,clean} helpers. Factor out the overlaps, so
rip_interface_reset uses rip_interface_clean.
(rip_interface_new) just use rip_interface_reset.
* ripd.h: Update for (rip_interface_{reset,clean})
Reported by xufeng zhang, with a suggested fix on which this commit expands.
See patchwork #604. This commit addresses only the split-horizon
discrepency, issue #2. The other issue they reported, #1, is not addressed,
though suggested fix seems inappropriate.
Cc: xufeng.zhang@windriver.com
2016-05-25 15:47:00 +02:00
|
|
|
static void rip_interface_reset(struct rip_interface *);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Allocate new RIP's interface configuration. */
|
2005-10-26 01:31:05 +02:00
|
|
|
static struct rip_interface *rip_interface_new(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct rip_interface *ri;
|
|
|
|
|
2008-08-18 23:13:29 +02:00
|
|
|
ri = XCALLOC(MTYPE_RIP_INTERFACE, sizeof(struct rip_interface));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
ripd: split-horizon default differed between rip_interface_new and _reset
* rip_interface.c: Default for split_horizon_default differed between
rip_interface_new and rip_interface_reset, causing at least some issues
after interface events. See patchwork #604. Fix, and consolidate code.
(rip_interface_{reset,clean}) rename these to 'interface', as that's more
appropriate. Spin the ri specific bodies of these functions out to
rip_interface_{reset,clean} helpers. Factor out the overlaps, so
rip_interface_reset uses rip_interface_clean.
(rip_interface_new) just use rip_interface_reset.
* ripd.h: Update for (rip_interface_{reset,clean})
Reported by xufeng zhang, with a suggested fix on which this commit expands.
See patchwork #604. This commit addresses only the split-horizon
discrepency, issue #2. The other issue they reported, #1, is not addressed,
though suggested fix seems inappropriate.
Cc: xufeng.zhang@windriver.com
2016-05-25 15:47:00 +02:00
|
|
|
rip_interface_reset(ri);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return ri;
|
|
|
|
}
|
|
|
|
|
2004-08-19 06:03:08 +02:00
|
|
|
void rip_interface_multicast_set(int sock, struct connected *connected)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-08-04 15:07:26 +02:00
|
|
|
struct in_addr addr;
|
|
|
|
|
2004-10-22 12:27:28 +02:00
|
|
|
assert(connected != NULL);
|
2016-08-04 15:07:26 +02:00
|
|
|
|
|
|
|
addr = CONNECTED_ID(connected)->u.prefix4;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-08-04 15:07:26 +02:00
|
|
|
if (setsockopt_ipv4_multicast_if(sock, addr, connected->ifp->ifindex)
|
2017-07-17 14:03:14 +02:00
|
|
|
< 0) {
|
|
|
|
zlog_warn(
|
2020-03-27 12:35:23 +01:00
|
|
|
"Can't setsockopt IP_MULTICAST_IF on fd %d to ifindex %d for interface %s",
|
2011-08-18 18:22:17 +02:00
|
|
|
sock, connected->ifp->ifindex, connected->ifp->name);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2016-08-04 15:07:26 +02:00
|
|
|
|
2004-10-19 21:44:43 +02:00
|
|
|
return;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Send RIP request packet to specified interface. */
|
2018-03-27 21:13:34 +02:00
|
|
|
static void rip_request_interface_send(struct interface *ifp, uint8_t version)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct sockaddr_in to;
|
|
|
|
|
|
|
|
/* RIPv2 support multicast. */
|
|
|
|
if (version == RIPv2 && if_is_multicast(ifp)) {
|
|
|
|
|
2004-01-23 16:31:42 +01:00
|
|
|
if (IS_RIP_DEBUG_EVENT)
|
|
|
|
zlog_debug("multicast request on %s", ifp->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2004-12-08 20:24:06 +01:00
|
|
|
rip_request_send(NULL, ifp, version, NULL);
|
2017-07-17 14:03:14 +02:00
|
|
|
return;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* RIPv1 and non multicast interface. */
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
if (if_is_pointopoint(ifp) || if_is_broadcast(ifp)) {
|
|
|
|
struct listnode *cnode, *cnnode;
|
|
|
|
struct connected *connected;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_RIP_DEBUG_EVENT)
|
2004-12-08 20:24:06 +01:00
|
|
|
zlog_debug("broadcast request to %s", ifp->name);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode,
|
2002-12-13 21:15:29 +01:00
|
|
|
connected)) {
|
2018-07-02 20:51:15 +02:00
|
|
|
if (connected->address->family != AF_INET)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
memset(&to, 0, sizeof(struct sockaddr_in));
|
|
|
|
to.sin_port = htons(RIP_PORT_DEFAULT);
|
|
|
|
if (connected->destination)
|
|
|
|
/* use specified broadcast or peer
|
|
|
|
* destination addr */
|
|
|
|
to.sin_addr = connected->destination->u.prefix4;
|
|
|
|
else if (connected->address->prefixlen
|
|
|
|
< IPV4_MAX_PREFIXLEN)
|
|
|
|
/* calculate the appropriate broadcast
|
|
|
|
* address */
|
|
|
|
to.sin_addr.s_addr = ipv4_broadcast_addr(
|
|
|
|
connected->address->u.prefix4.s_addr,
|
|
|
|
connected->address->prefixlen);
|
|
|
|
else
|
|
|
|
/* do not know where to send the packet
|
|
|
|
*/
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (IS_RIP_DEBUG_EVENT)
|
|
|
|
zlog_debug("SEND request to %s",
|
|
|
|
inet_ntoa(to.sin_addr));
|
|
|
|
|
|
|
|
rip_request_send(&to, ifp, version, connected);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This will be executed when interface goes up. */
|
|
|
|
static void rip_request_interface(struct interface *ifp)
|
|
|
|
{
|
|
|
|
struct rip_interface *ri;
|
2018-07-02 20:51:15 +02:00
|
|
|
int vsend;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* In default ripd doesn't send RIP_REQUEST to the loopback interface.
|
|
|
|
*/
|
|
|
|
if (if_is_loopback(ifp))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* If interface is down, don't send RIP packet. */
|
2002-12-13 22:03:13 +01:00
|
|
|
if (!if_is_operative(ifp))
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* Fetch RIP interface information. */
|
|
|
|
ri = ifp->info;
|
|
|
|
|
|
|
|
/* If there is no version configuration in the interface,
|
|
|
|
use rip's version setting. */
|
2019-01-04 22:08:10 +01:00
|
|
|
vsend = ((ri->ri_send == RI_RIP_UNSPEC) ? ri->rip->version_send
|
2018-07-02 20:51:15 +02:00
|
|
|
: ri->ri_send);
|
|
|
|
if (vsend & RIPv1)
|
|
|
|
rip_request_interface_send(ifp, RIPv1);
|
|
|
|
if (vsend & RIPv2)
|
|
|
|
rip_request_interface_send(ifp, RIPv2);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2009-12-10 17:16:05 +01:00
|
|
|
#if 0
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Send RIP request to the neighbor. */
|
2005-10-26 01:31:05 +02:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
rip_request_neighbor (struct in_addr addr)
|
|
|
|
{
|
|
|
|
struct sockaddr_in to;
|
|
|
|
|
2020-03-08 20:43:26 +01:00
|
|
|
memset (&to, 0, sizeof(struct sockaddr_in));
|
2002-12-13 21:15:29 +01:00
|
|
|
to.sin_port = htons (RIP_PORT_DEFAULT);
|
|
|
|
to.sin_addr = addr;
|
|
|
|
|
2004-01-23 16:31:42 +01:00
|
|
|
rip_request_send (&to, NULL, rip->version_send, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Request routes at all interfaces. */
|
2005-10-26 01:31:05 +02:00
|
|
|
static void
|
|
|
|
rip_request_neighbor_all (void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct route_node *rp;
|
|
|
|
|
|
|
|
if (! rip)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (IS_RIP_DEBUG_EVENT)
|
2004-12-08 20:24:06 +01:00
|
|
|
zlog_debug ("request to the all neighbor");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Send request to all neighbor. */
|
|
|
|
for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
|
|
|
|
if (rp->info)
|
|
|
|
rip_request_neighbor (rp->p.u.prefix4);
|
|
|
|
}
|
2009-12-10 17:16:05 +01:00
|
|
|
#endif
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Multicast packet receive socket. */
|
|
|
|
static int rip_multicast_join(struct interface *ifp, int sock)
|
|
|
|
{
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *cnode;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct connected *ifc;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2002-12-13 22:03:13 +01:00
|
|
|
if (if_is_operative(ifp) && if_is_multicast(ifp)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_RIP_DEBUG_EVENT)
|
2004-12-08 20:24:06 +01:00
|
|
|
zlog_debug("multicast join at %s", ifp->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, ifc)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
struct prefix_ipv4 *p;
|
|
|
|
struct in_addr group;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
p = (struct prefix_ipv4 *)ifc->address;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (p->family != AF_INET)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
group.s_addr = htonl(INADDR_RIP_GROUP);
|
|
|
|
if (ipv4_multicast_join(sock, group, p->prefix,
|
|
|
|
ifp->ifindex)
|
|
|
|
< 0)
|
|
|
|
return -1;
|
|
|
|
else
|
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Leave from multicast group. */
|
|
|
|
static void rip_multicast_leave(struct interface *ifp, int sock)
|
|
|
|
{
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *cnode;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct connected *connected;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (if_is_up(ifp) && if_is_multicast(ifp)) {
|
|
|
|
if (IS_RIP_DEBUG_EVENT)
|
2004-12-08 20:24:06 +01:00
|
|
|
zlog_debug("multicast leave from %s", ifp->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
struct prefix_ipv4 *p;
|
|
|
|
struct in_addr group;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
p = (struct prefix_ipv4 *)connected->address;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (p->family != AF_INET)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
group.s_addr = htonl(INADDR_RIP_GROUP);
|
|
|
|
if (ipv4_multicast_leave(sock, group, p->prefix,
|
|
|
|
ifp->ifindex)
|
|
|
|
== 0)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Is there and address on interface that I could use ? */
|
|
|
|
static int rip_if_ipv4_address_check(struct interface *ifp)
|
|
|
|
{
|
|
|
|
struct listnode *nn;
|
|
|
|
struct connected *connected;
|
|
|
|
int count = 0;
|
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(ifp->connected, nn, connected)) {
|
|
|
|
struct prefix *p;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
p = connected->address;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
if (p->family == AF_INET)
|
2017-07-17 14:03:14 +02:00
|
|
|
count++;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-09-29 21:54:53 +02:00
|
|
|
|
|
|
|
/* Does this address belongs to me ? */
|
2019-01-04 22:08:10 +01:00
|
|
|
int if_check_address(struct rip *rip, struct in_addr addr)
|
2003-09-29 21:54:53 +02:00
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct interface *ifp;
|
2003-09-29 21:54:53 +02:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
FOR_ALL_INTERFACES (rip->vrf, ifp) {
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *cnode;
|
2003-09-29 21:54:53 +02:00
|
|
|
struct connected *connected;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
|
|
|
|
struct prefix_ipv4 *p;
|
|
|
|
|
|
|
|
p = (struct prefix_ipv4 *)connected->address;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
if (p->family != AF_INET)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-09-29 21:54:53 +02:00
|
|
|
if (IPV4_ADDR_CMP(&p->prefix, &addr) == 0)
|
|
|
|
return 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2003-09-29 21:54:53 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Inteface link down message processing. */
|
2019-09-19 05:55:34 +02:00
|
|
|
static int rip_ifp_down(struct interface *ifp)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_interface_sync(ifp);
|
2002-12-13 21:15:29 +01:00
|
|
|
rip_if_down(ifp);
|
|
|
|
|
2020-02-14 14:22:33 +01:00
|
|
|
if (IS_RIP_DEBUG_ZEBRA) {
|
|
|
|
struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id);
|
|
|
|
|
2009-07-28 12:58:51 +02:00
|
|
|
zlog_debug(
|
2020-02-14 14:22:33 +01:00
|
|
|
"interface %s vrf %s(%u) index %d flags %llx metric %d mtu %d is down",
|
|
|
|
ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id, ifp->ifindex,
|
2019-01-04 22:08:10 +01:00
|
|
|
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
|
2020-02-14 14:22:33 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Inteface link up message processing */
|
2019-09-19 05:07:44 +02:00
|
|
|
static int rip_ifp_up(struct interface *ifp)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-02-14 14:22:33 +01:00
|
|
|
if (IS_RIP_DEBUG_ZEBRA) {
|
|
|
|
struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id);
|
|
|
|
|
2009-07-28 12:58:51 +02:00
|
|
|
zlog_debug(
|
2020-02-14 14:22:33 +01:00
|
|
|
"interface %s vrf %s(%u) index %d flags %#llx metric %d mtu %d is up",
|
|
|
|
ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id, ifp->ifindex,
|
2019-01-04 22:08:10 +01:00
|
|
|
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
|
2020-02-14 14:22:33 +01:00
|
|
|
}
|
2019-01-04 22:08:10 +01:00
|
|
|
|
|
|
|
rip_interface_sync(ifp);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2009-12-10 17:16:05 +01:00
|
|
|
/* Check if this interface is RIP enabled or not.*/
|
|
|
|
rip_enable_apply(ifp);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Check for a passive interface */
|
|
|
|
rip_passive_interface_apply(ifp);
|
|
|
|
|
|
|
|
/* Apply distribute list to the all interface. */
|
|
|
|
rip_distribute_update_interface(ifp);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Inteface addition message from zebra. */
|
2019-09-19 04:26:55 +02:00
|
|
|
static int rip_ifp_create(struct interface *ifp)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_interface_sync(ifp);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-02-14 14:22:33 +01:00
|
|
|
if (IS_RIP_DEBUG_ZEBRA) {
|
|
|
|
struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id);
|
2009-12-10 17:16:05 +01:00
|
|
|
zlog_debug(
|
2020-02-14 14:22:33 +01:00
|
|
|
"interface add %s vrf %s(%u) index %d flags %#llx metric %d mtu %d",
|
|
|
|
ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id, ifp->ifindex,
|
2019-01-04 22:08:10 +01:00
|
|
|
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
|
2020-02-14 14:22:33 +01:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Check if this interface is RIP enabled or not.*/
|
|
|
|
rip_enable_apply(ifp);
|
|
|
|
|
|
|
|
/* Check for a passive interface */
|
|
|
|
rip_passive_interface_apply(ifp);
|
|
|
|
|
|
|
|
/* Apply distribute list to the all interface. */
|
|
|
|
rip_distribute_update_interface(ifp);
|
|
|
|
|
2003-05-25 16:49:19 +02:00
|
|
|
/* rip_request_neighbor_all (); */
|
|
|
|
|
|
|
|
/* Check interface routemap. */
|
|
|
|
rip_if_rmap_update_interface(ifp);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-09-19 15:40:57 +02:00
|
|
|
static int rip_ifp_destroy(struct interface *ifp)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-02-14 14:22:33 +01:00
|
|
|
struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id);
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_interface_sync(ifp);
|
*: add VRF ID in the API message header
The API messages are used by zebra to exchange the interfaces, addresses,
routes and router-id information with its clients. To distinguish which
VRF the information belongs to, a new field "VRF ID" is added in the
message header. And hence the message version is increased to 3.
* The new field "VRF ID" in the message header:
Length (2 bytes)
Marker (1 byte)
Version (1 byte)
VRF ID (2 bytes, newly added)
Command (2 bytes)
- Client side:
- zclient_create_header() adds the VRF ID in the message header.
- zclient_read() extracts and validates the VRF ID from the header,
and passes the VRF ID to the callback functions registered to
the API messages.
- All relative functions are appended with a new parameter "vrf_id",
including all the callback functions.
- "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6".
Clients need to correctly set the VRF ID when using the API
functions zapi_ipv4_route() and zapi_ipv6_route().
- Till now all messages sent from a client have the default VRF ID
"0" in the header.
- The HELLO message is special, which is used as the heart-beat of
a client, and has no relation with VRF. The VRF ID in the HELLO
message header will always be 0 and ignored by zebra.
- Zebra side:
- zserv_create_header() adds the VRF ID in the message header.
- zebra_client_read() extracts and validates the VRF ID from the
header, and passes the VRF ID to the functions which process
the received messages.
- All relative functions are appended with a new parameter "vrf_id".
* Suppress the messages in a VRF which a client does not care:
Some clients may not care about the information in the VRF X, and
zebra should not send the messages in the VRF X to those clients.
Extra flags are used to indicate which VRF is registered by a client,
and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client
can unregister a VRF when it does not need any information in that
VRF.
A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF
will automatically register to that VRF.
- lib/vrf:
A new utility "VRF bit-map" is provided to manage the flags for
VRFs, one bit per VRF ID.
- Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a
bit-map;
- Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag
in the given bit-map, corresponding to the given VRF ID;
- Use vrf_bitmap_check() to test whether the flag, in the given
bit-map and for the given VRF ID, is set.
- Client side:
- In "struct zclient", the following flags are changed from
"u_char" to "vrf_bitmap_t":
redist[ZEBRA_ROUTE_MAX]
default_information
These flags are extended for each VRF, and controlled by the
clients themselves (or with the help of zclient_redistribute()
and zclient_redistribute_default()).
- Zebra side:
- In "struct zserv", the following flags are changed from
"u_char" to "vrf_bitmap_t":
redist[ZEBRA_ROUTE_MAX]
redist_default
ifinfo
ridinfo
These flags are extended for each VRF, as the VRF registration
flags. They are maintained on receiving a ZEBRA_XXX_ADD or
ZEBRA_XXX_DELETE message.
When sending an interface/address/route/router-id message in
a VRF to a client, if the corresponding VRF registration flag
is not set, this message will not be dropped by zebra.
- A new function zread_vrf_unregister() is introduced to process
the new command ZEBRA_VRF_UNREGISTER. All the VRF registration
flags are cleared for the requested VRF.
Those clients, who support only the default VRF, will never receive
a message in a non-default VRF, thanks to the filter in zebra.
* New callback for the event of successful connection to zebra:
- zclient_start() is splitted, keeping only the code of connecting
to zebra.
- Now zclient_init()=>zclient_connect()=>zclient_start() operations
are purely dealing with the connection to zbera.
- Once zebra is successfully connected, at the end of zclient_start(),
a new callback is used to inform the client about connection.
- Till now, in the callback of connect-to-zebra event, all clients
send messages to zebra to request the router-id/interface/routes
information in the default VRF.
Of corse in future the client can do anything it wants in this
callback. For example, it may send requests for both default VRF
and some non-default VRFs.
Signed-off-by: Feng Lu <lu.feng@6wind.com>
Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
Conflicts:
lib/zclient.h
lib/zebra.h
zebra/zserv.c
zebra/zserv.h
Conflicts:
bgpd/bgp_nexthop.c
bgpd/bgp_nht.c
bgpd/bgp_zebra.c
isisd/isis_zebra.c
lib/zclient.c
lib/zclient.h
lib/zebra.h
nhrpd/nhrp_interface.c
nhrpd/nhrp_route.c
nhrpd/nhrpd.h
ospf6d/ospf6_zebra.c
ospf6d/ospf6_zebra.h
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
pimd/pim_zebra.c
pimd/pim_zlookup.c
ripd/rip_zebra.c
ripngd/ripng_zebra.c
zebra/redistribute.c
zebra/rt_netlink.c
zebra/zebra_rnh.c
zebra/zebra_rnh.h
zebra/zserv.c
zebra/zserv.h
2014-10-16 03:52:36 +02:00
|
|
|
if (if_is_up(ifp)) {
|
|
|
|
rip_if_down(ifp);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-09-21 13:55:36 +02:00
|
|
|
if (IS_RIP_DEBUG_ZEBRA)
|
|
|
|
zlog_debug(
|
|
|
|
"interface delete %s vrf %s(%u) index %d flags %#llx metric %d mtu %d",
|
|
|
|
ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id, ifp->ifindex,
|
|
|
|
(unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
/* VRF update for an interface. */
|
2019-05-03 21:42:59 +02:00
|
|
|
int rip_interface_vrf_update(ZAPI_CALLBACK_ARGS)
|
2019-01-04 22:08:10 +01:00
|
|
|
{
|
|
|
|
struct interface *ifp;
|
|
|
|
vrf_id_t new_vrf_id;
|
|
|
|
|
|
|
|
ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
|
|
|
|
&new_vrf_id);
|
|
|
|
if (!ifp)
|
|
|
|
return 0;
|
|
|
|
|
2020-02-14 14:22:33 +01:00
|
|
|
if (IS_RIP_DEBUG_ZEBRA) {
|
|
|
|
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
|
|
|
|
struct vrf *nvrf = vrf_lookup_by_id(new_vrf_id);
|
|
|
|
|
|
|
|
zlog_debug("interface %s VRF change vrf %s(%u) new vrf %s(%u)",
|
|
|
|
ifp->name, VRF_LOGNAME(vrf), vrf_id,
|
|
|
|
VRF_LOGNAME(nvrf), new_vrf_id);
|
|
|
|
}
|
2019-01-04 22:08:10 +01:00
|
|
|
|
2019-06-24 01:46:39 +02:00
|
|
|
if_update_to_new_vrf(ifp, new_vrf_id);
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_interface_sync(ifp);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
ripd: split-horizon default differed between rip_interface_new and _reset
* rip_interface.c: Default for split_horizon_default differed between
rip_interface_new and rip_interface_reset, causing at least some issues
after interface events. See patchwork #604. Fix, and consolidate code.
(rip_interface_{reset,clean}) rename these to 'interface', as that's more
appropriate. Spin the ri specific bodies of these functions out to
rip_interface_{reset,clean} helpers. Factor out the overlaps, so
rip_interface_reset uses rip_interface_clean.
(rip_interface_new) just use rip_interface_reset.
* ripd.h: Update for (rip_interface_{reset,clean})
Reported by xufeng zhang, with a suggested fix on which this commit expands.
See patchwork #604. This commit addresses only the split-horizon
discrepency, issue #2. The other issue they reported, #1, is not addressed,
though suggested fix seems inappropriate.
Cc: xufeng.zhang@windriver.com
2016-05-25 15:47:00 +02:00
|
|
|
static void rip_interface_clean(struct rip_interface *ri)
|
2016-12-05 20:31:42 +01:00
|
|
|
{
|
|
|
|
ri->enable_network = 0;
|
|
|
|
ri->enable_interface = 0;
|
|
|
|
ri->running = 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-12-05 20:31:42 +01:00
|
|
|
if (ri->t_wakeup) {
|
|
|
|
thread_cancel(ri->t_wakeup);
|
|
|
|
ri->t_wakeup = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2016-12-05 20:31:42 +01:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
void rip_interfaces_clean(struct rip *rip)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct interface *ifp;
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
FOR_ALL_INTERFACES (rip->vrf, ifp)
|
ripd: split-horizon default differed between rip_interface_new and _reset
* rip_interface.c: Default for split_horizon_default differed between
rip_interface_new and rip_interface_reset, causing at least some issues
after interface events. See patchwork #604. Fix, and consolidate code.
(rip_interface_{reset,clean}) rename these to 'interface', as that's more
appropriate. Spin the ri specific bodies of these functions out to
rip_interface_{reset,clean} helpers. Factor out the overlaps, so
rip_interface_reset uses rip_interface_clean.
(rip_interface_new) just use rip_interface_reset.
* ripd.h: Update for (rip_interface_{reset,clean})
Reported by xufeng zhang, with a suggested fix on which this commit expands.
See patchwork #604. This commit addresses only the split-horizon
discrepency, issue #2. The other issue they reported, #1, is not addressed,
though suggested fix seems inappropriate.
Cc: xufeng.zhang@windriver.com
2016-05-25 15:47:00 +02:00
|
|
|
rip_interface_clean(ifp->info);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
ripd: split-horizon default differed between rip_interface_new and _reset
* rip_interface.c: Default for split_horizon_default differed between
rip_interface_new and rip_interface_reset, causing at least some issues
after interface events. See patchwork #604. Fix, and consolidate code.
(rip_interface_{reset,clean}) rename these to 'interface', as that's more
appropriate. Spin the ri specific bodies of these functions out to
rip_interface_{reset,clean} helpers. Factor out the overlaps, so
rip_interface_reset uses rip_interface_clean.
(rip_interface_new) just use rip_interface_reset.
* ripd.h: Update for (rip_interface_{reset,clean})
Reported by xufeng zhang, with a suggested fix on which this commit expands.
See patchwork #604. This commit addresses only the split-horizon
discrepency, issue #2. The other issue they reported, #1, is not addressed,
though suggested fix seems inappropriate.
Cc: xufeng.zhang@windriver.com
2016-05-25 15:47:00 +02:00
|
|
|
static void rip_interface_reset(struct rip_interface *ri)
|
2016-12-05 20:31:42 +01:00
|
|
|
{
|
2018-05-09 06:35:03 +02:00
|
|
|
ri->auth_type = yang_get_default_enum("%s/authentication-scheme/mode",
|
|
|
|
RIP_IFACE);
|
|
|
|
ri->md5_auth_len = yang_get_default_enum(
|
|
|
|
"%s/authentication-scheme/md5-auth-length", RIP_IFACE);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
ripd: split-horizon default differed between rip_interface_new and _reset
* rip_interface.c: Default for split_horizon_default differed between
rip_interface_new and rip_interface_reset, causing at least some issues
after interface events. See patchwork #604. Fix, and consolidate code.
(rip_interface_{reset,clean}) rename these to 'interface', as that's more
appropriate. Spin the ri specific bodies of these functions out to
rip_interface_{reset,clean} helpers. Factor out the overlaps, so
rip_interface_reset uses rip_interface_clean.
(rip_interface_new) just use rip_interface_reset.
* ripd.h: Update for (rip_interface_{reset,clean})
Reported by xufeng zhang, with a suggested fix on which this commit expands.
See patchwork #604. This commit addresses only the split-horizon
discrepency, issue #2. The other issue they reported, #1, is not addressed,
though suggested fix seems inappropriate.
Cc: xufeng.zhang@windriver.com
2016-05-25 15:47:00 +02:00
|
|
|
/* Set default split-horizon behavior. If the interface is Frame
|
|
|
|
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. */
|
2018-05-09 06:35:03 +02:00
|
|
|
ri->split_horizon =
|
|
|
|
yang_get_default_enum("%s/split-horizon", RIP_IFACE);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2018-05-09 06:35:03 +02:00
|
|
|
ri->ri_send = yang_get_default_enum("%s/version-send", RIP_IFACE);
|
|
|
|
ri->ri_receive = yang_get_default_enum("%s/version-receive", RIP_IFACE);
|
|
|
|
ri->v2_broadcast = yang_get_default_bool("%s/v2-broadcast", RIP_IFACE);
|
2016-11-10 15:55:09 +01:00
|
|
|
|
2019-02-25 21:18:13 +01:00
|
|
|
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
|
2018-08-01 01:31:09 +02:00
|
|
|
|
2019-02-25 21:18:13 +01:00
|
|
|
XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
|
2018-08-01 01:31:09 +02:00
|
|
|
|
2016-12-05 20:31:42 +01:00
|
|
|
ri->list[RIP_FILTER_IN] = NULL;
|
|
|
|
ri->list[RIP_FILTER_OUT] = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-12-05 20:31:42 +01:00
|
|
|
ri->prefix[RIP_FILTER_IN] = NULL;
|
|
|
|
ri->prefix[RIP_FILTER_OUT] = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-12-05 20:31:42 +01:00
|
|
|
ri->recv_badpackets = 0;
|
|
|
|
ri->recv_badroutes = 0;
|
|
|
|
ri->sent_updates = 0;
|
|
|
|
|
|
|
|
ri->passive = 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
ripd: split-horizon default differed between rip_interface_new and _reset
* rip_interface.c: Default for split_horizon_default differed between
rip_interface_new and rip_interface_reset, causing at least some issues
after interface events. See patchwork #604. Fix, and consolidate code.
(rip_interface_{reset,clean}) rename these to 'interface', as that's more
appropriate. Spin the ri specific bodies of these functions out to
rip_interface_{reset,clean} helpers. Factor out the overlaps, so
rip_interface_reset uses rip_interface_clean.
(rip_interface_new) just use rip_interface_reset.
* ripd.h: Update for (rip_interface_{reset,clean})
Reported by xufeng zhang, with a suggested fix on which this commit expands.
See patchwork #604. This commit addresses only the split-horizon
discrepency, issue #2. The other issue they reported, #1, is not addressed,
though suggested fix seems inappropriate.
Cc: xufeng.zhang@windriver.com
2016-05-25 15:47:00 +02:00
|
|
|
rip_interface_clean(ri);
|
2016-12-05 20:31:42 +01:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
int rip_if_down(struct interface *ifp)
|
|
|
|
{
|
2019-01-04 22:08:10 +01:00
|
|
|
struct rip *rip;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct route_node *rp;
|
|
|
|
struct rip_info *rinfo;
|
|
|
|
struct rip_interface *ri = NULL;
|
2014-07-18 08:13:18 +02:00
|
|
|
struct list *list = NULL;
|
|
|
|
struct listnode *listnode = NULL, *nextnode = NULL;
|
2019-01-04 22:08:10 +01:00
|
|
|
|
|
|
|
ri = ifp->info;
|
|
|
|
rip = ri->rip;
|
2002-12-13 21:15:29 +01:00
|
|
|
if (rip) {
|
2017-02-02 02:36:44 +01:00
|
|
|
for (rp = route_top(rip->table); rp; rp = route_next(rp))
|
|
|
|
if ((list = rp->info) != NULL)
|
|
|
|
for (ALL_LIST_ELEMENTS(list, listnode, nextnode,
|
|
|
|
rinfo))
|
2017-11-15 15:50:32 +01:00
|
|
|
if (rinfo->nh.ifindex == ifp->ifindex)
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_ecmp_delete(rip, rinfo);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-02-02 02:36:44 +01:00
|
|
|
if (ri->running) {
|
|
|
|
if (IS_RIP_DEBUG_EVENT)
|
|
|
|
zlog_debug("turn off %s", ifp->name);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-02-02 02:36:44 +01:00
|
|
|
/* Leave from multicast group. */
|
|
|
|
rip_multicast_leave(ifp, rip->sock);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-02-02 02:36:44 +01:00
|
|
|
ri->running = 0;
|
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-10-26 01:31:05 +02:00
|
|
|
static void rip_apply_address_add(struct connected *ifc)
|
|
|
|
{
|
2019-01-04 22:08:10 +01:00
|
|
|
struct rip_interface *ri = ifc->ifp->info;
|
|
|
|
struct rip *rip = ri->rip;
|
2003-05-25 16:49:19 +02:00
|
|
|
struct prefix_ipv4 address;
|
2017-11-15 17:19:06 +01:00
|
|
|
struct nexthop nh;
|
2003-05-25 16:49:19 +02:00
|
|
|
struct prefix *p;
|
|
|
|
|
|
|
|
if (!rip)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!if_is_up(ifc->ifp))
|
|
|
|
return;
|
|
|
|
|
|
|
|
p = ifc->address;
|
|
|
|
|
2016-10-01 21:43:17 +02:00
|
|
|
memset(&address, 0, sizeof(address));
|
2017-11-15 17:19:06 +01:00
|
|
|
memset(&nh, 0, sizeof(nh));
|
|
|
|
|
2003-05-25 16:49:19 +02:00
|
|
|
address.family = p->family;
|
2016-10-01 21:43:17 +02:00
|
|
|
address.prefix = p->u.prefix4;
|
|
|
|
address.prefixlen = p->prefixlen;
|
2003-05-25 16:49:19 +02:00
|
|
|
apply_mask_ipv4(&address);
|
|
|
|
|
2017-11-15 17:19:06 +01:00
|
|
|
nh.ifindex = ifc->ifp->ifindex;
|
|
|
|
nh.type = NEXTHOP_TYPE_IFINDEX;
|
|
|
|
|
2003-05-25 16:49:19 +02:00
|
|
|
/* Check if this interface is RIP enabled or not
|
|
|
|
or Check if this address's prefix is RIP enabled */
|
2019-01-04 22:08:10 +01:00
|
|
|
if ((rip_enable_if_lookup(rip, ifc->ifp->name) >= 0)
|
2003-05-25 16:49:19 +02:00
|
|
|
|| (rip_enable_network_lookup2(ifc) >= 0))
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_redistribute_add(rip, ZEBRA_ROUTE_CONNECT,
|
|
|
|
RIP_ROUTE_INTERFACE, &address, &nh, 0, 0,
|
|
|
|
0);
|
2003-05-25 16:49:19 +02:00
|
|
|
}
|
|
|
|
|
2019-05-03 21:42:59 +02:00
|
|
|
int rip_interface_address_add(ZAPI_CALLBACK_ARGS)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct connected *ifc;
|
|
|
|
struct prefix *p;
|
|
|
|
|
2004-05-08 13:48:26 +02:00
|
|
|
ifc = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD,
|
*: add VRF ID in the API message header
The API messages are used by zebra to exchange the interfaces, addresses,
routes and router-id information with its clients. To distinguish which
VRF the information belongs to, a new field "VRF ID" is added in the
message header. And hence the message version is increased to 3.
* The new field "VRF ID" in the message header:
Length (2 bytes)
Marker (1 byte)
Version (1 byte)
VRF ID (2 bytes, newly added)
Command (2 bytes)
- Client side:
- zclient_create_header() adds the VRF ID in the message header.
- zclient_read() extracts and validates the VRF ID from the header,
and passes the VRF ID to the callback functions registered to
the API messages.
- All relative functions are appended with a new parameter "vrf_id",
including all the callback functions.
- "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6".
Clients need to correctly set the VRF ID when using the API
functions zapi_ipv4_route() and zapi_ipv6_route().
- Till now all messages sent from a client have the default VRF ID
"0" in the header.
- The HELLO message is special, which is used as the heart-beat of
a client, and has no relation with VRF. The VRF ID in the HELLO
message header will always be 0 and ignored by zebra.
- Zebra side:
- zserv_create_header() adds the VRF ID in the message header.
- zebra_client_read() extracts and validates the VRF ID from the
header, and passes the VRF ID to the functions which process
the received messages.
- All relative functions are appended with a new parameter "vrf_id".
* Suppress the messages in a VRF which a client does not care:
Some clients may not care about the information in the VRF X, and
zebra should not send the messages in the VRF X to those clients.
Extra flags are used to indicate which VRF is registered by a client,
and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client
can unregister a VRF when it does not need any information in that
VRF.
A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF
will automatically register to that VRF.
- lib/vrf:
A new utility "VRF bit-map" is provided to manage the flags for
VRFs, one bit per VRF ID.
- Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a
bit-map;
- Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag
in the given bit-map, corresponding to the given VRF ID;
- Use vrf_bitmap_check() to test whether the flag, in the given
bit-map and for the given VRF ID, is set.
- Client side:
- In "struct zclient", the following flags are changed from
"u_char" to "vrf_bitmap_t":
redist[ZEBRA_ROUTE_MAX]
default_information
These flags are extended for each VRF, and controlled by the
clients themselves (or with the help of zclient_redistribute()
and zclient_redistribute_default()).
- Zebra side:
- In "struct zserv", the following flags are changed from
"u_char" to "vrf_bitmap_t":
redist[ZEBRA_ROUTE_MAX]
redist_default
ifinfo
ridinfo
These flags are extended for each VRF, as the VRF registration
flags. They are maintained on receiving a ZEBRA_XXX_ADD or
ZEBRA_XXX_DELETE message.
When sending an interface/address/route/router-id message in
a VRF to a client, if the corresponding VRF registration flag
is not set, this message will not be dropped by zebra.
- A new function zread_vrf_unregister() is introduced to process
the new command ZEBRA_VRF_UNREGISTER. All the VRF registration
flags are cleared for the requested VRF.
Those clients, who support only the default VRF, will never receive
a message in a non-default VRF, thanks to the filter in zebra.
* New callback for the event of successful connection to zebra:
- zclient_start() is splitted, keeping only the code of connecting
to zebra.
- Now zclient_init()=>zclient_connect()=>zclient_start() operations
are purely dealing with the connection to zbera.
- Once zebra is successfully connected, at the end of zclient_start(),
a new callback is used to inform the client about connection.
- Till now, in the callback of connect-to-zebra event, all clients
send messages to zebra to request the router-id/interface/routes
information in the default VRF.
Of corse in future the client can do anything it wants in this
callback. For example, it may send requests for both default VRF
and some non-default VRFs.
Signed-off-by: Feng Lu <lu.feng@6wind.com>
Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
Conflicts:
lib/zclient.h
lib/zebra.h
zebra/zserv.c
zebra/zserv.h
Conflicts:
bgpd/bgp_nexthop.c
bgpd/bgp_nht.c
bgpd/bgp_zebra.c
isisd/isis_zebra.c
lib/zclient.c
lib/zclient.h
lib/zebra.h
nhrpd/nhrp_interface.c
nhrpd/nhrp_route.c
nhrpd/nhrpd.h
ospf6d/ospf6_zebra.c
ospf6d/ospf6_zebra.h
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
pimd/pim_zebra.c
pimd/pim_zlookup.c
ripd/rip_zebra.c
ripngd/ripng_zebra.c
zebra/redistribute.c
zebra/rt_netlink.c
zebra/zebra_rnh.c
zebra/zebra_rnh.h
zebra/zserv.c
zebra/zserv.h
2014-10-16 03:52:36 +02:00
|
|
|
zclient->ibuf, vrf_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (ifc == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
p = ifc->address;
|
|
|
|
|
|
|
|
if (p->family == AF_INET) {
|
|
|
|
if (IS_RIP_DEBUG_ZEBRA)
|
2020-10-14 19:16:46 +02:00
|
|
|
zlog_debug("connected address %pFX is added", p);
|
2003-05-25 16:49:19 +02:00
|
|
|
|
2003-09-24 01:41:50 +02:00
|
|
|
rip_enable_apply(ifc->ifp);
|
2003-05-25 16:49:19 +02:00
|
|
|
/* Check if this prefix needs to be redistributed */
|
|
|
|
rip_apply_address_add(ifc);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-06-12 17:32:23 +02:00
|
|
|
hook_call(rip_ifaddr_add, ifc);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-05-25 16:49:19 +02:00
|
|
|
static void rip_apply_address_del(struct connected *ifc)
|
|
|
|
{
|
2019-01-04 22:08:10 +01:00
|
|
|
struct rip_interface *ri = ifc->ifp->info;
|
|
|
|
struct rip *rip = ri->rip;
|
2003-05-25 16:49:19 +02:00
|
|
|
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);
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_redistribute_delete(rip, ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
|
2003-05-25 16:49:19 +02:00
|
|
|
&address, ifc->ifp->ifindex);
|
|
|
|
}
|
|
|
|
|
2019-05-03 21:42:59 +02:00
|
|
|
int rip_interface_address_delete(ZAPI_CALLBACK_ARGS)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct connected *ifc;
|
|
|
|
struct prefix *p;
|
|
|
|
|
2016-06-12 17:32:23 +02:00
|
|
|
ifc = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE,
|
|
|
|
zclient->ibuf, vrf_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-05-25 16:49:19 +02:00
|
|
|
if (ifc) {
|
|
|
|
p = ifc->address;
|
|
|
|
if (p->family == AF_INET) {
|
|
|
|
if (IS_RIP_DEBUG_ZEBRA)
|
2020-10-14 19:16:46 +02:00
|
|
|
zlog_debug("connected address %pFX is deleted",
|
|
|
|
p);
|
2003-05-25 16:49:19 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
hook_call(rip_ifaddr_del, ifc);
|
|
|
|
|
|
|
|
/* Chech wether this prefix needs to be removed */
|
|
|
|
rip_apply_address_del(ifc);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-10-30 01:16:28 +01:00
|
|
|
connected_free(&ifc);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Check interface is enabled by network statement. */
|
2003-05-25 16:49:19 +02:00
|
|
|
/* Check wether the interface has at least a connected prefix that
|
|
|
|
* is within the ripng_enable_network table. */
|
|
|
|
static int rip_enable_network_lookup_if(struct interface *ifp)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2019-01-04 22:08:10 +01:00
|
|
|
struct rip_interface *ri = ifp->info;
|
|
|
|
struct rip *rip = ri->rip;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct connected *connected;
|
|
|
|
struct prefix_ipv4 address;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
if (!rip)
|
|
|
|
return -1;
|
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) {
|
|
|
|
struct prefix *p;
|
2018-09-12 12:55:31 +02:00
|
|
|
struct route_node *n;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
p = connected->address;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
if (p->family == AF_INET) {
|
|
|
|
address.family = AF_INET;
|
|
|
|
address.prefix = p->u.prefix4;
|
|
|
|
address.prefixlen = IPV4_MAX_BITLEN;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
n = route_node_match(rip->enable_network,
|
2018-09-12 12:55:31 +02:00
|
|
|
(struct prefix *)&address);
|
|
|
|
if (n) {
|
|
|
|
route_unlock_node(n);
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2003-05-25 16:49:19 +02:00
|
|
|
/* Check wether connected is within the ripng_enable_network table. */
|
2019-01-04 22:08:10 +01:00
|
|
|
static int rip_enable_network_lookup2(struct connected *connected)
|
2003-05-25 16:49:19 +02:00
|
|
|
{
|
2019-01-04 22:08:10 +01:00
|
|
|
struct rip_interface *ri = connected->ifp->info;
|
|
|
|
struct rip *rip = ri->rip;
|
2003-05-25 16:49:19 +02:00
|
|
|
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
|
2019-01-04 22:08:10 +01:00
|
|
|
* rip->enable_network */
|
|
|
|
node = route_node_match(rip->enable_network,
|
2003-05-25 16:49:19 +02:00
|
|
|
(struct prefix *)&address);
|
|
|
|
|
|
|
|
if (node) {
|
|
|
|
route_unlock_node(node);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Add RIP enable network. */
|
2019-01-04 22:08:10 +01:00
|
|
|
int rip_enable_network_add(struct rip *rip, struct prefix *p)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct route_node *node;
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
node = route_node_get(rip->enable_network, p);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (node->info) {
|
|
|
|
route_unlock_node(node);
|
2018-05-09 06:35:00 +02:00
|
|
|
return NB_ERR_INCONSISTENCY;
|
2002-12-13 21:15:29 +01:00
|
|
|
} else
|
2015-05-20 03:29:14 +02:00
|
|
|
node->info = (void *)1;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-05-25 16:49:19 +02:00
|
|
|
/* XXX: One should find a better solution than a generic one */
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_enable_apply_all(rip);
|
2003-05-25 16:49:19 +02:00
|
|
|
|
2018-05-09 06:35:00 +02:00
|
|
|
return NB_OK;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete RIP enable network. */
|
2019-01-04 22:08:10 +01:00
|
|
|
int rip_enable_network_delete(struct rip *rip, struct prefix *p)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct route_node *node;
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
node = route_node_lookup(rip->enable_network, p);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (node) {
|
|
|
|
node->info = NULL;
|
|
|
|
|
|
|
|
/* Unlock info lock. */
|
|
|
|
route_unlock_node(node);
|
|
|
|
|
|
|
|
/* Unlock lookup lock. */
|
|
|
|
route_unlock_node(node);
|
|
|
|
|
2003-05-25 16:49:19 +02:00
|
|
|
/* XXX: One should find a better solution than a generic one */
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_enable_apply_all(rip);
|
2003-05-25 16:49:19 +02:00
|
|
|
|
2018-05-09 06:35:00 +02:00
|
|
|
return NB_OK;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2018-05-09 06:35:00 +02:00
|
|
|
|
|
|
|
return NB_ERR_INCONSISTENCY;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check interface is enabled by ifname statement. */
|
2019-01-04 22:08:10 +01:00
|
|
|
static int rip_enable_if_lookup(struct rip *rip, const char *ifname)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-10-08 08:36:38 +02:00
|
|
|
unsigned int i;
|
2002-12-13 21:15:29 +01:00
|
|
|
char *str;
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
if (!rip)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
for (i = 0; i < vector_active(rip->enable_interface); i++)
|
|
|
|
if ((str = vector_slot(rip->enable_interface, i)) != NULL)
|
2002-12-13 21:15:29 +01:00
|
|
|
if (strcmp(str, ifname) == 0)
|
|
|
|
return i;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add interface to rip_enable_if. */
|
2019-01-04 22:08:10 +01:00
|
|
|
int rip_enable_if_add(struct rip *rip, const char *ifname)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
ret = rip_enable_if_lookup(rip, ifname);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret >= 0)
|
2018-05-09 06:35:00 +02:00
|
|
|
return NB_ERR_INCONSISTENCY;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
vector_set(rip->enable_interface,
|
2018-08-01 01:31:09 +02:00
|
|
|
XSTRDUP(MTYPE_RIP_INTERFACE_STRING, ifname));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_enable_apply_all(rip); /* TODOVJ */
|
2003-05-25 16:49:19 +02:00
|
|
|
|
2018-05-09 06:35:00 +02:00
|
|
|
return NB_OK;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete interface from rip_enable_if. */
|
2019-01-04 22:08:10 +01:00
|
|
|
int rip_enable_if_delete(struct rip *rip, const char *ifname)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int index;
|
|
|
|
char *str;
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
index = rip_enable_if_lookup(rip, ifname);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (index < 0)
|
2018-05-09 06:35:00 +02:00
|
|
|
return NB_ERR_INCONSISTENCY;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
str = vector_slot(rip->enable_interface, index);
|
2018-08-01 01:31:09 +02:00
|
|
|
XFREE(MTYPE_RIP_INTERFACE_STRING, str);
|
2019-01-04 22:08:10 +01:00
|
|
|
vector_unset(rip->enable_interface, index);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_enable_apply_all(rip); /* TODOVJ */
|
2003-05-25 16:49:19 +02:00
|
|
|
|
2018-05-09 06:35:00 +02:00
|
|
|
return NB_OK;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Join to multicast group and send request to the interface. */
|
|
|
|
static int rip_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. */
|
2019-01-04 22:08:10 +01:00
|
|
|
if (rip_multicast_join(ifp, ri->rip->sock) < 0) {
|
2018-09-13 21:34:28 +02:00
|
|
|
flog_err_sys(EC_LIB_SOCKET,
|
2018-08-06 18:36:50 +02:00
|
|
|
"multicast join failed, interface %s not running",
|
|
|
|
ifp->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set running flag. */
|
2003-05-25 16:49:19 +02:00
|
|
|
ri->running = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-10-26 01:31:05 +02:00
|
|
|
/* Send RIP request to the interface. */
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
rip_request_interface(ifp);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
static void rip_connect_set(struct interface *ifp, int set)
|
|
|
|
{
|
2019-01-04 22:08:10 +01:00
|
|
|
struct rip_interface *ri = ifp->info;
|
|
|
|
struct rip *rip = ri->rip;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct connected *connected;
|
|
|
|
struct prefix_ipv4 address;
|
2017-11-15 17:19:06 +01:00
|
|
|
struct nexthop nh;
|
|
|
|
|
|
|
|
memset(&nh, 0, sizeof(nh));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) {
|
|
|
|
struct prefix *p;
|
|
|
|
p = connected->address;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
if (p->family != AF_INET)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
address.family = AF_INET;
|
|
|
|
address.prefix = p->u.prefix4;
|
|
|
|
address.prefixlen = p->prefixlen;
|
|
|
|
apply_mask_ipv4(&address);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-11-15 17:19:06 +01:00
|
|
|
nh.ifindex = connected->ifp->ifindex;
|
|
|
|
nh.type = NEXTHOP_TYPE_IFINDEX;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
if (set) {
|
|
|
|
/* Check once more wether this prefix is within a
|
|
|
|
* "network IF_OR_PREF" one */
|
2019-01-04 22:08:10 +01:00
|
|
|
if ((rip_enable_if_lookup(rip, connected->ifp->name)
|
|
|
|
>= 0)
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|| (rip_enable_network_lookup2(connected) >= 0))
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_redistribute_add(rip, ZEBRA_ROUTE_CONNECT,
|
2018-03-06 20:02:52 +01:00
|
|
|
RIP_ROUTE_INTERFACE,
|
|
|
|
&address, &nh, 0, 0, 0);
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
} else {
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_redistribute_delete(rip, ZEBRA_ROUTE_CONNECT,
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
RIP_ROUTE_INTERFACE, &address,
|
|
|
|
connected->ifp->ifindex);
|
2019-01-04 22:08:10 +01:00
|
|
|
if (rip_redistribute_check(rip, ZEBRA_ROUTE_CONNECT))
|
|
|
|
rip_redistribute_add(rip, ZEBRA_ROUTE_CONNECT,
|
2018-03-06 20:02:52 +01:00
|
|
|
RIP_ROUTE_REDISTRIBUTE,
|
|
|
|
&address, &nh, 0, 0, 0);
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
}
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Update interface status. */
|
|
|
|
void rip_enable_apply(struct interface *ifp)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct rip_interface *ri = NULL;
|
|
|
|
|
|
|
|
/* Check interface. */
|
2002-12-13 22:03:13 +01:00
|
|
|
if (!if_is_operative(ifp))
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
ri = ifp->info;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Check network configuration. */
|
2003-05-25 16:49:19 +02:00
|
|
|
ret = rip_enable_network_lookup_if(ifp);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* If the interface is matched. */
|
|
|
|
if (ret > 0)
|
|
|
|
ri->enable_network = 1;
|
|
|
|
else
|
|
|
|
ri->enable_network = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Check interface name configuration. */
|
2019-01-04 22:08:10 +01:00
|
|
|
ret = rip_enable_if_lookup(ri->rip, ifp->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret >= 0)
|
|
|
|
ri->enable_interface = 1;
|
|
|
|
else
|
|
|
|
ri->enable_interface = 0;
|
|
|
|
|
|
|
|
/* any interface MUST have an IPv4 address */
|
2017-04-25 00:33:25 +02:00
|
|
|
if (!rip_if_ipv4_address_check(ifp)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
ri->enable_network = 0;
|
2017-04-25 00:33:25 +02:00
|
|
|
ri->enable_interface = 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Update running status of the interface. */
|
|
|
|
if (ri->enable_network || ri->enable_interface) {
|
2018-07-02 20:51:15 +02:00
|
|
|
if (IS_RIP_DEBUG_EVENT)
|
|
|
|
zlog_debug("turn on %s", ifp->name);
|
|
|
|
|
|
|
|
/* Add interface wake up thread. */
|
|
|
|
thread_add_timer(master, rip_interface_wakeup, ifp, 1,
|
|
|
|
&ri->t_wakeup);
|
|
|
|
rip_connect_set(ifp, 1);
|
|
|
|
} else if (ri->running) {
|
|
|
|
/* 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);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-07-02 20:51:15 +02:00
|
|
|
rip_connect_set(ifp, 0);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Apply network configuration to all interface. */
|
2019-01-04 22:08:10 +01:00
|
|
|
static void rip_enable_apply_all(struct rip *rip)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct interface *ifp;
|
|
|
|
|
|
|
|
/* Check each interface. */
|
2019-01-04 22:08:10 +01:00
|
|
|
FOR_ALL_INTERFACES (rip->vrf, ifp)
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
rip_enable_apply(ifp);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
int rip_neighbor_lookup(struct rip *rip, struct sockaddr_in *from)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
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. */
|
2019-01-04 22:08:10 +01:00
|
|
|
int rip_neighbor_add(struct rip *rip, struct prefix_ipv4 *p)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct route_node *node;
|
|
|
|
|
|
|
|
node = route_node_get(rip->neighbor, (struct prefix *)p);
|
|
|
|
|
|
|
|
if (node->info)
|
2018-05-09 06:34:59 +02:00
|
|
|
return NB_ERR_INCONSISTENCY;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
node->info = rip->neighbor;
|
|
|
|
|
2018-05-09 06:34:59 +02:00
|
|
|
return NB_OK;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete RIP neighbor from the neighbor tree. */
|
2019-01-04 22:08:10 +01:00
|
|
|
int rip_neighbor_delete(struct rip *rip, struct prefix_ipv4 *p)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct route_node *node;
|
|
|
|
|
|
|
|
/* Lock for look up. */
|
|
|
|
node = route_node_lookup(rip->neighbor, (struct prefix *)p);
|
|
|
|
if (!node)
|
2018-05-09 06:34:59 +02:00
|
|
|
return NB_ERR_INCONSISTENCY;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
node->info = NULL;
|
|
|
|
|
|
|
|
/* Unlock lookup lock. */
|
|
|
|
route_unlock_node(node);
|
|
|
|
|
|
|
|
/* Unlock real neighbor information lock. */
|
|
|
|
route_unlock_node(node);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-05-09 06:34:59 +02:00
|
|
|
return NB_OK;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear all network and neighbor configuration. */
|
2019-01-04 22:08:10 +01:00
|
|
|
void rip_clean_network(struct rip *rip)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-10-08 08:36:38 +02:00
|
|
|
unsigned int i;
|
2002-12-13 21:15:29 +01:00
|
|
|
char *str;
|
|
|
|
struct route_node *rn;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
/* rip->enable_network. */
|
|
|
|
for (rn = route_top(rip->enable_network); rn; rn = route_next(rn))
|
2002-12-13 21:15:29 +01:00
|
|
|
if (rn->info) {
|
|
|
|
rn->info = NULL;
|
|
|
|
route_unlock_node(rn);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
/* rip->enable_interface. */
|
|
|
|
for (i = 0; i < vector_active(rip->enable_interface); i++)
|
|
|
|
if ((str = vector_slot(rip->enable_interface, i)) != NULL) {
|
2018-08-01 01:31:09 +02:00
|
|
|
XFREE(MTYPE_RIP_INTERFACE_STRING, str);
|
2019-01-04 22:08:10 +01:00
|
|
|
vector_slot(rip->enable_interface, i) = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Utility function for looking up passive interface settings. */
|
2019-01-04 22:08:10 +01:00
|
|
|
static int rip_passive_nondefault_lookup(struct rip *rip, const char *ifname)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-10-08 08:36:38 +02:00
|
|
|
unsigned int i;
|
2002-12-13 21:15:29 +01:00
|
|
|
char *str;
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
for (i = 0; i < vector_active(rip->passive_nondefault); i++)
|
|
|
|
if ((str = vector_slot(rip->passive_nondefault, i)) != NULL)
|
2002-12-13 21:15:29 +01:00
|
|
|
if (strcmp(str, ifname) == 0)
|
|
|
|
return i;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
static void rip_passive_interface_apply(struct interface *ifp)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2019-01-04 22:08:10 +01:00
|
|
|
struct rip *rip;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct rip_interface *ri;
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
ri = ifp->info;
|
|
|
|
rip = ri->rip;
|
2018-05-09 06:35:00 +02:00
|
|
|
if (rip == NULL)
|
|
|
|
return;
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
ri->passive = ((rip_passive_nondefault_lookup(rip, ifp->name) < 0)
|
2018-05-09 06:35:00 +02:00
|
|
|
? rip->passive_default
|
|
|
|
: !rip->passive_default);
|
2003-06-07 03:04:45 +02:00
|
|
|
|
|
|
|
if (IS_RIP_DEBUG_ZEBRA)
|
2004-12-08 20:24:06 +01:00
|
|
|
zlog_debug("interface %s: passive = %d", ifp->name,
|
|
|
|
ri->passive);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
static void rip_passive_interface_apply_all(struct rip *rip)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct interface *ifp;
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
FOR_ALL_INTERFACES (rip->vrf, ifp)
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
rip_passive_interface_apply(ifp);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Passive interface. */
|
2019-01-04 22:08:10 +01:00
|
|
|
int rip_passive_nondefault_set(struct rip *rip, const char *ifname)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2019-01-04 22:08:10 +01:00
|
|
|
if (rip_passive_nondefault_lookup(rip, ifname) >= 0)
|
2018-05-09 06:35:00 +02:00
|
|
|
/*
|
|
|
|
* Don't return an error, this can happen after changing
|
|
|
|
* 'passive-default'.
|
|
|
|
*/
|
|
|
|
return NB_OK;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
vector_set(rip->passive_nondefault,
|
2018-08-01 01:31:09 +02:00
|
|
|
XSTRDUP(MTYPE_RIP_INTERFACE_STRING, ifname));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_passive_interface_apply_all(rip);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2018-05-09 06:35:00 +02:00
|
|
|
return NB_OK;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
int rip_passive_nondefault_unset(struct rip *rip, const char *ifname)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
char *str;
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
i = rip_passive_nondefault_lookup(rip, ifname);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (i < 0)
|
2018-05-09 06:35:00 +02:00
|
|
|
/*
|
|
|
|
* Don't return an error, this can happen after changing
|
|
|
|
* 'passive-default'.
|
|
|
|
*/
|
|
|
|
return NB_OK;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
str = vector_slot(rip->passive_nondefault, i);
|
2018-08-01 01:31:09 +02:00
|
|
|
XFREE(MTYPE_RIP_INTERFACE_STRING, str);
|
2019-01-04 22:08:10 +01:00
|
|
|
vector_unset(rip->passive_nondefault, i);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_passive_interface_apply_all(rip);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2018-05-09 06:35:00 +02:00
|
|
|
return NB_OK;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Free all configured RIP passive-interface settings. */
|
2019-01-04 22:08:10 +01:00
|
|
|
void rip_passive_nondefault_clean(struct rip *rip)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-10-08 08:36:38 +02:00
|
|
|
unsigned int i;
|
2002-12-13 21:15:29 +01:00
|
|
|
char *str;
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
for (i = 0; i < vector_active(rip->passive_nondefault); i++)
|
|
|
|
if ((str = vector_slot(rip->passive_nondefault, i)) != NULL) {
|
2018-08-01 01:31:09 +02:00
|
|
|
XFREE(MTYPE_RIP_INTERFACE_STRING, str);
|
2019-01-04 22:08:10 +01:00
|
|
|
vector_slot(rip->passive_nondefault, i) = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_passive_interface_apply_all(rip);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Write rip configuration of each interface. */
|
|
|
|
static int rip_interface_config_write(struct vty *vty)
|
|
|
|
{
|
2019-01-04 22:08:10 +01:00
|
|
|
struct vrf *vrf;
|
2018-05-09 06:35:03 +02:00
|
|
|
int write = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
|
|
|
struct interface *ifp;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
FOR_ALL_INTERFACES (vrf, ifp) {
|
|
|
|
struct lyd_node *dnode;
|
|
|
|
|
|
|
|
dnode = yang_dnode_get(
|
|
|
|
running_config->dnode,
|
|
|
|
"/frr-interface:lib/interface[name='%s'][vrf='%s']",
|
|
|
|
ifp->name, vrf->name);
|
|
|
|
if (dnode == NULL)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
write = 1;
|
|
|
|
nb_cli_show_dnode_cmds(vty, dnode, false);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2018-05-09 06:35:03 +02:00
|
|
|
|
|
|
|
return write;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
int rip_show_network_config(struct vty *vty, struct rip *rip)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
2003-05-25 16:49:19 +02:00
|
|
|
unsigned int i;
|
2002-12-13 21:15:29 +01:00
|
|
|
char *ifname;
|
|
|
|
struct route_node *node;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-05-25 16:49:19 +02:00
|
|
|
/* Network type RIP enable interface statement. */
|
2019-01-04 22:08:10 +01:00
|
|
|
for (node = route_top(rip->enable_network); node;
|
2002-12-13 21:15:29 +01:00
|
|
|
node = route_next(node))
|
|
|
|
if (node->info)
|
2018-05-09 06:35:00 +02:00
|
|
|
vty_out(vty, " %s/%u\n",
|
2003-05-25 16:49:19 +02:00
|
|
|
inet_ntoa(node->p.u.prefix4),
|
2017-07-13 17:49:13 +02:00
|
|
|
node->p.prefixlen);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-07-13 17:49:13 +02:00
|
|
|
/* Interface name RIP enable statement. */
|
2019-01-04 22:08:10 +01:00
|
|
|
for (i = 0; i < vector_active(rip->enable_interface); i++)
|
|
|
|
if ((ifname = vector_slot(rip->enable_interface, i)) != NULL)
|
2018-05-09 06:35:00 +02:00
|
|
|
vty_out(vty, " %s\n", ifname);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-07-13 17:49:13 +02:00
|
|
|
/* RIP neighbors listing. */
|
2002-12-13 21:15:29 +01:00
|
|
|
for (node = route_top(rip->neighbor); node; node = route_next(node))
|
|
|
|
if (node->info)
|
2018-05-09 06:35:00 +02:00
|
|
|
vty_out(vty, " %s\n", inet_ntoa(node->p.u.prefix4));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2017-06-21 05:10:57 +02:00
|
|
|
return 0;
|
2004-06-07 00:06:33 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-09-08 22:31:43 +02:00
|
|
|
static int rip_interface_config_write(struct vty *vty);
|
2002-12-13 21:15:29 +01:00
|
|
|
static struct cmd_node interface_node = {
|
2018-09-09 00:15:50 +02:00
|
|
|
.name = "interface",
|
2018-09-08 21:46:23 +02:00
|
|
|
.node = INTERFACE_NODE,
|
2018-09-08 23:15:09 +02:00
|
|
|
.parent_node = CONFIG_NODE,
|
2018-09-08 21:46:23 +02:00
|
|
|
.prompt = "%s(config-if)# ",
|
2018-09-08 22:31:43 +02:00
|
|
|
.config_write = rip_interface_config_write,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
|
|
|
|
2019-01-04 22:08:10 +01:00
|
|
|
void rip_interface_sync(struct interface *ifp)
|
|
|
|
{
|
|
|
|
struct vrf *vrf;
|
|
|
|
|
2019-06-24 01:46:39 +02:00
|
|
|
vrf = vrf_lookup_by_id(ifp->vrf_id);
|
2019-01-04 22:08:10 +01:00
|
|
|
if (vrf) {
|
|
|
|
struct rip_interface *ri;
|
|
|
|
|
|
|
|
ri = ifp->info;
|
|
|
|
if (ri)
|
|
|
|
ri->rip = vrf->info;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Called when interface structure allocated. */
|
|
|
|
static int rip_interface_new_hook(struct interface *ifp)
|
|
|
|
{
|
|
|
|
ifp->info = rip_interface_new();
|
2019-01-04 22:08:10 +01:00
|
|
|
rip_interface_sync(ifp);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Called when interface structure deleted. */
|
|
|
|
static int rip_interface_delete_hook(struct interface *ifp)
|
|
|
|
{
|
2018-07-09 15:46:40 +02:00
|
|
|
rip_interface_reset(ifp->info);
|
2002-12-13 21:15:29 +01:00
|
|
|
XFREE(MTYPE_RIP_INTERFACE, ifp->info);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate and initialize interface vector. */
|
2005-10-26 01:31:05 +02:00
|
|
|
void rip_if_init(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
/* Default initial size of interface vector. */
|
2017-08-08 10:50:43 +02:00
|
|
|
hook_register_prio(if_add, 0, rip_interface_new_hook);
|
|
|
|
hook_register_prio(if_del, 0, rip_interface_delete_hook);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Install interface node. */
|
2018-09-08 22:31:43 +02:00
|
|
|
install_node(&interface_node);
|
2016-11-16 07:00:52 +01:00
|
|
|
if_cmd_init();
|
2019-09-18 22:20:04 +02:00
|
|
|
if_zapi_callbacks(rip_ifp_create, rip_ifp_up,
|
|
|
|
rip_ifp_down, rip_ifp_destroy);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|