mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-06-24 05:49:46 +00:00
Multi-Instance OSPF Summary
——————————————------------- - etc/init.d/quagga is modified to support creating separate ospf daemon process for each instance. Each individual instance is monitored by watchquagga just like any protocol daemons.(requires initd-mi.patch). - Vtysh is modified to able to connect to multiple daemons of the same protocol (supported for OSPF only for now). - ospfd is modified to remember the Instance-ID that its invoked with. For the entire life of the process it caters to any command request that matches that instance-ID (unless its a non instance specific command). Routes/messages to zebra are tagged with instance-ID. - zebra route/redistribute mechanisms are modified to work with [protocol type + instance-id] - bgpd now has ability to have multiple instance specific redistribution for a protocol (OSPF only supported/tested for now). - zlog ability to display instance-id besides the protocol/daemon name. - Changes in other daemons are to because of the needed integration with some of the modified APIs/routines. (Didn’t prefer replicating too many separate instance specific APIs.) - config/show/debug commands are modified to take instance-id argument as appropriate. Guidelines to start using multi-instance ospf --------------------------------------------- The patch is backward compatible, i.e for any previous way of single ospf deamon(router ospf <cr>) will continue to work as is, including all the show commands etc. To enable multiple instances, do the following: 1. service quagga stop 2. Modify /etc/quagga/daemons to add instance-ids of each desired instance in the following format: ospfd=“yes" ospfd_instances="1,2,3" assuming you want to enable 3 instances with those instance ids. 3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf and ospfd-3.conf. 4. service quagga start/restart 5. Verify that the deamons are started as expected. You should see ospfd started with -n <instance-id> option. ps –ef | grep quagga With that /var/run/quagga/ should have ospfd-<instance-id>.pid and ospfd-<instance-id>/vty to each instance. 6. vtysh to work with instances as you would with any other deamons. 7. Overall most quagga semantics are the same working with the instance deamon, like it is for any other daemon. NOTE: To safeguard against errors leading to too many processes getting invoked, a hard limit on number of instance-ids is in place, currently its 5. Allowed instance-id range is <1-65535> Once daemons are up, show running from vtysh should show the instance-id of each daemon as 'router ospf <instance-id>’ (without needing explicit configuration) Instance-id can not be changed via vtysh, other router ospf configuration is allowed as before. Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com> Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
This commit is contained in:
parent
8c5fbd4858
commit
7c8ff89e93
@ -187,7 +187,7 @@ babel_init(int argc, char **argv)
|
|||||||
progname = babel_get_progname(argv[0]);
|
progname = babel_get_progname(argv[0]);
|
||||||
|
|
||||||
/* set default log (lib/log.h) */
|
/* set default log (lib/log.h) */
|
||||||
zlog_default = openzlog(progname, ZLOG_BABEL,
|
zlog_default = openzlog(progname, ZLOG_BABEL, 0,
|
||||||
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
||||||
/* set log destination as stdout until the config file is read */
|
/* set log destination as stdout until the config file is read */
|
||||||
zlog_set_level(NULL, ZLOG_DEST_STDOUT, LOG_WARNING);
|
zlog_set_level(NULL, ZLOG_DEST_STDOUT, LOG_WARNING);
|
||||||
|
@ -99,6 +99,7 @@ babel_zebra_read_ipv6 (int command, struct zclient *zclient,
|
|||||||
|
|
||||||
/* Type, flags, message. */
|
/* Type, flags, message. */
|
||||||
api.type = stream_getc (s);
|
api.type = stream_getc (s);
|
||||||
|
api.instance = stream_getw (s);
|
||||||
api.flags = stream_getc (s);
|
api.flags = stream_getc (s);
|
||||||
api.message = stream_getc (s);
|
api.message = stream_getc (s);
|
||||||
|
|
||||||
@ -151,6 +152,7 @@ babel_zebra_read_ipv4 (int command, struct zclient *zclient,
|
|||||||
|
|
||||||
/* Type, flags, message. */
|
/* Type, flags, message. */
|
||||||
api.type = stream_getc (s);
|
api.type = stream_getc (s);
|
||||||
|
api.instance = stream_getw (s);
|
||||||
api.flags = stream_getc (s);
|
api.flags = stream_getc (s);
|
||||||
api.message = stream_getc (s);
|
api.message = stream_getc (s);
|
||||||
|
|
||||||
@ -205,7 +207,7 @@ DEFUN (babel_redistribute_type,
|
|||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
|
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type, 0);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +231,7 @@ DEFUN (no_babel_redistribute_type,
|
|||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
|
zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, 0);
|
||||||
/* perhaps should we remove xroutes having the same type... */
|
/* perhaps should we remove xroutes having the same type... */
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -332,7 +334,7 @@ debug_babel_config_write (struct vty * vty)
|
|||||||
void babelz_zebra_init(void)
|
void babelz_zebra_init(void)
|
||||||
{
|
{
|
||||||
zclient = zclient_new();
|
zclient = zclient_new();
|
||||||
zclient_init(zclient, ZEBRA_ROUTE_BABEL);
|
zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0);
|
||||||
|
|
||||||
zclient->interface_add = babel_interface_add;
|
zclient->interface_add = babel_interface_add;
|
||||||
zclient->interface_delete = babel_interface_delete;
|
zclient->interface_delete = babel_interface_delete;
|
||||||
@ -362,7 +364,7 @@ zebra_config_write (struct vty *vty)
|
|||||||
vty_out (vty, "no router zebra%s", VTY_NEWLINE);
|
vty_out (vty, "no router zebra%s", VTY_NEWLINE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (! zclient->redist[ZEBRA_ROUTE_BABEL])
|
else if (! zclient->redist[ZEBRA_ROUTE_BABEL].enabled)
|
||||||
{
|
{
|
||||||
vty_out (vty, "router zebra%s", VTY_NEWLINE);
|
vty_out (vty, "router zebra%s", VTY_NEWLINE);
|
||||||
vty_out (vty, " no redistribute babel%s", VTY_NEWLINE);
|
vty_out (vty, " no redistribute babel%s", VTY_NEWLINE);
|
||||||
|
@ -111,7 +111,8 @@ babel_config_write (struct vty *vty)
|
|||||||
lines = 1 + babel_enable_if_config_write (vty);
|
lines = 1 + babel_enable_if_config_write (vty);
|
||||||
/* list redistributed protocols */
|
/* list redistributed protocols */
|
||||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
||||||
if (i != zclient->redist_default && zclient->redist[i])
|
if (i != zclient->redist_default &&
|
||||||
|
zclient->redist[i].enabled)
|
||||||
{
|
{
|
||||||
vty_out (vty, " redistribute %s%s", zebra_route_string (i), VTY_NEWLINE);
|
vty_out (vty, " redistribute %s%s", zebra_route_string (i), VTY_NEWLINE);
|
||||||
lines++;
|
lines++;
|
||||||
|
@ -324,7 +324,7 @@ main (int argc, char **argv)
|
|||||||
/* Preserve name of myself. */
|
/* Preserve name of myself. */
|
||||||
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
|
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
|
||||||
|
|
||||||
zlog_default = openzlog (progname, ZLOG_BGP,
|
zlog_default = openzlog (progname, ZLOG_BGP, 0,
|
||||||
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
||||||
|
|
||||||
/* BGP master init. */
|
/* BGP master init. */
|
||||||
|
@ -2044,7 +2044,7 @@ bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct bgp_info *
|
static struct bgp_info *
|
||||||
info_make (int type, int sub_type, struct peer *peer, struct attr *attr,
|
info_make (int type, int sub_type, u_short instance, struct peer *peer, struct attr *attr,
|
||||||
struct bgp_node *rn)
|
struct bgp_node *rn)
|
||||||
{
|
{
|
||||||
struct bgp_info *new;
|
struct bgp_info *new;
|
||||||
@ -2052,6 +2052,7 @@ info_make (int type, int sub_type, struct peer *peer, struct attr *attr,
|
|||||||
/* Make new BGP info. */
|
/* Make new BGP info. */
|
||||||
new = XCALLOC (MTYPE_BGP_ROUTE, sizeof (struct bgp_info));
|
new = XCALLOC (MTYPE_BGP_ROUTE, sizeof (struct bgp_info));
|
||||||
new->type = type;
|
new->type = type;
|
||||||
|
new->instance = instance;
|
||||||
new->sub_type = sub_type;
|
new->sub_type = sub_type;
|
||||||
new->peer = peer;
|
new->peer = peer;
|
||||||
new->attr = attr;
|
new->attr = attr;
|
||||||
@ -2205,7 +2206,7 @@ bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
|
|||||||
p->prefixlen, rsclient->host);
|
p->prefixlen, rsclient->host);
|
||||||
}
|
}
|
||||||
|
|
||||||
new = info_make(type, sub_type, peer, attr_new, rn);
|
new = info_make(type, sub_type, 0, peer, attr_new, rn);
|
||||||
|
|
||||||
/* Update MPLS tag. */
|
/* Update MPLS tag. */
|
||||||
if (safi == SAFI_MPLS_VPN)
|
if (safi == SAFI_MPLS_VPN)
|
||||||
@ -2546,7 +2547,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make new BGP info. */
|
/* Make new BGP info. */
|
||||||
new = info_make(type, sub_type, peer, attr_new, rn);
|
new = info_make(type, sub_type, 0, peer, attr_new, rn);
|
||||||
|
|
||||||
/* Update MPLS tag. */
|
/* Update MPLS tag. */
|
||||||
if (safi == SAFI_MPLS_VPN)
|
if (safi == SAFI_MPLS_VPN)
|
||||||
@ -3671,7 +3672,7 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make new BGP info. */
|
/* Make new BGP info. */
|
||||||
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, bgp->peer_self,
|
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
|
||||||
attr_new, rn);
|
attr_new, rn);
|
||||||
/* Nexthop reachability check. */
|
/* Nexthop reachability check. */
|
||||||
if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
|
if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
|
||||||
@ -3821,7 +3822,7 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make new BGP info. */
|
/* Make new BGP info. */
|
||||||
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, bgp->peer_self, attr_new,
|
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self, attr_new,
|
||||||
rn);
|
rn);
|
||||||
/* Nexthop reachability check. */
|
/* Nexthop reachability check. */
|
||||||
if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
|
if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
|
||||||
@ -3886,7 +3887,7 @@ bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
|
|||||||
rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
|
rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
|
||||||
|
|
||||||
/* Make new BGP info. */
|
/* Make new BGP info. */
|
||||||
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, bgp->peer_self,
|
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
|
||||||
bgp_attr_default_intern(BGP_ORIGIN_IGP), rn);
|
bgp_attr_default_intern(BGP_ORIGIN_IGP), rn);
|
||||||
|
|
||||||
SET_FLAG (new->flags, BGP_INFO_VALID);
|
SET_FLAG (new->flags, BGP_INFO_VALID);
|
||||||
@ -5041,7 +5042,7 @@ bgp_aggregate_route (struct bgp *bgp, struct prefix *p, struct bgp_info *rinew,
|
|||||||
if (aggregate->count > 0)
|
if (aggregate->count > 0)
|
||||||
{
|
{
|
||||||
rn = bgp_node_get (table, p);
|
rn = bgp_node_get (table, p);
|
||||||
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, bgp->peer_self,
|
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
|
||||||
bgp_attr_aggregate_intern(bgp, origin, aspath, community,
|
bgp_attr_aggregate_intern(bgp, origin, aspath, community,
|
||||||
aggregate->as_set,
|
aggregate->as_set,
|
||||||
atomic_aggregate), rn);
|
atomic_aggregate), rn);
|
||||||
@ -5236,7 +5237,7 @@ bgp_aggregate_add (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi,
|
|||||||
if (aggregate->count)
|
if (aggregate->count)
|
||||||
{
|
{
|
||||||
rn = bgp_node_get (table, p);
|
rn = bgp_node_get (table, p);
|
||||||
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, bgp->peer_self,
|
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
|
||||||
bgp_attr_aggregate_intern(bgp, origin, aspath, community,
|
bgp_attr_aggregate_intern(bgp, origin, aspath, community,
|
||||||
aggregate->as_set,
|
aggregate->as_set,
|
||||||
atomic_aggregate), rn);
|
atomic_aggregate), rn);
|
||||||
@ -5766,7 +5767,7 @@ ALIAS (no_ipv6_aggregate_address_summary_only,
|
|||||||
void
|
void
|
||||||
bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
|
bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
|
||||||
const struct in6_addr *nexthop6, unsigned int ifindex,
|
const struct in6_addr *nexthop6, unsigned int ifindex,
|
||||||
u_int32_t metric, u_char type, u_short tag)
|
u_int32_t metric, u_char type, u_short instance, u_short tag)
|
||||||
{
|
{
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
@ -5778,6 +5779,7 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
|
|||||||
struct attr *new_attr;
|
struct attr *new_attr;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
int ret;
|
int ret;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
|
||||||
/* Make default attribute. */
|
/* Make default attribute. */
|
||||||
bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE);
|
bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE);
|
||||||
@ -5802,7 +5804,8 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
|
|||||||
{
|
{
|
||||||
afi = family2afi (p->family);
|
afi = family2afi (p->family);
|
||||||
|
|
||||||
if (bgp->redist[afi][type])
|
red = bgp_redist_lookup(bgp, afi, type, instance);
|
||||||
|
if (red)
|
||||||
{
|
{
|
||||||
struct attr attr_new;
|
struct attr attr_new;
|
||||||
struct attr_extra extra_new;
|
struct attr_extra extra_new;
|
||||||
@ -5811,19 +5814,18 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
|
|||||||
attr_new.extra = &extra_new;
|
attr_new.extra = &extra_new;
|
||||||
bgp_attr_dup (&attr_new, &attr);
|
bgp_attr_dup (&attr_new, &attr);
|
||||||
|
|
||||||
if (bgp->redist_metric_flag[afi][type])
|
if (red->redist_metric_flag)
|
||||||
attr_new.med = bgp->redist_metric[afi][type];
|
attr_new.med = red->redist_metric;
|
||||||
|
|
||||||
/* Apply route-map. */
|
/* Apply route-map. */
|
||||||
if (bgp->rmap[afi][type].map)
|
if (red->rmap.map)
|
||||||
{
|
{
|
||||||
info.peer = bgp->peer_self;
|
info.peer = bgp->peer_self;
|
||||||
info.attr = &attr_new;
|
info.attr = &attr_new;
|
||||||
|
|
||||||
SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE);
|
SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE);
|
||||||
|
|
||||||
ret = route_map_apply (bgp->rmap[afi][type].map, p, RMAP_BGP,
|
ret = route_map_apply (red->rmap.map, p, RMAP_BGP, &info);
|
||||||
&info);
|
|
||||||
|
|
||||||
bgp->peer_self->rmap_type = 0;
|
bgp->peer_self->rmap_type = 0;
|
||||||
|
|
||||||
@ -5835,7 +5837,7 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
|
|||||||
/* Unintern original. */
|
/* Unintern original. */
|
||||||
aspath_unintern (&attr.aspath);
|
aspath_unintern (&attr.aspath);
|
||||||
bgp_attr_extra_free (&attr);
|
bgp_attr_extra_free (&attr);
|
||||||
bgp_redistribute_delete (p, type);
|
bgp_redistribute_delete (p, type, instance);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5885,7 +5887,7 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new = info_make(type, BGP_ROUTE_REDISTRIBUTE, bgp->peer_self,
|
new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance, bgp->peer_self,
|
||||||
new_attr, bn);
|
new_attr, bn);
|
||||||
SET_FLAG (new->flags, BGP_INFO_VALID);
|
SET_FLAG (new->flags, BGP_INFO_VALID);
|
||||||
|
|
||||||
@ -5902,19 +5904,21 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bgp_redistribute_delete (struct prefix *p, u_char type)
|
bgp_redistribute_delete (struct prefix *p, u_char type, u_short instance)
|
||||||
{
|
{
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_info *ri;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
|
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
|
||||||
{
|
{
|
||||||
afi = family2afi (p->family);
|
afi = family2afi (p->family);
|
||||||
|
|
||||||
if (bgp->redist[afi][type])
|
red = bgp_redist_lookup(bgp, afi, type, instance);
|
||||||
|
if (red)
|
||||||
{
|
{
|
||||||
rn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST, p, NULL);
|
rn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST, p, NULL);
|
||||||
|
|
||||||
@ -5936,7 +5940,7 @@ bgp_redistribute_delete (struct prefix *p, u_char type)
|
|||||||
|
|
||||||
/* Withdraw specified route type's route. */
|
/* Withdraw specified route type's route. */
|
||||||
void
|
void
|
||||||
bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type)
|
bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type, u_short instance)
|
||||||
{
|
{
|
||||||
struct bgp_node *rn;
|
struct bgp_node *rn;
|
||||||
struct bgp_info *ri;
|
struct bgp_info *ri;
|
||||||
@ -5948,7 +5952,8 @@ bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type)
|
|||||||
{
|
{
|
||||||
for (ri = rn->info; ri; ri = ri->next)
|
for (ri = rn->info; ri; ri = ri->next)
|
||||||
if (ri->peer == bgp->peer_self
|
if (ri->peer == bgp->peer_self
|
||||||
&& ri->type == type)
|
&& ri->type == type
|
||||||
|
&& ri->instance == instance)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (ri)
|
if (ri)
|
||||||
|
@ -105,6 +105,9 @@ struct bgp_info
|
|||||||
#define BGP_ROUTE_STATIC 1
|
#define BGP_ROUTE_STATIC 1
|
||||||
#define BGP_ROUTE_AGGREGATE 2
|
#define BGP_ROUTE_AGGREGATE 2
|
||||||
#define BGP_ROUTE_REDISTRIBUTE 3
|
#define BGP_ROUTE_REDISTRIBUTE 3
|
||||||
|
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* BGP static route configuration. */
|
/* BGP static route configuration. */
|
||||||
@ -224,9 +227,9 @@ extern int bgp_maximum_prefix_overflow (struct peer *, afi_t, safi_t, int);
|
|||||||
|
|
||||||
extern void bgp_redistribute_add (struct prefix *, const struct in_addr *,
|
extern void bgp_redistribute_add (struct prefix *, const struct in_addr *,
|
||||||
const struct in6_addr *, unsigned int ifindex,
|
const struct in6_addr *, unsigned int ifindex,
|
||||||
u_int32_t, u_char, u_short);
|
u_int32_t, u_char, u_short, u_short);
|
||||||
extern void bgp_redistribute_delete (struct prefix *, u_char);
|
extern void bgp_redistribute_delete (struct prefix *, u_char, u_short);
|
||||||
extern void bgp_redistribute_withdraw (struct bgp *, afi_t, int);
|
extern void bgp_redistribute_withdraw (struct bgp *, afi_t, int, u_short);
|
||||||
|
|
||||||
extern void bgp_static_delete (struct bgp *);
|
extern void bgp_static_delete (struct bgp *);
|
||||||
extern void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static *,
|
extern void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static *,
|
||||||
|
@ -2791,7 +2791,7 @@ bgp_route_map_process_update (void *arg, char *rmap_name, int route_update)
|
|||||||
char buf[INET6_ADDRSTRLEN];
|
char buf[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
if (!bgp)
|
if (!bgp)
|
||||||
return;
|
return (-1);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
|
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
|
||||||
{
|
{
|
||||||
@ -2875,20 +2875,31 @@ bgp_route_map_process_update (void *arg, char *rmap_name, int route_update)
|
|||||||
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
||||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
||||||
{
|
{
|
||||||
if (bgp->rmap[afi][i].name &&
|
struct list *red_list;
|
||||||
(strcmp(rmap_name, bgp->rmap[afi][i].name) == 0))
|
struct listnode *node;
|
||||||
{
|
struct bgp_redist *red;
|
||||||
bgp->rmap[afi][i].map =
|
|
||||||
route_map_lookup_by_name (bgp->rmap[afi][i].name);
|
|
||||||
|
|
||||||
if (bgp->redist[afi][i] && route_update)
|
red_list = bgp->redist[afi][i];
|
||||||
{
|
if (!red_list)
|
||||||
if (BGP_DEBUG (zebra, ZEBRA))
|
continue;
|
||||||
zlog_debug("Processing route_map %s update on "
|
|
||||||
"redistributed routes", rmap_name);
|
|
||||||
|
|
||||||
bgp_redistribute_resend (bgp, afi, i);
|
for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
|
||||||
}
|
{
|
||||||
|
if (red->rmap.name &&
|
||||||
|
(strcmp(rmap_name, red->rmap.name) == 0))
|
||||||
|
{
|
||||||
|
red->rmap.map =
|
||||||
|
route_map_lookup_by_name (red->rmap.name);
|
||||||
|
|
||||||
|
if (route_update)
|
||||||
|
{
|
||||||
|
if (bgp_debug_update(peer, NULL, 0))
|
||||||
|
zlog_debug("Processing route_map %s update on "
|
||||||
|
"redistributed routes", rmap_name);
|
||||||
|
|
||||||
|
bgp_redistribute_resend (bgp, afi, i, red->instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
268
bgpd/bgp_vty.c
268
bgpd/bgp_vty.c
@ -9639,7 +9639,8 @@ DEFUN (bgp_redistribute_ipv4,
|
|||||||
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
|
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
return bgp_redistribute_set (vty->index, AFI_IP, type);
|
bgp_redist_add(vty->index, AFI_IP, type, 0);
|
||||||
|
return bgp_redistribute_set (type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (bgp_redistribute_ipv4_rmap,
|
DEFUN (bgp_redistribute_ipv4_rmap,
|
||||||
@ -9651,6 +9652,7 @@ DEFUN (bgp_redistribute_ipv4_rmap,
|
|||||||
"Pointer to route-map entries\n")
|
"Pointer to route-map entries\n")
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
|
||||||
type = proto_redistnum (AFI_IP, argv[0]);
|
type = proto_redistnum (AFI_IP, argv[0]);
|
||||||
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
||||||
@ -9659,8 +9661,9 @@ DEFUN (bgp_redistribute_ipv4_rmap,
|
|||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
bgp_redistribute_rmap_set (vty->index, AFI_IP, type, argv[1]);
|
red = bgp_redist_add(vty->index, AFI_IP, type, 0);
|
||||||
return bgp_redistribute_set (vty->index, AFI_IP, type);
|
bgp_redistribute_rmap_set (red, argv[1]);
|
||||||
|
return bgp_redistribute_set (type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (bgp_redistribute_ipv4_metric,
|
DEFUN (bgp_redistribute_ipv4_metric,
|
||||||
@ -9673,6 +9676,7 @@ DEFUN (bgp_redistribute_ipv4_metric,
|
|||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
u_int32_t metric;
|
u_int32_t metric;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
|
||||||
type = proto_redistnum (AFI_IP, argv[0]);
|
type = proto_redistnum (AFI_IP, argv[0]);
|
||||||
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
||||||
@ -9682,8 +9686,9 @@ DEFUN (bgp_redistribute_ipv4_metric,
|
|||||||
}
|
}
|
||||||
VTY_GET_INTEGER ("metric", metric, argv[1]);
|
VTY_GET_INTEGER ("metric", metric, argv[1]);
|
||||||
|
|
||||||
bgp_redistribute_metric_set (vty->index, AFI_IP, type, metric);
|
red = bgp_redist_add(vty->index, AFI_IP, type, 0);
|
||||||
return bgp_redistribute_set (vty->index, AFI_IP, type);
|
bgp_redistribute_metric_set (red, metric);
|
||||||
|
return bgp_redistribute_set (type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (bgp_redistribute_ipv4_rmap_metric,
|
DEFUN (bgp_redistribute_ipv4_rmap_metric,
|
||||||
@ -9698,6 +9703,7 @@ DEFUN (bgp_redistribute_ipv4_rmap_metric,
|
|||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
u_int32_t metric;
|
u_int32_t metric;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
|
||||||
type = proto_redistnum (AFI_IP, argv[0]);
|
type = proto_redistnum (AFI_IP, argv[0]);
|
||||||
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
||||||
@ -9707,9 +9713,10 @@ DEFUN (bgp_redistribute_ipv4_rmap_metric,
|
|||||||
}
|
}
|
||||||
VTY_GET_INTEGER ("metric", metric, argv[2]);
|
VTY_GET_INTEGER ("metric", metric, argv[2]);
|
||||||
|
|
||||||
bgp_redistribute_rmap_set (vty->index, AFI_IP, type, argv[1]);
|
red = bgp_redist_add(vty->index, AFI_IP, type, 0);
|
||||||
bgp_redistribute_metric_set (vty->index, AFI_IP, type, metric);
|
bgp_redistribute_rmap_set (red, argv[1]);
|
||||||
return bgp_redistribute_set (vty->index, AFI_IP, type);
|
bgp_redistribute_metric_set (red, metric);
|
||||||
|
return bgp_redistribute_set (type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (bgp_redistribute_ipv4_metric_rmap,
|
DEFUN (bgp_redistribute_ipv4_metric_rmap,
|
||||||
@ -9724,6 +9731,7 @@ DEFUN (bgp_redistribute_ipv4_metric_rmap,
|
|||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
u_int32_t metric;
|
u_int32_t metric;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
|
||||||
type = proto_redistnum (AFI_IP, argv[0]);
|
type = proto_redistnum (AFI_IP, argv[0]);
|
||||||
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
||||||
@ -9733,11 +9741,171 @@ DEFUN (bgp_redistribute_ipv4_metric_rmap,
|
|||||||
}
|
}
|
||||||
VTY_GET_INTEGER ("metric", metric, argv[1]);
|
VTY_GET_INTEGER ("metric", metric, argv[1]);
|
||||||
|
|
||||||
bgp_redistribute_metric_set (vty->index, AFI_IP, type, metric);
|
red = bgp_redist_add(vty->index, AFI_IP, type, 0);
|
||||||
bgp_redistribute_rmap_set (vty->index, AFI_IP, type, argv[2]);
|
bgp_redistribute_metric_set (red, metric);
|
||||||
return bgp_redistribute_set (vty->index, AFI_IP, type);
|
bgp_redistribute_rmap_set (red, argv[2]);
|
||||||
|
return bgp_redistribute_set (type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFUN (bgp_redistribute_ipv4_ospf,
|
||||||
|
bgp_redistribute_ipv4_ospf_cmd,
|
||||||
|
"redistribute ospf <1-65535>",
|
||||||
|
"Redistribute information from another routing protocol\n"
|
||||||
|
"Open Shortest Path First (OSPFv2)\n"
|
||||||
|
"Instance ID\n")
|
||||||
|
{
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
|
VTY_GET_INTEGER ("Instance ID", instance, argv[0]);
|
||||||
|
bgp_redist_add(vty->index, AFI_IP, ZEBRA_ROUTE_OSPF, instance);
|
||||||
|
return bgp_redistribute_set (ZEBRA_ROUTE_OSPF, instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (bgp_redistribute_ipv4_ospf_rmap,
|
||||||
|
bgp_redistribute_ipv4_ospf_rmap_cmd,
|
||||||
|
"redistribute ospf <1-65535> route-map WORD",
|
||||||
|
"Redistribute information from another routing protocol\n"
|
||||||
|
"Open Shortest Path First (OSPFv2)\n"
|
||||||
|
"Instance ID\n"
|
||||||
|
"Route map reference\n"
|
||||||
|
"Pointer to route-map entries\n")
|
||||||
|
{
|
||||||
|
struct bgp_redist *red;
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
|
VTY_GET_INTEGER ("Instance ID", instance, argv[0]);
|
||||||
|
red = bgp_redist_add(vty->index, AFI_IP, ZEBRA_ROUTE_OSPF, instance);
|
||||||
|
bgp_redistribute_rmap_set (red, argv[1]);
|
||||||
|
return bgp_redistribute_set (ZEBRA_ROUTE_OSPF, instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (bgp_redistribute_ipv4_ospf_metric,
|
||||||
|
bgp_redistribute_ipv4_ospf_metric_cmd,
|
||||||
|
"redistribute ospf <1-65535> metric <0-4294967295>",
|
||||||
|
"Redistribute information from another routing protocol\n"
|
||||||
|
"Open Shortest Path First (OSPFv2)\n"
|
||||||
|
"Instance ID\n"
|
||||||
|
"Metric for redistributed routes\n"
|
||||||
|
"Default metric\n")
|
||||||
|
{
|
||||||
|
u_int32_t metric;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
|
VTY_GET_INTEGER ("Instance ID", instance, argv[0]);
|
||||||
|
VTY_GET_INTEGER ("metric", metric, argv[1]);
|
||||||
|
|
||||||
|
red = bgp_redist_add(vty->index, AFI_IP, ZEBRA_ROUTE_OSPF, instance);
|
||||||
|
bgp_redistribute_metric_set (red, metric);
|
||||||
|
return bgp_redistribute_set (ZEBRA_ROUTE_OSPF, instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric,
|
||||||
|
bgp_redistribute_ipv4_ospf_rmap_metric_cmd,
|
||||||
|
"redistribute ospf <1-65535> route-map WORD metric <0-4294967295>",
|
||||||
|
"Redistribute information from another routing protocol\n"
|
||||||
|
"Open Shortest Path First (OSPFv2)\n"
|
||||||
|
"Instance ID\n"
|
||||||
|
"Route map reference\n"
|
||||||
|
"Pointer to route-map entries\n"
|
||||||
|
"Metric for redistributed routes\n"
|
||||||
|
"Default metric\n")
|
||||||
|
{
|
||||||
|
u_int32_t metric;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
|
VTY_GET_INTEGER ("Instance ID", instance, argv[0]);
|
||||||
|
VTY_GET_INTEGER ("metric", metric, argv[2]);
|
||||||
|
|
||||||
|
red = bgp_redist_add(vty->index, AFI_IP, ZEBRA_ROUTE_OSPF, instance);
|
||||||
|
bgp_redistribute_rmap_set (red, argv[1]);
|
||||||
|
bgp_redistribute_metric_set (red, metric);
|
||||||
|
return bgp_redistribute_set (ZEBRA_ROUTE_OSPF, instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap,
|
||||||
|
bgp_redistribute_ipv4_ospf_metric_rmap_cmd,
|
||||||
|
"redistribute ospf <1-65535> metric <0-4294967295> route-map WORD",
|
||||||
|
"Redistribute information from another routing protocol\n"
|
||||||
|
"Open Shortest Path First (OSPFv2)\n"
|
||||||
|
"Instance ID\n"
|
||||||
|
"Metric for redistributed routes\n"
|
||||||
|
"Default metric\n"
|
||||||
|
"Route map reference\n"
|
||||||
|
"Pointer to route-map entries\n")
|
||||||
|
{
|
||||||
|
u_int32_t metric;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
|
VTY_GET_INTEGER ("Instance ID", instance, argv[0]);
|
||||||
|
VTY_GET_INTEGER ("metric", metric, argv[1]);
|
||||||
|
|
||||||
|
red = bgp_redist_add(vty->index, AFI_IP, ZEBRA_ROUTE_OSPF, instance);
|
||||||
|
bgp_redistribute_metric_set (red, metric);
|
||||||
|
bgp_redistribute_rmap_set (red, argv[2]);
|
||||||
|
return bgp_redistribute_set (ZEBRA_ROUTE_OSPF, instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (no_bgp_redistribute_ipv4_ospf,
|
||||||
|
no_bgp_redistribute_ipv4_ospf_cmd,
|
||||||
|
"no redistribute ospf <1-65535>",
|
||||||
|
NO_STR
|
||||||
|
"Redistribute information from another routing protocol\n"
|
||||||
|
"Open Shortest Path First (OSPFv2)\n"
|
||||||
|
"Instance ID\n")
|
||||||
|
{
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
|
VTY_GET_INTEGER ("Instance ID", instance, argv[0]);
|
||||||
|
return bgp_redistribute_unset (vty->index, AFI_IP, ZEBRA_ROUTE_OSPF, instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALIAS (no_bgp_redistribute_ipv4_ospf,
|
||||||
|
no_bgp_redistribute_ipv4_ospf_rmap_cmd,
|
||||||
|
"no redistribute ospf <1-65535> route-map WORD",
|
||||||
|
NO_STR
|
||||||
|
"Redistribute information from another routing protocol\n"
|
||||||
|
"Open Shortest Path First (OSPFv2)\n"
|
||||||
|
"Instance ID\n"
|
||||||
|
"Route map reference\n"
|
||||||
|
"Pointer to route-map entries\n")
|
||||||
|
|
||||||
|
ALIAS (no_bgp_redistribute_ipv4_ospf,
|
||||||
|
no_bgp_redistribute_ipv4_ospf_metric_cmd,
|
||||||
|
"no redistribute ospf <1-65535> metric <0-4294967295>",
|
||||||
|
NO_STR
|
||||||
|
"Redistribute information from another routing protocol\n"
|
||||||
|
"Open Shortest Path First (OSPFv2)\n"
|
||||||
|
"Instance ID\n"
|
||||||
|
"Metric for redistributed routes\n"
|
||||||
|
"Default metric\n")
|
||||||
|
|
||||||
|
ALIAS (no_bgp_redistribute_ipv4_ospf,
|
||||||
|
no_bgp_redistribute_ipv4_ospf_rmap_metric_cmd,
|
||||||
|
"no redistribute ospf <1-65535> route-map WORD metric <0-4294967295>",
|
||||||
|
NO_STR
|
||||||
|
"Redistribute information from another routing protocol\n"
|
||||||
|
"Open Shortest Path First (OSPFv2)\n"
|
||||||
|
"Instance ID\n"
|
||||||
|
"Route map reference\n"
|
||||||
|
"Pointer to route-map entries\n"
|
||||||
|
"Metric for redistributed routes\n"
|
||||||
|
"Default metric\n")
|
||||||
|
|
||||||
|
ALIAS (no_bgp_redistribute_ipv4_ospf,
|
||||||
|
no_bgp_redistribute_ipv4_ospf_metric_rmap_cmd,
|
||||||
|
"no redistribute ospf <1-65535> metric <0-4294967295> route-map WORD",
|
||||||
|
NO_STR
|
||||||
|
"Redistribute information from another routing protocol\n"
|
||||||
|
"Open Shortest Path First (OSPFv2)\n"
|
||||||
|
"Instance ID\n"
|
||||||
|
"Metric for redistributed routes\n"
|
||||||
|
"Default metric\n"
|
||||||
|
"Route map reference\n"
|
||||||
|
"Pointer to route-map entries\n")
|
||||||
|
|
||||||
DEFUN (no_bgp_redistribute_ipv4,
|
DEFUN (no_bgp_redistribute_ipv4,
|
||||||
no_bgp_redistribute_ipv4_cmd,
|
no_bgp_redistribute_ipv4_cmd,
|
||||||
"no redistribute " QUAGGA_IP_REDIST_STR_BGPD,
|
"no redistribute " QUAGGA_IP_REDIST_STR_BGPD,
|
||||||
@ -9753,8 +9921,7 @@ DEFUN (no_bgp_redistribute_ipv4,
|
|||||||
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
|
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
return bgp_redistribute_unset (vty->index, AFI_IP, type, 0);
|
||||||
return bgp_redistribute_unset (vty->index, AFI_IP, type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ALIAS (no_bgp_redistribute_ipv4,
|
ALIAS (no_bgp_redistribute_ipv4,
|
||||||
@ -9813,7 +9980,8 @@ DEFUN (bgp_redistribute_ipv6,
|
|||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bgp_redistribute_set (vty->index, AFI_IP6, type);
|
bgp_redist_add(vty->index, AFI_IP6, type, 0);
|
||||||
|
return bgp_redistribute_set (type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (bgp_redistribute_ipv6_rmap,
|
DEFUN (bgp_redistribute_ipv6_rmap,
|
||||||
@ -9825,6 +9993,7 @@ DEFUN (bgp_redistribute_ipv6_rmap,
|
|||||||
"Pointer to route-map entries\n")
|
"Pointer to route-map entries\n")
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
|
||||||
type = proto_redistnum (AFI_IP6, argv[0]);
|
type = proto_redistnum (AFI_IP6, argv[0]);
|
||||||
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
||||||
@ -9833,8 +10002,9 @@ DEFUN (bgp_redistribute_ipv6_rmap,
|
|||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
bgp_redistribute_rmap_set (vty->index, AFI_IP6, type, argv[1]);
|
red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
|
||||||
return bgp_redistribute_set (vty->index, AFI_IP6, type);
|
bgp_redistribute_rmap_set (red, argv[1]);
|
||||||
|
return bgp_redistribute_set (type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (bgp_redistribute_ipv6_metric,
|
DEFUN (bgp_redistribute_ipv6_metric,
|
||||||
@ -9847,6 +10017,7 @@ DEFUN (bgp_redistribute_ipv6_metric,
|
|||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
u_int32_t metric;
|
u_int32_t metric;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
|
||||||
type = proto_redistnum (AFI_IP6, argv[0]);
|
type = proto_redistnum (AFI_IP6, argv[0]);
|
||||||
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
||||||
@ -9856,8 +10027,9 @@ DEFUN (bgp_redistribute_ipv6_metric,
|
|||||||
}
|
}
|
||||||
VTY_GET_INTEGER ("metric", metric, argv[1]);
|
VTY_GET_INTEGER ("metric", metric, argv[1]);
|
||||||
|
|
||||||
bgp_redistribute_metric_set (vty->index, AFI_IP6, type, metric);
|
red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
|
||||||
return bgp_redistribute_set (vty->index, AFI_IP6, type);
|
bgp_redistribute_metric_set (red, metric);
|
||||||
|
return bgp_redistribute_set (type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (bgp_redistribute_ipv6_rmap_metric,
|
DEFUN (bgp_redistribute_ipv6_rmap_metric,
|
||||||
@ -9872,6 +10044,7 @@ DEFUN (bgp_redistribute_ipv6_rmap_metric,
|
|||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
u_int32_t metric;
|
u_int32_t metric;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
|
||||||
type = proto_redistnum (AFI_IP6, argv[0]);
|
type = proto_redistnum (AFI_IP6, argv[0]);
|
||||||
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
||||||
@ -9881,9 +10054,10 @@ DEFUN (bgp_redistribute_ipv6_rmap_metric,
|
|||||||
}
|
}
|
||||||
VTY_GET_INTEGER ("metric", metric, argv[2]);
|
VTY_GET_INTEGER ("metric", metric, argv[2]);
|
||||||
|
|
||||||
bgp_redistribute_rmap_set (vty->index, AFI_IP6, type, argv[1]);
|
red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
|
||||||
bgp_redistribute_metric_set (vty->index, AFI_IP6, type, metric);
|
bgp_redistribute_rmap_set (red, argv[1]);
|
||||||
return bgp_redistribute_set (vty->index, AFI_IP6, type);
|
bgp_redistribute_metric_set (red, metric);
|
||||||
|
return bgp_redistribute_set (type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (bgp_redistribute_ipv6_metric_rmap,
|
DEFUN (bgp_redistribute_ipv6_metric_rmap,
|
||||||
@ -9898,6 +10072,7 @@ DEFUN (bgp_redistribute_ipv6_metric_rmap,
|
|||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
u_int32_t metric;
|
u_int32_t metric;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
|
||||||
type = proto_redistnum (AFI_IP6, argv[0]);
|
type = proto_redistnum (AFI_IP6, argv[0]);
|
||||||
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
if (type < 0 || type == ZEBRA_ROUTE_BGP)
|
||||||
@ -9907,9 +10082,10 @@ DEFUN (bgp_redistribute_ipv6_metric_rmap,
|
|||||||
}
|
}
|
||||||
VTY_GET_INTEGER ("metric", metric, argv[1]);
|
VTY_GET_INTEGER ("metric", metric, argv[1]);
|
||||||
|
|
||||||
bgp_redistribute_metric_set (vty->index, AFI_IP6, type, metric);
|
red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
|
||||||
bgp_redistribute_rmap_set (vty->index, AFI_IP6, type, argv[2]);
|
bgp_redistribute_metric_set (red, metric);
|
||||||
return bgp_redistribute_set (vty->index, AFI_IP6, type);
|
bgp_redistribute_rmap_set (red, argv[2]);
|
||||||
|
return bgp_redistribute_set (type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (no_bgp_redistribute_ipv6,
|
DEFUN (no_bgp_redistribute_ipv6,
|
||||||
@ -9928,7 +10104,7 @@ DEFUN (no_bgp_redistribute_ipv6,
|
|||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bgp_redistribute_unset (vty->index, AFI_IP6, type);
|
return bgp_redistribute_unset (vty->index, AFI_IP6, type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALIAS (no_bgp_redistribute_ipv6,
|
ALIAS (no_bgp_redistribute_ipv6,
|
||||||
@ -9985,21 +10161,31 @@ bgp_config_write_redistribute (struct vty *vty, struct bgp *bgp, afi_t afi,
|
|||||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
||||||
{
|
{
|
||||||
/* Redistribute BGP does not make sense. */
|
/* Redistribute BGP does not make sense. */
|
||||||
if (bgp->redist[afi][i] && i != ZEBRA_ROUTE_BGP)
|
if (i != ZEBRA_ROUTE_BGP)
|
||||||
{
|
{
|
||||||
/* Display "address-family" when it is not yet diplayed. */
|
struct list *red_list;
|
||||||
bgp_config_write_family_header (vty, afi, safi, write);
|
struct listnode *node;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
|
||||||
/* "redistribute" configuration. */
|
red_list = bgp->redist[afi][i];
|
||||||
vty_out (vty, " redistribute %s", zebra_route_string(i));
|
if (!red_list)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (bgp->redist_metric_flag[afi][i])
|
for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
|
||||||
vty_out (vty, " metric %u", bgp->redist_metric[afi][i]);
|
{
|
||||||
|
/* Display "address-family" when it is not yet diplayed. */
|
||||||
|
bgp_config_write_family_header (vty, afi, safi, write);
|
||||||
|
|
||||||
if (bgp->rmap[afi][i].name)
|
/* "redistribute" configuration. */
|
||||||
vty_out (vty, " route-map %s", bgp->rmap[afi][i].name);
|
vty_out (vty, " redistribute %s", zebra_route_string(i));
|
||||||
|
if (red->instance)
|
||||||
vty_out (vty, "%s", VTY_NEWLINE);
|
vty_out (vty, " %d", red->instance);
|
||||||
|
if (red->redist_metric_flag)
|
||||||
|
vty_out (vty, " metric %u", red->redist_metric);
|
||||||
|
if (red->rmap.name)
|
||||||
|
vty_out (vty, " route-map %s", red->rmap.name);
|
||||||
|
vty_out (vty, "%s", VTY_NEWLINE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return *write;
|
return *write;
|
||||||
@ -11264,6 +11450,16 @@ bgp_vty_init (void)
|
|||||||
install_element (BGP_NODE, &bgp_redistribute_ipv4_metric_rmap_cmd);
|
install_element (BGP_NODE, &bgp_redistribute_ipv4_metric_rmap_cmd);
|
||||||
install_element (BGP_NODE, &no_bgp_redistribute_ipv4_rmap_metric_cmd);
|
install_element (BGP_NODE, &no_bgp_redistribute_ipv4_rmap_metric_cmd);
|
||||||
install_element (BGP_NODE, &no_bgp_redistribute_ipv4_metric_rmap_cmd);
|
install_element (BGP_NODE, &no_bgp_redistribute_ipv4_metric_rmap_cmd);
|
||||||
|
install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_cmd);
|
||||||
|
install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_cmd);
|
||||||
|
install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_rmap_cmd);
|
||||||
|
install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_rmap_cmd);
|
||||||
|
install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_metric_cmd);
|
||||||
|
install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_metric_cmd);
|
||||||
|
install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_rmap_metric_cmd);
|
||||||
|
install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_rmap_metric_cmd);
|
||||||
|
install_element (BGP_NODE, &bgp_redistribute_ipv4_ospf_metric_rmap_cmd);
|
||||||
|
install_element (BGP_NODE, &no_bgp_redistribute_ipv4_ospf_metric_rmap_cmd);
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
install_element (BGP_IPV6_NODE, &bgp_redistribute_ipv6_cmd);
|
install_element (BGP_IPV6_NODE, &bgp_redistribute_ipv6_cmd);
|
||||||
install_element (BGP_IPV6_NODE, &no_bgp_redistribute_ipv6_cmd);
|
install_element (BGP_IPV6_NODE, &no_bgp_redistribute_ipv6_cmd);
|
||||||
|
180
bgpd/bgp_zebra.c
180
bgpd/bgp_zebra.c
@ -428,6 +428,7 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
|
|
||||||
/* Type, flags, message. */
|
/* Type, flags, message. */
|
||||||
api.type = stream_getc (s);
|
api.type = stream_getc (s);
|
||||||
|
api.instance = stream_getw (s);
|
||||||
api.flags = stream_getc (s);
|
api.flags = stream_getc (s);
|
||||||
api.message = stream_getc (s);
|
api.message = stream_getc (s);
|
||||||
|
|
||||||
@ -468,8 +469,8 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
if (bgp_debug_zebra(&p))
|
if (bgp_debug_zebra(&p))
|
||||||
{
|
{
|
||||||
char buf[2][INET_ADDRSTRLEN];
|
char buf[2][INET_ADDRSTRLEN];
|
||||||
zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u tag %d",
|
zlog_debug("Zebra rcvd: IPv4 route add %s[%d] %s/%d nexthop %s metric %u tag %d",
|
||||||
zebra_route_string(api.type),
|
zebra_route_string(api.type), api.instance,
|
||||||
inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
|
inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
|
||||||
p.prefixlen,
|
p.prefixlen,
|
||||||
inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
|
inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
|
||||||
@ -477,23 +478,23 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
api.tag);
|
api.tag);
|
||||||
}
|
}
|
||||||
bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL, ifindex,
|
bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL, ifindex,
|
||||||
api.metric, api.type, api.tag);
|
api.metric, api.type, api.instance, api.tag);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bgp_debug_zebra(&p))
|
if (bgp_debug_zebra(&p))
|
||||||
{
|
{
|
||||||
char buf[2][INET_ADDRSTRLEN];
|
char buf[2][INET_ADDRSTRLEN];
|
||||||
zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
|
zlog_debug("Zebra rcvd: IPv4 route delete %s[%d] %s/%d "
|
||||||
"nexthop %s metric %u tag %d",
|
"nexthop %s metric %u tag %d",
|
||||||
zebra_route_string(api.type),
|
zebra_route_string(api.type), api.instance,
|
||||||
inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
|
inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
|
||||||
p.prefixlen,
|
p.prefixlen,
|
||||||
inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
|
inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
|
||||||
api.metric,
|
api.metric,
|
||||||
api.tag);
|
api.tag);
|
||||||
}
|
}
|
||||||
bgp_redistribute_delete((struct prefix *)&p, api.type);
|
bgp_redistribute_delete((struct prefix *)&p, api.type, api.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -515,6 +516,7 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
|
|
||||||
/* Type, flags, message. */
|
/* Type, flags, message. */
|
||||||
api.type = stream_getc (s);
|
api.type = stream_getc (s);
|
||||||
|
api.instance = stream_getw (s);
|
||||||
api.flags = stream_getc (s);
|
api.flags = stream_getc (s);
|
||||||
api.message = stream_getc (s);
|
api.message = stream_getc (s);
|
||||||
|
|
||||||
@ -561,8 +563,8 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
if (bgp_debug_zebra(&p))
|
if (bgp_debug_zebra(&p))
|
||||||
{
|
{
|
||||||
char buf[2][INET6_ADDRSTRLEN];
|
char buf[2][INET6_ADDRSTRLEN];
|
||||||
zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u tag %d",
|
zlog_debug("Zebra rcvd: IPv6 route add %s[%d] %s/%d nexthop %s metric %u tag %d",
|
||||||
zebra_route_string(api.type),
|
zebra_route_string(api.type), api.instance,
|
||||||
inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
|
inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
|
||||||
p.prefixlen,
|
p.prefixlen,
|
||||||
inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
|
inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
|
||||||
@ -570,23 +572,23 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
api.tag);
|
api.tag);
|
||||||
}
|
}
|
||||||
bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop, ifindex,
|
bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop, ifindex,
|
||||||
api.metric, api.type, api.tag);
|
api.metric, api.type, api.instance, api.tag);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bgp_debug_zebra(&p))
|
if (bgp_debug_zebra(&p))
|
||||||
{
|
{
|
||||||
char buf[2][INET6_ADDRSTRLEN];
|
char buf[2][INET6_ADDRSTRLEN];
|
||||||
zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
|
zlog_debug("Zebra rcvd: IPv6 route delete %s[%d] %s/%d "
|
||||||
"nexthop %s metric %u tag %d",
|
"nexthop %s metric %u tag %d",
|
||||||
zebra_route_string(api.type),
|
zebra_route_string(api.type), api.instance,
|
||||||
inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
|
inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
|
||||||
p.prefixlen,
|
p.prefixlen,
|
||||||
inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
|
inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
|
||||||
api.metric,
|
api.metric,
|
||||||
api.tag);
|
api.tag);
|
||||||
}
|
}
|
||||||
bgp_redistribute_delete ((struct prefix *) &p, api.type);
|
bgp_redistribute_delete ((struct prefix *) &p, api.type, api.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -942,7 +944,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
|
|||||||
if (zclient->sock < 0)
|
if (zclient->sock < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (! zclient->redist[ZEBRA_ROUTE_BGP])
|
if (!zclient->redist[ZEBRA_ROUTE_BGP].enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (bgp->main_zebra_update_hold)
|
if (bgp->main_zebra_update_hold)
|
||||||
@ -1049,6 +1051,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
|
|||||||
|
|
||||||
api.flags = flags;
|
api.flags = flags;
|
||||||
api.type = ZEBRA_ROUTE_BGP;
|
api.type = ZEBRA_ROUTE_BGP;
|
||||||
|
api.instance = 0;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = safi;
|
api.safi = safi;
|
||||||
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
|
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
|
||||||
@ -1217,6 +1220,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
|
|||||||
/* Make Zebra API structure. */
|
/* Make Zebra API structure. */
|
||||||
api.flags = flags;
|
api.flags = flags;
|
||||||
api.type = ZEBRA_ROUTE_BGP;
|
api.type = ZEBRA_ROUTE_BGP;
|
||||||
|
api.instance = 0;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = safi;
|
api.safi = safi;
|
||||||
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
|
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
|
||||||
@ -1280,7 +1284,7 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
|
|||||||
if (zclient->sock < 0)
|
if (zclient->sock < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (! zclient->redist[ZEBRA_ROUTE_BGP])
|
if (!zclient->redist[ZEBRA_ROUTE_BGP].enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
peer = info->peer;
|
peer = info->peer;
|
||||||
@ -1309,6 +1313,7 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
|
|||||||
nexthop = &info->attr->nexthop;
|
nexthop = &info->attr->nexthop;
|
||||||
|
|
||||||
api.type = ZEBRA_ROUTE_BGP;
|
api.type = ZEBRA_ROUTE_BGP;
|
||||||
|
api.instance = 0;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = safi;
|
api.safi = safi;
|
||||||
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
|
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
|
||||||
@ -1372,6 +1377,7 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
|
|||||||
|
|
||||||
api.flags = flags;
|
api.flags = flags;
|
||||||
api.type = ZEBRA_ROUTE_BGP;
|
api.type = ZEBRA_ROUTE_BGP;
|
||||||
|
api.instance = 0;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = safi;
|
api.safi = safi;
|
||||||
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
|
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
|
||||||
@ -1405,117 +1411,177 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
}
|
}
|
||||||
|
struct bgp_redist *
|
||||||
|
bgp_redist_lookup (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
|
||||||
|
{
|
||||||
|
struct list *red_list;
|
||||||
|
struct listnode *node;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
|
||||||
|
red_list = bgp->redist[afi][type];
|
||||||
|
if (!red_list)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
|
||||||
|
if (red->instance == instance)
|
||||||
|
return red;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bgp_redist *
|
||||||
|
bgp_redist_add (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
|
||||||
|
{
|
||||||
|
struct list *red_list;
|
||||||
|
struct bgp_redist *red;
|
||||||
|
|
||||||
|
red = bgp_redist_lookup(bgp, afi, type, instance);
|
||||||
|
if (red)
|
||||||
|
return red;
|
||||||
|
|
||||||
|
if (!bgp->redist[afi][type])
|
||||||
|
bgp->redist[afi][type] = list_new();
|
||||||
|
|
||||||
|
red_list = bgp->redist[afi][type];
|
||||||
|
red = (struct bgp_redist *)calloc (1, sizeof(struct bgp_redist));
|
||||||
|
red->instance = instance;
|
||||||
|
|
||||||
|
listnode_add(red_list, red);
|
||||||
|
|
||||||
|
return red;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bgp_redist_del (struct bgp *bgp, afi_t afi, u_char type, u_short instance)
|
||||||
|
{
|
||||||
|
struct bgp_redist *red;
|
||||||
|
|
||||||
|
red = bgp_redist_lookup(bgp, afi, type, instance);
|
||||||
|
|
||||||
|
if (red)
|
||||||
|
{
|
||||||
|
listnode_delete(bgp->redist[afi][type], red);
|
||||||
|
if (!bgp->redist[afi][type]->count)
|
||||||
|
{
|
||||||
|
list_free(bgp->redist[afi][type]);
|
||||||
|
bgp->redist[afi][type] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Other routes redistribution into BGP. */
|
/* Other routes redistribution into BGP. */
|
||||||
int
|
int
|
||||||
bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
|
bgp_redistribute_set (int type, u_short instance)
|
||||||
{
|
{
|
||||||
/* Set flag to BGP instance. */
|
|
||||||
bgp->redist[afi][type] = 1;
|
|
||||||
|
|
||||||
/* Return if already redistribute flag is set. */
|
/* Return if already redistribute flag is set. */
|
||||||
if (zclient->redist[type])
|
if (redist_check_instance(&zclient->redist[type], instance))
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
|
|
||||||
zclient->redist[type] = 1;
|
redist_add_instance(&zclient->redist[type], instance);
|
||||||
|
|
||||||
/* Return if zebra connection is not established. */
|
/* Return if zebra connection is not established. */
|
||||||
if (zclient->sock < 0)
|
if (zclient->sock < 0)
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
|
|
||||||
if (BGP_DEBUG (zebra, ZEBRA))
|
if (BGP_DEBUG (zebra, ZEBRA))
|
||||||
zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
|
zlog_debug("Zebra send: redistribute add %s %d", zebra_route_string(type),
|
||||||
|
instance);
|
||||||
|
|
||||||
/* Send distribute add message to zebra. */
|
/* Send distribute add message to zebra. */
|
||||||
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
|
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, instance);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
bgp_redistribute_resend (struct bgp *bgp, afi_t afi, int type)
|
bgp_redistribute_resend (struct bgp *bgp, afi_t afi, int type, u_short instance)
|
||||||
{
|
{
|
||||||
/* Return if zebra connection is not established. */
|
/* Return if zebra connection is not established. */
|
||||||
if (zclient->sock < 0)
|
if (zclient->sock < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (BGP_DEBUG (zebra, ZEBRA))
|
if (BGP_DEBUG (zebra, ZEBRA))
|
||||||
zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
|
zlog_debug("Zebra send: redistribute add %s %d", zebra_route_string(type),
|
||||||
|
instance);
|
||||||
|
|
||||||
/* Send distribute add message to zebra. */
|
/* Send distribute add message to zebra. */
|
||||||
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
|
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, instance);
|
||||||
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
|
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, instance);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Redistribute with route-map specification. */
|
/* Redistribute with route-map specification. */
|
||||||
int
|
int
|
||||||
bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
|
bgp_redistribute_rmap_set (struct bgp_redist *red, const char *name)
|
||||||
const char *name)
|
|
||||||
{
|
{
|
||||||
if (bgp->rmap[afi][type].name
|
if (red->rmap.name
|
||||||
&& (strcmp (bgp->rmap[afi][type].name, name) == 0))
|
&& (strcmp (red->rmap.name, name) == 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (bgp->rmap[afi][type].name)
|
if (red->rmap.name)
|
||||||
free (bgp->rmap[afi][type].name);
|
free (red->rmap.name);
|
||||||
bgp->rmap[afi][type].name = strdup (name);
|
red->rmap.name = strdup (name);
|
||||||
bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
|
red->rmap.map = route_map_lookup_by_name (name);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Redistribute with metric specification. */
|
/* Redistribute with metric specification. */
|
||||||
int
|
int
|
||||||
bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
|
bgp_redistribute_metric_set (struct bgp_redist *red, u_int32_t metric)
|
||||||
u_int32_t metric)
|
|
||||||
{
|
{
|
||||||
if (bgp->redist_metric_flag[afi][type]
|
if (red->redist_metric_flag
|
||||||
&& bgp->redist_metric[afi][type] == metric)
|
&& red->redist_metric == metric)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bgp->redist_metric_flag[afi][type] = 1;
|
red->redist_metric_flag = 1;
|
||||||
bgp->redist_metric[afi][type] = metric;
|
red->redist_metric = metric;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unset redistribution. */
|
/* Unset redistribution. */
|
||||||
int
|
int
|
||||||
bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
|
bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type, u_short instance)
|
||||||
{
|
{
|
||||||
/* Unset flag from BGP instance. */
|
struct bgp_redist *red;
|
||||||
bgp->redist[afi][type] = 0;
|
|
||||||
|
red = bgp_redist_lookup(bgp, afi, type, instance);
|
||||||
|
if (!red)
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
/* Unset route-map. */
|
/* Unset route-map. */
|
||||||
if (bgp->rmap[afi][type].name)
|
if (red->rmap.name)
|
||||||
free (bgp->rmap[afi][type].name);
|
free (red->rmap.name);
|
||||||
bgp->rmap[afi][type].name = NULL;
|
red->rmap.name = NULL;
|
||||||
bgp->rmap[afi][type].map = NULL;
|
red->rmap.map = NULL;
|
||||||
|
|
||||||
/* Unset metric. */
|
/* Unset metric. */
|
||||||
bgp->redist_metric_flag[afi][type] = 0;
|
red->redist_metric_flag = 0;
|
||||||
bgp->redist_metric[afi][type] = 0;
|
red->redist_metric = 0;
|
||||||
|
|
||||||
|
bgp_redist_del(bgp, afi, type, instance);
|
||||||
|
|
||||||
/* Return if zebra connection is disabled. */
|
/* Return if zebra connection is disabled. */
|
||||||
if (! zclient->redist[type])
|
if (!redist_check_instance(&zclient->redist[type], instance))
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
zclient->redist[type] = 0;
|
redist_del_instance(&zclient->redist[type], instance);
|
||||||
|
|
||||||
if (bgp->redist[AFI_IP][type] == 0
|
if (!bgp_redist_lookup(bgp, AFI_IP, type, instance)
|
||||||
&& bgp->redist[AFI_IP6][type] == 0
|
&& !bgp_redist_lookup(bgp, AFI_IP6, type, instance)
|
||||||
&& zclient->sock >= 0)
|
&& zclient->sock >= 0)
|
||||||
{
|
{
|
||||||
/* Send distribute delete message to zebra. */
|
/* Send distribute delete message to zebra. */
|
||||||
if (BGP_DEBUG (zebra, ZEBRA))
|
if (BGP_DEBUG (zebra, ZEBRA))
|
||||||
zlog_debug("Zebra send: redistribute delete %s",
|
zlog_debug("Zebra send: redistribute delete %s %d",
|
||||||
zebra_route_string(type));
|
zebra_route_string(type), instance);
|
||||||
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
|
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Withdraw redistributed routes from current BGP's routing table. */
|
/* Withdraw redistributed routes from current BGP's routing table. */
|
||||||
bgp_redistribute_withdraw (bgp, afi, type);
|
bgp_redistribute_withdraw (bgp, afi, type, instance);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1531,7 +1597,7 @@ bgp_zebra_init (void)
|
|||||||
{
|
{
|
||||||
/* Set default values. */
|
/* Set default values. */
|
||||||
zclient = zclient_new ();
|
zclient = zclient_new ();
|
||||||
zclient_init (zclient, ZEBRA_ROUTE_BGP);
|
zclient_init (zclient, ZEBRA_ROUTE_BGP, 0);
|
||||||
zclient->router_id_update = bgp_router_id_update;
|
zclient->router_id_update = bgp_router_id_update;
|
||||||
zclient->interface_add = bgp_interface_add;
|
zclient->interface_add = bgp_interface_add;
|
||||||
zclient->interface_delete = bgp_interface_delete;
|
zclient->interface_delete = bgp_interface_delete;
|
||||||
|
@ -38,11 +38,13 @@ extern void bgp_zebra_announce (struct prefix *, struct bgp_info *, struct bgp *
|
|||||||
extern void bgp_zebra_announce_table (struct bgp *, afi_t, safi_t);
|
extern void bgp_zebra_announce_table (struct bgp *, afi_t, safi_t);
|
||||||
extern void bgp_zebra_withdraw (struct prefix *, struct bgp_info *, safi_t);
|
extern void bgp_zebra_withdraw (struct prefix *, struct bgp_info *, safi_t);
|
||||||
|
|
||||||
extern int bgp_redistribute_set (struct bgp *, afi_t, int);
|
extern struct bgp_redist *bgp_redist_lookup (struct bgp *, afi_t, u_char, u_short);
|
||||||
extern int bgp_redistribute_resend (struct bgp *, afi_t, int);
|
extern struct bgp_redist *bgp_redist_add (struct bgp *, afi_t, u_char, u_short);
|
||||||
extern int bgp_redistribute_rmap_set (struct bgp *, afi_t, int, const char *);
|
extern int bgp_redistribute_set (int, u_short);
|
||||||
extern int bgp_redistribute_metric_set (struct bgp *, afi_t, int, u_int32_t);
|
extern int bgp_redistribute_resend (struct bgp *, afi_t, int, u_short);
|
||||||
extern int bgp_redistribute_unset (struct bgp *, afi_t, int);
|
extern int bgp_redistribute_rmap_set (struct bgp_redist *, const char *);
|
||||||
|
extern int bgp_redistribute_metric_set (struct bgp_redist *, u_int32_t);
|
||||||
|
extern int bgp_redistribute_unset (struct bgp *, afi_t, int, u_short);
|
||||||
|
|
||||||
extern struct interface *if_lookup_by_ipv4 (struct in_addr *);
|
extern struct interface *if_lookup_by_ipv4 (struct in_addr *);
|
||||||
extern struct interface *if_lookup_by_ipv4_exact (struct in_addr *);
|
extern struct interface *if_lookup_by_ipv4_exact (struct in_addr *);
|
||||||
|
@ -2397,7 +2397,7 @@ bgp_delete (struct bgp *bgp)
|
|||||||
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
||||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
||||||
if (i != ZEBRA_ROUTE_BGP)
|
if (i != ZEBRA_ROUTE_BGP)
|
||||||
bgp_redistribute_unset (bgp, afi, i);
|
bgp_redistribute_unset (bgp, afi, i, 0);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))
|
for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))
|
||||||
{
|
{
|
||||||
|
21
bgpd/bgpd.h
21
bgpd/bgpd.h
@ -70,6 +70,18 @@ struct bgp_rmap
|
|||||||
struct route_map *map;
|
struct route_map *map;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct bgp_redist
|
||||||
|
{
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
|
/* BGP redistribute metric configuration. */
|
||||||
|
u_char redist_metric_flag;
|
||||||
|
u_int32_t redist_metric;
|
||||||
|
|
||||||
|
/* BGP redistribute route-map. */
|
||||||
|
struct bgp_rmap rmap;
|
||||||
|
};
|
||||||
|
|
||||||
/* BGP instance structure. */
|
/* BGP instance structure. */
|
||||||
struct bgp
|
struct bgp
|
||||||
{
|
{
|
||||||
@ -185,14 +197,7 @@ struct bgp
|
|||||||
struct bgp_rmap table_map[AFI_MAX][SAFI_MAX];
|
struct bgp_rmap table_map[AFI_MAX][SAFI_MAX];
|
||||||
|
|
||||||
/* BGP redistribute configuration. */
|
/* BGP redistribute configuration. */
|
||||||
u_char redist[AFI_MAX][ZEBRA_ROUTE_MAX];
|
struct list *redist[AFI_MAX][ZEBRA_ROUTE_MAX];
|
||||||
|
|
||||||
/* BGP redistribute metric configuration. */
|
|
||||||
u_char redist_metric_flag[AFI_MAX][ZEBRA_ROUTE_MAX];
|
|
||||||
u_int32_t redist_metric[AFI_MAX][ZEBRA_ROUTE_MAX];
|
|
||||||
|
|
||||||
/* BGP redistribute route-map. */
|
|
||||||
struct bgp_rmap rmap[AFI_MAX][ZEBRA_ROUTE_MAX];
|
|
||||||
|
|
||||||
/* timer to dampen route map changes */
|
/* timer to dampen route map changes */
|
||||||
struct thread *t_rmap_update; /* Handle route map updates */
|
struct thread *t_rmap_update; /* Handle route map updates */
|
||||||
|
@ -239,7 +239,7 @@ main (int argc, char **argv, char **envp)
|
|||||||
/* Get the programname without the preceding path. */
|
/* Get the programname without the preceding path. */
|
||||||
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
|
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
|
||||||
|
|
||||||
zlog_default = openzlog (progname, ZLOG_ISIS,
|
zlog_default = openzlog (progname, ZLOG_ISIS, 0,
|
||||||
LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
|
LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
|
||||||
|
|
||||||
/* for reload */
|
/* for reload */
|
||||||
|
@ -236,7 +236,7 @@ isis_zebra_route_add_ipv4 (struct prefix *prefix,
|
|||||||
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
|
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (zclient->redist[ZEBRA_ROUTE_ISIS])
|
if (zclient->redist[ZEBRA_ROUTE_ISIS].enabled)
|
||||||
{
|
{
|
||||||
message = 0;
|
message = 0;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
@ -252,6 +252,8 @@ isis_zebra_route_add_ipv4 (struct prefix *prefix,
|
|||||||
zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD);
|
zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD);
|
||||||
/* type */
|
/* type */
|
||||||
stream_putc (stream, ZEBRA_ROUTE_ISIS);
|
stream_putc (stream, ZEBRA_ROUTE_ISIS);
|
||||||
|
/* instance */
|
||||||
|
stream_putw (stream, 0);
|
||||||
/* flags */
|
/* flags */
|
||||||
stream_putc (stream, flags);
|
stream_putc (stream, flags);
|
||||||
/* message */
|
/* message */
|
||||||
@ -301,9 +303,10 @@ isis_zebra_route_del_ipv4 (struct prefix *prefix,
|
|||||||
struct zapi_ipv4 api;
|
struct zapi_ipv4 api;
|
||||||
struct prefix_ipv4 prefix4;
|
struct prefix_ipv4 prefix4;
|
||||||
|
|
||||||
if (zclient->redist[ZEBRA_ROUTE_ISIS])
|
if (zclient->redist[ZEBRA_ROUTE_ISIS].enabled)
|
||||||
{
|
{
|
||||||
api.type = ZEBRA_ROUTE_ISIS;
|
api.type = ZEBRA_ROUTE_ISIS;
|
||||||
|
api.instance = 0;
|
||||||
api.flags = 0;
|
api.flags = 0;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = SAFI_UNICAST;
|
api.safi = SAFI_UNICAST;
|
||||||
@ -334,6 +337,7 @@ isis_zebra_route_add_ipv6 (struct prefix *prefix,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
api.type = ZEBRA_ROUTE_ISIS;
|
api.type = ZEBRA_ROUTE_ISIS;
|
||||||
|
api.instance = 0;
|
||||||
api.flags = 0;
|
api.flags = 0;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = SAFI_UNICAST;
|
api.safi = SAFI_UNICAST;
|
||||||
@ -419,6 +423,7 @@ isis_zebra_route_del_ipv6 (struct prefix *prefix,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
api.type = ZEBRA_ROUTE_ISIS;
|
api.type = ZEBRA_ROUTE_ISIS;
|
||||||
|
api.instance = 0;
|
||||||
api.flags = 0;
|
api.flags = 0;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = SAFI_UNICAST;
|
api.safi = SAFI_UNICAST;
|
||||||
@ -488,7 +493,7 @@ isis_zebra_route_update (struct prefix *prefix,
|
|||||||
if (zclient->sock < 0)
|
if (zclient->sock < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!zclient->redist[ZEBRA_ROUTE_ISIS])
|
if (!zclient->redist[ZEBRA_ROUTE_ISIS].enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE))
|
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE))
|
||||||
@ -527,6 +532,7 @@ isis_zebra_read_ipv4 (int command, struct zclient *zclient,
|
|||||||
ifindex = 0;
|
ifindex = 0;
|
||||||
|
|
||||||
api.type = stream_getc (stream);
|
api.type = stream_getc (stream);
|
||||||
|
api.instance = stream_getw (stream);
|
||||||
api.flags = stream_getc (stream);
|
api.flags = stream_getc (stream);
|
||||||
api.message = stream_getc (stream);
|
api.message = stream_getc (stream);
|
||||||
|
|
||||||
@ -570,7 +576,8 @@ isis_zebra_read_ipv6 (int command, struct zclient *zclient,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ISIS_TYPE_IS_REDISTRIBUTED(T) \
|
#define ISIS_TYPE_IS_REDISTRIBUTED(T) \
|
||||||
T == ZEBRA_ROUTE_MAX ? zclient->default_information : zclient->redist[type]
|
T == ZEBRA_ROUTE_MAX ? zclient->default_information : \
|
||||||
|
zclient->redist[type].enabled
|
||||||
|
|
||||||
int
|
int
|
||||||
isis_distribute_list_update (int routetype)
|
isis_distribute_list_update (int routetype)
|
||||||
@ -591,7 +598,7 @@ void
|
|||||||
isis_zebra_init ()
|
isis_zebra_init ()
|
||||||
{
|
{
|
||||||
zclient = zclient_new ();
|
zclient = zclient_new ();
|
||||||
zclient_init (zclient, ZEBRA_ROUTE_ISIS);
|
zclient_init (zclient, ZEBRA_ROUTE_ISIS, 0);
|
||||||
zclient->router_id_update = isis_router_id_update_zebra;
|
zclient->router_id_update = isis_router_id_update_zebra;
|
||||||
zclient->interface_add = isis_zebra_if_add;
|
zclient->interface_add = isis_zebra_if_add;
|
||||||
zclient->interface_delete = isis_zebra_if_del;
|
zclient->interface_delete = isis_zebra_if_del;
|
||||||
|
15
lib/log.c
15
lib/log.c
@ -150,6 +150,7 @@ time_print(FILE *fp, struct timestamp_control *ctl)
|
|||||||
static void
|
static void
|
||||||
vzlog (struct zlog *zl, int priority, const char *format, va_list args)
|
vzlog (struct zlog *zl, int priority, const char *format, va_list args)
|
||||||
{
|
{
|
||||||
|
char proto_str[32];
|
||||||
struct timestamp_control tsctl;
|
struct timestamp_control tsctl;
|
||||||
tsctl.already_rendered = 0;
|
tsctl.already_rendered = 0;
|
||||||
|
|
||||||
@ -181,6 +182,11 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args)
|
|||||||
va_end(ac);
|
va_end(ac);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zl->instance)
|
||||||
|
sprintf (proto_str, "%s[%d]: ", zlog_proto_names[zl->protocol], zl->instance);
|
||||||
|
else
|
||||||
|
sprintf (proto_str, "%s: ", zlog_proto_names[zl->protocol]);
|
||||||
|
|
||||||
/* File output. */
|
/* File output. */
|
||||||
if ((priority <= zl->maxlvl[ZLOG_DEST_FILE]) && zl->fp)
|
if ((priority <= zl->maxlvl[ZLOG_DEST_FILE]) && zl->fp)
|
||||||
{
|
{
|
||||||
@ -188,7 +194,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args)
|
|||||||
time_print (zl->fp, &tsctl);
|
time_print (zl->fp, &tsctl);
|
||||||
if (zl->record_priority)
|
if (zl->record_priority)
|
||||||
fprintf (zl->fp, "%s: ", zlog_priority[priority]);
|
fprintf (zl->fp, "%s: ", zlog_priority[priority]);
|
||||||
fprintf (zl->fp, "%s: ", zlog_proto_names[zl->protocol]);
|
fprintf (zl->fp, "%s", proto_str);
|
||||||
va_copy(ac, args);
|
va_copy(ac, args);
|
||||||
vfprintf (zl->fp, format, ac);
|
vfprintf (zl->fp, format, ac);
|
||||||
va_end(ac);
|
va_end(ac);
|
||||||
@ -203,7 +209,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args)
|
|||||||
time_print (stdout, &tsctl);
|
time_print (stdout, &tsctl);
|
||||||
if (zl->record_priority)
|
if (zl->record_priority)
|
||||||
fprintf (stdout, "%s: ", zlog_priority[priority]);
|
fprintf (stdout, "%s: ", zlog_priority[priority]);
|
||||||
fprintf (stdout, "%s: ", zlog_proto_names[zl->protocol]);
|
fprintf (stdout, "%s", proto_str);
|
||||||
va_copy(ac, args);
|
va_copy(ac, args);
|
||||||
vfprintf (stdout, format, ac);
|
vfprintf (stdout, format, ac);
|
||||||
va_end(ac);
|
va_end(ac);
|
||||||
@ -214,7 +220,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args)
|
|||||||
/* Terminal monitor. */
|
/* Terminal monitor. */
|
||||||
if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR])
|
if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR])
|
||||||
vty_log ((zl->record_priority ? zlog_priority[priority] : NULL),
|
vty_log ((zl->record_priority ? zlog_priority[priority] : NULL),
|
||||||
zlog_proto_names[zl->protocol], format, &tsctl, args);
|
proto_str, format, &tsctl, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
@ -600,7 +606,7 @@ _zlog_assert_failed (const char *assertion, const char *file,
|
|||||||
|
|
||||||
/* Open log stream */
|
/* Open log stream */
|
||||||
struct zlog *
|
struct zlog *
|
||||||
openzlog (const char *progname, zlog_proto_t protocol,
|
openzlog (const char *progname, zlog_proto_t protocol, u_short instance,
|
||||||
int syslog_flags, int syslog_facility)
|
int syslog_flags, int syslog_facility)
|
||||||
{
|
{
|
||||||
struct zlog *zl;
|
struct zlog *zl;
|
||||||
@ -610,6 +616,7 @@ openzlog (const char *progname, zlog_proto_t protocol,
|
|||||||
|
|
||||||
zl->ident = progname;
|
zl->ident = progname;
|
||||||
zl->protocol = protocol;
|
zl->protocol = protocol;
|
||||||
|
zl->instance = instance;
|
||||||
zl->facility = syslog_facility;
|
zl->facility = syslog_facility;
|
||||||
zl->syslog_options = syslog_flags;
|
zl->syslog_options = syslog_flags;
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ struct zlog
|
|||||||
{
|
{
|
||||||
const char *ident; /* daemon name (first arg to openlog) */
|
const char *ident; /* daemon name (first arg to openlog) */
|
||||||
zlog_proto_t protocol;
|
zlog_proto_t protocol;
|
||||||
|
u_short instance;
|
||||||
int maxlvl[ZLOG_NUM_DESTS]; /* maximum priority to send to associated
|
int maxlvl[ZLOG_NUM_DESTS]; /* maximum priority to send to associated
|
||||||
logging destination */
|
logging destination */
|
||||||
int default_lvl; /* maxlvl to use if none is specified */
|
int default_lvl; /* maxlvl to use if none is specified */
|
||||||
@ -97,7 +98,7 @@ extern struct zlog *zlog_default;
|
|||||||
|
|
||||||
/* Open zlog function */
|
/* Open zlog function */
|
||||||
extern struct zlog *openzlog (const char *progname, zlog_proto_t protocol,
|
extern struct zlog *openzlog (const char *progname, zlog_proto_t protocol,
|
||||||
int syslog_options, int syslog_facility);
|
u_short instance, int syslog_options, int syslog_facility);
|
||||||
|
|
||||||
/* Close zlog function. */
|
/* Close zlog function. */
|
||||||
extern void closezlog (struct zlog *zl);
|
extern void closezlog (struct zlog *zl);
|
||||||
|
@ -327,8 +327,10 @@ vty_show_route_map_entry (struct vty *vty, struct route_map *map)
|
|||||||
|
|
||||||
/* Print the name of the protocol */
|
/* Print the name of the protocol */
|
||||||
if (zlog_default)
|
if (zlog_default)
|
||||||
vty_out (vty, "%s:%s", zlog_proto_names[zlog_default->protocol],
|
vty_out (vty, "%s", zlog_proto_names[zlog_default->protocol]);
|
||||||
VTY_NEWLINE);
|
if (zlog_default->instance)
|
||||||
|
vty_out (vty, " %d", zlog_default->instance);
|
||||||
|
vty_out (vty, ":%s", VTY_NEWLINE);
|
||||||
|
|
||||||
for (index = map->head; index; index = index->next)
|
for (index = map->head; index; index = index->next)
|
||||||
{
|
{
|
||||||
|
@ -78,10 +78,66 @@ zclient_free (struct zclient *zclient)
|
|||||||
XFREE (MTYPE_ZCLIENT, zclient);
|
XFREE (MTYPE_ZCLIENT, zclient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
redist_check_instance (struct redist_proto *red, u_short instance)
|
||||||
|
{
|
||||||
|
struct listnode *node;
|
||||||
|
u_short *id;
|
||||||
|
|
||||||
|
if (!red->instances)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO (red->instances, node, id))
|
||||||
|
if (*id == instance)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
redist_add_instance (struct redist_proto *red, u_short instance)
|
||||||
|
{
|
||||||
|
u_short *in;
|
||||||
|
|
||||||
|
red->enabled = 1;
|
||||||
|
|
||||||
|
if (!red->instances)
|
||||||
|
red->instances = list_new();
|
||||||
|
|
||||||
|
in = (u_short *)calloc(1, sizeof(u_short));
|
||||||
|
*in = instance;
|
||||||
|
listnode_add (red->instances, in);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
redist_del_instance (struct redist_proto *red, u_short instance)
|
||||||
|
{
|
||||||
|
struct listnode *node;
|
||||||
|
u_short *id = NULL;
|
||||||
|
|
||||||
|
if (!red->instances)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO (red->instances, node, id))
|
||||||
|
if (*id == instance)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (id)
|
||||||
|
{
|
||||||
|
listnode_delete(red->instances, id);
|
||||||
|
if (!red->instances->count)
|
||||||
|
{
|
||||||
|
red->enabled = 0;
|
||||||
|
list_free(red->instances);
|
||||||
|
red->instances = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize zebra client. Argument redist_default is unwanted
|
/* Initialize zebra client. Argument redist_default is unwanted
|
||||||
redistribute route type. */
|
redistribute route type. */
|
||||||
void
|
void
|
||||||
zclient_init (struct zclient *zclient, int redist_default)
|
zclient_init (struct zclient *zclient, int redist_default, u_short instance)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -93,12 +149,13 @@ zclient_init (struct zclient *zclient, int redist_default)
|
|||||||
|
|
||||||
/* Clear redistribution flags. */
|
/* Clear redistribution flags. */
|
||||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
||||||
zclient->redist[i] = 0;
|
memset(&zclient->redist[i], 0, sizeof(struct redist_proto));
|
||||||
|
|
||||||
/* Set unwanted redistribute route. bgpd does not need BGP route
|
/* Set unwanted redistribute route. bgpd does not need BGP route
|
||||||
redistribution. */
|
redistribution. */
|
||||||
zclient->redist_default = redist_default;
|
zclient->redist_default = redist_default;
|
||||||
zclient->redist[redist_default] = 1;
|
zclient->instance = instance;
|
||||||
|
redist_add_instance (&zclient->redist[redist_default], instance);
|
||||||
|
|
||||||
/* Set default-information redistribute to zero. */
|
/* Set default-information redistribute to zero. */
|
||||||
zclient->default_information = 0;
|
zclient->default_information = 0;
|
||||||
@ -142,7 +199,7 @@ void
|
|||||||
zclient_reset (struct zclient *zclient)
|
zclient_reset (struct zclient *zclient)
|
||||||
{
|
{
|
||||||
zclient_stop (zclient);
|
zclient_stop (zclient);
|
||||||
zclient_init (zclient, zclient->redist_default);
|
zclient_init (zclient, zclient->redist_default, zclient->instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_TCP_ZEBRA
|
#ifdef HAVE_TCP_ZEBRA
|
||||||
@ -330,6 +387,7 @@ zebra_hello_send (struct zclient *zclient)
|
|||||||
|
|
||||||
zclient_create_header (s, ZEBRA_HELLO);
|
zclient_create_header (s, ZEBRA_HELLO);
|
||||||
stream_putc (s, zclient->redist_default);
|
stream_putc (s, zclient->redist_default);
|
||||||
|
stream_putw (s, zclient->instance);
|
||||||
stream_putw_at (s, 0, stream_get_endp (s));
|
stream_putw_at (s, 0, stream_get_endp (s));
|
||||||
return zclient_send_message(zclient);
|
return zclient_send_message(zclient);
|
||||||
}
|
}
|
||||||
@ -388,8 +446,15 @@ zclient_start (struct zclient *zclient)
|
|||||||
|
|
||||||
/* Flush all redistribute request. */
|
/* Flush all redistribute request. */
|
||||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
||||||
if (i != zclient->redist_default && zclient->redist[i])
|
if (zclient->redist[i].enabled)
|
||||||
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, i);
|
{
|
||||||
|
struct listnode *node;
|
||||||
|
u_short *id;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(zclient->redist[i].instances, node, id))
|
||||||
|
if (!(i == zclient->redist_default && *id == zclient->instance))
|
||||||
|
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, i, *id);
|
||||||
|
}
|
||||||
|
|
||||||
/* If default information is needed. */
|
/* If default information is needed. */
|
||||||
if (zclient->default_information)
|
if (zclient->default_information)
|
||||||
@ -491,6 +556,7 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
|
|||||||
|
|
||||||
/* Put type and nexthop. */
|
/* Put type and nexthop. */
|
||||||
stream_putc (s, api->type);
|
stream_putc (s, api->type);
|
||||||
|
stream_putw (s, api->instance);
|
||||||
stream_putc (s, api->flags);
|
stream_putc (s, api->flags);
|
||||||
stream_putc (s, api->message);
|
stream_putc (s, api->message);
|
||||||
stream_putw (s, api->safi);
|
stream_putw (s, api->safi);
|
||||||
@ -572,6 +638,7 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
|
|||||||
|
|
||||||
/* Put type and nexthop. */
|
/* Put type and nexthop. */
|
||||||
stream_putc (s, api->type);
|
stream_putc (s, api->type);
|
||||||
|
stream_putw (s, api->instance);
|
||||||
stream_putc (s, api->flags);
|
stream_putc (s, api->flags);
|
||||||
stream_putc (s, api->message);
|
stream_putc (s, api->message);
|
||||||
stream_putw (s, api->safi);
|
stream_putw (s, api->safi);
|
||||||
@ -627,7 +694,8 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
|
|||||||
* sending client
|
* sending client
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zebra_redistribute_send (int command, struct zclient *zclient, int type)
|
zebra_redistribute_send (int command, struct zclient *zclient, int type,
|
||||||
|
u_short instance)
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
|
|
||||||
@ -636,6 +704,7 @@ zebra_redistribute_send (int command, struct zclient *zclient, int type)
|
|||||||
|
|
||||||
zclient_create_header (s, command);
|
zclient_create_header (s, command);
|
||||||
stream_putc (s, type);
|
stream_putc (s, type);
|
||||||
|
stream_putw (s, instance);
|
||||||
|
|
||||||
stream_putw_at (s, 0, stream_get_endp (s));
|
stream_putw_at (s, 0, stream_get_endp (s));
|
||||||
|
|
||||||
@ -1153,24 +1222,25 @@ zclient_read (struct thread *thread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zclient_redistribute (int command, struct zclient *zclient, int type)
|
zclient_redistribute (int command, struct zclient *zclient, int type,
|
||||||
|
u_short instance)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (command == ZEBRA_REDISTRIBUTE_ADD)
|
if (command == ZEBRA_REDISTRIBUTE_ADD)
|
||||||
{
|
{
|
||||||
if (zclient->redist[type])
|
if (redist_check_instance(&zclient->redist[type], instance))
|
||||||
return;
|
return;
|
||||||
zclient->redist[type] = 1;
|
redist_add_instance(&zclient->redist[type], instance);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!zclient->redist[type])
|
if (!redist_check_instance(&zclient->redist[type], instance))
|
||||||
return;
|
return;
|
||||||
zclient->redist[type] = 0;
|
redist_del_instance(&zclient->redist[type], instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zclient->sock > 0)
|
if (zclient->sock > 0)
|
||||||
zebra_redistribute_send (command, zclient, type);
|
zebra_redistribute_send (command, zclient, type, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,6 +34,12 @@
|
|||||||
/* Zebra header size. */
|
/* Zebra header size. */
|
||||||
#define ZEBRA_HEADER_SIZE 6
|
#define ZEBRA_HEADER_SIZE 6
|
||||||
|
|
||||||
|
struct redist_proto
|
||||||
|
{
|
||||||
|
u_char enabled;
|
||||||
|
struct list *instances;
|
||||||
|
};
|
||||||
|
|
||||||
/* Structure for the zebra client. */
|
/* Structure for the zebra client. */
|
||||||
struct zclient
|
struct zclient
|
||||||
{
|
{
|
||||||
@ -64,8 +70,9 @@ struct zclient
|
|||||||
struct thread *t_write;
|
struct thread *t_write;
|
||||||
|
|
||||||
/* Redistribute information. */
|
/* Redistribute information. */
|
||||||
u_char redist_default;
|
u_char redist_default; /* clients protocol */
|
||||||
u_char redist[ZEBRA_ROUTE_MAX];
|
u_short instance;
|
||||||
|
struct redist_proto redist[ZEBRA_ROUTE_MAX];
|
||||||
|
|
||||||
/* Redistribute defauilt. */
|
/* Redistribute defauilt. */
|
||||||
u_char default_information;
|
u_char default_information;
|
||||||
@ -112,6 +119,7 @@ struct zserv_header
|
|||||||
struct zapi_ipv4
|
struct zapi_ipv4
|
||||||
{
|
{
|
||||||
u_char type;
|
u_char type;
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
u_char flags;
|
u_char flags;
|
||||||
|
|
||||||
@ -134,7 +142,7 @@ struct zapi_ipv4
|
|||||||
|
|
||||||
/* Prototypes of zebra client service functions. */
|
/* Prototypes of zebra client service functions. */
|
||||||
extern struct zclient *zclient_new (void);
|
extern struct zclient *zclient_new (void);
|
||||||
extern void zclient_init (struct zclient *, int);
|
extern void zclient_init (struct zclient *, int, u_short);
|
||||||
extern int zclient_start (struct zclient *);
|
extern int zclient_start (struct zclient *);
|
||||||
extern void zclient_stop (struct zclient *);
|
extern void zclient_stop (struct zclient *);
|
||||||
extern void zclient_reset (struct zclient *);
|
extern void zclient_reset (struct zclient *);
|
||||||
@ -143,11 +151,16 @@ extern void zclient_free (struct zclient *);
|
|||||||
extern int zclient_socket_connect (struct zclient *);
|
extern int zclient_socket_connect (struct zclient *);
|
||||||
extern void zclient_serv_path_set (char *path);
|
extern void zclient_serv_path_set (char *path);
|
||||||
|
|
||||||
|
extern int redist_check_instance (struct redist_proto *, u_short);
|
||||||
|
extern void redist_add_instance (struct redist_proto *, u_short);
|
||||||
|
extern void redist_del_instance (struct redist_proto *, u_short);
|
||||||
|
|
||||||
/* Send redistribute command to zebra daemon. Do not update zclient state. */
|
/* Send redistribute command to zebra daemon. Do not update zclient state. */
|
||||||
extern int zebra_redistribute_send (int command, struct zclient *, int type);
|
extern int zebra_redistribute_send (int command, struct zclient *, int type, u_short instance);
|
||||||
|
|
||||||
/* If state has changed, update state and call zebra_redistribute_send. */
|
/* If state has changed, update state and call zebra_redistribute_send. */
|
||||||
extern void zclient_redistribute (int command, struct zclient *, int type);
|
extern void zclient_redistribute (int command, struct zclient *, int type,
|
||||||
|
u_short instance);
|
||||||
|
|
||||||
/* If state has changed, update state and send the command to zebra. */
|
/* If state has changed, update state and send the command to zebra. */
|
||||||
extern void zclient_redistribute_default (int command, struct zclient *);
|
extern void zclient_redistribute_default (int command, struct zclient *);
|
||||||
@ -175,6 +188,7 @@ extern int zapi_ipv4_route (u_char, struct zclient *, struct prefix_ipv4 *,
|
|||||||
struct zapi_ipv6
|
struct zapi_ipv6
|
||||||
{
|
{
|
||||||
u_char type;
|
u_char type;
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
u_char flags;
|
u_char flags;
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ main (int argc, char *argv[], char *envp[])
|
|||||||
master = thread_master_create ();
|
master = thread_master_create ();
|
||||||
|
|
||||||
/* Initializations. */
|
/* Initializations. */
|
||||||
zlog_default = openzlog (progname, ZLOG_OSPF6,
|
zlog_default = openzlog (progname, ZLOG_OSPF6, 0,
|
||||||
LOG_CONS|LOG_NDELAY|LOG_PID,
|
LOG_CONS|LOG_NDELAY|LOG_PID,
|
||||||
LOG_DAEMON);
|
LOG_DAEMON);
|
||||||
zprivs_init (&ospf6d_privs);
|
zprivs_init (&ospf6d_privs);
|
||||||
|
@ -70,21 +70,21 @@ ospf6_router_id_update_zebra (int command, struct zclient *zclient,
|
|||||||
void
|
void
|
||||||
ospf6_zebra_redistribute (int type)
|
ospf6_zebra_redistribute (int type)
|
||||||
{
|
{
|
||||||
if (zclient->redist[type])
|
if (zclient->redist[type].enabled)
|
||||||
return;
|
return;
|
||||||
zclient->redist[type] = 1;
|
redist_add_instance(&zclient->redist[type], 0);
|
||||||
if (zclient->sock > 0)
|
if (zclient->sock > 0)
|
||||||
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
|
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ospf6_zebra_no_redistribute (int type)
|
ospf6_zebra_no_redistribute (int type)
|
||||||
{
|
{
|
||||||
if (! zclient->redist[type])
|
if (! zclient->redist[type].enabled)
|
||||||
return;
|
return;
|
||||||
zclient->redist[type] = 0;
|
redist_del_instance(&zclient->redist[type], 0);
|
||||||
if (zclient->sock > 0)
|
if (zclient->sock > 0)
|
||||||
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
|
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inteface addition message from zebra. */
|
/* Inteface addition message from zebra. */
|
||||||
@ -215,6 +215,7 @@ ospf6_zebra_read_ipv6 (int command, struct zclient *zclient,
|
|||||||
|
|
||||||
/* Type, flags, message. */
|
/* Type, flags, message. */
|
||||||
api.type = stream_getc (s);
|
api.type = stream_getc (s);
|
||||||
|
api.instance = stream_getw (s);
|
||||||
api.flags = stream_getc (s);
|
api.flags = stream_getc (s);
|
||||||
api.message = stream_getc (s);
|
api.message = stream_getc (s);
|
||||||
|
|
||||||
@ -296,7 +297,7 @@ DEFUN (show_zebra,
|
|||||||
vty_out (vty, " redistribute:");
|
vty_out (vty, " redistribute:");
|
||||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
||||||
{
|
{
|
||||||
if (zclient->redist[i])
|
if (zclient->redist[i].enabled)
|
||||||
vty_out (vty, " %s", zebra_route_string(i));
|
vty_out (vty, " %s", zebra_route_string(i));
|
||||||
}
|
}
|
||||||
vty_out (vty, "%s", VNL);
|
vty_out (vty, "%s", VNL);
|
||||||
@ -336,7 +337,7 @@ config_write_ospf6_zebra (struct vty *vty)
|
|||||||
vty_out (vty, "no router zebra%s", VNL);
|
vty_out (vty, "no router zebra%s", VNL);
|
||||||
vty_out (vty, "!%s", VNL);
|
vty_out (vty, "!%s", VNL);
|
||||||
}
|
}
|
||||||
else if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
|
else if (! zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
|
||||||
{
|
{
|
||||||
vty_out (vty, "router zebra%s", VNL);
|
vty_out (vty, "router zebra%s", VNL);
|
||||||
vty_out (vty, " no redistribute ospf6%s", VNL);
|
vty_out (vty, " no redistribute ospf6%s", VNL);
|
||||||
@ -438,6 +439,7 @@ ospf6_zebra_route_update (int type, struct ospf6_route *request)
|
|||||||
ospf6_route_zebra_copy_nexthops (request, ifindexes, nexthops, nhcount);
|
ospf6_route_zebra_copy_nexthops (request, ifindexes, nexthops, nhcount);
|
||||||
|
|
||||||
api.type = ZEBRA_ROUTE_OSPF6;
|
api.type = ZEBRA_ROUTE_OSPF6;
|
||||||
|
api.instance = 0;
|
||||||
api.flags = 0;
|
api.flags = 0;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = SAFI_UNICAST;
|
api.safi = SAFI_UNICAST;
|
||||||
@ -470,7 +472,7 @@ ospf6_zebra_route_update (int type, struct ospf6_route *request)
|
|||||||
void
|
void
|
||||||
ospf6_zebra_route_update_add (struct ospf6_route *request)
|
ospf6_zebra_route_update_add (struct ospf6_route *request)
|
||||||
{
|
{
|
||||||
if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
|
if (! zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
|
||||||
{
|
{
|
||||||
ospf6->route_table->hook_add = NULL;
|
ospf6->route_table->hook_add = NULL;
|
||||||
ospf6->route_table->hook_remove = NULL;
|
ospf6->route_table->hook_remove = NULL;
|
||||||
@ -482,7 +484,7 @@ ospf6_zebra_route_update_add (struct ospf6_route *request)
|
|||||||
void
|
void
|
||||||
ospf6_zebra_route_update_remove (struct ospf6_route *request)
|
ospf6_zebra_route_update_remove (struct ospf6_route *request)
|
||||||
{
|
{
|
||||||
if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
|
if (! zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
|
||||||
{
|
{
|
||||||
ospf6->route_table->hook_add = NULL;
|
ospf6->route_table->hook_add = NULL;
|
||||||
ospf6->route_table->hook_remove = NULL;
|
ospf6->route_table->hook_remove = NULL;
|
||||||
@ -498,12 +500,13 @@ ospf6_zebra_add_discard (struct ospf6_route *request)
|
|||||||
char buf[INET6_ADDRSTRLEN];
|
char buf[INET6_ADDRSTRLEN];
|
||||||
struct prefix_ipv6 *dest;
|
struct prefix_ipv6 *dest;
|
||||||
|
|
||||||
if (zclient->redist[ZEBRA_ROUTE_OSPF6])
|
if (zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
|
||||||
{
|
{
|
||||||
if (!CHECK_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED))
|
if (!CHECK_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED))
|
||||||
{
|
{
|
||||||
api.type = ZEBRA_ROUTE_OSPF6;
|
api.type = ZEBRA_ROUTE_OSPF6;
|
||||||
api.flags = ZEBRA_FLAG_BLACKHOLE;
|
api.flags = ZEBRA_FLAG_BLACKHOLE;
|
||||||
|
api.instance = 0;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = SAFI_UNICAST;
|
api.safi = SAFI_UNICAST;
|
||||||
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
|
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
|
||||||
@ -541,13 +544,14 @@ ospf6_zebra_delete_discard (struct ospf6_route *request)
|
|||||||
char buf[INET6_ADDRSTRLEN];
|
char buf[INET6_ADDRSTRLEN];
|
||||||
struct prefix_ipv6 *dest;
|
struct prefix_ipv6 *dest;
|
||||||
|
|
||||||
if (zclient->redist[ZEBRA_ROUTE_OSPF6])
|
if (zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED))
|
if (CHECK_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED))
|
||||||
{
|
{
|
||||||
|
|
||||||
api.type = ZEBRA_ROUTE_OSPF6;
|
api.type = ZEBRA_ROUTE_OSPF6;
|
||||||
api.flags = ZEBRA_FLAG_BLACKHOLE;
|
api.flags = ZEBRA_FLAG_BLACKHOLE;
|
||||||
|
api.instance = 0;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = SAFI_UNICAST;
|
api.safi = SAFI_UNICAST;
|
||||||
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
|
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
|
||||||
@ -583,10 +587,10 @@ DEFUN (redistribute_ospf6,
|
|||||||
{
|
{
|
||||||
struct ospf6_route *route;
|
struct ospf6_route *route;
|
||||||
|
|
||||||
if (zclient->redist[ZEBRA_ROUTE_OSPF6])
|
if (zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
zclient->redist[ZEBRA_ROUTE_OSPF6] = 1;
|
redist_add_instance(&zclient->redist[ZEBRA_ROUTE_OSPF6], 0);
|
||||||
|
|
||||||
if (ospf6 == NULL)
|
if (ospf6 == NULL)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -611,10 +615,10 @@ DEFUN (no_redistribute_ospf6,
|
|||||||
{
|
{
|
||||||
struct ospf6_route *route;
|
struct ospf6_route *route;
|
||||||
|
|
||||||
if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
|
if (! zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
zclient->redist[ZEBRA_ROUTE_OSPF6] = 0;
|
redist_del_instance(&zclient->redist[ZEBRA_ROUTE_OSPF6], 0);
|
||||||
|
|
||||||
if (ospf6 == NULL)
|
if (ospf6 == NULL)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -635,7 +639,7 @@ ospf6_zebra_init (void)
|
|||||||
{
|
{
|
||||||
/* Allocate zebra structure. */
|
/* Allocate zebra structure. */
|
||||||
zclient = zclient_new ();
|
zclient = zclient_new ();
|
||||||
zclient_init (zclient, ZEBRA_ROUTE_OSPF6);
|
zclient_init (zclient, ZEBRA_ROUTE_OSPF6, 0);
|
||||||
zclient->router_id_update = ospf6_router_id_update_zebra;
|
zclient->router_id_update = ospf6_router_id_update_zebra;
|
||||||
zclient->interface_add = ospf6_zebra_if_add;
|
zclient->interface_add = ospf6_zebra_if_add;
|
||||||
zclient->interface_delete = ospf6_zebra_if_del;
|
zclient->interface_delete = ospf6_zebra_if_del;
|
||||||
|
@ -42,7 +42,7 @@ extern void ospf6_zebra_route_update_remove (struct ospf6_route *request);
|
|||||||
|
|
||||||
extern void ospf6_zebra_redistribute (int);
|
extern void ospf6_zebra_redistribute (int);
|
||||||
extern void ospf6_zebra_no_redistribute (int);
|
extern void ospf6_zebra_no_redistribute (int);
|
||||||
#define ospf6_zebra_is_redistribute(type) (zclient->redist[type])
|
#define ospf6_zebra_is_redistribute(type) (zclient->redist[type].enabled)
|
||||||
extern void ospf6_zebra_init (void);
|
extern void ospf6_zebra_init (void);
|
||||||
extern void ospf6_zebra_add_discard (struct ospf6_route *request);
|
extern void ospf6_zebra_add_discard (struct ospf6_route *request);
|
||||||
extern void ospf6_zebra_delete_discard (struct ospf6_route *request);
|
extern void ospf6_zebra_delete_discard (struct ospf6_route *request);
|
||||||
|
@ -99,13 +99,14 @@ ospf_external_route_lookup (struct ospf *ospf,
|
|||||||
|
|
||||||
/* Add an External info for AS-external-LSA. */
|
/* Add an External info for AS-external-LSA. */
|
||||||
struct external_info *
|
struct external_info *
|
||||||
ospf_external_info_new (u_char type)
|
ospf_external_info_new (u_char type, u_short instance)
|
||||||
{
|
{
|
||||||
struct external_info *new;
|
struct external_info *new;
|
||||||
|
|
||||||
new = (struct external_info *)
|
new = (struct external_info *)
|
||||||
XCALLOC (MTYPE_OSPF_EXTERNAL_INFO, sizeof (struct external_info));
|
XCALLOC (MTYPE_OSPF_EXTERNAL_INFO, sizeof (struct external_info));
|
||||||
new->type = type;
|
new->type = type;
|
||||||
|
new->instance = instance;
|
||||||
|
|
||||||
ospf_reset_route_map_set_values (&new->route_map_set);
|
ospf_reset_route_map_set_values (&new->route_map_set);
|
||||||
return new;
|
return new;
|
||||||
@ -134,32 +135,33 @@ ospf_route_map_set_compare (struct route_map_set_values *values1,
|
|||||||
|
|
||||||
/* Add an External info for AS-external-LSA. */
|
/* Add an External info for AS-external-LSA. */
|
||||||
struct external_info *
|
struct external_info *
|
||||||
ospf_external_info_add (u_char type, struct prefix_ipv4 p,
|
ospf_external_info_add (u_char type, u_short instance, struct prefix_ipv4 p,
|
||||||
unsigned int ifindex, struct in_addr nexthop,
|
unsigned int ifindex, struct in_addr nexthop,
|
||||||
u_short tag)
|
u_short tag)
|
||||||
{
|
{
|
||||||
struct external_info *new;
|
struct external_info *new;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
|
struct ospf_external *ext;
|
||||||
|
|
||||||
/* Initialize route table. */
|
ext = ospf_external_lookup(type, instance);
|
||||||
if (EXTERNAL_INFO (type) == NULL)
|
if (!ext)
|
||||||
EXTERNAL_INFO (type) = route_table_init ();
|
ext = ospf_external_add(type, instance);
|
||||||
|
|
||||||
rn = route_node_get (EXTERNAL_INFO (type), (struct prefix *) &p);
|
rn = route_node_get (EXTERNAL_INFO (ext), (struct prefix *) &p);
|
||||||
/* If old info exists, -- discard new one or overwrite with new one? */
|
/* If old info exists, -- discard new one or overwrite with new one? */
|
||||||
if (rn)
|
if (rn)
|
||||||
if (rn->info)
|
if (rn->info)
|
||||||
{
|
{
|
||||||
route_unlock_node (rn);
|
route_unlock_node (rn);
|
||||||
zlog_warn ("Redistribute[%s]: %s/%d already exists, discard.",
|
zlog_warn ("Redistribute[%s][%d]: %s/%d already exists, discard.",
|
||||||
ospf_redist_string(type),
|
ospf_redist_string(type), instance,
|
||||||
inet_ntoa (p.prefix), p.prefixlen);
|
inet_ntoa (p.prefix), p.prefixlen);
|
||||||
/* XFREE (MTYPE_OSPF_TMP, rn->info); */
|
/* XFREE (MTYPE_OSPF_TMP, rn->info); */
|
||||||
return rn->info;
|
return rn->info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create new External info instance. */
|
/* Create new External info instance. */
|
||||||
new = ospf_external_info_new (type);
|
new = ospf_external_info_new (type, instance);
|
||||||
new->p = p;
|
new->p = p;
|
||||||
new->ifindex = ifindex;
|
new->ifindex = ifindex;
|
||||||
new->nexthop = nexthop;
|
new->nexthop = nexthop;
|
||||||
@ -176,11 +178,16 @@ ospf_external_info_add (u_char type, struct prefix_ipv4 p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ospf_external_info_delete (u_char type, struct prefix_ipv4 p)
|
ospf_external_info_delete (u_char type, u_short instance, struct prefix_ipv4 p)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
|
struct ospf_external *ext;
|
||||||
|
|
||||||
rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
|
ext = ospf_external_lookup(type, instance);
|
||||||
|
if (!ext)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rn = route_node_lookup (EXTERNAL_INFO (ext), (struct prefix *) &p);
|
||||||
if (rn)
|
if (rn)
|
||||||
{
|
{
|
||||||
ospf_external_info_free (rn->info);
|
ospf_external_info_free (rn->info);
|
||||||
@ -191,10 +198,16 @@ ospf_external_info_delete (u_char type, struct prefix_ipv4 p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct external_info *
|
struct external_info *
|
||||||
ospf_external_info_lookup (u_char type, struct prefix_ipv4 *p)
|
ospf_external_info_lookup (u_char type, u_short instance, struct prefix_ipv4 *p)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) p);
|
struct ospf_external *ext;
|
||||||
|
|
||||||
|
ext = ospf_external_lookup(type, instance);
|
||||||
|
if (!ext)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
rn = route_node_lookup (EXTERNAL_INFO (ext), (struct prefix *) p);
|
||||||
if (rn)
|
if (rn)
|
||||||
{
|
{
|
||||||
route_unlock_node (rn);
|
route_unlock_node (rn);
|
||||||
@ -271,14 +284,19 @@ ospf_asbr_status_update (struct ospf *ospf, u_char status)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ospf_redistribute_withdraw (struct ospf *ospf, u_char type)
|
ospf_redistribute_withdraw (struct ospf *ospf, u_char type, u_short instance)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct external_info *ei;
|
struct external_info *ei;
|
||||||
|
struct ospf_external *ext;
|
||||||
|
|
||||||
|
ext = ospf_external_lookup(type, instance);
|
||||||
|
if (!ext)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Delete external info for specified type. */
|
/* Delete external info for specified type. */
|
||||||
if (EXTERNAL_INFO (type))
|
if (EXTERNAL_INFO (ext))
|
||||||
for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
|
for (rn = route_top (EXTERNAL_INFO (ext)); rn; rn = route_next (rn))
|
||||||
if ((ei = rn->info))
|
if ((ei = rn->info))
|
||||||
if (ospf_external_info_find_lsa (ospf, &ei->p))
|
if (ospf_external_info_find_lsa (ospf, &ei->p))
|
||||||
{
|
{
|
||||||
|
@ -35,6 +35,8 @@ struct external_info
|
|||||||
/* Type of source protocol. */
|
/* Type of source protocol. */
|
||||||
u_char type;
|
u_char type;
|
||||||
|
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
/* Prefix. */
|
/* Prefix. */
|
||||||
struct prefix_ipv4 p;
|
struct prefix_ipv4 p;
|
||||||
|
|
||||||
@ -55,23 +57,23 @@ struct external_info
|
|||||||
#define OSPF_ASBR_CHECK_DELAY 30
|
#define OSPF_ASBR_CHECK_DELAY 30
|
||||||
|
|
||||||
extern void ospf_external_route_remove (struct ospf *, struct prefix_ipv4 *);
|
extern void ospf_external_route_remove (struct ospf *, struct prefix_ipv4 *);
|
||||||
extern struct external_info *ospf_external_info_new (u_char);
|
extern struct external_info *ospf_external_info_new (u_char, u_short);
|
||||||
extern void ospf_reset_route_map_set_values (struct route_map_set_values *);
|
extern void ospf_reset_route_map_set_values (struct route_map_set_values *);
|
||||||
extern int ospf_route_map_set_compare (struct route_map_set_values *,
|
extern int ospf_route_map_set_compare (struct route_map_set_values *,
|
||||||
struct route_map_set_values *);
|
struct route_map_set_values *);
|
||||||
extern struct external_info *ospf_external_info_add (u_char,
|
extern struct external_info *ospf_external_info_add (u_char, u_short,
|
||||||
struct prefix_ipv4,
|
struct prefix_ipv4,
|
||||||
unsigned int,
|
unsigned int,
|
||||||
struct in_addr,
|
struct in_addr,
|
||||||
u_short);
|
u_short);
|
||||||
extern void ospf_external_info_delete (u_char, struct prefix_ipv4);
|
extern void ospf_external_info_delete (u_char, u_short, struct prefix_ipv4);
|
||||||
extern struct external_info *ospf_external_info_lookup (u_char,
|
extern struct external_info *ospf_external_info_lookup (u_char, u_short,
|
||||||
struct prefix_ipv4 *);
|
struct prefix_ipv4 *);
|
||||||
extern struct ospf_route *ospf_external_route_lookup (struct ospf *,
|
extern struct ospf_route *ospf_external_route_lookup (struct ospf *,
|
||||||
struct prefix_ipv4 *);
|
struct prefix_ipv4 *);
|
||||||
extern void ospf_asbr_status_update (struct ospf *, u_char);
|
extern void ospf_asbr_status_update (struct ospf *, u_char);
|
||||||
|
|
||||||
extern void ospf_redistribute_withdraw (struct ospf *, u_char);
|
extern void ospf_redistribute_withdraw (struct ospf *, u_char, u_short);
|
||||||
extern void ospf_asbr_check (void);
|
extern void ospf_asbr_check (void);
|
||||||
extern void ospf_schedule_asbr_check (void);
|
extern void ospf_schedule_asbr_check (void);
|
||||||
extern void ospf_asbr_route_install_lsa (struct ospf_lsa *);
|
extern void ospf_asbr_route_install_lsa (struct ospf_lsa *);
|
||||||
|
1285
ospfd/ospf_dump.c
1285
ospfd/ospf_dump.c
File diff suppressed because it is too large
Load Diff
@ -92,19 +92,33 @@ ospf_external_info_check (struct ospf_lsa *lsa)
|
|||||||
|
|
||||||
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
|
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
|
||||||
{
|
{
|
||||||
int redist_type = is_prefix_default (&p) ? DEFAULT_ROUTE : type;
|
int redist_on = 0;
|
||||||
if (ospf_is_type_redistributed (redist_type))
|
|
||||||
if (EXTERNAL_INFO (type))
|
redist_on = is_prefix_default (&p) ? zclient->default_information :
|
||||||
{
|
zclient->redist[type].enabled;
|
||||||
rn = route_node_lookup (EXTERNAL_INFO (type),
|
if (redist_on)
|
||||||
(struct prefix *) &p);
|
{
|
||||||
if (rn)
|
struct list *ext_list;
|
||||||
{
|
struct listnode *node;
|
||||||
route_unlock_node (rn);
|
struct ospf_external *ext;
|
||||||
if (rn->info != NULL)
|
|
||||||
return (struct external_info *) rn->info;
|
ext_list = om->external[type];
|
||||||
}
|
if (!ext_list)
|
||||||
}
|
continue;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
|
||||||
|
{
|
||||||
|
if (ext->external_info)
|
||||||
|
rn = route_node_lookup (ext->external_info,
|
||||||
|
(struct prefix *) &p);
|
||||||
|
if (rn)
|
||||||
|
{
|
||||||
|
route_unlock_node (rn);
|
||||||
|
if (rn->info != NULL)
|
||||||
|
return (struct external_info *) rn->info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1590,16 +1590,23 @@ ospf_get_nssa_ip (struct ospf_area *area)
|
|||||||
#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
|
#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
|
||||||
|
|
||||||
int
|
int
|
||||||
metric_type (struct ospf *ospf, u_char src)
|
metric_type (struct ospf *ospf, u_char src, u_short instance)
|
||||||
{
|
{
|
||||||
return (ospf->dmetric[src].type < 0 ?
|
struct ospf_redist *red;
|
||||||
DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
|
|
||||||
|
red = ospf_redist_lookup(ospf, src, instance);
|
||||||
|
|
||||||
|
return ((!red || red->dmetric.type < 0) ?
|
||||||
|
DEFAULT_METRIC_TYPE : red->dmetric.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
metric_value (struct ospf *ospf, u_char src)
|
metric_value (struct ospf *ospf, u_char src, u_short instance)
|
||||||
{
|
{
|
||||||
if (ospf->dmetric[src].value < 0)
|
struct ospf_redist *red;
|
||||||
|
|
||||||
|
red = ospf_redist_lookup(ospf, src, instance);
|
||||||
|
if (!red || red->dmetric.value < 0)
|
||||||
{
|
{
|
||||||
if (src == DEFAULT_ROUTE)
|
if (src == DEFAULT_ROUTE)
|
||||||
{
|
{
|
||||||
@ -1614,7 +1621,7 @@ metric_value (struct ospf *ospf, u_char src)
|
|||||||
return ospf->default_metric;
|
return ospf->default_metric;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ospf->dmetric[src].value;
|
return red->dmetric.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set AS-external-LSA body. */
|
/* Set AS-external-LSA body. */
|
||||||
@ -1627,6 +1634,7 @@ ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
|
|||||||
u_int32_t mvalue;
|
u_int32_t mvalue;
|
||||||
int mtype;
|
int mtype;
|
||||||
int type;
|
int type;
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
/* Put Network Mask. */
|
/* Put Network Mask. */
|
||||||
masklen2ip (p->prefixlen, &mask);
|
masklen2ip (p->prefixlen, &mask);
|
||||||
@ -1634,12 +1642,13 @@ ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
|
|||||||
|
|
||||||
/* If prefix is default, specify DEFAULT_ROUTE. */
|
/* If prefix is default, specify DEFAULT_ROUTE. */
|
||||||
type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
|
type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
|
||||||
|
instance = is_prefix_default (&ei->p) ? 0 : ei->instance;
|
||||||
|
|
||||||
mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
|
mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
|
||||||
ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
|
ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type, instance);
|
||||||
|
|
||||||
mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
|
mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
|
||||||
ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
|
ROUTEMAP_METRIC (ei) : metric_value (ospf, type, instance);
|
||||||
|
|
||||||
/* Put type of external metric. */
|
/* Put type of external metric. */
|
||||||
stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
|
stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
|
||||||
@ -2106,17 +2115,25 @@ ospf_external_lsa_originate_timer (struct thread *thread)
|
|||||||
struct external_info *ei;
|
struct external_info *ei;
|
||||||
struct route_table *rt;
|
struct route_table *rt;
|
||||||
int type = THREAD_VAL (thread);
|
int type = THREAD_VAL (thread);
|
||||||
|
struct list *ext_list;
|
||||||
|
struct listnode *node;
|
||||||
|
struct ospf_external *ext;
|
||||||
|
|
||||||
ospf->t_external_lsa = NULL;
|
ospf->t_external_lsa = NULL;
|
||||||
|
|
||||||
/* Originate As-external-LSA from all type of distribute source. */
|
ext_list = om->external[type];
|
||||||
if ((rt = EXTERNAL_INFO (type)))
|
if (!ext_list)
|
||||||
for (rn = route_top (rt); rn; rn = route_next (rn))
|
return 0;
|
||||||
if ((ei = rn->info) != NULL)
|
|
||||||
if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
|
for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
|
||||||
if (!ospf_external_lsa_originate (ospf, ei))
|
/* Originate As-external-LSA from all type of distribute source. */
|
||||||
zlog_warn ("LSA: AS-external-LSA was not originated.");
|
if ((rt = ext->external_info))
|
||||||
|
for (rn = route_top (rt); rn; rn = route_next (rn))
|
||||||
|
if ((ei = rn->info) != NULL)
|
||||||
|
if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
|
||||||
|
if (!ospf_external_lsa_originate (ospf, ei))
|
||||||
|
zlog_warn ("LSA: AS-external-LSA was not originated.");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2133,17 +2150,30 @@ ospf_default_external_info (struct ospf *ospf)
|
|||||||
|
|
||||||
/* First, lookup redistributed default route. */
|
/* First, lookup redistributed default route. */
|
||||||
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
|
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
|
||||||
if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
|
{
|
||||||
{
|
struct list *ext_list;
|
||||||
rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
|
struct listnode *node;
|
||||||
if (rn != NULL)
|
struct ospf_external *ext;
|
||||||
{
|
|
||||||
route_unlock_node (rn);
|
if (type == ZEBRA_ROUTE_OSPF)
|
||||||
assert (rn->info);
|
continue;
|
||||||
if (ospf_redistribute_check (ospf, rn->info, NULL))
|
|
||||||
return rn->info;
|
ext_list = om->external[type];
|
||||||
}
|
if (!ext_list)
|
||||||
}
|
continue;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
|
||||||
|
{
|
||||||
|
rn = route_node_lookup (ext->external_info, (struct prefix *) &p);
|
||||||
|
if (rn != NULL)
|
||||||
|
{
|
||||||
|
route_unlock_node (rn);
|
||||||
|
assert (rn->info);
|
||||||
|
if (ospf_redistribute_check (ospf, rn->info, NULL))
|
||||||
|
return rn->info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -2167,7 +2197,7 @@ ospf_default_originate_timer (struct thread *thread)
|
|||||||
/* If there is no default route via redistribute,
|
/* If there is no default route via redistribute,
|
||||||
then originate AS-external-LSA with nexthop 0 (self). */
|
then originate AS-external-LSA with nexthop 0 (self). */
|
||||||
nexthop.s_addr = 0;
|
nexthop.s_addr = 0;
|
||||||
ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop, 0);
|
ospf_external_info_add (DEFAULT_ROUTE, 0, p, 0, nexthop, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ei = ospf_default_external_info (ospf)))
|
if ((ei = ospf_default_external_info (ospf)))
|
||||||
@ -2298,15 +2328,18 @@ ospf_external_lsa_refresh_default (struct ospf *ospf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
|
ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, u_short instance,
|
||||||
|
int force)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct external_info *ei;
|
struct external_info *ei;
|
||||||
|
struct ospf_external *ext;
|
||||||
|
|
||||||
if (type != DEFAULT_ROUTE)
|
if (type != DEFAULT_ROUTE)
|
||||||
if (EXTERNAL_INFO(type))
|
if ((ext = ospf_external_lookup(type, instance)) &&
|
||||||
|
EXTERNAL_INFO (ext))
|
||||||
/* Refresh each redistributed AS-external-LSAs. */
|
/* Refresh each redistributed AS-external-LSAs. */
|
||||||
for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
|
for (rn = route_top (EXTERNAL_INFO (ext)); rn; rn = route_next (rn))
|
||||||
if ((ei = rn->info))
|
if ((ei = rn->info))
|
||||||
if (!is_prefix_default (&ei->p))
|
if (!is_prefix_default (&ei->p))
|
||||||
{
|
{
|
||||||
|
@ -314,7 +314,7 @@ extern struct ospf_lsa *ospf_lsa_refresh (struct ospf *, struct ospf_lsa *);
|
|||||||
|
|
||||||
extern void ospf_external_lsa_refresh_default (struct ospf *);
|
extern void ospf_external_lsa_refresh_default (struct ospf *);
|
||||||
|
|
||||||
extern void ospf_external_lsa_refresh_type (struct ospf *, u_char, int);
|
extern void ospf_external_lsa_refresh_type (struct ospf *, u_char, u_short, int);
|
||||||
extern struct ospf_lsa *ospf_external_lsa_refresh (struct ospf *,
|
extern struct ospf_lsa *ospf_external_lsa_refresh (struct ospf *,
|
||||||
struct ospf_lsa *,
|
struct ospf_lsa *,
|
||||||
struct external_info *,
|
struct external_info *,
|
||||||
@ -333,8 +333,8 @@ extern void ospf_lsa_maxage_delete (struct ospf *, struct ospf_lsa *);
|
|||||||
extern void ospf_discard_from_db (struct ospf *, struct ospf_lsdb *, struct ospf_lsa*);
|
extern void ospf_discard_from_db (struct ospf *, struct ospf_lsdb *, struct ospf_lsa*);
|
||||||
extern int is_prefix_default (struct prefix_ipv4 *);
|
extern int is_prefix_default (struct prefix_ipv4 *);
|
||||||
|
|
||||||
extern int metric_type (struct ospf *, u_char);
|
extern int metric_type (struct ospf *, u_char, u_short);
|
||||||
extern int metric_value (struct ospf *, u_char);
|
extern int metric_value (struct ospf *, u_char, u_short);
|
||||||
|
|
||||||
extern struct in_addr ospf_get_nssa_ip (struct ospf_area *);
|
extern struct in_addr ospf_get_nssa_ip (struct ospf_area *);
|
||||||
extern int ospf_translated_nssa_compare (struct ospf_lsa *, struct ospf_lsa *);
|
extern int ospf_translated_nssa_compare (struct ospf_lsa *, struct ospf_lsa *);
|
||||||
|
@ -73,12 +73,13 @@ struct zebra_privs_t ospfd_privs =
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Configuration filename and directory. */
|
/* Configuration filename and directory. */
|
||||||
char config_default[] = SYSCONFDIR OSPF_DEFAULT_CONFIG;
|
char config_default[100];
|
||||||
|
|
||||||
/* OSPFd options. */
|
/* OSPFd options. */
|
||||||
struct option longopts[] =
|
struct option longopts[] =
|
||||||
{
|
{
|
||||||
{ "daemon", no_argument, NULL, 'd'},
|
{ "daemon", no_argument, NULL, 'd'},
|
||||||
|
{ "instance", required_argument, NULL, 'n'},
|
||||||
{ "config_file", required_argument, NULL, 'f'},
|
{ "config_file", required_argument, NULL, 'f'},
|
||||||
{ "pid_file", required_argument, NULL, 'i'},
|
{ "pid_file", required_argument, NULL, 'i'},
|
||||||
{ "socket", required_argument, NULL, 'z'},
|
{ "socket", required_argument, NULL, 'z'},
|
||||||
@ -99,7 +100,7 @@ struct option longopts[] =
|
|||||||
struct thread_master *master;
|
struct thread_master *master;
|
||||||
|
|
||||||
/* Process ID saved for use by init system */
|
/* Process ID saved for use by init system */
|
||||||
const char *pid_file = PATH_OSPFD_PID;
|
char pid_file[100];
|
||||||
|
|
||||||
#ifdef SUPPORT_OSPF_API
|
#ifdef SUPPORT_OSPF_API
|
||||||
extern int ospf_apiserver_enable;
|
extern int ospf_apiserver_enable;
|
||||||
@ -116,6 +117,7 @@ usage (char *progname, int status)
|
|||||||
printf ("Usage : %s [OPTION...]\n\
|
printf ("Usage : %s [OPTION...]\n\
|
||||||
Daemon which manages OSPF.\n\n\
|
Daemon which manages OSPF.\n\n\
|
||||||
-d, --daemon Runs in daemon mode\n\
|
-d, --daemon Runs in daemon mode\n\
|
||||||
|
-n, --instance Set the instance id\n\
|
||||||
-f, --config_file Set configuration file name\n\
|
-f, --config_file Set configuration file name\n\
|
||||||
-i, --pid_file Set process identifier file name\n\
|
-i, --pid_file Set process identifier file name\n\
|
||||||
-z, --socket Set path of zebra socket\n\
|
-z, --socket Set path of zebra socket\n\
|
||||||
@ -182,9 +184,11 @@ main (int argc, char **argv)
|
|||||||
char *p;
|
char *p;
|
||||||
char *vty_addr = NULL;
|
char *vty_addr = NULL;
|
||||||
int vty_port = OSPF_VTY_PORT;
|
int vty_port = OSPF_VTY_PORT;
|
||||||
|
char vty_path[100];
|
||||||
int daemon_mode = 0;
|
int daemon_mode = 0;
|
||||||
char *config_file = NULL;
|
char *config_file = NULL;
|
||||||
char *progname;
|
char *progname;
|
||||||
|
u_short instance = 0;
|
||||||
struct thread thread;
|
struct thread thread;
|
||||||
int dryrun = 0;
|
int dryrun = 0;
|
||||||
|
|
||||||
@ -203,13 +207,18 @@ main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
opt = getopt_long (argc, argv, "df:i:z:hA:P:u:g:avC", longopts, 0);
|
opt = getopt_long (argc, argv, "df:i:n:z:hA:P:u:g:avC", longopts, 0);
|
||||||
|
|
||||||
if (opt == EOF)
|
if (opt == EOF)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (opt)
|
switch (opt)
|
||||||
{
|
{
|
||||||
|
case 'n':
|
||||||
|
instance = atoi(optarg);
|
||||||
|
if (instance < 1 || instance > 65535)
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
@ -222,7 +231,7 @@ main (int argc, char **argv)
|
|||||||
vty_addr = optarg;
|
vty_addr = optarg;
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
pid_file = optarg;
|
strcpy(pid_file,optarg);
|
||||||
break;
|
break;
|
||||||
case 'z':
|
case 'z':
|
||||||
zclient_serv_path_set (optarg);
|
zclient_serv_path_set (optarg);
|
||||||
@ -274,7 +283,7 @@ main (int argc, char **argv)
|
|||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
zlog_default = openzlog (progname, ZLOG_OSPF,
|
zlog_default = openzlog (progname, ZLOG_OSPF, instance,
|
||||||
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
||||||
|
|
||||||
/* OSPF master init. */
|
/* OSPF master init. */
|
||||||
@ -296,7 +305,7 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
/* OSPFd inits. */
|
/* OSPFd inits. */
|
||||||
ospf_if_init ();
|
ospf_if_init ();
|
||||||
ospf_zebra_init ();
|
ospf_zebra_init (instance);
|
||||||
|
|
||||||
/* OSPF vty inits. */
|
/* OSPF vty inits. */
|
||||||
ospf_vty_init ();
|
ospf_vty_init ();
|
||||||
@ -314,13 +323,17 @@ main (int argc, char **argv)
|
|||||||
/* Need to initialize the default ospf structure, so the interface mode
|
/* Need to initialize the default ospf structure, so the interface mode
|
||||||
commands can be duly processed if they are received before 'router ospf',
|
commands can be duly processed if they are received before 'router ospf',
|
||||||
when quagga(ospfd) is restarted */
|
when quagga(ospfd) is restarted */
|
||||||
if (!ospf_get())
|
if (!ospf_get_instance(instance))
|
||||||
{
|
{
|
||||||
zlog_err("OSPF instance init failed: %s", strerror(errno));
|
zlog_err("OSPF instance init failed: %s", strerror(errno));
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get configuration file. */
|
/* Get configuration file. */
|
||||||
|
if (instance)
|
||||||
|
sprintf(config_default, "%sospfd-%d.conf", SYSCONFDIR, instance);
|
||||||
|
else
|
||||||
|
sprintf(config_default, "%s%s", SYSCONFDIR, OSPF_DEFAULT_CONFIG);
|
||||||
vty_read_config (config_file, config_default);
|
vty_read_config (config_file, config_default);
|
||||||
|
|
||||||
/* Start execution only if not in dry-run mode */
|
/* Start execution only if not in dry-run mode */
|
||||||
@ -334,14 +347,23 @@ main (int argc, char **argv)
|
|||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create VTY socket */
|
||||||
|
if (instance)
|
||||||
|
{
|
||||||
|
sprintf(pid_file, "/var/run/quagga/ospfd-%d.pid", instance);
|
||||||
|
sprintf(vty_path, "/var/run/quagga/ospfd-%d.vty", instance);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(pid_file, PATH_OSPFD_PID);
|
||||||
|
strcpy(vty_path, OSPF_VTYSH_PATH);
|
||||||
|
}
|
||||||
/* Process id file create. */
|
/* Process id file create. */
|
||||||
pid_output (pid_file);
|
pid_output (pid_file);
|
||||||
|
vty_serv_sock (vty_addr, vty_port, vty_path);
|
||||||
/* Create VTY socket */
|
|
||||||
vty_serv_sock (vty_addr, vty_port, OSPF_VTYSH_PATH);
|
|
||||||
|
|
||||||
/* Print banner. */
|
/* Print banner. */
|
||||||
zlog_notice ("OSPFd %s starting: vty@%d", QUAGGA_VERSION, vty_port);
|
zlog_notice ("OSPFd %s starting: vty@%d, %s", QUAGGA_VERSION, vty_port, vty_path);
|
||||||
|
|
||||||
/* Fetch next active thread. */
|
/* Fetch next active thread. */
|
||||||
while (thread_fetch (master, &thread))
|
while (thread_fetch (master, &thread))
|
||||||
|
@ -719,9 +719,19 @@ nsm_change_state (struct ospf_neighbor *nbr, int state)
|
|||||||
/* kevinm: refresh any redistributions */
|
/* kevinm: refresh any redistributions */
|
||||||
for (x = ZEBRA_ROUTE_SYSTEM; x < ZEBRA_ROUTE_MAX; x++)
|
for (x = ZEBRA_ROUTE_SYSTEM; x < ZEBRA_ROUTE_MAX; x++)
|
||||||
{
|
{
|
||||||
if (x == ZEBRA_ROUTE_OSPF || x == ZEBRA_ROUTE_OSPF6)
|
struct list *red_list;
|
||||||
continue;
|
struct listnode *node;
|
||||||
ospf_external_lsa_refresh_type (oi->ospf, x, force);
|
struct ospf_redist *red;
|
||||||
|
|
||||||
|
if (x == ZEBRA_ROUTE_OSPF6)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
red_list = oi->ospf->redist[x];
|
||||||
|
if (!red_list)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
|
||||||
|
ospf_external_lsa_refresh_type (oi->ospf, x, red->instance, force);
|
||||||
}
|
}
|
||||||
/* XXX: Clearly some thing is wrong with refresh of external LSAs
|
/* XXX: Clearly some thing is wrong with refresh of external LSAs
|
||||||
* this added to hack around defaults not refreshing after a timer
|
* this added to hack around defaults not refreshing after a timer
|
||||||
|
@ -767,6 +767,9 @@ DEFUN (capability_opaque,
|
|||||||
{
|
{
|
||||||
struct ospf *ospf = (struct ospf *) vty->index;
|
struct ospf *ospf = (struct ospf *) vty->index;
|
||||||
|
|
||||||
|
if (!ospf)
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
/* Turn on the "master switch" of opaque-lsa capability. */
|
/* Turn on the "master switch" of opaque-lsa capability. */
|
||||||
if (!CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
|
if (!CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
|
||||||
{
|
{
|
||||||
@ -794,6 +797,9 @@ DEFUN (no_capability_opaque,
|
|||||||
{
|
{
|
||||||
struct ospf *ospf = (struct ospf *) vty->index;
|
struct ospf *ospf = (struct ospf *) vty->index;
|
||||||
|
|
||||||
|
if (!ospf)
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
/* Turn off the "master switch" of opaque-lsa capability. */
|
/* Turn off the "master switch" of opaque-lsa capability. */
|
||||||
if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
|
if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
|
||||||
{
|
{
|
||||||
|
@ -2889,7 +2889,7 @@ ospf_read (struct thread *thread)
|
|||||||
{
|
{
|
||||||
if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
|
if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
|
||||||
{
|
{
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (!ospf->instance && IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug ("Packet from [%s] received on link %s"
|
zlog_debug ("Packet from [%s] received on link %s"
|
||||||
" but no ospf_interface",
|
" but no ospf_interface",
|
||||||
inet_ntoa (iph->ip_src), ifp->name);
|
inet_ntoa (iph->ip_src), ifp->name);
|
||||||
|
@ -45,6 +45,7 @@ ospf_route_map_update (const char *name)
|
|||||||
{
|
{
|
||||||
struct ospf *ospf;
|
struct ospf *ospf;
|
||||||
int type;
|
int type;
|
||||||
|
u_short instance; // PENDING
|
||||||
|
|
||||||
/* If OSPF instatnce does not exist, return right now. */
|
/* If OSPF instatnce does not exist, return right now. */
|
||||||
ospf = ospf_lookup ();
|
ospf = ospf_lookup ();
|
||||||
@ -54,22 +55,33 @@ ospf_route_map_update (const char *name)
|
|||||||
/* Update route-map */
|
/* Update route-map */
|
||||||
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
|
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
|
||||||
{
|
{
|
||||||
if (ROUTEMAP_NAME (ospf, type)
|
struct list *red_list;
|
||||||
&& strcmp (ROUTEMAP_NAME (ospf, type), name) == 0)
|
struct listnode *node;
|
||||||
{
|
struct ospf_redist *red;
|
||||||
/* Keep old route-map. */
|
|
||||||
struct route_map *old = ROUTEMAP (ospf, type);
|
|
||||||
|
|
||||||
/* Update route-map. */
|
red_list = ospf->redist[type];
|
||||||
ROUTEMAP (ospf, type) =
|
if (!red_list)
|
||||||
route_map_lookup_by_name (ROUTEMAP_NAME (ospf, type));
|
continue;
|
||||||
|
|
||||||
/* No update for this distribute type. */
|
for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
|
||||||
if (old == NULL && ROUTEMAP (ospf, type) == NULL)
|
{
|
||||||
continue;
|
if (ROUTEMAP_NAME (red)
|
||||||
|
&& strcmp (ROUTEMAP_NAME (red), name) == 0)
|
||||||
|
{
|
||||||
|
/* Keep old route-map. */
|
||||||
|
struct route_map *old = ROUTEMAP (red);
|
||||||
|
|
||||||
ospf_distribute_list_update (ospf, type);
|
/* Update route-map. */
|
||||||
}
|
ROUTEMAP (red) =
|
||||||
|
route_map_lookup_by_name (ROUTEMAP_NAME (red));
|
||||||
|
|
||||||
|
/* No update for this distribute type. */
|
||||||
|
if (old == NULL && ROUTEMAP (red) == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ospf_distribute_list_update (ospf, type, red->instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,13 +96,23 @@ ospf_route_map_event (route_map_event_t event, const char *name)
|
|||||||
if (ospf == NULL)
|
if (ospf == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Update route-map. */
|
|
||||||
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
|
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
|
||||||
{
|
{
|
||||||
if (ROUTEMAP_NAME (ospf, type) && ROUTEMAP (ospf, type)
|
struct list *red_list;
|
||||||
&& !strcmp (ROUTEMAP_NAME (ospf, type), name))
|
struct listnode *node;
|
||||||
|
struct ospf_redist *red;
|
||||||
|
|
||||||
|
red_list = ospf->redist[type];
|
||||||
|
if (!red_list)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
|
||||||
{
|
{
|
||||||
ospf_distribute_list_update (ospf, type);
|
if (ROUTEMAP_NAME (red) && ROUTEMAP (red)
|
||||||
|
&& !strcmp (ROUTEMAP_NAME (red), name))
|
||||||
|
{
|
||||||
|
ospf_distribute_list_update (ospf, type, red->instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1473,6 +1473,10 @@ DEFUN (mpls_te,
|
|||||||
{
|
{
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
struct mpls_te_link *lp;
|
struct mpls_te_link *lp;
|
||||||
|
struct ospf *ospf = vty->index;
|
||||||
|
|
||||||
|
if (!ospf)
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
if (OspfMplsTE.status == enabled)
|
if (OspfMplsTE.status == enabled)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -1511,6 +1515,10 @@ DEFUN (no_mpls_te,
|
|||||||
{
|
{
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
struct mpls_te_link *lp;
|
struct mpls_te_link *lp;
|
||||||
|
struct ospf *ospf = vty->index;
|
||||||
|
|
||||||
|
if (!ospf)
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
if (OspfMplsTE.status == disabled)
|
if (OspfMplsTE.status == disabled)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -1537,6 +1545,10 @@ DEFUN (mpls_te_router_addr,
|
|||||||
{
|
{
|
||||||
struct te_tlv_router_addr *ra = &OspfMplsTE.router_addr;
|
struct te_tlv_router_addr *ra = &OspfMplsTE.router_addr;
|
||||||
struct in_addr value;
|
struct in_addr value;
|
||||||
|
struct ospf *ospf = vty->index;
|
||||||
|
|
||||||
|
if (!ospf)
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
if (! inet_aton (argv[0], &value))
|
if (! inet_aton (argv[0], &value))
|
||||||
{
|
{
|
||||||
|
1604
ospfd/ospf_vty.c
1604
ospfd/ospf_vty.c
File diff suppressed because it is too large
Load Diff
@ -386,8 +386,9 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
|
|||||||
#ifdef HAVE_NETLINK
|
#ifdef HAVE_NETLINK
|
||||||
int ol_cnt = 0, not_ol_cnt = 0;
|
int ol_cnt = 0, not_ol_cnt = 0;
|
||||||
#endif /* HAVE_NETLINK */
|
#endif /* HAVE_NETLINK */
|
||||||
|
struct ospf *ospf = ospf_lookup ();
|
||||||
|
|
||||||
if (zclient->redist[ZEBRA_ROUTE_OSPF])
|
if (redist_check_instance(&zclient->redist[ZEBRA_ROUTE_OSPF], ospf->instance))
|
||||||
{
|
{
|
||||||
message = 0;
|
message = 0;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
@ -414,6 +415,7 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
|
|||||||
/* Put command, type, flags, message. */
|
/* Put command, type, flags, message. */
|
||||||
zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD);
|
zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD);
|
||||||
stream_putc (s, ZEBRA_ROUTE_OSPF);
|
stream_putc (s, ZEBRA_ROUTE_OSPF);
|
||||||
|
stream_putw (s, ospf->instance);
|
||||||
stream_putc (s, flags);
|
stream_putc (s, flags);
|
||||||
stream_putc (s, message);
|
stream_putc (s, message);
|
||||||
stream_putw (s, SAFI_UNICAST);
|
stream_putw (s, SAFI_UNICAST);
|
||||||
@ -529,8 +531,9 @@ ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
|
|||||||
struct stream *s;
|
struct stream *s;
|
||||||
struct ospf_path *path;
|
struct ospf_path *path;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
|
struct ospf *ospf = ospf_lookup ();
|
||||||
|
|
||||||
if (zclient->redist[ZEBRA_ROUTE_OSPF])
|
if (redist_check_instance(&zclient->redist[ZEBRA_ROUTE_OSPF], ospf->instance))
|
||||||
{
|
{
|
||||||
message = 0;
|
message = 0;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
@ -543,6 +546,7 @@ ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
|
|||||||
/* Put command, type, flags, message. */
|
/* Put command, type, flags, message. */
|
||||||
zclient_create_header (s, ZEBRA_IPV4_ROUTE_DELETE);
|
zclient_create_header (s, ZEBRA_IPV4_ROUTE_DELETE);
|
||||||
stream_putc (s, ZEBRA_ROUTE_OSPF);
|
stream_putc (s, ZEBRA_ROUTE_OSPF);
|
||||||
|
stream_putw (s, ospf->instance);
|
||||||
stream_putc (s, flags);
|
stream_putc (s, flags);
|
||||||
stream_putc (s, message);
|
stream_putc (s, message);
|
||||||
stream_putw (s, SAFI_UNICAST);
|
stream_putw (s, SAFI_UNICAST);
|
||||||
@ -610,10 +614,12 @@ void
|
|||||||
ospf_zebra_add_discard (struct prefix_ipv4 *p)
|
ospf_zebra_add_discard (struct prefix_ipv4 *p)
|
||||||
{
|
{
|
||||||
struct zapi_ipv4 api;
|
struct zapi_ipv4 api;
|
||||||
|
struct ospf *ospf = ospf_lookup ();
|
||||||
|
|
||||||
if (zclient->redist[ZEBRA_ROUTE_OSPF])
|
if (redist_check_instance(&zclient->redist[ZEBRA_ROUTE_OSPF], ospf->instance))
|
||||||
{
|
{
|
||||||
api.type = ZEBRA_ROUTE_OSPF;
|
api.type = ZEBRA_ROUTE_OSPF;
|
||||||
|
api.instance = ospf->instance;
|
||||||
api.flags = ZEBRA_FLAG_BLACKHOLE;
|
api.flags = ZEBRA_FLAG_BLACKHOLE;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = SAFI_UNICAST;
|
api.safi = SAFI_UNICAST;
|
||||||
@ -634,10 +640,12 @@ void
|
|||||||
ospf_zebra_delete_discard (struct prefix_ipv4 *p)
|
ospf_zebra_delete_discard (struct prefix_ipv4 *p)
|
||||||
{
|
{
|
||||||
struct zapi_ipv4 api;
|
struct zapi_ipv4 api;
|
||||||
|
struct ospf *ospf = ospf_lookup ();
|
||||||
|
|
||||||
if (zclient->redist[ZEBRA_ROUTE_OSPF])
|
if (redist_check_instance(&zclient->redist[ZEBRA_ROUTE_OSPF], ospf->instance))
|
||||||
{
|
{
|
||||||
api.type = ZEBRA_ROUTE_OSPF;
|
api.type = ZEBRA_ROUTE_OSPF;
|
||||||
|
api.instance = ospf->instance;
|
||||||
api.flags = ZEBRA_FLAG_BLACKHOLE;
|
api.flags = ZEBRA_FLAG_BLACKHOLE;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = SAFI_UNICAST;
|
api.safi = SAFI_UNICAST;
|
||||||
@ -655,50 +663,180 @@ ospf_zebra_delete_discard (struct prefix_ipv4 *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
struct ospf_external *
|
||||||
ospf_is_type_redistributed (int type)
|
ospf_external_lookup (u_char type, u_short instance)
|
||||||
{
|
{
|
||||||
return (DEFAULT_ROUTE_TYPE (type)) ?
|
struct list *ext_list;
|
||||||
zclient->default_information : zclient->redist[type];
|
struct listnode *node;
|
||||||
|
struct ospf_external *ext;
|
||||||
|
|
||||||
|
ext_list = om->external[type];
|
||||||
|
if (!ext_list)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
|
||||||
|
if (ext->instance == instance)
|
||||||
|
return ext;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ospf_external *
|
||||||
|
ospf_external_add (u_char type, u_short instance)
|
||||||
|
{
|
||||||
|
struct list *ext_list;
|
||||||
|
struct ospf_external *ext;
|
||||||
|
|
||||||
|
ext = ospf_external_lookup(type, instance);
|
||||||
|
if (ext)
|
||||||
|
return ext;
|
||||||
|
|
||||||
|
if (!om->external[type])
|
||||||
|
om->external[type] = list_new();
|
||||||
|
|
||||||
|
ext_list = om->external[type];
|
||||||
|
ext = (struct ospf_external *)calloc (1, sizeof(struct ospf_external));
|
||||||
|
ext->instance = instance;
|
||||||
|
EXTERNAL_INFO (ext) = route_table_init ();
|
||||||
|
|
||||||
|
listnode_add(ext_list, ext);
|
||||||
|
|
||||||
|
return ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ospf_external_del (u_char type, u_short instance)
|
||||||
|
{
|
||||||
|
struct ospf_external *ext;
|
||||||
|
|
||||||
|
ext = ospf_external_lookup(type, instance);
|
||||||
|
|
||||||
|
if (ext)
|
||||||
|
{
|
||||||
|
if (EXTERNAL_INFO (ext))
|
||||||
|
route_table_finish(EXTERNAL_INFO (ext));
|
||||||
|
|
||||||
|
listnode_delete(om->external[type], ext);
|
||||||
|
if (!om->external[type]->count)
|
||||||
|
{
|
||||||
|
list_free(om->external[type]);
|
||||||
|
om->external[type] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ospf_redist *
|
||||||
|
ospf_redist_lookup (struct ospf *ospf, u_char type, u_short instance)
|
||||||
|
{
|
||||||
|
struct list *red_list;
|
||||||
|
struct listnode *node;
|
||||||
|
struct ospf_redist *red;
|
||||||
|
|
||||||
|
red_list = ospf->redist[type];
|
||||||
|
if (!red_list)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
|
||||||
|
if (red->instance == instance)
|
||||||
|
return red;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ospf_redist *
|
||||||
|
ospf_redist_add (struct ospf *ospf, u_char type, u_short instance)
|
||||||
|
{
|
||||||
|
struct list *red_list;
|
||||||
|
struct ospf_redist *red;
|
||||||
|
|
||||||
|
red = ospf_redist_lookup(ospf, type, instance);
|
||||||
|
if (red)
|
||||||
|
return red;
|
||||||
|
|
||||||
|
if (!ospf->redist[type])
|
||||||
|
ospf->redist[type] = list_new();
|
||||||
|
|
||||||
|
red_list = ospf->redist[type];
|
||||||
|
red = (struct ospf_redist *)calloc (1, sizeof(struct ospf_redist));
|
||||||
|
red->instance = instance;
|
||||||
|
red->dmetric.type = -1;
|
||||||
|
red->dmetric.value = -1;
|
||||||
|
|
||||||
|
listnode_add(red_list, red);
|
||||||
|
|
||||||
|
return red;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ospf_redist_del (struct ospf *ospf, u_char type, u_short instance)
|
||||||
|
{
|
||||||
|
struct ospf_redist *red;
|
||||||
|
|
||||||
|
red = ospf_redist_lookup(ospf, type, instance);
|
||||||
|
|
||||||
|
if (red)
|
||||||
|
{
|
||||||
|
listnode_delete(ospf->redist[type], red);
|
||||||
|
if (!ospf->redist[type]->count)
|
||||||
|
{
|
||||||
|
list_free(ospf->redist[type]);
|
||||||
|
ospf->redist[type] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
ospf_is_type_redistributed (int type, u_short instance)
|
||||||
|
{
|
||||||
|
return (DEFAULT_ROUTE_TYPE (type) ?
|
||||||
|
zclient->default_information :
|
||||||
|
redist_check_instance(&zclient->redist[type], instance));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue)
|
ospf_redistribute_set (struct ospf *ospf, int type, u_short instance, int mtype,
|
||||||
|
int mvalue)
|
||||||
{
|
{
|
||||||
int force = 0;
|
int force = 0;
|
||||||
|
struct ospf_redist *red;
|
||||||
|
|
||||||
if (ospf_is_type_redistributed (type))
|
red = ospf_redist_lookup(ospf, type, instance);
|
||||||
|
if (ospf_is_type_redistributed (type, instance))
|
||||||
{
|
{
|
||||||
if (mtype != ospf->dmetric[type].type)
|
if (mtype != red->dmetric.type)
|
||||||
{
|
{
|
||||||
ospf->dmetric[type].type = mtype;
|
red->dmetric.type = mtype;
|
||||||
force = LSA_REFRESH_FORCE;
|
force = LSA_REFRESH_FORCE;
|
||||||
}
|
}
|
||||||
if (mvalue != ospf->dmetric[type].value)
|
if (mvalue != red->dmetric.value)
|
||||||
{
|
{
|
||||||
ospf->dmetric[type].value = mvalue;
|
red->dmetric.value = mvalue;
|
||||||
force = LSA_REFRESH_FORCE;
|
force = LSA_REFRESH_FORCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ospf_external_lsa_refresh_type (ospf, type, force);
|
ospf_external_lsa_refresh_type (ospf, type, instance, force);
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
|
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
|
||||||
zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
|
zlog_debug ("Redistribute[%s][%d]: Refresh Type[%d], Metric[%d]",
|
||||||
ospf_redist_string(type),
|
ospf_redist_string(type), instance,
|
||||||
metric_type (ospf, type), metric_value (ospf, type));
|
metric_type (ospf, type, instance),
|
||||||
|
metric_value (ospf, type, instance));
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ospf->dmetric[type].type = mtype;
|
red->dmetric.type = mtype;
|
||||||
ospf->dmetric[type].value = mvalue;
|
red->dmetric.value = mvalue;
|
||||||
|
|
||||||
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
|
ospf_external_add(type, instance);
|
||||||
|
|
||||||
|
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type, instance);
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
|
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
|
||||||
zlog_debug ("Redistribute[%s]: Start Type[%d], Metric[%d]",
|
zlog_debug ("Redistribute[%s][%d]: Start Type[%d], Metric[%d]",
|
||||||
ospf_redist_string(type),
|
ospf_redist_string(type), instance,
|
||||||
metric_type (ospf, type), metric_value (ospf, type));
|
metric_type (ospf, type, instance), metric_value (ospf, type, instance));
|
||||||
|
|
||||||
ospf_asbr_status_update (ospf, ++ospf->redistribute);
|
ospf_asbr_status_update (ospf, ++ospf->redistribute);
|
||||||
|
|
||||||
@ -706,25 +844,26 @@ ospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ospf_redistribute_unset (struct ospf *ospf, int type)
|
ospf_redistribute_unset (struct ospf *ospf, int type, u_short instance)
|
||||||
{
|
{
|
||||||
if (type == zclient->redist_default)
|
if (type == zclient->redist_default && instance == zclient->instance)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
if (!ospf_is_type_redistributed (type))
|
if (!ospf_is_type_redistributed (type, instance))
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
|
zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, instance);
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
|
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
|
||||||
zlog_debug ("Redistribute[%s]: Stop",
|
zlog_debug ("Redistribute[%s][%d]: Stop",
|
||||||
ospf_redist_string(type));
|
ospf_redist_string(type), instance);
|
||||||
|
|
||||||
ospf->dmetric[type].type = -1;
|
ospf_redist_del (ospf, type, instance);
|
||||||
ospf->dmetric[type].value = -1;
|
|
||||||
|
|
||||||
/* Remove the routes from OSPF table. */
|
/* Remove the routes from OSPF table. */
|
||||||
ospf_redistribute_withdraw (ospf, type);
|
ospf_redistribute_withdraw (ospf, type, instance);
|
||||||
|
|
||||||
|
ospf_external_del(type, instance);
|
||||||
|
|
||||||
ospf_asbr_status_update (ospf, --ospf->redistribute);
|
ospf_asbr_status_update (ospf, --ospf->redistribute);
|
||||||
|
|
||||||
@ -735,11 +874,17 @@ int
|
|||||||
ospf_redistribute_default_set (struct ospf *ospf, int originate,
|
ospf_redistribute_default_set (struct ospf *ospf, int originate,
|
||||||
int mtype, int mvalue)
|
int mtype, int mvalue)
|
||||||
{
|
{
|
||||||
ospf->default_originate = originate;
|
struct ospf_redist *red;
|
||||||
ospf->dmetric[DEFAULT_ROUTE].type = mtype;
|
|
||||||
ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
|
|
||||||
|
|
||||||
if (ospf_is_type_redistributed (DEFAULT_ROUTE))
|
ospf->default_originate = originate;
|
||||||
|
|
||||||
|
red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0);
|
||||||
|
red->dmetric.type = mtype;
|
||||||
|
red->dmetric.value = mvalue;
|
||||||
|
|
||||||
|
ospf_external_add(DEFAULT_ROUTE, 0);
|
||||||
|
|
||||||
|
if (ospf_is_type_redistributed (DEFAULT_ROUTE, 0))
|
||||||
{
|
{
|
||||||
/* if ospf->default_originate changes value, is calling
|
/* if ospf->default_originate changes value, is calling
|
||||||
ospf_external_lsa_refresh_default sufficient to implement
|
ospf_external_lsa_refresh_default sufficient to implement
|
||||||
@ -749,8 +894,8 @@ ospf_redistribute_default_set (struct ospf *ospf, int originate,
|
|||||||
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
|
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
|
||||||
zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
|
zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
|
||||||
ospf_redist_string(DEFAULT_ROUTE),
|
ospf_redist_string(DEFAULT_ROUTE),
|
||||||
metric_type (ospf, DEFAULT_ROUTE),
|
metric_type (ospf, DEFAULT_ROUTE, 0),
|
||||||
metric_value (ospf, DEFAULT_ROUTE));
|
metric_value (ospf, DEFAULT_ROUTE, 0));
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -758,8 +903,8 @@ ospf_redistribute_default_set (struct ospf *ospf, int originate,
|
|||||||
|
|
||||||
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
|
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
|
||||||
zlog_debug ("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]",
|
zlog_debug ("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]",
|
||||||
metric_type (ospf, DEFAULT_ROUTE),
|
metric_type (ospf, DEFAULT_ROUTE, 0),
|
||||||
metric_value (ospf, DEFAULT_ROUTE));
|
metric_value (ospf, DEFAULT_ROUTE, 0));
|
||||||
|
|
||||||
if (ospf->router_id.s_addr == 0)
|
if (ospf->router_id.s_addr == 0)
|
||||||
ospf->external_origin |= (1 << DEFAULT_ROUTE);
|
ospf->external_origin |= (1 << DEFAULT_ROUTE);
|
||||||
@ -774,18 +919,19 @@ ospf_redistribute_default_set (struct ospf *ospf, int originate,
|
|||||||
int
|
int
|
||||||
ospf_redistribute_default_unset (struct ospf *ospf)
|
ospf_redistribute_default_unset (struct ospf *ospf)
|
||||||
{
|
{
|
||||||
if (!ospf_is_type_redistributed (DEFAULT_ROUTE))
|
if (!ospf_is_type_redistributed (DEFAULT_ROUTE, 0))
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
ospf->default_originate = DEFAULT_ORIGINATE_NONE;
|
ospf->default_originate = DEFAULT_ORIGINATE_NONE;
|
||||||
ospf->dmetric[DEFAULT_ROUTE].type = -1;
|
ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
|
||||||
ospf->dmetric[DEFAULT_ROUTE].value = -1;
|
|
||||||
|
|
||||||
zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient);
|
zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient);
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
|
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
|
||||||
zlog_debug ("Redistribute[DEFAULT]: Stop");
|
zlog_debug ("Redistribute[DEFAULT]: Stop");
|
||||||
|
|
||||||
|
//Pending: how does the external_info cleanup work in this case?
|
||||||
|
|
||||||
ospf_asbr_status_update (ospf, --ospf->redistribute);
|
ospf_asbr_status_update (ospf, --ospf->redistribute);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -836,7 +982,9 @@ ospf_redistribute_check (struct ospf *ospf,
|
|||||||
{
|
{
|
||||||
struct route_map_set_values save_values;
|
struct route_map_set_values save_values;
|
||||||
struct prefix_ipv4 *p = &ei->p;
|
struct prefix_ipv4 *p = &ei->p;
|
||||||
|
struct ospf_redist *red;
|
||||||
u_char type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
|
u_char type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
|
||||||
|
u_short instance = is_prefix_default (&ei->p) ? 0 : ei->instance;
|
||||||
|
|
||||||
if (changed)
|
if (changed)
|
||||||
*changed = 0;
|
*changed = 0;
|
||||||
@ -865,11 +1013,12 @@ ospf_redistribute_check (struct ospf *ospf,
|
|||||||
ospf_reset_route_map_set_values (&ei->route_map_set);
|
ospf_reset_route_map_set_values (&ei->route_map_set);
|
||||||
|
|
||||||
/* apply route-map if needed */
|
/* apply route-map if needed */
|
||||||
if (ROUTEMAP_NAME (ospf, type))
|
red = ospf_redist_lookup (ospf, type, instance);
|
||||||
|
if (red && ROUTEMAP_NAME(red))
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = route_map_apply (ROUTEMAP (ospf, type), (struct prefix *) p,
|
ret = route_map_apply (ROUTEMAP (red), (struct prefix *) p,
|
||||||
RMAP_OSPF, ei);
|
RMAP_OSPF, ei);
|
||||||
|
|
||||||
if (ret == RMAP_DENYMATCH)
|
if (ret == RMAP_DENYMATCH)
|
||||||
@ -893,23 +1042,23 @@ ospf_redistribute_check (struct ospf *ospf,
|
|||||||
|
|
||||||
/* OSPF route-map set for redistribution */
|
/* OSPF route-map set for redistribution */
|
||||||
void
|
void
|
||||||
ospf_routemap_set (struct ospf *ospf, int type, const char *name)
|
ospf_routemap_set (struct ospf_redist *red, const char *name)
|
||||||
{
|
{
|
||||||
if (ROUTEMAP_NAME (ospf, type))
|
if (ROUTEMAP_NAME (red))
|
||||||
free (ROUTEMAP_NAME (ospf, type));
|
free (ROUTEMAP_NAME (red));
|
||||||
|
|
||||||
ROUTEMAP_NAME (ospf, type) = strdup (name);
|
ROUTEMAP_NAME (red) = strdup (name);
|
||||||
ROUTEMAP (ospf, type) = route_map_lookup_by_name (name);
|
ROUTEMAP (red) = route_map_lookup_by_name (name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ospf_routemap_unset (struct ospf *ospf, int type)
|
ospf_routemap_unset (struct ospf_redist *red)
|
||||||
{
|
{
|
||||||
if (ROUTEMAP_NAME (ospf, type))
|
if (ROUTEMAP_NAME (red))
|
||||||
free (ROUTEMAP_NAME (ospf, type));
|
free (ROUTEMAP_NAME (red));
|
||||||
|
|
||||||
ROUTEMAP_NAME (ospf, type) = NULL;
|
ROUTEMAP_NAME (red) = NULL;
|
||||||
ROUTEMAP (ospf, type) = NULL;
|
ROUTEMAP (red) = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zebra route add and delete treatment. */
|
/* Zebra route add and delete treatment. */
|
||||||
@ -931,6 +1080,7 @@ ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
|
|||||||
|
|
||||||
/* Type, flags, message. */
|
/* Type, flags, message. */
|
||||||
api.type = stream_getc (s);
|
api.type = stream_getc (s);
|
||||||
|
api.instance = stream_getw (s);
|
||||||
api.flags = stream_getc (s);
|
api.flags = stream_getc (s);
|
||||||
api.message = stream_getc (s);
|
api.message = stream_getc (s);
|
||||||
|
|
||||||
@ -985,7 +1135,8 @@ ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
|
|||||||
if (ospf->dtag[api.type] > 0)
|
if (ospf->dtag[api.type] > 0)
|
||||||
api.tag = ospf->dtag[api.type];
|
api.tag = ospf->dtag[api.type];
|
||||||
|
|
||||||
ei = ospf_external_info_add (api.type, p, ifindex, nexthop, api.tag);
|
ei = ospf_external_info_add (api.type, api.instance, p, ifindex,
|
||||||
|
nexthop, api.tag);
|
||||||
|
|
||||||
if (ospf->router_id.s_addr == 0)
|
if (ospf->router_id.s_addr == 0)
|
||||||
/* Set flags to generate AS-external-LSA originate event
|
/* Set flags to generate AS-external-LSA originate event
|
||||||
@ -1016,7 +1167,7 @@ ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
|
|||||||
}
|
}
|
||||||
else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
|
else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
|
||||||
{
|
{
|
||||||
ospf_external_info_delete (api.type, p);
|
ospf_external_info_delete (api.type, api.instance, p);
|
||||||
if (is_prefix_default (&p))
|
if (is_prefix_default (&p))
|
||||||
ospf_external_lsa_refresh_default (ospf);
|
ospf_external_lsa_refresh_default (ospf);
|
||||||
else
|
else
|
||||||
@ -1042,7 +1193,7 @@ ospf_distribute_list_out_set (struct ospf *ospf, int type, const char *name)
|
|||||||
|
|
||||||
/* If access-list have been set, schedule update timer. */
|
/* If access-list have been set, schedule update timer. */
|
||||||
if (DISTRIBUTE_LIST (ospf, type))
|
if (DISTRIBUTE_LIST (ospf, type))
|
||||||
ospf_distribute_list_update (ospf, type);
|
ospf_distribute_list_update (ospf, type, 0);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1052,7 +1203,7 @@ ospf_distribute_list_out_unset (struct ospf *ospf, int type, const char *name)
|
|||||||
{
|
{
|
||||||
/* Schedule update timer. */
|
/* Schedule update timer. */
|
||||||
if (DISTRIBUTE_LIST (ospf, type))
|
if (DISTRIBUTE_LIST (ospf, type))
|
||||||
ospf_distribute_list_update (ospf, type);
|
ospf_distribute_list_update (ospf, type, 0);
|
||||||
|
|
||||||
/* Unset distribute-list. */
|
/* Unset distribute-list. */
|
||||||
DISTRIBUTE_LIST (ospf, type) = NULL;
|
DISTRIBUTE_LIST (ospf, type) = NULL;
|
||||||
@ -1088,19 +1239,30 @@ ospf_distribute_list_update_timer (struct thread *thread)
|
|||||||
/* foreach all external info. */
|
/* foreach all external info. */
|
||||||
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
|
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
|
||||||
{
|
{
|
||||||
rt = EXTERNAL_INFO (type);
|
struct list *ext_list;
|
||||||
if (!rt)
|
struct listnode *node;
|
||||||
continue;
|
struct ospf_external *ext;
|
||||||
for (rn = route_top (rt); rn; rn = route_next (rn))
|
|
||||||
if ((ei = rn->info) != NULL)
|
ext_list = om->external[type];
|
||||||
{
|
if (!ext_list)
|
||||||
if (is_prefix_default (&ei->p))
|
continue;
|
||||||
default_refresh = 1;
|
|
||||||
else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
|
for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
|
||||||
ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED);
|
{
|
||||||
else
|
rt = ext->external_info;
|
||||||
ospf_external_lsa_originate (ospf, ei);
|
if (!rt)
|
||||||
}
|
continue;
|
||||||
|
for (rn = route_top (rt); rn; rn = route_next (rn))
|
||||||
|
if ((ei = rn->info) != NULL)
|
||||||
|
{
|
||||||
|
if (is_prefix_default (&ei->p))
|
||||||
|
default_refresh = 1;
|
||||||
|
else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
|
||||||
|
ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED);
|
||||||
|
else
|
||||||
|
ospf_external_lsa_originate (ospf, ei);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (default_refresh)
|
if (default_refresh)
|
||||||
ospf_external_lsa_refresh_default (ospf);
|
ospf_external_lsa_refresh_default (ospf);
|
||||||
@ -1111,12 +1273,15 @@ ospf_distribute_list_update_timer (struct thread *thread)
|
|||||||
|
|
||||||
/* Update distribute-list and set timer to apply access-list. */
|
/* Update distribute-list and set timer to apply access-list. */
|
||||||
void
|
void
|
||||||
ospf_distribute_list_update (struct ospf *ospf, uintptr_t type)
|
ospf_distribute_list_update (struct ospf *ospf, uintptr_t type,
|
||||||
|
u_short instance)
|
||||||
{
|
{
|
||||||
struct route_table *rt;
|
struct route_table *rt;
|
||||||
|
struct ospf_external *ext;
|
||||||
|
|
||||||
/* External info does not exist. */
|
/* External info does not exist. */
|
||||||
if (!(rt = EXTERNAL_INFO (type)))
|
ext = ospf_external_lookup(type, instance);
|
||||||
|
if (!ext || !(rt = EXTERNAL_INFO (ext)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* If exists previously invoked thread, then let it continue. */
|
/* If exists previously invoked thread, then let it continue. */
|
||||||
@ -1139,7 +1304,7 @@ ospf_filter_update (struct access_list *access)
|
|||||||
struct ospf_area *area;
|
struct ospf_area *area;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
|
|
||||||
/* If OSPF instatnce does not exist, return right now. */
|
/* If OSPF instance does not exist, return right now. */
|
||||||
ospf = ospf_lookup ();
|
ospf = ospf_lookup ();
|
||||||
if (ospf == NULL)
|
if (ospf == NULL)
|
||||||
return;
|
return;
|
||||||
@ -1147,12 +1312,20 @@ ospf_filter_update (struct access_list *access)
|
|||||||
/* Update distribute-list, and apply filter. */
|
/* Update distribute-list, and apply filter. */
|
||||||
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
|
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
|
||||||
{
|
{
|
||||||
if (ROUTEMAP (ospf, type) != NULL)
|
struct list *red_list;
|
||||||
{
|
struct listnode *node;
|
||||||
/* if route-map is not NULL it may be using this access list */
|
struct ospf_redist *red;
|
||||||
ospf_distribute_list_update (ospf, type);
|
|
||||||
continue;
|
red_list = ospf->redist[type];
|
||||||
}
|
if (red_list)
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
|
||||||
|
{
|
||||||
|
if (ROUTEMAP (red))
|
||||||
|
{
|
||||||
|
/* if route-map is not NULL it may be using this access list */
|
||||||
|
ospf_distribute_list_update (ospf, type, red->instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* There is place for route-map for default-information (ZEBRA_ROUTE_MAX),
|
/* There is place for route-map for default-information (ZEBRA_ROUTE_MAX),
|
||||||
* but no distribute list. */
|
* but no distribute list. */
|
||||||
@ -1175,7 +1348,7 @@ ospf_filter_update (struct access_list *access)
|
|||||||
/* Schedule distribute-list update timer. */
|
/* Schedule distribute-list update timer. */
|
||||||
if (DISTRIBUTE_LIST (ospf, type) == NULL ||
|
if (DISTRIBUTE_LIST (ospf, type) == NULL ||
|
||||||
strcmp (DISTRIBUTE_NAME (ospf, type), access->name) == 0)
|
strcmp (DISTRIBUTE_NAME (ospf, type), access->name) == 0)
|
||||||
ospf_distribute_list_update (ospf, type);
|
ospf_distribute_list_update (ospf, type, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1220,12 +1393,20 @@ ospf_prefix_list_update (struct prefix_list *plist)
|
|||||||
*/
|
*/
|
||||||
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
|
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
|
||||||
{
|
{
|
||||||
if (ROUTEMAP (ospf, type) != NULL)
|
struct list *red_list;
|
||||||
{
|
struct listnode *node;
|
||||||
/* If route-map is not NULL it may be using this prefix list */
|
struct ospf_redist *red;
|
||||||
ospf_distribute_list_update (ospf, type);
|
|
||||||
continue;
|
red_list = ospf->redist[type];
|
||||||
}
|
if (red_list)
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
|
||||||
|
{
|
||||||
|
if (ROUTEMAP (red))
|
||||||
|
{
|
||||||
|
/* if route-map is not NULL it may be using this prefix list */
|
||||||
|
ospf_distribute_list_update (ospf, type, red->instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update area filter-lists. */
|
/* Update area filter-lists. */
|
||||||
@ -1400,11 +1581,11 @@ ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ospf_zebra_init ()
|
ospf_zebra_init (u_short instance)
|
||||||
{
|
{
|
||||||
/* Allocate zebra structure. */
|
/* Allocate zebra structure. */
|
||||||
zclient = zclient_new ();
|
zclient = zclient_new ();
|
||||||
zclient_init (zclient, ZEBRA_ROUTE_OSPF);
|
zclient_init (zclient, ZEBRA_ROUTE_OSPF, instance);
|
||||||
zclient->router_id_update = ospf_router_id_update_zebra;
|
zclient->router_id_update = ospf_router_id_update_zebra;
|
||||||
zclient->interface_add = ospf_interface_add;
|
zclient->interface_add = ospf_interface_add;
|
||||||
zclient->interface_delete = ospf_interface_delete;
|
zclient->interface_delete = ospf_interface_delete;
|
||||||
|
@ -54,25 +54,32 @@ extern int ospf_redistribute_check (struct ospf *, struct external_info *,
|
|||||||
int *);
|
int *);
|
||||||
extern int ospf_distribute_check_connected (struct ospf *,
|
extern int ospf_distribute_check_connected (struct ospf *,
|
||||||
struct external_info *);
|
struct external_info *);
|
||||||
extern void ospf_distribute_list_update (struct ospf *, uintptr_t);
|
extern void ospf_distribute_list_update (struct ospf *, uintptr_t, u_short);
|
||||||
|
|
||||||
extern int ospf_is_type_redistributed (int);
|
extern int ospf_is_type_redistributed (int, u_short);
|
||||||
extern void ospf_distance_reset (struct ospf *);
|
extern void ospf_distance_reset (struct ospf *);
|
||||||
extern u_char ospf_distance_apply (struct prefix_ipv4 *, struct ospf_route *);
|
extern u_char ospf_distance_apply (struct prefix_ipv4 *, struct ospf_route *);
|
||||||
|
extern struct ospf_external *ospf_external_lookup (u_char, u_short);
|
||||||
|
extern struct ospf_external *ospf_external_add (u_char, u_short);
|
||||||
|
extern void ospf_external_del (u_char, u_short);
|
||||||
|
extern struct ospf_redist *ospf_redist_lookup (struct ospf *, u_char, u_short);
|
||||||
|
extern struct ospf_redist *ospf_redist_add (struct ospf *, u_char, u_short);
|
||||||
|
extern void ospf_redist_del (struct ospf *, u_char, u_short);
|
||||||
|
|
||||||
extern int ospf_redistribute_set (struct ospf *, int, int, int);
|
|
||||||
extern int ospf_redistribute_unset (struct ospf *, int);
|
extern int ospf_redistribute_set (struct ospf *, int, u_short, int, int);
|
||||||
|
extern int ospf_redistribute_unset (struct ospf *, int, u_short);
|
||||||
extern int ospf_redistribute_default_set (struct ospf *, int, int, int);
|
extern int ospf_redistribute_default_set (struct ospf *, int, int, int);
|
||||||
extern int ospf_redistribute_default_unset (struct ospf *);
|
extern int ospf_redistribute_default_unset (struct ospf *);
|
||||||
extern int ospf_distribute_list_out_set (struct ospf *, int, const char *);
|
extern int ospf_distribute_list_out_set (struct ospf *, int, const char *);
|
||||||
extern int ospf_distribute_list_out_unset (struct ospf *, int, const char *);
|
extern int ospf_distribute_list_out_unset (struct ospf *, int, const char *);
|
||||||
extern void ospf_routemap_set (struct ospf *, int, const char *);
|
extern void ospf_routemap_set (struct ospf_redist *, const char *);
|
||||||
extern void ospf_routemap_unset (struct ospf *, int);
|
extern void ospf_routemap_unset (struct ospf_redist *);
|
||||||
extern int ospf_distance_set (struct vty *, struct ospf *, const char *,
|
extern int ospf_distance_set (struct vty *, struct ospf *, const char *,
|
||||||
const char *, const char *);
|
const char *, const char *);
|
||||||
extern int ospf_distance_unset (struct vty *, struct ospf *, const char *,
|
extern int ospf_distance_unset (struct vty *, struct ospf *, const char *,
|
||||||
const char *, const char *);
|
const char *, const char *);
|
||||||
extern void ospf_zebra_init (void);
|
extern void ospf_zebra_init (u_short);
|
||||||
|
|
||||||
#endif /* _ZEBRA_OSPF_ZEBRA_H */
|
#endif /* _ZEBRA_OSPF_ZEBRA_H */
|
||||||
|
|
||||||
|
107
ospfd/ospfd.c
107
ospfd/ospfd.c
@ -153,12 +153,13 @@ ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
|
|||||||
|
|
||||||
/* Allocate new ospf structure. */
|
/* Allocate new ospf structure. */
|
||||||
static struct ospf *
|
static struct ospf *
|
||||||
ospf_new (void)
|
ospf_new (u_short instance)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
|
struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
|
||||||
|
|
||||||
|
new->instance = instance;
|
||||||
new->router_id.s_addr = htonl (0);
|
new->router_id.s_addr = htonl (0);
|
||||||
new->router_id_static.s_addr = htonl (0);
|
new->router_id_static.s_addr = htonl (0);
|
||||||
|
|
||||||
@ -187,8 +188,6 @@ ospf_new (void)
|
|||||||
/* Distribute parameter init. */
|
/* Distribute parameter init. */
|
||||||
for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
|
for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
|
||||||
{
|
{
|
||||||
new->dmetric[i].type = -1;
|
|
||||||
new->dmetric[i].value = -1;
|
|
||||||
new->dtag[i] = 0;
|
new->dtag[i] = 0;
|
||||||
}
|
}
|
||||||
new->default_metric = -1;
|
new->default_metric = -1;
|
||||||
@ -248,6 +247,23 @@ ospf_lookup ()
|
|||||||
return listgetdata (listhead (om->ospf));
|
return listgetdata (listhead (om->ospf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ospf *
|
||||||
|
ospf_lookup_instance (u_short instance)
|
||||||
|
{
|
||||||
|
struct ospf *ospf;
|
||||||
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
|
if (listcount (om->ospf) == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
|
||||||
|
if ((ospf->instance == 0 && instance == 0)
|
||||||
|
|| (ospf->instance && instance && ospf->instance == instance))
|
||||||
|
return ospf;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ospf_add (struct ospf *ospf)
|
ospf_add (struct ospf *ospf)
|
||||||
{
|
{
|
||||||
@ -268,7 +284,29 @@ ospf_get ()
|
|||||||
ospf = ospf_lookup ();
|
ospf = ospf_lookup ();
|
||||||
if (ospf == NULL)
|
if (ospf == NULL)
|
||||||
{
|
{
|
||||||
ospf = ospf_new ();
|
ospf = ospf_new (0);
|
||||||
|
ospf_add (ospf);
|
||||||
|
|
||||||
|
if (ospf->router_id_static.s_addr == 0)
|
||||||
|
ospf_router_id_update (ospf);
|
||||||
|
|
||||||
|
#ifdef HAVE_OPAQUE_LSA
|
||||||
|
ospf_opaque_type11_lsa_init (ospf);
|
||||||
|
#endif /* HAVE_OPAQUE_LSA */
|
||||||
|
}
|
||||||
|
|
||||||
|
return ospf;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ospf *
|
||||||
|
ospf_get_instance (u_short instance)
|
||||||
|
{
|
||||||
|
struct ospf *ospf;
|
||||||
|
|
||||||
|
ospf = ospf_lookup_instance (instance);
|
||||||
|
if (ospf == NULL)
|
||||||
|
{
|
||||||
|
ospf = ospf_new (instance);
|
||||||
ospf_add (ospf);
|
ospf_add (ospf);
|
||||||
|
|
||||||
if (ospf->router_id_static.s_addr == 0)
|
if (ospf->router_id_static.s_addr == 0)
|
||||||
@ -409,6 +447,7 @@ ospf_finish_final (struct ospf *ospf)
|
|||||||
struct ospf_vl_data *vl_data;
|
struct ospf_vl_data *vl_data;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
int i;
|
int i;
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
#ifdef HAVE_OPAQUE_LSA
|
#ifdef HAVE_OPAQUE_LSA
|
||||||
ospf_opaque_type11_lsa_term (ospf);
|
ospf_opaque_type11_lsa_term (ospf);
|
||||||
@ -419,7 +458,17 @@ ospf_finish_final (struct ospf *ospf)
|
|||||||
|
|
||||||
/* Unregister redistribution */
|
/* Unregister redistribution */
|
||||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
||||||
ospf_redistribute_unset (ospf, i);
|
{
|
||||||
|
struct list *red_list;
|
||||||
|
struct ospf_redist *red;
|
||||||
|
|
||||||
|
red_list = ospf->redist[i];
|
||||||
|
if (!red_list)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS(red_list, node, nnode, red))
|
||||||
|
ospf_redistribute_unset (ospf, i, red->instance);
|
||||||
|
}
|
||||||
ospf_redistribute_default_unset (ospf);
|
ospf_redistribute_default_unset (ospf);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
|
for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
|
||||||
@ -557,23 +606,43 @@ ospf_finish_final (struct ospf *ospf)
|
|||||||
list_delete (ospf->areas);
|
list_delete (ospf->areas);
|
||||||
|
|
||||||
for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
|
for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
|
||||||
if (EXTERNAL_INFO (i) != NULL)
|
{
|
||||||
for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
|
struct list *ext_list;
|
||||||
{
|
struct listnode *node;
|
||||||
if (rn->info == NULL)
|
struct ospf_external *ext;
|
||||||
continue;
|
|
||||||
|
ext_list = om->external[i];
|
||||||
XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
|
if (!ext_list)
|
||||||
rn->info = NULL;
|
continue;
|
||||||
route_unlock_node (rn);
|
|
||||||
}
|
for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
|
||||||
|
{
|
||||||
|
if (ext->external_info)
|
||||||
|
for (rn = route_top (ext->external_info); rn; rn = route_next (rn))
|
||||||
|
{
|
||||||
|
if (rn->info == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
|
||||||
|
rn->info = NULL;
|
||||||
|
route_unlock_node (rn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ospf_distance_reset (ospf);
|
ospf_distance_reset (ospf);
|
||||||
route_table_finish (ospf->distance_table);
|
route_table_finish (ospf->distance_table);
|
||||||
|
|
||||||
|
if (!CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
|
||||||
|
instance = ospf->instance;
|
||||||
|
|
||||||
ospf_delete (ospf);
|
ospf_delete (ospf);
|
||||||
|
|
||||||
XFREE (MTYPE_OSPF_TOP, ospf);
|
XFREE (MTYPE_OSPF_TOP, ospf);
|
||||||
|
|
||||||
|
if (!CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
|
||||||
|
ospf_get_instance(instance);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -775,11 +844,13 @@ static void update_redistributed(struct ospf *ospf, int add_to_ospf)
|
|||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct external_info *ei;
|
struct external_info *ei;
|
||||||
|
struct ospf_external *ext;
|
||||||
|
|
||||||
if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
|
if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT, 0))
|
||||||
if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
|
if ((ext = ospf_external_lookup(ZEBRA_ROUTE_CONNECT, 0)) &&
|
||||||
|
EXTERNAL_INFO (ext))
|
||||||
{
|
{
|
||||||
for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
|
for (rn = route_top (EXTERNAL_INFO (ext));
|
||||||
rn; rn = route_next (rn))
|
rn; rn = route_next (rn))
|
||||||
{
|
{
|
||||||
if ((ei = rn->info) != NULL)
|
if ((ei = rn->info) != NULL)
|
||||||
|
@ -76,6 +76,12 @@
|
|||||||
#define OSPF_LS_REFRESH_SHIFT (60 * 15)
|
#define OSPF_LS_REFRESH_SHIFT (60 * 15)
|
||||||
#define OSPF_LS_REFRESH_JITTER 60
|
#define OSPF_LS_REFRESH_JITTER 60
|
||||||
|
|
||||||
|
struct ospf_external
|
||||||
|
{
|
||||||
|
u_short instance;
|
||||||
|
struct route_table *external_info;
|
||||||
|
};
|
||||||
|
|
||||||
/* OSPF master for system wide configuration and variables. */
|
/* OSPF master for system wide configuration and variables. */
|
||||||
struct ospf_master
|
struct ospf_master
|
||||||
{
|
{
|
||||||
@ -89,8 +95,8 @@ struct ospf_master
|
|||||||
struct list *iflist;
|
struct list *iflist;
|
||||||
|
|
||||||
/* Redistributed external information. */
|
/* Redistributed external information. */
|
||||||
struct route_table *external_info[ZEBRA_ROUTE_MAX + 1];
|
struct list *external[ZEBRA_ROUTE_MAX + 1];
|
||||||
#define EXTERNAL_INFO(T) om->external_info[T]
|
#define EXTERNAL_INFO(E) (E->external_info)
|
||||||
|
|
||||||
/* OSPF start time. */
|
/* OSPF start time. */
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
@ -100,9 +106,34 @@ struct ospf_master
|
|||||||
#define OSPF_MASTER_SHUTDOWN (1 << 0) /* deferred-shutdown */
|
#define OSPF_MASTER_SHUTDOWN (1 << 0) /* deferred-shutdown */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ospf_redist
|
||||||
|
{
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
|
/* Redistribute metric info. */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int type; /* External metric type (E1 or E2). */
|
||||||
|
int value; /* Value for static metric (24-bit).
|
||||||
|
-1 means metric value is not set. */
|
||||||
|
} dmetric;
|
||||||
|
|
||||||
|
/* For redistribute route map. */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
struct route_map *map;
|
||||||
|
} route_map; /* +1 is for default-information */
|
||||||
|
#define ROUTEMAP_NAME(R) (R->route_map.name)
|
||||||
|
#define ROUTEMAP(R) (R->route_map.map)
|
||||||
|
};
|
||||||
|
|
||||||
/* OSPF instance structure. */
|
/* OSPF instance structure. */
|
||||||
struct ospf
|
struct ospf
|
||||||
{
|
{
|
||||||
|
/* OSPF instance ID */
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
/* OSPF Router ID. */
|
/* OSPF Router ID. */
|
||||||
struct in_addr router_id; /* Configured automatically. */
|
struct in_addr router_id; /* Configured automatically. */
|
||||||
struct in_addr router_id_static; /* Configured manually. */
|
struct in_addr router_id_static; /* Configured manually. */
|
||||||
@ -236,26 +267,12 @@ struct ospf
|
|||||||
#define DISTRIBUTE_NAME(O,T) (O)->dlist[T].name
|
#define DISTRIBUTE_NAME(O,T) (O)->dlist[T].name
|
||||||
#define DISTRIBUTE_LIST(O,T) (O)->dlist[T].list
|
#define DISTRIBUTE_LIST(O,T) (O)->dlist[T].list
|
||||||
|
|
||||||
/* Redistribute metric info. */
|
/* OSPF redistribute configuration */
|
||||||
struct
|
struct list *redist[ZEBRA_ROUTE_MAX + 1];
|
||||||
{
|
|
||||||
int type; /* External metric type (E1 or E2). */
|
|
||||||
int value; /* Value for static metric (24-bit).
|
|
||||||
-1 means metric value is not set. */
|
|
||||||
} dmetric [ZEBRA_ROUTE_MAX + 1];
|
|
||||||
|
|
||||||
/* Redistribute tag info. */
|
/* Redistribute tag info. */
|
||||||
u_short dtag [ZEBRA_ROUTE_MAX + 1];
|
u_short dtag[ZEBRA_ROUTE_MAX + 1]; //Pending: cant configure as of now
|
||||||
|
|
||||||
/* For redistribute route map. */
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
struct route_map *map;
|
|
||||||
} route_map [ZEBRA_ROUTE_MAX + 1]; /* +1 is for default-information */
|
|
||||||
#define ROUTEMAP_NAME(O,T) (O)->route_map[T].name
|
|
||||||
#define ROUTEMAP(O,T) (O)->route_map[T].map
|
|
||||||
|
|
||||||
int default_metric; /* Default metric for redistribute. */
|
int default_metric; /* Default metric for redistribute. */
|
||||||
|
|
||||||
#define OSPF_LSA_REFRESHER_GRANULARITY 10
|
#define OSPF_LSA_REFRESHER_GRANULARITY 10
|
||||||
@ -514,7 +531,9 @@ extern int ospf_zlog;
|
|||||||
/* Prototypes. */
|
/* Prototypes. */
|
||||||
extern const char *ospf_redist_string(u_int route_type);
|
extern const char *ospf_redist_string(u_int route_type);
|
||||||
extern struct ospf *ospf_lookup (void);
|
extern struct ospf *ospf_lookup (void);
|
||||||
|
extern struct ospf *ospf_lookup_instance (u_short);
|
||||||
extern struct ospf *ospf_get (void);
|
extern struct ospf *ospf_get (void);
|
||||||
|
extern struct ospf *ospf_get_instance (u_short);
|
||||||
extern void ospf_finish (struct ospf *);
|
extern void ospf_finish (struct ospf *);
|
||||||
extern void ospf_router_id_update (struct ospf *ospf);
|
extern void ospf_router_id_update (struct ospf *ospf);
|
||||||
extern int ospf_network_set (struct ospf *, struct prefix_ipv4 *,
|
extern int ospf_network_set (struct ospf *, struct prefix_ipv4 *,
|
||||||
|
@ -201,7 +201,7 @@ main (int argc, char **argv)
|
|||||||
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
|
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
|
||||||
|
|
||||||
/* First of all we need logging init. */
|
/* First of all we need logging init. */
|
||||||
zlog_default = openzlog (progname, ZLOG_RIP,
|
zlog_default = openzlog (progname, ZLOG_RIP, 0,
|
||||||
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
||||||
|
|
||||||
/* Command line option parse. */
|
/* Command line option parse. */
|
||||||
|
@ -41,9 +41,10 @@ rip_zebra_ipv4_add (struct prefix_ipv4 *p, struct in_addr *nexthop,
|
|||||||
{
|
{
|
||||||
struct zapi_ipv4 api;
|
struct zapi_ipv4 api;
|
||||||
|
|
||||||
if (zclient->redist[ZEBRA_ROUTE_RIP])
|
if (zclient->redist[ZEBRA_ROUTE_RIP].enabled)
|
||||||
{
|
{
|
||||||
api.type = ZEBRA_ROUTE_RIP;
|
api.type = ZEBRA_ROUTE_RIP;
|
||||||
|
api.instance = 0;
|
||||||
api.flags = 0;
|
api.flags = 0;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = SAFI_UNICAST;
|
api.safi = SAFI_UNICAST;
|
||||||
@ -72,9 +73,10 @@ rip_zebra_ipv4_delete (struct prefix_ipv4 *p, struct in_addr *nexthop,
|
|||||||
{
|
{
|
||||||
struct zapi_ipv4 api;
|
struct zapi_ipv4 api;
|
||||||
|
|
||||||
if (zclient->redist[ZEBRA_ROUTE_RIP])
|
if (zclient->redist[ZEBRA_ROUTE_RIP].enabled)
|
||||||
{
|
{
|
||||||
api.type = ZEBRA_ROUTE_RIP;
|
api.type = ZEBRA_ROUTE_RIP;
|
||||||
|
api.instance = 0;
|
||||||
api.flags = 0;
|
api.flags = 0;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = SAFI_UNICAST;
|
api.safi = SAFI_UNICAST;
|
||||||
@ -107,6 +109,7 @@ rip_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
|
|
||||||
/* Type, flags, message. */
|
/* Type, flags, message. */
|
||||||
api.type = stream_getc (s);
|
api.type = stream_getc (s);
|
||||||
|
api.instance = stream_getw (s);
|
||||||
api.flags = stream_getc (s);
|
api.flags = stream_getc (s);
|
||||||
api.message = stream_getc (s);
|
api.message = stream_getc (s);
|
||||||
|
|
||||||
@ -255,13 +258,13 @@ rip_redistribute_set (int type)
|
|||||||
static int
|
static int
|
||||||
rip_redistribute_unset (int type)
|
rip_redistribute_unset (int type)
|
||||||
{
|
{
|
||||||
if (! zclient->redist[type])
|
if (! zclient->redist[type].enabled)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
zclient->redist[type] = 0;
|
redist_del_instance(&zclient->redist[type], 0);
|
||||||
|
|
||||||
if (zclient->sock > 0)
|
if (zclient->sock > 0)
|
||||||
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
|
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, 0);
|
||||||
|
|
||||||
/* Remove the routes from RIP table. */
|
/* Remove the routes from RIP table. */
|
||||||
rip_redistribute_withdraw (type);
|
rip_redistribute_withdraw (type);
|
||||||
@ -272,7 +275,7 @@ rip_redistribute_unset (int type)
|
|||||||
int
|
int
|
||||||
rip_redistribute_check (int type)
|
rip_redistribute_check (int type)
|
||||||
{
|
{
|
||||||
return (zclient->redist[type]);
|
return (zclient->redist[type].enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -282,13 +285,13 @@ rip_redistribute_clean (void)
|
|||||||
|
|
||||||
for (i = 0; redist_type[i].str; i++)
|
for (i = 0; redist_type[i].str; i++)
|
||||||
{
|
{
|
||||||
if (zclient->redist[redist_type[i].type])
|
if (zclient->redist[redist_type[i].type].enabled)
|
||||||
{
|
{
|
||||||
if (zclient->sock > 0)
|
if (zclient->sock > 0)
|
||||||
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
|
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
|
||||||
zclient, redist_type[i].type);
|
zclient, redist_type[i].type, 0);
|
||||||
|
|
||||||
zclient->redist[redist_type[i].type] = 0;
|
redist_del_instance(&zclient->redist[redist_type[i].type], 0);
|
||||||
|
|
||||||
/* Remove the routes from RIP table. */
|
/* Remove the routes from RIP table. */
|
||||||
rip_redistribute_withdraw (redist_type[i].type);
|
rip_redistribute_withdraw (redist_type[i].type);
|
||||||
@ -302,7 +305,7 @@ DEFUN (rip_redistribute_rip,
|
|||||||
"Redistribute information from another routing protocol\n"
|
"Redistribute information from another routing protocol\n"
|
||||||
"Routing Information Protocol (RIP)\n")
|
"Routing Information Protocol (RIP)\n")
|
||||||
{
|
{
|
||||||
zclient->redist[ZEBRA_ROUTE_RIP] = 1;
|
redist_add_instance(&zclient->redist[ZEBRA_ROUTE_RIP], 0);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,7 +316,7 @@ DEFUN (no_rip_redistribute_rip,
|
|||||||
"Redistribute information from another routing protocol\n"
|
"Redistribute information from another routing protocol\n"
|
||||||
"Routing Information Protocol (RIP)\n")
|
"Routing Information Protocol (RIP)\n")
|
||||||
{
|
{
|
||||||
zclient->redist[ZEBRA_ROUTE_RIP] = 0;
|
redist_del_instance(&zclient->redist[ZEBRA_ROUTE_RIP], 0);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,7 +334,7 @@ DEFUN (rip_redistribute_type,
|
|||||||
redist_type[i].str_min_len) == 0)
|
redist_type[i].str_min_len) == 0)
|
||||||
{
|
{
|
||||||
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient,
|
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient,
|
||||||
redist_type[i].type);
|
redist_type[i].type, 0);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -384,7 +387,7 @@ DEFUN (rip_redistribute_type_routemap,
|
|||||||
redist_type[i].str_min_len) == 0)
|
redist_type[i].str_min_len) == 0)
|
||||||
{
|
{
|
||||||
rip_routemap_set (redist_type[i].type, argv[1]);
|
rip_routemap_set (redist_type[i].type, argv[1]);
|
||||||
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
|
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type, 0);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -442,7 +445,7 @@ DEFUN (rip_redistribute_type_metric,
|
|||||||
redist_type[i].str_min_len) == 0)
|
redist_type[i].str_min_len) == 0)
|
||||||
{
|
{
|
||||||
rip_redistribute_metric_set (redist_type[i].type, metric);
|
rip_redistribute_metric_set (redist_type[i].type, metric);
|
||||||
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
|
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type, 0);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -503,7 +506,7 @@ DEFUN (rip_redistribute_type_metric_routemap,
|
|||||||
{
|
{
|
||||||
rip_redistribute_metric_set (redist_type[i].type, metric);
|
rip_redistribute_metric_set (redist_type[i].type, metric);
|
||||||
rip_routemap_set (redist_type[i].type, argv[2]);
|
rip_routemap_set (redist_type[i].type, argv[2]);
|
||||||
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
|
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type, 0);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -607,7 +610,7 @@ config_write_zebra (struct vty *vty)
|
|||||||
vty_out (vty, "no router zebra%s", VTY_NEWLINE);
|
vty_out (vty, "no router zebra%s", VTY_NEWLINE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (! zclient->redist[ZEBRA_ROUTE_RIP])
|
else if (! zclient->redist[ZEBRA_ROUTE_RIP].enabled)
|
||||||
{
|
{
|
||||||
vty_out (vty, "router zebra%s", VTY_NEWLINE);
|
vty_out (vty, "router zebra%s", VTY_NEWLINE);
|
||||||
vty_out (vty, " no redistribute rip%s", VTY_NEWLINE);
|
vty_out (vty, " no redistribute rip%s", VTY_NEWLINE);
|
||||||
@ -622,7 +625,8 @@ config_write_rip_redistribute (struct vty *vty, int config_mode)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
||||||
if (i != zclient->redist_default && zclient->redist[i])
|
if (i != zclient->redist_default &&
|
||||||
|
zclient->redist[i].enabled)
|
||||||
{
|
{
|
||||||
if (config_mode)
|
if (config_mode)
|
||||||
{
|
{
|
||||||
@ -667,7 +671,7 @@ rip_zclient_init ()
|
|||||||
{
|
{
|
||||||
/* Set default value to the zebra client structure. */
|
/* Set default value to the zebra client structure. */
|
||||||
zclient = zclient_new ();
|
zclient = zclient_new ();
|
||||||
zclient_init (zclient, ZEBRA_ROUTE_RIP);
|
zclient_init (zclient, ZEBRA_ROUTE_RIP, 0);
|
||||||
zclient->interface_add = rip_interface_add;
|
zclient->interface_add = rip_interface_add;
|
||||||
zclient->interface_delete = rip_interface_delete;
|
zclient->interface_delete = rip_interface_delete;
|
||||||
zclient->interface_address_add = rip_interface_address_add;
|
zclient->interface_address_add = rip_interface_address_add;
|
||||||
|
@ -200,7 +200,7 @@ main (int argc, char **argv)
|
|||||||
/* get program name */
|
/* get program name */
|
||||||
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
|
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
|
||||||
|
|
||||||
zlog_default = openzlog(progname, ZLOG_RIPNG,
|
zlog_default = openzlog(progname, ZLOG_RIPNG, 0,
|
||||||
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
|
@ -48,9 +48,10 @@ ripng_zebra_ipv6_add (struct prefix_ipv6 *p, struct in6_addr *nexthop,
|
|||||||
{
|
{
|
||||||
struct zapi_ipv6 api;
|
struct zapi_ipv6 api;
|
||||||
|
|
||||||
if (zclient->redist[ZEBRA_ROUTE_RIPNG])
|
if (zclient->redist[ZEBRA_ROUTE_RIPNG].enabled)
|
||||||
{
|
{
|
||||||
api.type = ZEBRA_ROUTE_RIPNG;
|
api.type = ZEBRA_ROUTE_RIPNG;
|
||||||
|
api.instance = 0;
|
||||||
api.flags = 0;
|
api.flags = 0;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = SAFI_UNICAST;
|
api.safi = SAFI_UNICAST;
|
||||||
@ -73,9 +74,10 @@ ripng_zebra_ipv6_delete (struct prefix_ipv6 *p, struct in6_addr *nexthop,
|
|||||||
{
|
{
|
||||||
struct zapi_ipv6 api;
|
struct zapi_ipv6 api;
|
||||||
|
|
||||||
if (zclient->redist[ZEBRA_ROUTE_RIPNG])
|
if (zclient->redist[ZEBRA_ROUTE_RIPNG].enabled)
|
||||||
{
|
{
|
||||||
api.type = ZEBRA_ROUTE_RIPNG;
|
api.type = ZEBRA_ROUTE_RIPNG;
|
||||||
|
api.instance = 0;
|
||||||
api.flags = 0;
|
api.flags = 0;
|
||||||
api.message = 0;
|
api.message = 0;
|
||||||
api.safi = SAFI_UNICAST;
|
api.safi = SAFI_UNICAST;
|
||||||
@ -107,6 +109,7 @@ ripng_zebra_read_ipv6 (int command, struct zclient *zclient,
|
|||||||
|
|
||||||
/* Type, flags, message. */
|
/* Type, flags, message. */
|
||||||
api.type = stream_getc (s);
|
api.type = stream_getc (s);
|
||||||
|
api.instance = stream_getw (s);
|
||||||
api.flags = stream_getc (s);
|
api.flags = stream_getc (s);
|
||||||
api.message = stream_getc (s);
|
api.message = stream_getc (s);
|
||||||
|
|
||||||
@ -153,13 +156,13 @@ ripng_zclient_reset (void)
|
|||||||
static int
|
static int
|
||||||
ripng_redistribute_unset (int type)
|
ripng_redistribute_unset (int type)
|
||||||
{
|
{
|
||||||
if (! zclient->redist[type])
|
if (! zclient->redist[type].enabled)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
zclient->redist[type] = 0;
|
redist_del_instance(&zclient->redist[type], 0);
|
||||||
|
|
||||||
if (zclient->sock > 0)
|
if (zclient->sock > 0)
|
||||||
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
|
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, 0);
|
||||||
|
|
||||||
ripng_redistribute_withdraw (type);
|
ripng_redistribute_withdraw (type);
|
||||||
|
|
||||||
@ -169,7 +172,7 @@ ripng_redistribute_unset (int type)
|
|||||||
int
|
int
|
||||||
ripng_redistribute_check (int type)
|
ripng_redistribute_check (int type)
|
||||||
{
|
{
|
||||||
return (zclient->redist[type]);
|
return (zclient->redist[type].enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -229,13 +232,13 @@ ripng_redistribute_clean ()
|
|||||||
|
|
||||||
for (i = 0; redist_type[i].str; i++)
|
for (i = 0; redist_type[i].str; i++)
|
||||||
{
|
{
|
||||||
if (zclient->redist[redist_type[i].type])
|
if (zclient->redist[redist_type[i].type].enabled)
|
||||||
{
|
{
|
||||||
if (zclient->sock > 0)
|
if (zclient->sock > 0)
|
||||||
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
|
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
|
||||||
zclient, redist_type[i].type);
|
zclient, redist_type[i].type, 0);
|
||||||
|
|
||||||
zclient->redist[redist_type[i].type] = 0;
|
redist_del_instance(&zclient->redist[redist_type[i].type], 0);
|
||||||
|
|
||||||
/* Remove the routes from RIPng table. */
|
/* Remove the routes from RIPng table. */
|
||||||
ripng_redistribute_withdraw (redist_type[i].type);
|
ripng_redistribute_withdraw (redist_type[i].type);
|
||||||
@ -273,7 +276,7 @@ DEFUN (ripng_redistribute_ripng,
|
|||||||
"Redistribute information from another routing protocol\n"
|
"Redistribute information from another routing protocol\n"
|
||||||
"RIPng route\n")
|
"RIPng route\n")
|
||||||
{
|
{
|
||||||
zclient->redist[ZEBRA_ROUTE_RIPNG] = 1;
|
redist_add_instance(&zclient->redist[ZEBRA_ROUTE_RIPNG], 0);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +287,7 @@ DEFUN (no_ripng_redistribute_ripng,
|
|||||||
"Redistribute information from another routing protocol\n"
|
"Redistribute information from another routing protocol\n"
|
||||||
"RIPng route\n")
|
"RIPng route\n")
|
||||||
{
|
{
|
||||||
zclient->redist[ZEBRA_ROUTE_RIPNG] = 0;
|
redist_del_instance(&zclient->redist[ZEBRA_ROUTE_RIPNG], 0);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,7 +307,7 @@ DEFUN (ripng_redistribute_type,
|
|||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
|
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type, 0);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,7 +355,7 @@ DEFUN (ripng_redistribute_type_metric,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ripng_redistribute_metric_set (type, metric);
|
ripng_redistribute_metric_set (type, metric);
|
||||||
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
|
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type, 0);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,7 +387,7 @@ DEFUN (ripng_redistribute_type_routemap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ripng_redistribute_routemap_set (type, argv[1]);
|
ripng_redistribute_routemap_set (type, argv[1]);
|
||||||
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
|
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type, 0);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,7 +424,7 @@ DEFUN (ripng_redistribute_type_metric_routemap,
|
|||||||
|
|
||||||
ripng_redistribute_metric_set (type, metric);
|
ripng_redistribute_metric_set (type, metric);
|
||||||
ripng_redistribute_routemap_set (type, argv[2]);
|
ripng_redistribute_routemap_set (type, argv[2]);
|
||||||
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
|
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type, 0);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,7 +443,8 @@ ripng_redistribute_write (struct vty *vty, int config_mode)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
||||||
if (i != zclient->redist_default && zclient->redist[i])
|
if (i != zclient->redist_default &&
|
||||||
|
zclient->redist[i].enabled)
|
||||||
{
|
{
|
||||||
if (config_mode)
|
if (config_mode)
|
||||||
{
|
{
|
||||||
@ -480,7 +484,7 @@ zebra_config_write (struct vty *vty)
|
|||||||
vty_out (vty, "no router zebra%s", VTY_NEWLINE);
|
vty_out (vty, "no router zebra%s", VTY_NEWLINE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (! zclient->redist[ZEBRA_ROUTE_RIPNG])
|
else if (! zclient->redist[ZEBRA_ROUTE_RIPNG].enabled)
|
||||||
{
|
{
|
||||||
vty_out (vty, "router zebra%s", VTY_NEWLINE);
|
vty_out (vty, "router zebra%s", VTY_NEWLINE);
|
||||||
vty_out (vty, " no redistribute ripng%s", VTY_NEWLINE);
|
vty_out (vty, " no redistribute ripng%s", VTY_NEWLINE);
|
||||||
@ -502,7 +506,7 @@ zebra_init ()
|
|||||||
{
|
{
|
||||||
/* Allocate zebra structure. */
|
/* Allocate zebra structure. */
|
||||||
zclient = zclient_new ();
|
zclient = zclient_new ();
|
||||||
zclient_init (zclient, ZEBRA_ROUTE_RIPNG);
|
zclient_init (zclient, ZEBRA_ROUTE_RIPNG, 0);
|
||||||
|
|
||||||
zclient->interface_up = ripng_interface_up;
|
zclient->interface_up = ripng_interface_up;
|
||||||
zclient->interface_down = ripng_interface_down;
|
zclient->interface_down = ripng_interface_down;
|
||||||
|
@ -46,7 +46,7 @@ main (void)
|
|||||||
master = thread_master_create ();
|
master = thread_master_create ();
|
||||||
signal_init (master, array_size(sigs), sigs);
|
signal_init (master, array_size(sigs), sigs);
|
||||||
|
|
||||||
zlog_default = openzlog("testsig", ZLOG_NONE,
|
zlog_default = openzlog("testsig", ZLOG_NONE, 0,
|
||||||
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
||||||
zlog_set_level (NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
|
zlog_set_level (NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
|
||||||
zlog_set_level (NULL, ZLOG_DEST_STDOUT, LOG_DEBUG);
|
zlog_set_level (NULL, ZLOG_DEST_STDOUT, LOG_DEBUG);
|
||||||
|
@ -35,7 +35,7 @@ $ignore{'"ip vrf NAME"'} = "ignore";
|
|||||||
$ignore{'"router rip"'} = "ignore";
|
$ignore{'"router rip"'} = "ignore";
|
||||||
$ignore{'"router ripng"'} = "ignore";
|
$ignore{'"router ripng"'} = "ignore";
|
||||||
$ignore{'"router ospf"'} = "ignore";
|
$ignore{'"router ospf"'} = "ignore";
|
||||||
$ignore{'"router ospf <0-65535>"'} = "ignore";
|
$ignore{'"router ospf <1-65535>"'} = "ignore";
|
||||||
$ignore{'"router ospf6"'} = "ignore";
|
$ignore{'"router ospf6"'} = "ignore";
|
||||||
$ignore{'"router babel"'} = "ignore";
|
$ignore{'"router babel"'} = "ignore";
|
||||||
$ignore{'"router bgp " "<1-4294967295>"'} = "ignore";
|
$ignore{'"router bgp " "<1-4294967295>"'} = "ignore";
|
||||||
|
196
vtysh/vtysh.c
196
vtysh/vtysh.c
@ -30,6 +30,10 @@
|
|||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "vtysh/vtysh.h"
|
#include "vtysh/vtysh.h"
|
||||||
@ -46,19 +50,22 @@ char *vtysh_pager_name = NULL;
|
|||||||
struct vtysh_client
|
struct vtysh_client
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
const char *name;
|
char *name;
|
||||||
int flag;
|
int flag;
|
||||||
const char *path;
|
char *path;
|
||||||
} vtysh_client[] =
|
struct vtysh_client *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct vtysh_client vtysh_client[] =
|
||||||
{
|
{
|
||||||
{ .fd = -1, .name = "zebra", .flag = VTYSH_ZEBRA, .path = ZEBRA_VTYSH_PATH},
|
{ .fd = -1, .name = "zebra", .flag = VTYSH_ZEBRA, .path = ZEBRA_VTYSH_PATH, .next = NULL},
|
||||||
{ .fd = -1, .name = "ripd", .flag = VTYSH_RIPD, .path = RIP_VTYSH_PATH},
|
{ .fd = -1, .name = "ripd", .flag = VTYSH_RIPD, .path = RIP_VTYSH_PATH, .next = NULL},
|
||||||
{ .fd = -1, .name = "ripngd", .flag = VTYSH_RIPNGD, .path = RIPNG_VTYSH_PATH},
|
{ .fd = -1, .name = "ripngd", .flag = VTYSH_RIPNGD, .path = RIPNG_VTYSH_PATH, .next = NULL},
|
||||||
{ .fd = -1, .name = "ospfd", .flag = VTYSH_OSPFD, .path = OSPF_VTYSH_PATH},
|
{ .fd = -1, .name = "ospfd", .flag = VTYSH_OSPFD, .path = OSPF_VTYSH_PATH, .next = NULL},
|
||||||
{ .fd = -1, .name = "ospf6d", .flag = VTYSH_OSPF6D, .path = OSPF6_VTYSH_PATH},
|
{ .fd = -1, .name = "ospf6d", .flag = VTYSH_OSPF6D, .path = OSPF6_VTYSH_PATH, .next = NULL},
|
||||||
{ .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH},
|
{ .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH, .next = NULL},
|
||||||
{ .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH},
|
{ .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH, .next = NULL},
|
||||||
{ .fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .path = BABEL_VTYSH_PATH},
|
{ .fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .path = BABEL_VTYSH_PATH, .next = NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -88,7 +95,7 @@ vclient_close (struct vtysh_client *vclient)
|
|||||||
* under load - it SHOULD handle it. */
|
* under load - it SHOULD handle it. */
|
||||||
#define ERR_WHERE_STRING "vtysh(): vtysh_client_config(): "
|
#define ERR_WHERE_STRING "vtysh(): vtysh_client_config(): "
|
||||||
static int
|
static int
|
||||||
vtysh_client_config (struct vtysh_client *vclient, char *line)
|
vtysh_client_config_one (struct vtysh_client *vclient, char *line)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char *buf;
|
char *buf;
|
||||||
@ -186,7 +193,28 @@ vtysh_client_config (struct vtysh_client *vclient, char *line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vtysh_client_execute (struct vtysh_client *vclient, const char *line, FILE *fp)
|
vtysh_client_config (struct vtysh_client *head_client, char *line)
|
||||||
|
{
|
||||||
|
struct vtysh_client *client;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = vtysh_client_config_one(head_client, line);
|
||||||
|
if (rc != CMD_SUCCESS)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
client = head_client->next;
|
||||||
|
while (client)
|
||||||
|
{
|
||||||
|
rc = vtysh_client_config_one(client, line);
|
||||||
|
if (rc != CMD_SUCCESS)
|
||||||
|
return rc;
|
||||||
|
client = client->next;
|
||||||
|
}
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vtysh_client_execute_one (struct vtysh_client *vclient, const char *line, FILE *fp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char buf[1001];
|
char buf[1001];
|
||||||
@ -250,6 +278,27 @@ vtysh_client_execute (struct vtysh_client *vclient, const char *line, FILE *fp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vtysh_client_execute (struct vtysh_client *head_client, const char *line, FILE *fp)
|
||||||
|
{
|
||||||
|
struct vtysh_client *client;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = vtysh_client_execute_one(head_client, line, fp);
|
||||||
|
if (rc != CMD_SUCCESS)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
client = head_client->next;
|
||||||
|
while (client)
|
||||||
|
{
|
||||||
|
rc = vtysh_client_execute_one(client, line, fp);
|
||||||
|
if (rc != CMD_SUCCESS)
|
||||||
|
return rc;
|
||||||
|
client = client->next;
|
||||||
|
}
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
vtysh_exit_ripd_only (void)
|
vtysh_exit_ripd_only (void)
|
||||||
{
|
{
|
||||||
@ -1005,6 +1054,14 @@ DEFUNSH (VTYSH_OSPFD,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALIAS_SH (VTYSH_OSPFD,
|
||||||
|
router_ospf,
|
||||||
|
router_ospf_instance_cmd,
|
||||||
|
"router ospf <1-65535>",
|
||||||
|
"Enable a routing process\n"
|
||||||
|
"Start OSPF configuration\n"
|
||||||
|
"Instance ID\n")
|
||||||
|
|
||||||
DEFUNSH (VTYSH_OSPF6D,
|
DEFUNSH (VTYSH_OSPF6D,
|
||||||
router_ospf6,
|
router_ospf6,
|
||||||
router_ospf6_cmd,
|
router_ospf6_cmd,
|
||||||
@ -2177,6 +2234,114 @@ vtysh_connect (struct vtysh_client *vclient)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true if str begins with prefix, else return false */
|
||||||
|
static int
|
||||||
|
begins_with(const char *str, const char *prefix)
|
||||||
|
{
|
||||||
|
if (!str || !prefix)
|
||||||
|
return 0;
|
||||||
|
size_t lenstr = strlen(str);
|
||||||
|
size_t lenprefix = strlen(prefix);
|
||||||
|
if (lenprefix > lenstr)
|
||||||
|
return 0;
|
||||||
|
return strncmp(str, prefix, lenprefix) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return true if str ends with suffix, else return false */
|
||||||
|
static int
|
||||||
|
ends_with(const char *str, const char *suffix)
|
||||||
|
{
|
||||||
|
if (!str || !suffix)
|
||||||
|
return 0;
|
||||||
|
size_t lenstr = strlen(str);
|
||||||
|
size_t lensuffix = strlen(suffix);
|
||||||
|
if (lensuffix > lenstr)
|
||||||
|
return 0;
|
||||||
|
return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vtysh_client_sorted_insert (struct vtysh_client *head_client,
|
||||||
|
struct vtysh_client *client)
|
||||||
|
{
|
||||||
|
struct vtysh_client *prev_node, *current_node;
|
||||||
|
|
||||||
|
prev_node = head_client;
|
||||||
|
current_node = head_client->next;
|
||||||
|
while (current_node)
|
||||||
|
{
|
||||||
|
if (strcmp(current_node->path, client->path) > 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
prev_node = current_node;
|
||||||
|
current_node = current_node->next;
|
||||||
|
}
|
||||||
|
client->next = current_node;
|
||||||
|
prev_node->next = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAXIMUM_INSTANCES 10
|
||||||
|
|
||||||
|
static void
|
||||||
|
vtysh_update_all_insances(struct vtysh_client * head_client)
|
||||||
|
{
|
||||||
|
struct vtysh_client *client;
|
||||||
|
char *path;
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent *file;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
if (head_client->flag != VTYSH_OSPFD) return;
|
||||||
|
|
||||||
|
/* ls /var/run/quagga/ and look for all files ending in .vty */
|
||||||
|
dir = opendir("/var/run/quagga/");
|
||||||
|
if (dir)
|
||||||
|
{
|
||||||
|
while ((file = readdir(dir)) != NULL)
|
||||||
|
{
|
||||||
|
if (begins_with(file->d_name, "ospfd-") && ends_with(file->d_name, ".vty"))
|
||||||
|
{
|
||||||
|
if (n == MAXIMUM_INSTANCES)
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"Parsing /var/run/quagga/, client limit(%d) reached!\n", n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
client = (struct vtysh_client *) malloc(sizeof(struct vtysh_client));
|
||||||
|
client->fd = -1;
|
||||||
|
client->name = (char *) malloc(10);
|
||||||
|
strcpy(client->name, "ospfd");
|
||||||
|
client->flag = VTYSH_OSPFD;
|
||||||
|
client->path = (char *) malloc(100);
|
||||||
|
sprintf(client->path, "/var/run/quagga/%s", file->d_name);
|
||||||
|
client->next = NULL;
|
||||||
|
vtysh_client_sorted_insert(head_client, client);
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
vtysh_connect_all_instances (struct vtysh_client *head_client)
|
||||||
|
{
|
||||||
|
struct vtysh_client *client;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
vtysh_update_all_insances(head_client);
|
||||||
|
|
||||||
|
client = head_client->next;
|
||||||
|
while (client)
|
||||||
|
{
|
||||||
|
if (vtysh_connect(client) == 0)
|
||||||
|
rc++;
|
||||||
|
client = client->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
vtysh_connect_all(const char *daemon_name)
|
vtysh_connect_all(const char *daemon_name)
|
||||||
{
|
{
|
||||||
@ -2194,7 +2359,9 @@ vtysh_connect_all(const char *daemon_name)
|
|||||||
/* We need direct access to ripd in vtysh_exit_ripd_only. */
|
/* We need direct access to ripd in vtysh_exit_ripd_only. */
|
||||||
if (vtysh_client[i].flag == VTYSH_RIPD)
|
if (vtysh_client[i].flag == VTYSH_RIPD)
|
||||||
ripd_client = &vtysh_client[i];
|
ripd_client = &vtysh_client[i];
|
||||||
}
|
|
||||||
|
rc += vtysh_connect_all_instances(&vtysh_client[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!matches)
|
if (!matches)
|
||||||
fprintf(stderr, "Error: no daemons match name %s!\n", daemon_name);
|
fprintf(stderr, "Error: no daemons match name %s!\n", daemon_name);
|
||||||
@ -2368,6 +2535,7 @@ vtysh_init_vty (void)
|
|||||||
install_element (CONFIG_NODE, &router_ripng_cmd);
|
install_element (CONFIG_NODE, &router_ripng_cmd);
|
||||||
#endif
|
#endif
|
||||||
install_element (CONFIG_NODE, &router_ospf_cmd);
|
install_element (CONFIG_NODE, &router_ospf_cmd);
|
||||||
|
install_element (CONFIG_NODE, &router_ospf_instance_cmd);
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
install_element (CONFIG_NODE, &router_ospf6_cmd);
|
install_element (CONFIG_NODE, &router_ospf6_cmd);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1336,7 +1336,7 @@ main(int argc, char **argv)
|
|||||||
return usage(progname,1);
|
return usage(progname,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
zlog_default = openzlog(progname, ZLOG_NONE,
|
zlog_default = openzlog(progname, ZLOG_NONE, 0,
|
||||||
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
||||||
zlog_set_level(NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
|
zlog_set_level(NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
|
||||||
if (daemon_mode)
|
if (daemon_mode)
|
||||||
|
@ -207,10 +207,10 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
|
|||||||
if (prefix_ipv4_any (&p))
|
if (prefix_ipv4_any (&p))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex,
|
rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, NULL, ifp->ifindex,
|
||||||
RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST);
|
RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST);
|
||||||
|
|
||||||
rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex,
|
rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, NULL, ifp->ifindex,
|
||||||
RT_TABLE_MAIN, ifp->metric, 0, SAFI_MULTICAST);
|
RT_TABLE_MAIN, ifp->metric, 0, SAFI_MULTICAST);
|
||||||
|
|
||||||
rib_update ();
|
rib_update ();
|
||||||
@ -323,9 +323,9 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Same logic as for connected_up_ipv4(): push the changes into the head. */
|
/* Same logic as for connected_up_ipv4(): push the changes into the head. */
|
||||||
rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, SAFI_UNICAST);
|
rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex, 0, SAFI_UNICAST);
|
||||||
|
|
||||||
rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, SAFI_MULTICAST);
|
rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex, 0, SAFI_MULTICAST);
|
||||||
|
|
||||||
rib_update ();
|
rib_update ();
|
||||||
}
|
}
|
||||||
@ -410,7 +410,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
|
|||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, RT_TABLE_MAIN,
|
rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex, RT_TABLE_MAIN,
|
||||||
ifp->metric, 0, SAFI_UNICAST);
|
ifp->metric, 0, SAFI_UNICAST);
|
||||||
|
|
||||||
rib_update ();
|
rib_update ();
|
||||||
@ -496,7 +496,7 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
|
|||||||
if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
|
if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, SAFI_UNICAST);
|
rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex, 0, SAFI_UNICAST);
|
||||||
|
|
||||||
rib_update ();
|
rib_update ();
|
||||||
}
|
}
|
||||||
|
@ -934,16 +934,16 @@ rtm_read (struct rt_msghdr *rtm)
|
|||||||
* to specify the route really
|
* to specify the route really
|
||||||
*/
|
*/
|
||||||
if (rtm->rtm_type == RTM_CHANGE)
|
if (rtm->rtm_type == RTM_CHANGE)
|
||||||
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
|
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
|
||||||
NULL, 0, 0, SAFI_UNICAST);
|
NULL, 0, 0, SAFI_UNICAST);
|
||||||
|
|
||||||
if (rtm->rtm_type == RTM_GET
|
if (rtm->rtm_type == RTM_GET
|
||||||
|| rtm->rtm_type == RTM_ADD
|
|| rtm->rtm_type == RTM_ADD
|
||||||
|| rtm->rtm_type == RTM_CHANGE)
|
|| rtm->rtm_type == RTM_CHANGE)
|
||||||
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags,
|
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
|
||||||
&p, &gate.sin.sin_addr, NULL, 0, 0, 0, 0, SAFI_UNICAST);
|
&p, &gate.sin.sin_addr, NULL, 0, 0, 0, 0, SAFI_UNICAST);
|
||||||
else
|
else
|
||||||
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags,
|
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0 zebra_flags,
|
||||||
&p, &gate.sin.sin_addr, 0, 0, SAFI_UNICAST);
|
&p, &gate.sin.sin_addr, 0, 0, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
@ -976,16 +976,16 @@ rtm_read (struct rt_msghdr *rtm)
|
|||||||
* to specify the route really
|
* to specify the route really
|
||||||
*/
|
*/
|
||||||
if (rtm->rtm_type == RTM_CHANGE)
|
if (rtm->rtm_type == RTM_CHANGE)
|
||||||
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
|
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
|
||||||
NULL, 0, 0, SAFI_UNICAST);
|
NULL, 0, 0, SAFI_UNICAST);
|
||||||
|
|
||||||
if (rtm->rtm_type == RTM_GET
|
if (rtm->rtm_type == RTM_GET
|
||||||
|| rtm->rtm_type == RTM_ADD
|
|| rtm->rtm_type == RTM_ADD
|
||||||
|| rtm->rtm_type == RTM_CHANGE)
|
|| rtm->rtm_type == RTM_CHANGE)
|
||||||
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags,
|
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
|
||||||
&p, &gate.sin6.sin6_addr, ifindex, 0, 0, 0, SAFI_UNICAST);
|
&p, &gate.sin6.sin6_addr, ifindex, 0, 0, 0, SAFI_UNICAST);
|
||||||
else
|
else
|
||||||
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags,
|
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
|
||||||
&p, &gate.sin6.sin6_addr, ifindex, 0, SAFI_UNICAST);
|
&p, &gate.sin6.sin6_addr, ifindex, 0, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
|
@ -228,7 +228,7 @@ main (int argc, char **argv)
|
|||||||
/* preserve my name */
|
/* preserve my name */
|
||||||
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
|
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
|
||||||
|
|
||||||
zlog_default = openzlog (progname, ZLOG_ZEBRA,
|
zlog_default = openzlog (progname, ZLOG_ZEBRA, 0,
|
||||||
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
|
@ -142,7 +142,7 @@ zebra_redistribute_default (struct zserv *client)
|
|||||||
|
|
||||||
/* Redistribute routes. */
|
/* Redistribute routes. */
|
||||||
static void
|
static void
|
||||||
zebra_redistribute (struct zserv *client, int type)
|
zebra_redistribute (struct zserv *client, int type, u_short instance)
|
||||||
{
|
{
|
||||||
struct rib *newrib;
|
struct rib *newrib;
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
@ -153,7 +153,8 @@ zebra_redistribute (struct zserv *client, int type)
|
|||||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||||
RNODE_FOREACH_RIB (rn, newrib)
|
RNODE_FOREACH_RIB (rn, newrib)
|
||||||
if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
|
if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
|
||||||
&& newrib->type == type
|
&& newrib->type == type
|
||||||
|
&& newrib->instance == instance
|
||||||
&& newrib->distance != DISTANCE_INFINITY
|
&& newrib->distance != DISTANCE_INFINITY
|
||||||
&& zebra_check_addr (&rn->p))
|
&& zebra_check_addr (&rn->p))
|
||||||
{
|
{
|
||||||
@ -167,7 +168,8 @@ zebra_redistribute (struct zserv *client, int type)
|
|||||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||||
RNODE_FOREACH_RIB (rn, newrib)
|
RNODE_FOREACH_RIB (rn, newrib)
|
||||||
if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
|
if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
|
||||||
&& newrib->type == type
|
&& newrib->type == type
|
||||||
|
&& newrib->instance == instance
|
||||||
&& newrib->distance != DISTANCE_INFINITY
|
&& newrib->distance != DISTANCE_INFINITY
|
||||||
&& zebra_check_addr (&rn->p))
|
&& zebra_check_addr (&rn->p))
|
||||||
{
|
{
|
||||||
@ -187,7 +189,8 @@ redistribute_add (struct prefix *p, struct rib *rib)
|
|||||||
{
|
{
|
||||||
if (is_default (p))
|
if (is_default (p))
|
||||||
{
|
{
|
||||||
if (client->redist_default || client->redist[rib->type])
|
if (client->redist_default ||
|
||||||
|
redist_check_instance(&client->redist[rib->type], rib->instance))
|
||||||
{
|
{
|
||||||
if (p->family == AF_INET)
|
if (p->family == AF_INET)
|
||||||
{
|
{
|
||||||
@ -203,7 +206,7 @@ redistribute_add (struct prefix *p, struct rib *rib)
|
|||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (client->redist[rib->type])
|
else if (redist_check_instance(&client->redist[rib->type], rib->instance))
|
||||||
{
|
{
|
||||||
if (p->family == AF_INET)
|
if (p->family == AF_INET)
|
||||||
{
|
{
|
||||||
@ -235,7 +238,8 @@ redistribute_delete (struct prefix *p, struct rib *rib)
|
|||||||
{
|
{
|
||||||
if (is_default (p))
|
if (is_default (p))
|
||||||
{
|
{
|
||||||
if (client->redist_default || client->redist[rib->type])
|
if (client->redist_default ||
|
||||||
|
redist_check_instance(&client->redist[rib->type], rib->instance))
|
||||||
{
|
{
|
||||||
if (p->family == AF_INET)
|
if (p->family == AF_INET)
|
||||||
zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
|
zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
|
||||||
@ -247,8 +251,8 @@ redistribute_delete (struct prefix *p, struct rib *rib)
|
|||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (client->redist[rib->type])
|
else if (redist_check_instance(&client->redist[rib->type], rib->instance))
|
||||||
{
|
{
|
||||||
if (p->family == AF_INET)
|
if (p->family == AF_INET)
|
||||||
zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib);
|
zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib);
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
@ -263,16 +267,18 @@ void
|
|||||||
zebra_redistribute_add (int command, struct zserv *client, int length)
|
zebra_redistribute_add (int command, struct zserv *client, int length)
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
type = stream_getc (client->ibuf);
|
type = stream_getc (client->ibuf);
|
||||||
|
instance = stream_getw (client->ibuf);
|
||||||
|
|
||||||
if (type == 0 || type >= ZEBRA_ROUTE_MAX)
|
if (type == 0 || type >= ZEBRA_ROUTE_MAX)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (! client->redist[type])
|
if (!redist_check_instance(&client->redist[type], instance))
|
||||||
{
|
{
|
||||||
client->redist[type] = 1;
|
redist_add_instance(&client->redist[type], instance);
|
||||||
zebra_redistribute (client, type);
|
zebra_redistribute (client, type, instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,13 +286,19 @@ void
|
|||||||
zebra_redistribute_delete (int command, struct zserv *client, int length)
|
zebra_redistribute_delete (int command, struct zserv *client, int length)
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
type = stream_getc (client->ibuf);
|
type = stream_getc (client->ibuf);
|
||||||
|
instance = stream_getw (client->ibuf);
|
||||||
|
|
||||||
if (type == 0 || type >= ZEBRA_ROUTE_MAX)
|
if (type == 0 || type >= ZEBRA_ROUTE_MAX)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
client->redist[type] = 0;
|
if (redist_check_instance(&client->redist[type], instance))
|
||||||
|
{
|
||||||
|
redist_del_instance(&client->redist[type], instance);
|
||||||
|
//Pending: why no reaction here?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
13
zebra/rib.h
13
zebra/rib.h
@ -48,6 +48,9 @@ struct rib
|
|||||||
/* Type fo this route. */
|
/* Type fo this route. */
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
|
/* Source protocol instance */
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
/* Which routing table */
|
/* Which routing table */
|
||||||
int table;
|
int table;
|
||||||
|
|
||||||
@ -383,14 +386,14 @@ extern struct route_table *vrf_static_table (afi_t afi, safi_t safi, u_int32_t i
|
|||||||
/* NOTE:
|
/* NOTE:
|
||||||
* All rib_add_ipv[46]* functions will not just add prefix into RIB, but
|
* All rib_add_ipv[46]* functions will not just add prefix into RIB, but
|
||||||
* also implicitly withdraw equal prefix of same type. */
|
* also implicitly withdraw equal prefix of same type. */
|
||||||
extern int rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
|
extern int rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
||||||
struct in_addr *gate, struct in_addr *src,
|
struct in_addr *gate, struct in_addr *src,
|
||||||
unsigned int ifindex, u_int32_t vrf_id,
|
unsigned int ifindex, u_int32_t vrf_id,
|
||||||
u_int32_t, u_char, safi_t);
|
u_int32_t, u_char, safi_t);
|
||||||
|
|
||||||
extern int rib_add_ipv4_multipath (struct prefix_ipv4 *, struct rib *, safi_t);
|
extern int rib_add_ipv4_multipath (struct prefix_ipv4 *, struct rib *, safi_t);
|
||||||
|
|
||||||
extern int rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
|
extern int rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
||||||
struct in_addr *gate, unsigned int ifindex,
|
struct in_addr *gate, unsigned int ifindex,
|
||||||
u_int32_t, safi_t safi);
|
u_int32_t, safi_t safi);
|
||||||
|
|
||||||
@ -403,7 +406,7 @@ extern void rib_weed_tables (void);
|
|||||||
extern void rib_sweep_route (void);
|
extern void rib_sweep_route (void);
|
||||||
extern void rib_close (void);
|
extern void rib_close (void);
|
||||||
extern void rib_init (void);
|
extern void rib_init (void);
|
||||||
extern unsigned long rib_score_proto (u_char proto);
|
extern unsigned long rib_score_proto (u_char proto, u_short instance);
|
||||||
struct zebra_t;
|
struct zebra_t;
|
||||||
extern void rib_queue_add (struct zebra_t *zebra, struct route_node *rn);
|
extern void rib_queue_add (struct zebra_t *zebra, struct route_node *rn);
|
||||||
|
|
||||||
@ -418,12 +421,12 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
|
|||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
extern int
|
extern int
|
||||||
rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
|
rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
||||||
struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
|
struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
|
||||||
u_int32_t metric, u_char distance, safi_t safi);
|
u_int32_t metric, u_char distance, safi_t safi);
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
|
rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
||||||
struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi);
|
struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi);
|
||||||
|
|
||||||
extern struct rib *rib_lookup_ipv6 (struct in6_addr *);
|
extern struct rib *rib_lookup_ipv6 (struct in6_addr *);
|
||||||
|
@ -743,7 +743,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
p.prefixlen = rtm->rtm_dst_len;
|
p.prefixlen = rtm->rtm_dst_len;
|
||||||
|
|
||||||
if (!tb[RTA_MULTIPATH])
|
if (!tb[RTA_MULTIPATH])
|
||||||
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, src, index,
|
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, flags, &p, gate, src, index,
|
||||||
table, metric, 0, SAFI_UNICAST);
|
table, metric, 0, SAFI_UNICAST);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -809,7 +809,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
memcpy (&p.prefix, dest, 16);
|
memcpy (&p.prefix, dest, 16);
|
||||||
p.prefixlen = rtm->rtm_dst_len;
|
p.prefixlen = rtm->rtm_dst_len;
|
||||||
|
|
||||||
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table,
|
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, flags, &p, gate, index, table,
|
||||||
metric, 0, SAFI_UNICAST);
|
metric, 0, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
@ -948,7 +948,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
if (h->nlmsg_type == RTM_NEWROUTE)
|
if (h->nlmsg_type == RTM_NEWROUTE)
|
||||||
{
|
{
|
||||||
if (!tb[RTA_MULTIPATH])
|
if (!tb[RTA_MULTIPATH])
|
||||||
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, table,
|
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, 0, &p, gate, src, index, table,
|
||||||
metric, 0, SAFI_UNICAST);
|
metric, 0, SAFI_UNICAST);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1007,7 +1007,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, gate, index,
|
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, gate, index,
|
||||||
table, SAFI_UNICAST);
|
table, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1034,9 +1034,9 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (h->nlmsg_type == RTM_NEWROUTE)
|
if (h->nlmsg_type == RTM_NEWROUTE)
|
||||||
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, metric, 0, SAFI_UNICAST);
|
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, 0, &p, gate, index, table, metric, 0, SAFI_UNICAST);
|
||||||
else
|
else
|
||||||
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, gate, index,
|
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, gate, index,
|
||||||
table, SAFI_UNICAST);
|
table, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
|
@ -89,7 +89,7 @@ handle_route_entry (mib2_ipRouteEntry_t *routeEntry)
|
|||||||
|
|
||||||
gateway.s_addr = routeEntry->ipRouteNextHop;
|
gateway.s_addr = routeEntry->ipRouteNextHop;
|
||||||
|
|
||||||
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &prefix,
|
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &prefix,
|
||||||
&gateway, NULL, 0, 0, 0, 0, SAFI_UNICAST);
|
&gateway, NULL, 0, 0, 0, 0, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ proc_route_read (void)
|
|||||||
p.prefixlen = ip_masklen (tmpmask);
|
p.prefixlen = ip_masklen (tmpmask);
|
||||||
sscanf (gate, "%lX", (unsigned long *)&gateway);
|
sscanf (gate, "%lX", (unsigned long *)&gateway);
|
||||||
|
|
||||||
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, NULL, 0, 0, 0, 0, SAFI_UNICAST);
|
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, &gateway, NULL, 0, 0, 0, 0, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
|
@ -215,7 +215,7 @@ main (int argc, char **argv)
|
|||||||
/* preserve my name */
|
/* preserve my name */
|
||||||
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
|
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
|
||||||
|
|
||||||
zlog_default = openzlog (progname, ZLOG_ZEBRA,
|
zlog_default = openzlog (progname, ZLOG_ZEBRA, 0,
|
||||||
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
|
@ -2029,7 +2029,7 @@ rib_delnode (struct route_node *rn, struct rib *rib)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
|
rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
||||||
struct in_addr *gate, struct in_addr *src,
|
struct in_addr *gate, struct in_addr *src,
|
||||||
unsigned int ifindex, u_int32_t vrf_id,
|
unsigned int ifindex, u_int32_t vrf_id,
|
||||||
u_int32_t metric, u_char distance, safi_t safi)
|
u_int32_t metric, u_char distance, safi_t safi)
|
||||||
@ -2073,6 +2073,8 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
|
|||||||
|
|
||||||
if (rib->type != type)
|
if (rib->type != type)
|
||||||
continue;
|
continue;
|
||||||
|
if (rib->instance != instance)
|
||||||
|
continue;
|
||||||
if (rib->type != ZEBRA_ROUTE_CONNECT)
|
if (rib->type != ZEBRA_ROUTE_CONNECT)
|
||||||
{
|
{
|
||||||
same = rib;
|
same = rib;
|
||||||
@ -2092,6 +2094,7 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
|
|||||||
/* Allocate new rib structure. */
|
/* Allocate new rib structure. */
|
||||||
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||||
rib->type = type;
|
rib->type = type;
|
||||||
|
rib->instance = instance;
|
||||||
rib->distance = distance;
|
rib->distance = distance;
|
||||||
rib->flags = flags;
|
rib->flags = flags;
|
||||||
rib->metric = metric;
|
rib->metric = metric;
|
||||||
@ -2149,11 +2152,12 @@ void _rib_dump (const char * func,
|
|||||||
zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
|
zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
|
||||||
zlog_debug
|
zlog_debug
|
||||||
(
|
(
|
||||||
"%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
|
"%s: refcnt == %lu, uptime == %lu, type == %u, instance == %d, table == %d",
|
||||||
func,
|
func,
|
||||||
rib->refcnt,
|
rib->refcnt,
|
||||||
(unsigned long) rib->uptime,
|
(unsigned long) rib->uptime,
|
||||||
rib->type,
|
rib->type,
|
||||||
|
rib->instance,
|
||||||
rib->table
|
rib->table
|
||||||
);
|
);
|
||||||
zlog_debug
|
zlog_debug
|
||||||
@ -2330,7 +2334,8 @@ rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
|
|||||||
if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
|
if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (same->type == rib->type && same->table == rib->table
|
if (same->type == rib->type && same->instance == rib->instance
|
||||||
|
&& same->table == rib->table
|
||||||
&& same->type != ZEBRA_ROUTE_CONNECT)
|
&& same->type != ZEBRA_ROUTE_CONNECT)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2369,7 +2374,7 @@ rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
|
|||||||
|
|
||||||
/* XXX factor with rib_delete_ipv6 */
|
/* XXX factor with rib_delete_ipv6 */
|
||||||
int
|
int
|
||||||
rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
|
rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
||||||
struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
|
struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
|
||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
@ -2437,6 +2442,8 @@ rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
|
|||||||
|
|
||||||
if (rib->type != type)
|
if (rib->type != type)
|
||||||
continue;
|
continue;
|
||||||
|
if (rib->instance != instance)
|
||||||
|
continue;
|
||||||
if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
|
if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
|
||||||
nexthop->type == NEXTHOP_TYPE_IFINDEX)
|
nexthop->type == NEXTHOP_TYPE_IFINDEX)
|
||||||
{
|
{
|
||||||
@ -2575,6 +2582,7 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
|
|||||||
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||||
|
|
||||||
rib->type = ZEBRA_ROUTE_STATIC;
|
rib->type = ZEBRA_ROUTE_STATIC;
|
||||||
|
rib->instance = 0;
|
||||||
rib->distance = si->distance;
|
rib->distance = si->distance;
|
||||||
rib->metric = 0;
|
rib->metric = 0;
|
||||||
rib->table = zebrad.rtm_table_default;
|
rib->table = zebrad.rtm_table_default;
|
||||||
@ -2876,7 +2884,7 @@ rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
|
rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
||||||
struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
|
struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
|
||||||
u_int32_t metric, u_char distance, safi_t safi)
|
u_int32_t metric, u_char distance, safi_t safi)
|
||||||
{
|
{
|
||||||
@ -2917,6 +2925,8 @@ rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
|
|||||||
|
|
||||||
if (rib->type != type)
|
if (rib->type != type)
|
||||||
continue;
|
continue;
|
||||||
|
if (rib->instance != instance)
|
||||||
|
continue;
|
||||||
if (rib->type != ZEBRA_ROUTE_CONNECT)
|
if (rib->type != ZEBRA_ROUTE_CONNECT)
|
||||||
{
|
{
|
||||||
same = rib;
|
same = rib;
|
||||||
@ -2935,6 +2945,7 @@ rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
|
|||||||
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||||
|
|
||||||
rib->type = type;
|
rib->type = type;
|
||||||
|
rib->instance = instance;
|
||||||
rib->distance = distance;
|
rib->distance = distance;
|
||||||
rib->flags = flags;
|
rib->flags = flags;
|
||||||
rib->metric = metric;
|
rib->metric = metric;
|
||||||
@ -3029,6 +3040,10 @@ rib_add_ipv6_multipath (struct prefix_ipv6 *p, struct rib *rib, safi_t safi,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (same->instance != rib->instance) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (same->table != rib->table) {
|
if (same->table != rib->table) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -3072,7 +3087,7 @@ rib_add_ipv6_multipath (struct prefix_ipv6 *p, struct rib *rib, safi_t safi,
|
|||||||
|
|
||||||
/* XXX factor with rib_delete_ipv6 */
|
/* XXX factor with rib_delete_ipv6 */
|
||||||
int
|
int
|
||||||
rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
|
rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
||||||
struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
|
struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi)
|
||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
@ -3125,6 +3140,8 @@ rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
|
|||||||
|
|
||||||
if (rib->type != type)
|
if (rib->type != type)
|
||||||
continue;
|
continue;
|
||||||
|
if (rib->instance != instance)
|
||||||
|
continue;
|
||||||
if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
|
if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
|
||||||
nexthop->type == NEXTHOP_TYPE_IFINDEX)
|
nexthop->type == NEXTHOP_TYPE_IFINDEX)
|
||||||
{
|
{
|
||||||
@ -3265,6 +3282,7 @@ static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
|
|||||||
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||||
|
|
||||||
rib->type = ZEBRA_ROUTE_STATIC;
|
rib->type = ZEBRA_ROUTE_STATIC;
|
||||||
|
rib->instance = 0;
|
||||||
rib->distance = si->distance;
|
rib->distance = si->distance;
|
||||||
rib->metric = 0;
|
rib->metric = 0;
|
||||||
rib->table = zebrad.rtm_table_default;
|
rib->table = zebrad.rtm_table_default;
|
||||||
@ -3616,7 +3634,7 @@ rib_sweep_route (void)
|
|||||||
|
|
||||||
/* Remove specific by protocol routes from 'table'. */
|
/* Remove specific by protocol routes from 'table'. */
|
||||||
static unsigned long
|
static unsigned long
|
||||||
rib_score_proto_table (u_char proto, struct route_table *table)
|
rib_score_proto_table (u_char proto, u_short instance, struct route_table *table)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct rib *rib;
|
struct rib *rib;
|
||||||
@ -3629,7 +3647,7 @@ rib_score_proto_table (u_char proto, struct route_table *table)
|
|||||||
{
|
{
|
||||||
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
|
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
|
||||||
continue;
|
continue;
|
||||||
if (rib->type == proto)
|
if (rib->type == proto && rib->instance == instance)
|
||||||
{
|
{
|
||||||
rib_delnode (rn, rib);
|
rib_delnode (rn, rib);
|
||||||
n++;
|
n++;
|
||||||
@ -3641,10 +3659,10 @@ rib_score_proto_table (u_char proto, struct route_table *table)
|
|||||||
|
|
||||||
/* Remove specific by protocol routes. */
|
/* Remove specific by protocol routes. */
|
||||||
unsigned long
|
unsigned long
|
||||||
rib_score_proto (u_char proto)
|
rib_score_proto (u_char proto, u_short instance)
|
||||||
{
|
{
|
||||||
return rib_score_proto_table (proto, vrf_table (AFI_IP, SAFI_UNICAST, 0))
|
return rib_score_proto_table (proto, instance, vrf_table (AFI_IP, SAFI_UNICAST, 0))
|
||||||
+rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
|
+rib_score_proto_table (proto, instance, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close RIB and clean up kernel routes. */
|
/* Close RIB and clean up kernel routes. */
|
||||||
|
@ -893,7 +893,10 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
|
|||||||
vty_out (vty, "Routing entry for %s/%d%s",
|
vty_out (vty, "Routing entry for %s/%d%s",
|
||||||
inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
|
inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
|
||||||
VTY_NEWLINE);
|
VTY_NEWLINE);
|
||||||
vty_out (vty, " Known via \"%s\"", zebra_route_string (rib->type));
|
vty_out (vty, " Known via \"%s", zebra_route_string (rib->type));
|
||||||
|
if (rib->instance)
|
||||||
|
vty_out (vty, "[%d]", rib->instance);
|
||||||
|
vty_out (vty, "\"");
|
||||||
vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
|
vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric);
|
||||||
if (rib->tag)
|
if (rib->tag)
|
||||||
vty_out (vty, ", tag %d", rib->tag);
|
vty_out (vty, ", tag %d", rib->tag);
|
||||||
@ -1022,15 +1025,17 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
|
|||||||
if (nexthop == rib->nexthop)
|
if (nexthop == rib->nexthop)
|
||||||
{
|
{
|
||||||
/* Prefix information. */
|
/* Prefix information. */
|
||||||
len = vty_out (vty, "%c%c%c %s/%d",
|
len = vty_out (vty, "%c", zebra_route_char (rib->type));
|
||||||
zebra_route_char (rib->type),
|
if (rib->instance)
|
||||||
|
len += vty_out (vty, "[%d]", rib->instance);
|
||||||
|
len += vty_out (vty, "%c%c %s/%d",
|
||||||
CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
|
CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)
|
||||||
? '>' : ' ',
|
? '>' : ' ',
|
||||||
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
|
CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
|
||||||
? '*' : ' ',
|
? '*' : ' ',
|
||||||
inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
|
inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
|
||||||
rn->p.prefixlen);
|
rn->p.prefixlen);
|
||||||
|
|
||||||
/* Distance and metric display. */
|
/* Distance and metric display. */
|
||||||
if (rib->type != ZEBRA_ROUTE_CONNECT
|
if (rib->type != ZEBRA_ROUTE_CONNECT
|
||||||
&& rib->type != ZEBRA_ROUTE_KERNEL)
|
&& rib->type != ZEBRA_ROUTE_KERNEL)
|
||||||
@ -1348,6 +1353,42 @@ DEFUN (show_ip_route_protocol,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFUN (show_ip_route_ospf_instance,
|
||||||
|
show_ip_route_ospf_instance_cmd,
|
||||||
|
"show ip route ospf <1-65535>",
|
||||||
|
SHOW_STR
|
||||||
|
IP_STR
|
||||||
|
"IP routing table\n"
|
||||||
|
"Open Shortest Path First (OSPFv2)\n"
|
||||||
|
"Instance ID\n")
|
||||||
|
{
|
||||||
|
struct route_table *table;
|
||||||
|
struct route_node *rn;
|
||||||
|
struct rib *rib;
|
||||||
|
int first = 1;
|
||||||
|
u_short instance = 0;
|
||||||
|
|
||||||
|
VTY_GET_INTEGER ("Instance", instance, argv[0]);
|
||||||
|
|
||||||
|
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
||||||
|
if (! table)
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
|
/* Show matched type IPv4 routes. */
|
||||||
|
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||||
|
RNODE_FOREACH_RIB (rn, rib)
|
||||||
|
if (rib->type == ZEBRA_ROUTE_OSPF && rib->instance == instance)
|
||||||
|
{
|
||||||
|
if (first)
|
||||||
|
{
|
||||||
|
vty_out (vty, SHOW_ROUTE_V4_HEADER);
|
||||||
|
first = 0;
|
||||||
|
}
|
||||||
|
vty_show_ip_route (vty, rn, rib);
|
||||||
|
}
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (show_ip_route_addr,
|
DEFUN (show_ip_route_addr,
|
||||||
show_ip_route_addr_cmd,
|
show_ip_route_addr_cmd,
|
||||||
"show ip route A.B.C.D",
|
"show ip route A.B.C.D",
|
||||||
@ -2899,6 +2940,7 @@ zebra_vty_init (void)
|
|||||||
install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_distance2_cmd);
|
install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_distance2_cmd);
|
||||||
|
|
||||||
install_element (VIEW_NODE, &show_ip_route_cmd);
|
install_element (VIEW_NODE, &show_ip_route_cmd);
|
||||||
|
install_element (VIEW_NODE, &show_ip_route_ospf_instance_cmd);
|
||||||
install_element (VIEW_NODE, &show_ip_route_tag_cmd);
|
install_element (VIEW_NODE, &show_ip_route_tag_cmd);
|
||||||
install_element (VIEW_NODE, &show_ip_nht_cmd);
|
install_element (VIEW_NODE, &show_ip_nht_cmd);
|
||||||
install_element (VIEW_NODE, &show_ipv6_nht_cmd);
|
install_element (VIEW_NODE, &show_ipv6_nht_cmd);
|
||||||
@ -2910,6 +2952,7 @@ zebra_vty_init (void)
|
|||||||
install_element (VIEW_NODE, &show_ip_route_summary_cmd);
|
install_element (VIEW_NODE, &show_ip_route_summary_cmd);
|
||||||
install_element (VIEW_NODE, &show_ip_route_summary_prefix_cmd);
|
install_element (VIEW_NODE, &show_ip_route_summary_prefix_cmd);
|
||||||
install_element (ENABLE_NODE, &show_ip_route_cmd);
|
install_element (ENABLE_NODE, &show_ip_route_cmd);
|
||||||
|
install_element (ENABLE_NODE, &show_ip_route_ospf_instance_cmd);
|
||||||
install_element (ENABLE_NODE, &show_ip_route_tag_cmd);
|
install_element (ENABLE_NODE, &show_ip_route_tag_cmd);
|
||||||
install_element (ENABLE_NODE, &show_ip_nht_cmd);
|
install_element (ENABLE_NODE, &show_ip_nht_cmd);
|
||||||
install_element (ENABLE_NODE, &show_ipv6_nht_cmd);
|
install_element (ENABLE_NODE, &show_ipv6_nht_cmd);
|
||||||
|
@ -66,15 +66,6 @@ zserv_delayed_close(struct thread *thread)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When client connects, it sends hello message
|
|
||||||
* with promise to send zebra routes of specific type.
|
|
||||||
* Zebra stores a socket fd of the client into
|
|
||||||
* this array. And use it to clean up routes that
|
|
||||||
* client didn't remove for some reasons after closing
|
|
||||||
* connection.
|
|
||||||
*/
|
|
||||||
static int route_type_oaths[ZEBRA_ROUTE_MAX];
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zserv_flush_data(struct thread *thread)
|
zserv_flush_data(struct thread *thread)
|
||||||
{
|
{
|
||||||
@ -552,6 +543,7 @@ zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
|
|||||||
|
|
||||||
/* Put type and nexthop. */
|
/* Put type and nexthop. */
|
||||||
stream_putc (s, rib->type);
|
stream_putc (s, rib->type);
|
||||||
|
stream_putw (s, rib->instance);
|
||||||
stream_putc (s, rib->flags);
|
stream_putc (s, rib->flags);
|
||||||
|
|
||||||
/* marker for message flags field */
|
/* marker for message flags field */
|
||||||
@ -1032,6 +1024,7 @@ zread_ipv4_add (struct zserv *client, u_short length)
|
|||||||
|
|
||||||
/* Type, flags, message. */
|
/* Type, flags, message. */
|
||||||
rib->type = stream_getc (s);
|
rib->type = stream_getc (s);
|
||||||
|
rib->instance = stream_getw (s);
|
||||||
rib->flags = stream_getc (s);
|
rib->flags = stream_getc (s);
|
||||||
message = stream_getc (s);
|
message = stream_getc (s);
|
||||||
safi = stream_getw (s);
|
safi = stream_getw (s);
|
||||||
@ -1133,6 +1126,7 @@ zread_ipv4_delete (struct zserv *client, u_short length)
|
|||||||
|
|
||||||
/* Type, flags, message. */
|
/* Type, flags, message. */
|
||||||
api.type = stream_getc (s);
|
api.type = stream_getc (s);
|
||||||
|
api.instance = stream_getw (s);
|
||||||
api.flags = stream_getc (s);
|
api.flags = stream_getc (s);
|
||||||
api.message = stream_getc (s);
|
api.message = stream_getc (s);
|
||||||
api.safi = stream_getw (s);
|
api.safi = stream_getw (s);
|
||||||
@ -1195,7 +1189,7 @@ zread_ipv4_delete (struct zserv *client, u_short length)
|
|||||||
else
|
else
|
||||||
api.tag = 0;
|
api.tag = 0;
|
||||||
|
|
||||||
rib_delete_ipv4 (api.type, api.flags, &p, nexthop_p, ifindex,
|
rib_delete_ipv4 (api.type, api.instance, api.flags, &p, nexthop_p, ifindex,
|
||||||
client->rtm_table, api.safi);
|
client->rtm_table, api.safi);
|
||||||
client->v4_route_del_cnt++;
|
client->v4_route_del_cnt++;
|
||||||
return 0;
|
return 0;
|
||||||
@ -1259,6 +1253,7 @@ zread_ipv6_add (struct zserv *client, u_short length)
|
|||||||
|
|
||||||
/* Type, flags, message. */
|
/* Type, flags, message. */
|
||||||
rib->type = stream_getc (s);
|
rib->type = stream_getc (s);
|
||||||
|
rib->instance = stream_getw (s);
|
||||||
rib->flags = stream_getc (s);
|
rib->flags = stream_getc (s);
|
||||||
message = stream_getc (s);
|
message = stream_getc (s);
|
||||||
safi = stream_getw (s);
|
safi = stream_getw (s);
|
||||||
@ -1375,6 +1370,7 @@ zread_ipv6_delete (struct zserv *client, u_short length)
|
|||||||
|
|
||||||
/* Type, flags, message. */
|
/* Type, flags, message. */
|
||||||
api.type = stream_getc (s);
|
api.type = stream_getc (s);
|
||||||
|
api.instance = stream_getw (s);
|
||||||
api.flags = stream_getc (s);
|
api.flags = stream_getc (s);
|
||||||
api.message = stream_getc (s);
|
api.message = stream_getc (s);
|
||||||
api.safi = stream_getw (s);
|
api.safi = stream_getw (s);
|
||||||
@ -1426,9 +1422,9 @@ zread_ipv6_delete (struct zserv *client, u_short length)
|
|||||||
api.tag = 0;
|
api.tag = 0;
|
||||||
|
|
||||||
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
|
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
|
||||||
rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, client->rtm_table, api.safi);
|
rib_delete_ipv6 (api.type, api.instance, api.flags, &p, NULL, ifindex, client->rtm_table, api.safi);
|
||||||
else
|
else
|
||||||
rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, client->rtm_table, api.safi);
|
rib_delete_ipv6 (api.type, api.instance, api.flags, &p, &nexthop, ifindex, client->rtm_table, api.safi);
|
||||||
|
|
||||||
client->v6_route_del_cnt++;
|
client->v6_route_del_cnt++;
|
||||||
return 0;
|
return 0;
|
||||||
@ -1477,7 +1473,10 @@ zread_hello (struct zserv *client)
|
|||||||
{
|
{
|
||||||
/* type of protocol (lib/zebra.h) */
|
/* type of protocol (lib/zebra.h) */
|
||||||
u_char proto;
|
u_char proto;
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
proto = stream_getc (client->ibuf);
|
proto = stream_getc (client->ibuf);
|
||||||
|
instance = stream_getw (client->ibuf);
|
||||||
|
|
||||||
/* accept only dynamic routing protocols */
|
/* accept only dynamic routing protocols */
|
||||||
if ((proto < ZEBRA_ROUTE_MAX)
|
if ((proto < ZEBRA_ROUTE_MAX)
|
||||||
@ -1485,36 +1484,14 @@ zread_hello (struct zserv *client)
|
|||||||
{
|
{
|
||||||
zlog_notice ("client %d says hello and bids fair to announce only %s routes",
|
zlog_notice ("client %d says hello and bids fair to announce only %s routes",
|
||||||
client->sock, zebra_route_string(proto));
|
client->sock, zebra_route_string(proto));
|
||||||
|
if (instance)
|
||||||
|
zlog_notice ("client protocol instance %d", instance);
|
||||||
|
|
||||||
/* if route-type was binded by other client */
|
|
||||||
if (route_type_oaths[proto])
|
|
||||||
zlog_warn ("sender of %s routes changed %c->%c",
|
|
||||||
zebra_route_string(proto), route_type_oaths[proto],
|
|
||||||
client->sock);
|
|
||||||
|
|
||||||
route_type_oaths[proto] = client->sock;
|
|
||||||
client->proto = proto;
|
client->proto = proto;
|
||||||
|
client->instance = instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If client sent routes of specific type, zebra removes it
|
|
||||||
* and returns number of deleted routes.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
zebra_score_rib (int client_sock)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++)
|
|
||||||
if (client_sock == route_type_oaths[i])
|
|
||||||
{
|
|
||||||
zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
|
|
||||||
client_sock, rib_score_proto (i), zebra_route_string (i));
|
|
||||||
route_type_oaths[i] = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close zebra client. */
|
/* Close zebra client. */
|
||||||
static void
|
static void
|
||||||
zebra_client_close (struct zserv *client)
|
zebra_client_close (struct zserv *client)
|
||||||
@ -1525,8 +1502,12 @@ zebra_client_close (struct zserv *client)
|
|||||||
/* Close file descriptor. */
|
/* Close file descriptor. */
|
||||||
if (client->sock)
|
if (client->sock)
|
||||||
{
|
{
|
||||||
|
unsigned long nroutes;
|
||||||
|
|
||||||
close (client->sock);
|
close (client->sock);
|
||||||
zebra_score_rib (client->sock);
|
nroutes = rib_score_proto (client->proto, client->instance);
|
||||||
|
zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
|
||||||
|
client->sock, nroutes, zebra_route_string (client->proto));
|
||||||
client->sock = -1;
|
client->sock = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1814,7 +1795,6 @@ zebra_serv ()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset (&route_type_oaths, 0, sizeof (route_type_oaths));
|
|
||||||
memset (&addr, 0, sizeof (struct sockaddr_in));
|
memset (&addr, 0, sizeof (struct sockaddr_in));
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = htons (ZEBRA_PORT);
|
addr.sin_port = htons (ZEBRA_PORT);
|
||||||
@ -1885,8 +1865,6 @@ zebra_serv_un (const char *path)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset (&route_type_oaths, 0, sizeof (route_type_oaths));
|
|
||||||
|
|
||||||
/* Make server socket. */
|
/* Make server socket. */
|
||||||
memset (&serv, 0, sizeof (struct sockaddr_un));
|
memset (&serv, 0, sizeof (struct sockaddr_un));
|
||||||
serv.sun_family = AF_UNIX;
|
serv.sun_family = AF_UNIX;
|
||||||
@ -1984,8 +1962,11 @@ zebra_show_client_detail (struct vty *vty, struct zserv *client)
|
|||||||
char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF];
|
char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF];
|
||||||
char wbuf[ZEBRA_TIME_BUF], nhbuf[ZEBRA_TIME_BUF], mbuf[ZEBRA_TIME_BUF];
|
char wbuf[ZEBRA_TIME_BUF], nhbuf[ZEBRA_TIME_BUF], mbuf[ZEBRA_TIME_BUF];
|
||||||
|
|
||||||
vty_out (vty, "Client: %s %s",
|
vty_out (vty, "Client: %s", zebra_route_string(client->proto));
|
||||||
zebra_route_string(client->proto), VTY_NEWLINE);
|
if (client->instance)
|
||||||
|
vty_out (vty, " Instance: %d", client->instance);
|
||||||
|
vty_out (vty, "%s", VTY_NEWLINE);
|
||||||
|
|
||||||
vty_out (vty, "------------------------ %s", VTY_NEWLINE);
|
vty_out (vty, "------------------------ %s", VTY_NEWLINE);
|
||||||
vty_out (vty, "FD: %d %s", client->sock, VTY_NEWLINE);
|
vty_out (vty, "FD: %d %s", client->sock, VTY_NEWLINE);
|
||||||
vty_out (vty, "Route Table ID: %d %s", client->rtm_table, VTY_NEWLINE);
|
vty_out (vty, "Route Table ID: %d %s", client->rtm_table, VTY_NEWLINE);
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "if.h"
|
#include "if.h"
|
||||||
#include "workqueue.h"
|
#include "workqueue.h"
|
||||||
#include "routemap.h"
|
#include "routemap.h"
|
||||||
|
#include "zclient.h"
|
||||||
|
|
||||||
/* Default port information. */
|
/* Default port information. */
|
||||||
#define ZEBRA_VTY_PORT 2601
|
#define ZEBRA_VTY_PORT 2601
|
||||||
@ -59,7 +60,7 @@ struct zserv
|
|||||||
int rtm_table;
|
int rtm_table;
|
||||||
|
|
||||||
/* This client's redistribute flag. */
|
/* This client's redistribute flag. */
|
||||||
u_char redist[ZEBRA_ROUTE_MAX];
|
struct redist_proto redist[ZEBRA_ROUTE_MAX];
|
||||||
|
|
||||||
/* Redistribute default route flag. */
|
/* Redistribute default route flag. */
|
||||||
u_char redist_default;
|
u_char redist_default;
|
||||||
@ -72,6 +73,7 @@ struct zserv
|
|||||||
|
|
||||||
/* client's protocol */
|
/* client's protocol */
|
||||||
u_char proto;
|
u_char proto;
|
||||||
|
u_short instance;
|
||||||
|
|
||||||
/* Statistics */
|
/* Statistics */
|
||||||
u_int32_t redist_v4_add_cnt;
|
u_int32_t redist_v4_add_cnt;
|
||||||
|
Loading…
Reference in New Issue
Block a user