mirror of
https://git.proxmox.com/git/mirror_frr
synced 2026-02-01 18:56:52 +00:00
zebra: add srcdest support to rib
Add srcdest support to the zebra rib and to the kernel and redistribution interfaces. Signed-off-by: Christian Franke <chris@opensourcerouting.org>
This commit is contained in:
parent
a27428eb71
commit
0573778371
@ -32,7 +32,8 @@
|
||||
#include "zebra/rt_netlink.h"
|
||||
#include "zebra/rib.h"
|
||||
|
||||
int kernel_route_rib (struct prefix *a, struct rib *old, struct rib *new) { return 0; }
|
||||
int kernel_route_rib (struct prefix *a, struct prefix *b,
|
||||
struct rib *old, struct rib *new) { return 0; }
|
||||
|
||||
int kernel_address_add_ipv4 (struct interface *a, struct connected *b)
|
||||
{
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include "linklist.h"
|
||||
#include "log.h"
|
||||
#include "vrf.h"
|
||||
#include "srcdest_table.h"
|
||||
|
||||
#include "zebra/rib.h"
|
||||
#include "zebra/zserv.h"
|
||||
@ -98,7 +99,7 @@ zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id)
|
||||
RNODE_FOREACH_RIB (rn, newrib)
|
||||
if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
|
||||
&& newrib->distance != DISTANCE_INFINITY)
|
||||
zsend_redistribute_route (1, client, &rn->p, newrib);
|
||||
zsend_redistribute_route (1, client, &rn->p, NULL, newrib);
|
||||
|
||||
route_unlock_node (rn);
|
||||
}
|
||||
@ -122,12 +123,15 @@ zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t v
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, newrib)
|
||||
{
|
||||
struct prefix *dst_p, *src_p;
|
||||
srcdest_rnode_prefixes(rn, &dst_p, &src_p);
|
||||
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug("%s: checking: selected=%d, type=%d, distance=%d, "
|
||||
"zebra_check_addr=%d", __func__,
|
||||
CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED),
|
||||
newrib->type, newrib->distance,
|
||||
zebra_check_addr (&rn->p));
|
||||
zebra_check_addr (dst_p));
|
||||
|
||||
if (! CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED))
|
||||
continue;
|
||||
@ -136,10 +140,10 @@ zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t v
|
||||
continue;
|
||||
if (newrib->distance == DISTANCE_INFINITY)
|
||||
continue;
|
||||
if (! zebra_check_addr (&rn->p))
|
||||
if (! zebra_check_addr (dst_p))
|
||||
continue;
|
||||
|
||||
zsend_redistribute_route (1, client, &rn->p, newrib);
|
||||
zsend_redistribute_route (1, client, dst_p, src_p, newrib);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -147,7 +151,8 @@ zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t v
|
||||
/* Either advertise a route for redistribution to registered clients or */
|
||||
/* withdraw redistribution if add cannot be done for client */
|
||||
void
|
||||
redistribute_update (struct prefix *p, struct rib *rib, struct rib *prev_rib)
|
||||
redistribute_update (struct prefix *p, struct prefix *src_p,
|
||||
struct rib *rib, struct rib *prev_rib)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct zserv *client;
|
||||
@ -186,7 +191,7 @@ redistribute_update (struct prefix *p, struct rib *rib, struct rib *prev_rib)
|
||||
|
||||
if (send_redistribute)
|
||||
{
|
||||
zsend_redistribute_route (1, client, p, rib);
|
||||
zsend_redistribute_route (1, client, p, src_p, rib);
|
||||
}
|
||||
else if (prev_rib &&
|
||||
((rib->instance &&
|
||||
@ -194,13 +199,13 @@ redistribute_update (struct prefix *p, struct rib *rib, struct rib *prev_rib)
|
||||
rib->instance)) ||
|
||||
vrf_bitmap_check (client->redist[afi][prev_rib->type], rib->vrf_id)))
|
||||
{
|
||||
zsend_redistribute_route (0, client, p, prev_rib);
|
||||
zsend_redistribute_route (0, client, p, src_p, prev_rib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
redistribute_delete (struct prefix *p, struct rib *rib)
|
||||
redistribute_delete (struct prefix *p, struct prefix *src_p, struct rib *rib)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct zserv *client;
|
||||
@ -235,7 +240,7 @@ redistribute_delete (struct prefix *p, struct rib *rib)
|
||||
rib->instance)) ||
|
||||
vrf_bitmap_check (client->redist[afi][rib->type], rib->vrf_id))
|
||||
{
|
||||
zsend_redistribute_route (0, client, p, rib);
|
||||
zsend_redistribute_route (0, client, p, src_p, rib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,8 +36,9 @@ extern void zebra_redistribute_default_add (int, struct zserv *, int,
|
||||
extern void zebra_redistribute_default_delete (int, struct zserv *, int,
|
||||
struct zebra_vrf *zvrf);
|
||||
|
||||
extern void redistribute_update (struct prefix *, struct rib *, struct rib *);
|
||||
extern void redistribute_delete (struct prefix *, struct rib *);
|
||||
extern void redistribute_update (struct prefix *, struct prefix *,
|
||||
struct rib *, struct rib *);
|
||||
extern void redistribute_delete (struct prefix *, struct prefix *, struct rib *);
|
||||
|
||||
extern void zebra_interface_up_update (struct interface *);
|
||||
extern void zebra_interface_down_update (struct interface *);
|
||||
|
||||
@ -39,9 +39,10 @@ void zebra_redistribute_default_delete (int a, struct zserv *b, int c,
|
||||
struct zebra_vrf *zvrf)
|
||||
{ return; }
|
||||
|
||||
void redistribute_update (struct prefix *a, struct rib *b, struct rib *c)
|
||||
void redistribute_update (struct prefix *a, struct prefix *b,
|
||||
struct rib *c, struct rib *d)
|
||||
{ return; }
|
||||
void redistribute_delete (struct prefix *a, struct rib *b)
|
||||
void redistribute_delete (struct prefix *a, struct prefix *b, struct rib *c)
|
||||
{ return; }
|
||||
|
||||
void zebra_interface_up_update (struct interface *a)
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
#include "vrf.h"
|
||||
#include "if.h"
|
||||
#include "mpls.h"
|
||||
#include "srcdest_table.h"
|
||||
|
||||
#define DISTANCE_INFINITY 255
|
||||
#define ZEBRA_KERNEL_TABLE_MAX 252 /* support for no more than this rt tables */
|
||||
@ -311,8 +312,9 @@ extern enum multicast_mode multicast_mode_ipv4_get (void);
|
||||
extern int nexthop_has_fib_child(struct nexthop *);
|
||||
extern void rib_lookup_and_dump (struct prefix_ipv4 *, vrf_id_t);
|
||||
extern void rib_lookup_and_pushup (struct prefix_ipv4 *, vrf_id_t);
|
||||
#define rib_dump(prefix ,rib) _rib_dump(__func__, prefix, rib)
|
||||
#define rib_dump(prefix, src, rib) _rib_dump(__func__, prefix, src, rib)
|
||||
extern void _rib_dump (const char *,
|
||||
union prefix46constptr,
|
||||
union prefix46constptr, const struct rib *);
|
||||
extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *,
|
||||
vrf_id_t);
|
||||
@ -444,7 +446,7 @@ rib_dest_af (rib_dest_t *dest)
|
||||
static inline struct route_table *
|
||||
rib_dest_table (rib_dest_t *dest)
|
||||
{
|
||||
return dest->rnode->table;
|
||||
return srcdest_rnode_table(dest->rnode);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -29,7 +29,8 @@
|
||||
#include "zebra/zebra_ns.h"
|
||||
#include "zebra/zebra_mpls.h"
|
||||
|
||||
extern int kernel_route_rib (struct prefix *, struct rib *, struct rib *);
|
||||
extern int kernel_route_rib (struct prefix *, struct prefix *,
|
||||
struct rib *, struct rib *);
|
||||
|
||||
extern int kernel_address_add_ipv4 (struct interface *, struct connected *);
|
||||
extern int kernel_address_delete_ipv4 (struct interface *, struct connected *);
|
||||
|
||||
@ -134,18 +134,20 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
struct rtattr *tb[RTA_MAX + 1];
|
||||
u_char flags = 0;
|
||||
struct prefix p;
|
||||
struct prefix_ipv6 src_p;
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
|
||||
char anyaddr[16] = { 0 };
|
||||
|
||||
int index;
|
||||
int index = 0;
|
||||
int table;
|
||||
int metric;
|
||||
int metric = 0;
|
||||
u_int32_t mtu = 0;
|
||||
|
||||
void *dest;
|
||||
void *gate;
|
||||
void *src;
|
||||
void *dest = NULL;
|
||||
void *gate = NULL;
|
||||
void *prefsrc = NULL; /* IPv4 preferred source host address */
|
||||
void *src = NULL; /* IPv6 srcdest source prefix */
|
||||
|
||||
rtm = NLMSG_DATA (h);
|
||||
|
||||
@ -168,9 +170,6 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
if (rtm->rtm_protocol == RTPROT_KERNEL)
|
||||
return 0;
|
||||
|
||||
if (rtm->rtm_src_len != 0)
|
||||
return 0;
|
||||
|
||||
/* We don't care about change notifications for the MPLS table. */
|
||||
/* TODO: Revisit this. */
|
||||
if (rtm->rtm_family == AF_MPLS)
|
||||
@ -195,12 +194,6 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
if (rtm->rtm_protocol == RTPROT_ZEBRA)
|
||||
flags |= ZEBRA_FLAG_SELFROUTE;
|
||||
|
||||
index = 0;
|
||||
metric = 0;
|
||||
dest = NULL;
|
||||
gate = NULL;
|
||||
src = NULL;
|
||||
|
||||
if (tb[RTA_OIF])
|
||||
index = *(int *) RTA_DATA (tb[RTA_OIF]);
|
||||
|
||||
@ -209,8 +202,13 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
else
|
||||
dest = anyaddr;
|
||||
|
||||
if (tb[RTA_SRC])
|
||||
src = RTA_DATA (tb[RTA_SRC]);
|
||||
else
|
||||
src = anyaddr;
|
||||
|
||||
if (tb[RTA_PREFSRC])
|
||||
src = RTA_DATA (tb[RTA_PREFSRC]);
|
||||
prefsrc = RTA_DATA (tb[RTA_PREFSRC]);
|
||||
|
||||
if (tb[RTA_GATEWAY])
|
||||
gate = RTA_DATA (tb[RTA_GATEWAY]);
|
||||
@ -236,9 +234,12 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
memcpy (&p.u.prefix4, dest, 4);
|
||||
p.prefixlen = rtm->rtm_dst_len;
|
||||
|
||||
if (rtm->rtm_src_len != 0)
|
||||
return 0;
|
||||
|
||||
if (!tb[RTA_MULTIPATH])
|
||||
rib_add (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
|
||||
0, flags, &p, NULL, gate, src, index,
|
||||
0, flags, &p, NULL, gate, prefsrc, index,
|
||||
table, metric, mtu, 0);
|
||||
else
|
||||
{
|
||||
@ -280,9 +281,9 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
if (gate)
|
||||
{
|
||||
if (index)
|
||||
rib_nexthop_ipv4_ifindex_add (rib, gate, src, index);
|
||||
rib_nexthop_ipv4_ifindex_add (rib, gate, prefsrc, index);
|
||||
else
|
||||
rib_nexthop_ipv4_add (rib, gate, src);
|
||||
rib_nexthop_ipv4_add (rib, gate, prefsrc);
|
||||
}
|
||||
else
|
||||
rib_nexthop_ifindex_add (rib, index);
|
||||
@ -305,8 +306,12 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
memcpy (&p.u.prefix6, dest, 16);
|
||||
p.prefixlen = rtm->rtm_dst_len;
|
||||
|
||||
src_p.family = AF_INET6;
|
||||
memcpy (&src_p.prefix, src, 16);
|
||||
src_p.prefixlen = rtm->rtm_src_len;
|
||||
|
||||
rib_add (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
|
||||
0, flags, &p, NULL, gate, src, index,
|
||||
0, flags, &p, &src_p, gate, prefsrc, index,
|
||||
table, metric, mtu, 0);
|
||||
}
|
||||
|
||||
@ -326,14 +331,15 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
char anyaddr[16] = { 0 };
|
||||
|
||||
int index;
|
||||
int index = 0;
|
||||
int table;
|
||||
int metric;
|
||||
int metric = 0;
|
||||
u_int32_t mtu = 0;
|
||||
|
||||
void *dest;
|
||||
void *gate;
|
||||
void *src;
|
||||
void *dest = NULL;
|
||||
void *gate = NULL;
|
||||
void *prefsrc = NULL; /* IPv4 preferred source host address */
|
||||
void *src = NULL; /* IPv6 srcdest source prefix */
|
||||
|
||||
rtm = NLMSG_DATA (h);
|
||||
|
||||
@ -354,12 +360,6 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
if (rtm->rtm_protocol == RTPROT_ZEBRA)
|
||||
SET_FLAG(zebra_flags, ZEBRA_FLAG_SELFROUTE);
|
||||
|
||||
if (rtm->rtm_src_len != 0)
|
||||
{
|
||||
zlog_warn ("netlink_route_change(): no src len");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Table corresponding to route. */
|
||||
if (tb[RTA_TABLE])
|
||||
table = *(int *) RTA_DATA (tb[RTA_TABLE]);
|
||||
@ -375,12 +375,6 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
return 0;
|
||||
}
|
||||
|
||||
index = 0;
|
||||
metric = 0;
|
||||
dest = NULL;
|
||||
gate = NULL;
|
||||
src = NULL;
|
||||
|
||||
if (tb[RTA_OIF])
|
||||
index = *(int *) RTA_DATA (tb[RTA_OIF]);
|
||||
|
||||
@ -389,11 +383,16 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
else
|
||||
dest = anyaddr;
|
||||
|
||||
if (tb[RTA_SRC])
|
||||
src = RTA_DATA (tb[RTA_SRC]);
|
||||
else
|
||||
src = anyaddr;
|
||||
|
||||
if (tb[RTA_GATEWAY])
|
||||
gate = RTA_DATA (tb[RTA_GATEWAY]);
|
||||
|
||||
if (tb[RTA_PREFSRC])
|
||||
src = RTA_DATA (tb[RTA_PREFSRC]);
|
||||
prefsrc = RTA_DATA (tb[RTA_PREFSRC]);
|
||||
|
||||
if (h->nlmsg_type == RTM_NEWROUTE)
|
||||
{
|
||||
@ -419,6 +418,13 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
memcpy (&p.u.prefix4, dest, 4);
|
||||
p.prefixlen = rtm->rtm_dst_len;
|
||||
|
||||
if (rtm->rtm_src_len != 0)
|
||||
{
|
||||
zlog_warn ("unsupported IPv4 sourcedest route (dest %s/%d)",
|
||||
inet_ntoa (p.u.prefix4), p.prefixlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
{
|
||||
char buf[PREFIX_STRLEN];
|
||||
@ -431,8 +437,8 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
{
|
||||
if (!tb[RTA_MULTIPATH])
|
||||
rib_add (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
|
||||
0, 0, &p, NULL, gate, src, index,
|
||||
table, metric, mtu, 0);
|
||||
0, 0, &p, NULL, gate, prefsrc, index,
|
||||
table, metric, mtu, 0);
|
||||
else
|
||||
{
|
||||
/* This is a multipath route */
|
||||
@ -473,9 +479,9 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
if (gate)
|
||||
{
|
||||
if (index)
|
||||
rib_nexthop_ipv4_ifindex_add (rib, gate, src, index);
|
||||
rib_nexthop_ipv4_ifindex_add (rib, gate, prefsrc, index);
|
||||
else
|
||||
rib_nexthop_ipv4_add (rib, gate, src);
|
||||
rib_nexthop_ipv4_add (rib, gate, prefsrc);
|
||||
}
|
||||
else
|
||||
rib_nexthop_ifindex_add (rib, index);
|
||||
@ -501,26 +507,35 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
if (rtm->rtm_family == AF_INET6)
|
||||
{
|
||||
struct prefix p;
|
||||
struct prefix_ipv6 src_p;
|
||||
|
||||
p.family = AF_INET6;
|
||||
memcpy (&p.u.prefix6, dest, 16);
|
||||
p.prefixlen = rtm->rtm_dst_len;
|
||||
|
||||
src_p.family = AF_INET6;
|
||||
memcpy (&src_p.prefix, src, 16);
|
||||
src_p.prefixlen = rtm->rtm_src_len;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
{
|
||||
char buf[PREFIX_STRLEN];
|
||||
zlog_debug ("%s %s vrf %u",
|
||||
char buf2[PREFIX_STRLEN];
|
||||
zlog_debug ("%s %s%s%s vrf %u",
|
||||
nl_msg_type_to_str (h->nlmsg_type),
|
||||
prefix2str (&p, buf, sizeof(buf)), vrf_id);
|
||||
prefix2str (&p, buf, sizeof(buf)),
|
||||
src_p.prefixlen ? " from " : "",
|
||||
src_p.prefixlen ? prefix2str(&src_p, buf2, sizeof(buf2)) : "",
|
||||
vrf_id);
|
||||
}
|
||||
|
||||
if (h->nlmsg_type == RTM_NEWROUTE)
|
||||
rib_add (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
|
||||
0, 0, &p, NULL, gate, src, index,
|
||||
0, 0, &p, &src_p, gate, prefsrc, index,
|
||||
table, metric, mtu, 0);
|
||||
else
|
||||
rib_delete (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
|
||||
0, zebra_flags, &p, NULL, gate, index, table);
|
||||
0, zebra_flags, &p, &src_p, gate, index, table);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1233,8 +1248,8 @@ netlink_neigh_update (int cmd, int ifindex, uint32_t addr, char *lla, int llalen
|
||||
/* Routing table change via netlink interface. */
|
||||
/* Update flag indicates whether this is a "replace" or not. */
|
||||
static int
|
||||
netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
||||
int update)
|
||||
netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p,
|
||||
struct rib *rib, int update)
|
||||
{
|
||||
int bytelen;
|
||||
struct sockaddr_nl snl;
|
||||
@ -1268,6 +1283,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
||||
req.n.nlmsg_type = cmd;
|
||||
req.r.rtm_family = family;
|
||||
req.r.rtm_dst_len = p->prefixlen;
|
||||
req.r.rtm_src_len = src_p ? src_p->prefixlen : 0;
|
||||
req.r.rtm_protocol = RTPROT_ZEBRA;
|
||||
req.r.rtm_scope = RT_SCOPE_UNIVERSE;
|
||||
|
||||
@ -1292,6 +1308,8 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
||||
}
|
||||
|
||||
addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen);
|
||||
if (src_p)
|
||||
addattr_l (&req.n, sizeof req, RTA_SRC, &src_p->u.prefix, bytelen);
|
||||
|
||||
/* Metric. */
|
||||
/* Hardcode the metric for all routes coming from zebra. Metric isn't used
|
||||
@ -1559,14 +1577,15 @@ kernel_get_ipmr_sg_stats (void *in)
|
||||
}
|
||||
|
||||
int
|
||||
kernel_route_rib (struct prefix *p, struct rib *old, struct rib *new)
|
||||
kernel_route_rib (struct prefix *p, struct prefix *src_p,
|
||||
struct rib *old, struct rib *new)
|
||||
{
|
||||
if (!old && new)
|
||||
return netlink_route_multipath (RTM_NEWROUTE, p, new, 0);
|
||||
return netlink_route_multipath (RTM_NEWROUTE, p, src_p, new, 0);
|
||||
if (old && !new)
|
||||
return netlink_route_multipath (RTM_DELROUTE, p, old, 0);
|
||||
return netlink_route_multipath (RTM_DELROUTE, p, src_p, old, 0);
|
||||
|
||||
return netlink_route_multipath (RTM_NEWROUTE, p, new, 1);
|
||||
return netlink_route_multipath (RTM_NEWROUTE, p, src_p, new, 1);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@ -182,7 +182,7 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib)
|
||||
{
|
||||
zlog_debug ("%s: %s: attention! gate not found for rib %p",
|
||||
__func__, prefix_buf, rib);
|
||||
rib_dump (p, rib);
|
||||
rib_dump (p, NULL, rib);
|
||||
}
|
||||
else
|
||||
inet_ntop (AF_INET, &sin_gate.sin_addr, gate_buf, INET_ADDRSTRLEN);
|
||||
@ -391,10 +391,17 @@ kernel_rtm (int cmd, struct prefix *p, struct rib *rib)
|
||||
}
|
||||
|
||||
int
|
||||
kernel_route_rib (struct prefix *p, struct rib *old, struct rib *new)
|
||||
kernel_route_rib (struct prefix *p, struct prefix *src_p,
|
||||
struct rib *old, struct rib *new)
|
||||
{
|
||||
int route = 0;
|
||||
|
||||
if (src_p && src_p->prefixlen)
|
||||
{
|
||||
zlog (NULL, LOG_ERR, "route add: IPv6 sourcedest routes unsupported!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (zserv_privs.change(ZPRIVS_RAISE))
|
||||
zlog (NULL, LOG_ERR, "Can't raise privileges");
|
||||
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
#include "nexthop.h"
|
||||
#include "vrf.h"
|
||||
#include "mpls.h"
|
||||
#include "srcdest_table.h"
|
||||
|
||||
#include "zebra/rib.h"
|
||||
#include "zebra/rt.h"
|
||||
@ -88,7 +89,7 @@ static void __attribute__((format (printf, 5, 6)))
|
||||
_rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn, int priority,
|
||||
const char *msgfmt, ...)
|
||||
{
|
||||
char buf[PREFIX_STRLEN + 8];
|
||||
char buf[SRCDEST2STR_BUFFER + sizeof(" (MRIB)")];
|
||||
char msgbuf[512];
|
||||
va_list ap;
|
||||
|
||||
@ -98,9 +99,9 @@ _rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn, int prior
|
||||
|
||||
if (rn)
|
||||
{
|
||||
rib_table_info_t *info = rn->table->info;
|
||||
rib_table_info_t *info = srcdest_rnode_table_info (rn);
|
||||
srcdest_rnode2str(rn, buf, sizeof(buf));
|
||||
|
||||
prefix2str(&rn->p, buf, sizeof(buf));
|
||||
if (info->safi == SAFI_MULTICAST)
|
||||
strcat(buf, " (MRIB)");
|
||||
}
|
||||
@ -1051,11 +1052,12 @@ static unsigned
|
||||
nexthop_active_check (struct route_node *rn, struct rib *rib,
|
||||
struct nexthop *nexthop, int set)
|
||||
{
|
||||
rib_table_info_t *info = rn->table->info;
|
||||
struct interface *ifp;
|
||||
route_map_result_t ret = RMAP_MATCH;
|
||||
int family;
|
||||
char buf[INET6_ADDRSTRLEN+1];
|
||||
char buf[SRCDEST2STR_BUFFER];
|
||||
struct prefix *p, *src_p;
|
||||
srcdest_rnode_prefixes (rn, &p, &src_p);
|
||||
|
||||
if (rn->p.family == AF_INET)
|
||||
family = AFI_IP;
|
||||
@ -1119,8 +1121,8 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
|
||||
/* XXX: What exactly do those checks do? Do we support
|
||||
* e.g. IPv4 routes with IPv6 nexthops or vice versa? */
|
||||
if (RIB_SYSTEM_ROUTE(rib) ||
|
||||
(family == AFI_IP && rn->p.family != AF_INET) ||
|
||||
(family == AFI_IP6 && rn->p.family != AF_INET6))
|
||||
(family == AFI_IP && p->family != AF_INET) ||
|
||||
(family == AFI_IP6 && p->family != AF_INET6))
|
||||
return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||
|
||||
/* The original code didn't determine the family correctly
|
||||
@ -1130,20 +1132,25 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
|
||||
* in every case.
|
||||
*/
|
||||
if (!family)
|
||||
family = info->afi;
|
||||
{
|
||||
rib_table_info_t *info;
|
||||
|
||||
info = srcdest_rnode_table_info(rn);
|
||||
family = info->afi;
|
||||
}
|
||||
|
||||
memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr));
|
||||
|
||||
/* It'll get set if required inside */
|
||||
ret = zebra_route_map_check(family, rib->type, &rn->p, nexthop, rib->vrf_id,
|
||||
ret = zebra_route_map_check(family, rib->type, p, nexthop, rib->vrf_id,
|
||||
rib->tag);
|
||||
if (ret == RMAP_DENYMATCH)
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf));
|
||||
zlog_debug("%u:%s/%d: Filtering out with NH out %s due to route map",
|
||||
rib->vrf_id, buf, rn->p.prefixlen,
|
||||
srcdest_rnode2str(rn, buf, sizeof(buf));
|
||||
zlog_debug("%u:%s: Filtering out with NH out %s due to route map",
|
||||
rib->vrf_id, buf,
|
||||
ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id));
|
||||
}
|
||||
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||
@ -1216,8 +1223,11 @@ rib_install_kernel (struct route_node *rn, struct rib *rib, struct rib *old)
|
||||
{
|
||||
int ret = 0;
|
||||
struct nexthop *nexthop, *tnexthop;
|
||||
rib_table_info_t *info = rn->table->info;
|
||||
rib_table_info_t *info = srcdest_rnode_table_info(rn);
|
||||
int recursing;
|
||||
struct prefix *p, *src_p;
|
||||
|
||||
srcdest_rnode_prefixes (rn, &p, &src_p);
|
||||
|
||||
if (info->safi != SAFI_UNICAST)
|
||||
{
|
||||
@ -1231,7 +1241,7 @@ rib_install_kernel (struct route_node *rn, struct rib *rib, struct rib *old)
|
||||
* the kernel.
|
||||
*/
|
||||
zfpm_trigger_update (rn, "installing in kernel");
|
||||
ret = kernel_route_rib (&rn->p, old, rib);
|
||||
ret = kernel_route_rib (p, src_p, old, rib);
|
||||
|
||||
/* If install succeeds, update FIB flag for nexthops. */
|
||||
if (!ret)
|
||||
@ -1257,8 +1267,11 @@ rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
|
||||
{
|
||||
int ret = 0;
|
||||
struct nexthop *nexthop, *tnexthop;
|
||||
rib_table_info_t *info = rn->table->info;
|
||||
rib_table_info_t *info = srcdest_rnode_table_info(rn);
|
||||
int recursing;
|
||||
struct prefix *p, *src_p;
|
||||
|
||||
srcdest_rnode_prefixes (rn, &p, &src_p);
|
||||
|
||||
if (info->safi != SAFI_UNICAST)
|
||||
{
|
||||
@ -1272,7 +1285,7 @@ rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
|
||||
* the kernel.
|
||||
*/
|
||||
zfpm_trigger_update (rn, "uninstalling from kernel");
|
||||
ret = kernel_route_rib (&rn->p, rib, NULL);
|
||||
ret = kernel_route_rib (p, src_p, rib, NULL);
|
||||
|
||||
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
|
||||
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
|
||||
@ -1284,7 +1297,7 @@ rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
|
||||
static void
|
||||
rib_uninstall (struct route_node *rn, struct rib *rib)
|
||||
{
|
||||
rib_table_info_t *info = rn->table->info;
|
||||
rib_table_info_t *info = srcdest_rnode_table_info(rn);
|
||||
|
||||
if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
|
||||
{
|
||||
@ -1298,7 +1311,10 @@ rib_uninstall (struct route_node *rn, struct rib *rib)
|
||||
|
||||
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
|
||||
{
|
||||
redistribute_delete (&rn->p, rib);
|
||||
struct prefix *p, *src_p;
|
||||
srcdest_rnode_prefixes (rn, &p, &src_p);
|
||||
|
||||
redistribute_delete (p, src_p, rib);
|
||||
UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
|
||||
}
|
||||
}
|
||||
@ -1367,8 +1383,6 @@ static void
|
||||
rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
||||
struct rib *new)
|
||||
{
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
|
||||
zfpm_trigger_update (rn, "new route selected");
|
||||
|
||||
/* Update real nexthop. This may actually determine if nexthop is active or not. */
|
||||
@ -1381,18 +1395,20 @@ rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
||||
SET_FLAG (new->status, RIB_ENTRY_SELECTED_FIB);
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_debug ("%u:%s/%d: Adding route rn %p, rib %p (type %d)",
|
||||
zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type);
|
||||
char buf[SRCDEST2STR_BUFFER];
|
||||
srcdest_rnode2str(rn, buf, sizeof(buf));
|
||||
zlog_debug ("%u:%s: Adding route rn %p, rib %p (type %d)",
|
||||
zvrf_id (zvrf), buf, rn, new, new->type);
|
||||
}
|
||||
|
||||
if (!RIB_SYSTEM_ROUTE (new))
|
||||
{
|
||||
if (rib_install_kernel (rn, new, NULL))
|
||||
{
|
||||
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_warn ("%u:%s/%d: Route install failed",
|
||||
zvrf_id (zvrf), buf, rn->p.prefixlen);
|
||||
char buf[SRCDEST2STR_BUFFER];
|
||||
srcdest_rnode2str(rn, buf, sizeof(buf));
|
||||
zlog_warn ("%u:%s: Route install failed",
|
||||
zvrf_id (zvrf), buf);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1403,16 +1419,15 @@ static void
|
||||
rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
|
||||
struct rib *old)
|
||||
{
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
|
||||
zfpm_trigger_update (rn, "removing existing route");
|
||||
|
||||
/* Uninstall from kernel. */
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d)",
|
||||
zvrf_id (zvrf), buf, rn->p.prefixlen, rn, old, old->type);
|
||||
char buf[SRCDEST2STR_BUFFER];
|
||||
srcdest_rnode2str(rn, buf, sizeof(buf));
|
||||
zlog_debug ("%u:%s: Deleting route rn %p, rib %p (type %d)",
|
||||
zvrf_id (zvrf), buf, rn, old, old->type);
|
||||
}
|
||||
|
||||
if (!RIB_SYSTEM_ROUTE (old))
|
||||
@ -1429,15 +1444,11 @@ static void
|
||||
rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
|
||||
struct rib *old, struct rib *new)
|
||||
{
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
struct nexthop *nexthop = NULL, *tnexthop;
|
||||
int recursing;
|
||||
int nh_active = 0;
|
||||
int installed = 1;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
|
||||
/*
|
||||
* We have to install or update if a new route has been selected or
|
||||
* something has changed.
|
||||
@ -1459,23 +1470,25 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
char buf[SRCDEST2STR_BUFFER];
|
||||
srcdest_rnode2str(rn, buf, sizeof(buf));
|
||||
if (new != old)
|
||||
zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d) "
|
||||
"old %p (type %d)", zvrf_id (zvrf), buf, rn->p.prefixlen,
|
||||
zlog_debug ("%u:%s: Updating route rn %p, rib %p (type %d) "
|
||||
"old %p (type %d)", zvrf_id (zvrf), buf,
|
||||
rn, new, new->type, old, old->type);
|
||||
else
|
||||
zlog_debug ("%u:%s/%d: Updating route rn %p, rib %p (type %d)",
|
||||
zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type);
|
||||
zlog_debug ("%u:%s: Updating route rn %p, rib %p (type %d)",
|
||||
zvrf_id (zvrf), buf, rn, new, new->type);
|
||||
}
|
||||
/* Non-system route should be installed. */
|
||||
if (!RIB_SYSTEM_ROUTE (new))
|
||||
{
|
||||
if (rib_install_kernel (rn, new, old))
|
||||
{
|
||||
char buf[SRCDEST2STR_BUFFER];
|
||||
srcdest_rnode2str(rn, buf, sizeof(buf));
|
||||
installed = 0;
|
||||
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_warn ("%u:%s/%d: Route install failed",
|
||||
zvrf_id (zvrf), buf, rn->p.prefixlen);
|
||||
zlog_warn ("%u:%s: Route install failed", zvrf_id (zvrf), buf);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1507,14 +1520,16 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn,
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
char buf[SRCDEST2STR_BUFFER];
|
||||
srcdest_rnode2str(rn, buf, sizeof(buf));
|
||||
if (new != old)
|
||||
zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) "
|
||||
"old %p (type %d) - %s", zvrf_id (zvrf), buf, rn->p.prefixlen,
|
||||
zlog_debug ("%u:%s: Deleting route rn %p, rib %p (type %d) "
|
||||
"old %p (type %d) - %s", zvrf_id (zvrf), buf,
|
||||
rn, new, new->type, old, old->type,
|
||||
nh_active ? "install failed" : "nexthop inactive");
|
||||
else
|
||||
zlog_debug ("%u:%s/%d: Deleting route rn %p, rib %p (type %d) - %s",
|
||||
zvrf_id (zvrf), buf, rn->p.prefixlen, rn, new, new->type,
|
||||
zlog_debug ("%u:%s: Deleting route rn %p, rib %p (type %d) - %s",
|
||||
zvrf_id (zvrf), buf, rn, new, new->type,
|
||||
nh_active ? "install failed" : "nexthop inactive");
|
||||
}
|
||||
|
||||
@ -1613,9 +1628,11 @@ rib_process (struct route_node *rn)
|
||||
struct rib *old_fib = NULL;
|
||||
struct rib *new_fib = NULL;
|
||||
struct rib *best = NULL;
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
char buf[SRCDEST2STR_BUFFER];
|
||||
rib_dest_t *dest;
|
||||
struct zebra_vrf *zvrf = NULL;
|
||||
struct prefix *p, *src_p;
|
||||
srcdest_rnode_prefixes(rn, &p, &src_p);
|
||||
vrf_id_t vrf_id = VRF_UNKNOWN;
|
||||
|
||||
assert (rn);
|
||||
@ -1628,17 +1645,17 @@ rib_process (struct route_node *rn)
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
srcdest_rnode2str(rn, buf, sizeof(buf));
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||
zlog_debug ("%u:%s/%d: Processing rn %p", vrf_id, buf, rn->p.prefixlen, rn);
|
||||
zlog_debug ("%u:%s: Processing rn %p", vrf_id, buf, rn);
|
||||
|
||||
RNODE_FOREACH_RIB_SAFE (rn, rib, next)
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||
zlog_debug ("%u:%s/%d: Examine rib %p (type %d) status %x flags %x "
|
||||
zlog_debug ("%u:%s: Examine rib %p (type %d) status %x flags %x "
|
||||
"dist %d metric %d",
|
||||
vrf_id, buf, rn->p.prefixlen, rib, rib->type, rib->status,
|
||||
vrf_id, buf, rib, rib->type, rib->status,
|
||||
rib->flags, rib->distance, rib->metric);
|
||||
|
||||
UNSET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
|
||||
@ -1687,9 +1704,9 @@ rib_process (struct route_node *rn)
|
||||
if (rib != old_selected)
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
zlog_debug ("%s: %s/%d: imported via import-table but denied "
|
||||
zlog_debug ("%s: %s: imported via import-table but denied "
|
||||
"by the ip protocol table route-map",
|
||||
__func__, buf, rn->p.prefixlen);
|
||||
__func__, buf);
|
||||
rib_unlink (rn, rib);
|
||||
}
|
||||
else
|
||||
@ -1740,8 +1757,8 @@ rib_process (struct route_node *rn)
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||
{
|
||||
zlog_debug ("%u:%s/%d: After processing: old_selected %p new_selected %p old_fib %p new_fib %p",
|
||||
vrf_id, buf, rn->p.prefixlen,
|
||||
zlog_debug ("%u:%s: After processing: old_selected %p new_selected %p old_fib %p new_fib %p",
|
||||
vrf_id, buf,
|
||||
(void *)old_selected,
|
||||
(void *)new_selected,
|
||||
(void *)old_fib,
|
||||
@ -1789,7 +1806,7 @@ rib_process (struct route_node *rn)
|
||||
if (old_selected)
|
||||
{
|
||||
if (!new_selected)
|
||||
redistribute_delete(&rn->p, old_selected);
|
||||
redistribute_delete(p, src_p, old_selected);
|
||||
if (old_selected != new_selected)
|
||||
UNSET_FLAG (old_selected->flags, ZEBRA_FLAG_SELECTED);
|
||||
}
|
||||
@ -1798,7 +1815,7 @@ rib_process (struct route_node *rn)
|
||||
{
|
||||
/* Install new or replace existing redistributed entry */
|
||||
SET_FLAG (new_selected->flags, ZEBRA_FLAG_SELECTED);
|
||||
redistribute_update (&rn->p, new_selected, old_selected);
|
||||
redistribute_update (p, src_p, new_selected, old_selected);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2006,7 +2023,6 @@ process_subq (struct list * subq, u_char qindex)
|
||||
{
|
||||
struct listnode *lnode = listhead (subq);
|
||||
struct route_node *rnode;
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
rib_dest_t *dest;
|
||||
struct zebra_vrf *zvrf = NULL;
|
||||
|
||||
@ -2022,9 +2038,10 @@ process_subq (struct list * subq, u_char qindex)
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||
{
|
||||
inet_ntop (rnode->p.family, &rnode->p.u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_debug ("%u:%s/%d: rn %p dequeued from sub-queue %u",
|
||||
zvrf ? zvrf_id (zvrf) : 0, buf, rnode->p.prefixlen, rnode, qindex);
|
||||
char buf[SRCDEST2STR_BUFFER];
|
||||
srcdest_rnode2str(rnode, buf, sizeof(buf));
|
||||
zlog_debug ("%u:%s: rn %p dequeued from sub-queue %u",
|
||||
zvrf ? zvrf_id (zvrf) : 0, buf, rnode, qindex);
|
||||
}
|
||||
|
||||
if (rnode->info)
|
||||
@ -2405,13 +2422,10 @@ rib_delnode (struct route_node *rn, struct rib *rib)
|
||||
/* Just clean up if non main table */
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_debug ("%u:%s/%d: Freeing route rn %p, rib %p (type %d)",
|
||||
rib->vrf_id, buf, rn->p.prefixlen, rn, rib, rib->type);
|
||||
}
|
||||
char buf[SRCDEST2STR_BUFFER];
|
||||
srcdest_rnode2str(rn, buf, sizeof(buf));
|
||||
zlog_debug ("%u:%s: Freeing route rn %p, rib %p (type %d)",
|
||||
rib->vrf_id, buf, rn, rib, rib->type);
|
||||
}
|
||||
|
||||
rib_unlink(rn, rib);
|
||||
@ -2428,15 +2442,23 @@ rib_delnode (struct route_node *rn, struct rib *rib)
|
||||
*/
|
||||
|
||||
void _rib_dump (const char * func,
|
||||
union prefix46constptr pp, const struct rib * rib)
|
||||
union prefix46constptr pp,
|
||||
union prefix46constptr src_pp,
|
||||
const struct rib * rib)
|
||||
{
|
||||
const struct prefix *p = pp.p;
|
||||
const struct prefix *src_p = src_pp.p;
|
||||
bool is_srcdst = src_p && src_p->prefixlen;
|
||||
char straddr[PREFIX_STRLEN];
|
||||
char srcaddr[PREFIX_STRLEN];
|
||||
struct nexthop *nexthop, *tnexthop;
|
||||
int recursing;
|
||||
|
||||
zlog_debug ("%s: dumping RIB entry %p for %s vrf %u", func, (const void *)rib,
|
||||
prefix2str(pp, straddr, sizeof(straddr)), rib->vrf_id);
|
||||
zlog_debug ("%s: dumping RIB entry %p for %s%s%s vrf %u", func, (const void *)rib,
|
||||
prefix2str(pp, straddr, sizeof(straddr)),
|
||||
is_srcdst ? " from " : "",
|
||||
is_srcdst ? prefix2str(src_pp, srcaddr, sizeof(srcaddr)) : "",
|
||||
rib->vrf_id);
|
||||
zlog_debug
|
||||
(
|
||||
"%s: refcnt == %lu, uptime == %lu, type == %u, instance == %d, table == %d",
|
||||
@ -2527,7 +2549,7 @@ void rib_lookup_and_dump (struct prefix_ipv4 * p, vrf_id_t vrf_id)
|
||||
(CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"),
|
||||
(CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected")
|
||||
);
|
||||
rib_dump (p, rib);
|
||||
rib_dump (p, NULL, rib);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2574,7 +2596,7 @@ void rib_lookup_and_pushup (struct prefix_ipv4 * p, vrf_id_t vrf_id)
|
||||
char buf[PREFIX_STRLEN];
|
||||
zlog_debug ("%u:%s: freeing way for connected prefix",
|
||||
rib->vrf_id, prefix2str(&rn->p, buf, sizeof(buf)));
|
||||
rib_dump (&rn->p, rib);
|
||||
rib_dump (&rn->p, NULL, rib);
|
||||
}
|
||||
rib_uninstall (rn, rib);
|
||||
}
|
||||
@ -2602,6 +2624,8 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
|
||||
else
|
||||
family = AFI_IP6;
|
||||
|
||||
assert(!src_p || family == AFI_IP6);
|
||||
|
||||
/* Lookup table. */
|
||||
table = zebra_vrf_table_with_table_id (family, safi, rib->vrf_id, rib->table);
|
||||
if (! table)
|
||||
@ -2609,6 +2633,8 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
|
||||
|
||||
/* Make it sure prefixlen is applied to the prefix. */
|
||||
apply_mask (p);
|
||||
if (src_p)
|
||||
apply_mask_ipv6 (src_p);
|
||||
|
||||
/* Set default distance by route type. */
|
||||
if (rib->distance == 0)
|
||||
@ -2622,7 +2648,7 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
|
||||
}
|
||||
|
||||
/* Lookup route node.*/
|
||||
rn = route_node_get (table, p);
|
||||
rn = srcdest_rnode_get (table, p, src_p);
|
||||
|
||||
/* If same type of route are installed, treat it as a implicit
|
||||
withdraw. */
|
||||
@ -2645,18 +2671,11 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
|
||||
/* Link new rib to node.*/
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d) "
|
||||
"existing %p",
|
||||
rib->vrf_id, buf, p->prefixlen, (void *)rn,
|
||||
(void *)rib, rib->type, (void *)same);
|
||||
}
|
||||
rnode_debug(rn, rib->vrf_id, "Inserting route rn %p, rib %p (type %d) existing %p",
|
||||
(void *)rn, (void *)rib, rib->type, (void *)same);
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||
rib_dump ((struct prefix *)p, rib);
|
||||
rib_dump (p, src_p, rib);
|
||||
}
|
||||
rib_addnode (rn, rib, 1);
|
||||
ret = 1;
|
||||
@ -2684,9 +2703,10 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
|
||||
struct rib *same = NULL;
|
||||
struct nexthop *nexthop, *tnexthop;
|
||||
int recursing;
|
||||
char buf1[PREFIX_STRLEN];
|
||||
char buf2[INET6_ADDRSTRLEN];
|
||||
|
||||
assert(!src_p || afi == AFI_IP6);
|
||||
|
||||
/* Lookup table. */
|
||||
table = zebra_vrf_table_with_table_id (afi, safi, vrf_id, table_id);
|
||||
if (! table)
|
||||
@ -2694,14 +2714,26 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
|
||||
|
||||
/* Apply mask. */
|
||||
apply_mask (p);
|
||||
if (src_p)
|
||||
apply_mask_ipv6 (src_p);
|
||||
|
||||
/* Lookup route node. */
|
||||
rn = route_node_lookup (table, p);
|
||||
rn = srcdest_rnode_lookup (table, p, src_p);
|
||||
if (! rn)
|
||||
{
|
||||
char dst_buf[PREFIX_STRLEN], src_buf[PREFIX_STRLEN];
|
||||
|
||||
prefix2str(p, dst_buf, sizeof(dst_buf));
|
||||
if (src_p && src_p->prefixlen)
|
||||
prefix2str(src_p, src_buf, sizeof(src_buf));
|
||||
else
|
||||
src_buf[0] = '\0';
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
zlog_debug ("%u:%s: doesn't exist in rib",
|
||||
vrf_id, prefix2str (p, buf1, sizeof(buf1)));
|
||||
zlog_debug ("%u:%s%s%s doesn't exist in rib",
|
||||
vrf_id, dst_buf,
|
||||
(src_buf[0] != '\0') ? " from " : "",
|
||||
src_buf);
|
||||
return ZEBRA_ERR_RTNOEXIST;
|
||||
}
|
||||
|
||||
@ -2761,10 +2793,8 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
zlog_debug ("%u:%s: rn %p, rib %p (type %d) was deleted "
|
||||
"from kernel, adding",
|
||||
vrf_id, prefix2str(p, buf1, INET6_ADDRSTRLEN),
|
||||
rn, fib, fib->type);
|
||||
rnode_debug (rn, vrf_id, "rn %p, rib %p (type %d) was deleted from kernel, adding",
|
||||
rn, fib, fib->type);
|
||||
}
|
||||
if (allow_delete)
|
||||
{
|
||||
@ -2786,15 +2816,13 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
if (gate)
|
||||
zlog_debug ("%u:%s: via %s ifindex %d type %d "
|
||||
rnode_debug(rn, vrf_id, "via %s ifindex %d type %d "
|
||||
"doesn't exist in rib",
|
||||
vrf_id, prefix2str (p, buf1, sizeof(buf1)),
|
||||
inet_ntop (family2afi(afi), gate, buf2, INET_ADDRSTRLEN),
|
||||
inet_ntop (family2afi(afi), gate, buf2, INET_ADDRSTRLEN), /* FIXME */
|
||||
ifindex,
|
||||
type);
|
||||
else
|
||||
zlog_debug ("%u:%s: ifindex %d type %d doesn't exist in rib",
|
||||
vrf_id, prefix2str (p, buf1, sizeof(buf1)),
|
||||
rnode_debug (rn, vrf_id, "ifindex %d type %d doesn't exist in rib",
|
||||
ifindex,
|
||||
type);
|
||||
}
|
||||
@ -2826,6 +2854,8 @@ rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
||||
struct route_node *rn;
|
||||
struct nexthop *nexthop;
|
||||
|
||||
assert(!src_p || afi == AFI_IP6);
|
||||
|
||||
/* Lookup table. */
|
||||
table = zebra_vrf_table_with_table_id (afi, safi, vrf_id, table_id);
|
||||
if (! table)
|
||||
@ -2833,6 +2863,8 @@ rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
||||
|
||||
/* Make sure mask is applied. */
|
||||
apply_mask (p);
|
||||
if (src_p)
|
||||
apply_mask_ipv6 (src_p);
|
||||
|
||||
/* Set default distance by route type. */
|
||||
if (distance == 0)
|
||||
@ -2848,7 +2880,7 @@ rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
||||
}
|
||||
|
||||
/* Lookup route node.*/
|
||||
rn = route_node_get (table, p);
|
||||
rn = srcdest_rnode_get (table, p, src_p);
|
||||
|
||||
/* If same type of route are installed, treat it as a implicit
|
||||
withdraw. */
|
||||
@ -2920,18 +2952,11 @@ rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
||||
/* Link new rib to node.*/
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
|
||||
zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d) "
|
||||
"existing %p",
|
||||
vrf_id, buf, p->prefixlen, (void *)rn,
|
||||
(void *)rib, rib->type, (void *)same);
|
||||
}
|
||||
rnode_debug (rn, vrf_id, "Inserting route rn %p, rib %p (type %d) existing %p",
|
||||
(void *)rn, (void *)rib, rib->type, (void *)same);
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||
rib_dump (p, rib);
|
||||
rib_dump (p, src_p, rib);
|
||||
}
|
||||
rib_addnode (rn, rib, 1);
|
||||
|
||||
@ -2953,7 +2978,7 @@ rib_update_table (struct route_table *table, rib_update_event_t event)
|
||||
/* Walk all routes and queue for processing, if appropriate for
|
||||
* the trigger event.
|
||||
*/
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
@ -3029,7 +3054,7 @@ rib_weed_table (struct route_table *table)
|
||||
struct rib *next;
|
||||
|
||||
if (table)
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB_SAFE (rn, rib, next)
|
||||
{
|
||||
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
|
||||
@ -3066,7 +3091,7 @@ rib_sweep_table (struct route_table *table)
|
||||
int ret = 0;
|
||||
|
||||
if (table)
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB_SAFE (rn, rib, next)
|
||||
{
|
||||
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
|
||||
@ -3107,7 +3132,7 @@ rib_score_proto_table (u_char proto, u_short instance, struct route_table *table
|
||||
unsigned long n = 0;
|
||||
|
||||
if (table)
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB_SAFE (rn, rib, next)
|
||||
{
|
||||
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
|
||||
@ -3118,7 +3143,6 @@ rib_score_proto_table (u_char proto, u_short instance, struct route_table *table
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -3147,7 +3171,7 @@ rib_close_table (struct route_table *table)
|
||||
struct rib *rib;
|
||||
|
||||
if (table)
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
{
|
||||
if (!CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB))
|
||||
|
||||
@ -328,13 +328,13 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
|
||||
rib_install_kernel (rn, rib, rib);
|
||||
/* Update redistribution if it's selected */
|
||||
if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED))
|
||||
redistribute_update (&rn->p, rib, NULL);
|
||||
redistribute_update (&rn->p, NULL, rib, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove from redistribute if selected route becomes inactive */
|
||||
if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED))
|
||||
redistribute_delete (&rn->p, rib);
|
||||
redistribute_delete (&rn->p, NULL, rib);
|
||||
/* Remove from kernel if fib route becomes inactive */
|
||||
if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
|
||||
rib_uninstall_kernel (rn, rib);
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include "linklist.h"
|
||||
#include "command.h"
|
||||
#include "memory.h"
|
||||
#include "srcdest_table.h"
|
||||
|
||||
#include "vty.h"
|
||||
#include "zebra/debug.h"
|
||||
@ -331,8 +332,7 @@ zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
|
||||
}
|
||||
|
||||
static void
|
||||
zebra_rtable_node_destroy (route_table_delegate_t *delegate,
|
||||
struct route_table *table, struct route_node *node)
|
||||
zebra_rtable_node_cleanup (struct route_table *table, struct route_node *node)
|
||||
{
|
||||
struct rib *rib, *next;
|
||||
|
||||
@ -341,8 +341,6 @@ zebra_rtable_node_destroy (route_table_delegate_t *delegate,
|
||||
|
||||
if (node->info)
|
||||
XFREE (MTYPE_RIB_DEST, node->info);
|
||||
|
||||
route_node_destroy (delegate, table, node);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -362,30 +360,17 @@ zebra_stable_node_destroy (route_table_delegate_t *delegate,
|
||||
}
|
||||
|
||||
static void
|
||||
zebra_rnhtable_node_destroy (route_table_delegate_t *delegate,
|
||||
struct route_table *table, struct route_node *node)
|
||||
zebra_rnhtable_node_cleanup (struct route_table *table, struct route_node *node)
|
||||
{
|
||||
if (node->info)
|
||||
zebra_free_rnh (node->info);
|
||||
|
||||
route_node_destroy (delegate, table, node);
|
||||
}
|
||||
|
||||
route_table_delegate_t zebra_rtable_delegate = {
|
||||
.create_node = route_node_create,
|
||||
.destroy_node = zebra_rtable_node_destroy
|
||||
};
|
||||
|
||||
route_table_delegate_t zebra_stable_delegate = {
|
||||
.create_node = route_node_create,
|
||||
.destroy_node = zebra_stable_node_destroy
|
||||
};
|
||||
|
||||
route_table_delegate_t zebra_rnhtable_delegate = {
|
||||
.create_node = route_node_create,
|
||||
.destroy_node = zebra_rnhtable_node_destroy
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a routing table for the specific AFI/SAFI in the given VRF.
|
||||
*/
|
||||
@ -397,7 +382,11 @@ zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
|
||||
|
||||
assert (!zvrf->table[afi][safi]);
|
||||
|
||||
table = route_table_init_with_delegate (&zebra_rtable_delegate);
|
||||
if (afi == AFI_IP6)
|
||||
table = srcdest_table_init();
|
||||
else
|
||||
table = route_table_init();
|
||||
table->cleanup = zebra_rtable_node_cleanup;
|
||||
zvrf->table[afi][safi] = table;
|
||||
|
||||
info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
|
||||
@ -414,6 +403,7 @@ zebra_vrf_alloc (void)
|
||||
struct zebra_vrf *zvrf;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
struct route_table *table;
|
||||
|
||||
zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
|
||||
|
||||
@ -426,10 +416,13 @@ zebra_vrf_alloc (void)
|
||||
route_table_init_with_delegate (&zebra_stable_delegate);
|
||||
}
|
||||
|
||||
zvrf->rnh_table[afi] =
|
||||
route_table_init_with_delegate (&zebra_rnhtable_delegate);
|
||||
zvrf->import_check_table[afi] =
|
||||
route_table_init_with_delegate (&zebra_rnhtable_delegate);
|
||||
table = route_table_init();
|
||||
table->cleanup = zebra_rnhtable_node_cleanup;
|
||||
zvrf->rnh_table[afi] = table;
|
||||
|
||||
table = route_table_init();
|
||||
table->cleanup = zebra_rnhtable_node_cleanup;
|
||||
zvrf->import_check_table[afi] = table;
|
||||
}
|
||||
|
||||
zebra_mpls_init_tables (zvrf);
|
||||
@ -509,7 +502,7 @@ zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id)
|
||||
{
|
||||
if (zvrf->other_table[afi][table_id] == NULL)
|
||||
{
|
||||
table = route_table_init();
|
||||
table = (afi == AFI_IP6) ? srcdest_table_init() : route_table_init();
|
||||
info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
|
||||
info->zvrf = zvrf;
|
||||
info->afi = afi;
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
#include "vrf.h"
|
||||
#include "mpls.h"
|
||||
#include "routemap.h"
|
||||
#include "srcdest_table.h"
|
||||
|
||||
#include "zebra/zserv.h"
|
||||
#include "zebra/zebra_vrf.h"
|
||||
@ -639,7 +640,7 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
|
||||
struct rib *rib;
|
||||
struct nexthop *nexthop, *tnexthop;
|
||||
int recursing;
|
||||
char buf[PREFIX_STRLEN];
|
||||
char buf[SRCDEST2STR_BUFFER];
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
@ -647,14 +648,14 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
|
||||
const char *mcast_info = "";
|
||||
if (mcast)
|
||||
{
|
||||
rib_table_info_t *info = rn->table->info;
|
||||
rib_table_info_t *info = srcdest_rnode_table_info(rn);
|
||||
mcast_info = (info->safi == SAFI_MULTICAST)
|
||||
? " using Multicast RIB"
|
||||
: " using Unicast RIB";
|
||||
}
|
||||
|
||||
vty_out (vty, "Routing entry for %s%s%s",
|
||||
prefix2str (&rn->p, buf, sizeof(buf)), mcast_info,
|
||||
srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info,
|
||||
VTY_NEWLINE);
|
||||
vty_out (vty, " Known via \"%s", zebra_route_string (rib->type));
|
||||
if (rib->instance)
|
||||
@ -797,7 +798,7 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
|
||||
struct nexthop *nexthop, *tnexthop;
|
||||
int recursing;
|
||||
int len = 0;
|
||||
char buf[BUFSIZ];
|
||||
char buf[SRCDEST2STR_BUFFER];
|
||||
json_object *json_nexthops = NULL;
|
||||
json_object *json_nexthop = NULL;
|
||||
json_object *json_route = NULL;
|
||||
@ -807,7 +808,7 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
|
||||
json_route = json_object_new_object();
|
||||
json_nexthops = json_object_new_array();
|
||||
|
||||
json_object_string_add(json_route, "prefix", prefix2str (&rn->p, buf, sizeof buf));
|
||||
json_object_string_add(json_route, "prefix", srcdest_rnode2str (rn, buf, sizeof buf));
|
||||
json_object_string_add(json_route, "protocol", zebra_route_string(rib->type));
|
||||
|
||||
if (rib->instance)
|
||||
@ -951,7 +952,7 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib,
|
||||
? '>' : ' ',
|
||||
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
|
||||
? '*' : ' ',
|
||||
prefix2str (&rn->p, buf, sizeof buf));
|
||||
srcdest_rnode2str (rn, buf, sizeof buf));
|
||||
|
||||
/* Distance and metric display. */
|
||||
if (rib->type != ZEBRA_ROUTE_CONNECT
|
||||
@ -1665,7 +1666,7 @@ vty_show_ip_route_summary (struct vty *vty, struct route_table *table)
|
||||
|
||||
memset (&rib_cnt, 0, sizeof(rib_cnt));
|
||||
memset (&fib_cnt, 0, sizeof(fib_cnt));
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
{
|
||||
is_ibgp = (rib->type == ZEBRA_ROUTE_BGP &&
|
||||
@ -1741,7 +1742,7 @@ vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table)
|
||||
|
||||
memset (&rib_cnt, 0, sizeof(rib_cnt));
|
||||
memset (&fib_cnt, 0, sizeof(fib_cnt));
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
{
|
||||
|
||||
@ -2767,7 +2768,7 @@ DEFUN (show_ipv6_route,
|
||||
int first = 1;
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
struct zebra_vrf *zvrf = NULL;
|
||||
char buf[BUFSIZ];
|
||||
char buf[SRCDEST2STR_BUFFER];
|
||||
json_object *json = NULL;
|
||||
json_object *json_prefix = NULL;
|
||||
|
||||
@ -2811,7 +2812,7 @@ DEFUN (show_ipv6_route,
|
||||
json = json_object_new_object();
|
||||
|
||||
/* Show all IPv6 route. */
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
{
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
{
|
||||
@ -2822,7 +2823,7 @@ DEFUN (show_ipv6_route,
|
||||
|
||||
if (json_prefix)
|
||||
{
|
||||
prefix2str (&rn->p, buf, sizeof buf);
|
||||
srcdest_rnode2str (rn, buf, sizeof buf);
|
||||
json_object_object_add(json, buf, json_prefix);
|
||||
json_prefix = NULL;
|
||||
}
|
||||
@ -2834,7 +2835,7 @@ DEFUN (show_ipv6_route,
|
||||
else
|
||||
{
|
||||
/* Show all IPv6 route. */
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
{
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
{
|
||||
@ -2887,7 +2888,7 @@ DEFUN (show_ipv6_route_tag,
|
||||
return CMD_SUCCESS;
|
||||
|
||||
/* Show all IPv6 routes with matching tag value. */
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
{
|
||||
if (rib->tag != tag)
|
||||
@ -2942,17 +2943,22 @@ DEFUN (show_ipv6_route_prefix_longer,
|
||||
return CMD_SUCCESS;
|
||||
|
||||
/* Show matched type IPv6 routes. */
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
if (prefix_match (&p, &rn->p))
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
vty_out (vty, SHOW_ROUTE_V6_HEADER);
|
||||
first = 0;
|
||||
}
|
||||
vty_show_ip_route (vty, rn, rib, NULL);
|
||||
}
|
||||
{
|
||||
struct prefix *p, *src_p;
|
||||
srcdest_rnode_prefixes(rn, &p, &src_p);
|
||||
|
||||
if (prefix_match (p, &rn->p))
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
vty_out (vty, SHOW_ROUTE_V6_HEADER);
|
||||
first = 0;
|
||||
}
|
||||
vty_show_ip_route (vty, rn, rib, NULL);
|
||||
}
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@ -2990,7 +2996,7 @@ DEFUN (show_ipv6_route_protocol,
|
||||
return CMD_SUCCESS;
|
||||
|
||||
/* Show matched type IPv6 routes. */
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
if (rib->type == type)
|
||||
{
|
||||
@ -3180,7 +3186,7 @@ DEFUN (show_ipv6_mroute,
|
||||
return CMD_SUCCESS;
|
||||
|
||||
/* Show all IPv6 route. */
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
{
|
||||
if (first)
|
||||
@ -3217,7 +3223,7 @@ DEFUN (show_ipv6_route_vrf_all,
|
||||
continue;
|
||||
|
||||
/* Show all IPv6 route. */
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
{
|
||||
if (first)
|
||||
@ -3269,7 +3275,7 @@ DEFUN (show_ipv6_route_vrf_all_tag,
|
||||
continue;
|
||||
|
||||
/* Show all IPv6 routes with matching tag value. */
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
{
|
||||
if (rib->tag != tag)
|
||||
@ -3329,23 +3335,27 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer,
|
||||
continue;
|
||||
|
||||
/* Show matched type IPv6 routes. */
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
if (prefix_match (&p, &rn->p))
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
vty_out (vty, SHOW_ROUTE_V6_HEADER);
|
||||
first = 0;
|
||||
}
|
||||
|
||||
if (vrf_header)
|
||||
{
|
||||
struct prefix *p, *src_p;
|
||||
srcdest_rnode_prefixes(rn, &p, &src_p);
|
||||
if (prefix_match (p, &rn->p))
|
||||
{
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
|
||||
vrf_header = 0;
|
||||
if (first)
|
||||
{
|
||||
vty_out (vty, SHOW_ROUTE_V6_HEADER);
|
||||
first = 0;
|
||||
}
|
||||
|
||||
if (vrf_header)
|
||||
{
|
||||
vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE);
|
||||
vrf_header = 0;
|
||||
}
|
||||
vty_show_ip_route (vty, rn, rib, NULL);
|
||||
}
|
||||
vty_show_ip_route (vty, rn, rib, NULL);
|
||||
}
|
||||
}
|
||||
vrf_header = 1;
|
||||
}
|
||||
|
||||
@ -3386,7 +3396,7 @@ DEFUN (show_ipv6_route_vrf_all_protocol,
|
||||
continue;
|
||||
|
||||
/* Show matched type IPv6 routes. */
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
if (rib->type == type)
|
||||
{
|
||||
@ -3539,7 +3549,7 @@ DEFUN (show_ipv6_mroute_vrf_all,
|
||||
continue;
|
||||
|
||||
/* Show all IPv6 route. */
|
||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||
for (rn = route_top (table); rn; rn = srcdest_route_next (rn))
|
||||
RNODE_FOREACH_RIB (rn, rib)
|
||||
{
|
||||
if (first)
|
||||
|
||||
@ -601,7 +601,7 @@ zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
|
||||
*/
|
||||
int
|
||||
zsend_redistribute_route (int add, struct zserv *client, struct prefix *p,
|
||||
struct rib *rib)
|
||||
struct prefix *src_p, struct rib *rib)
|
||||
{
|
||||
afi_t afi;
|
||||
int cmd;
|
||||
@ -667,6 +667,14 @@ zsend_redistribute_route (int add, struct zserv *client, struct prefix *p,
|
||||
stream_putc (s, p->prefixlen);
|
||||
stream_write (s, (u_char *) & p->u.prefix, psize);
|
||||
|
||||
if (src_p)
|
||||
{
|
||||
SET_FLAG (zapi_flags, ZAPI_MESSAGE_SRCPFX);
|
||||
psize = PSIZE (src_p->prefixlen);
|
||||
stream_putc (s, src_p->prefixlen);
|
||||
stream_write (s, (u_char *) & src_p->u.prefix, psize);
|
||||
}
|
||||
|
||||
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
|
||||
{
|
||||
/* We don't send any nexthops when there's a multipath */
|
||||
|
||||
@ -162,7 +162,7 @@ extern void nbr_connected_add_ipv6 (struct interface *, struct in6_addr *);
|
||||
extern void nbr_connected_delete_ipv6 (struct interface *, struct in6_addr *);
|
||||
extern int zsend_interface_update (int, struct zserv *, struct interface *);
|
||||
extern int zsend_redistribute_route (int, struct zserv *, struct prefix *,
|
||||
struct rib *);
|
||||
struct prefix *, struct rib *);
|
||||
extern int zsend_router_id_update (struct zserv *, struct prefix *,
|
||||
vrf_id_t);
|
||||
extern int zsend_interface_vrf_update (struct zserv *, struct interface *,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user