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:
Donald Sharp 2015-05-19 18:03:42 -07:00
parent 8c5fbd4858
commit 7c8ff89e93
60 changed files with 3839 additions and 1276 deletions

View File

@ -187,7 +187,7 @@ babel_init(int argc, char **argv)
progname = babel_get_progname(argv[0]);
/* 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);
/* set log destination as stdout until the config file is read */
zlog_set_level(NULL, ZLOG_DEST_STDOUT, LOG_WARNING);

View File

@ -99,6 +99,7 @@ babel_zebra_read_ipv6 (int command, struct zclient *zclient,
/* Type, flags, message. */
api.type = stream_getc (s);
api.instance = stream_getw (s);
api.flags = stream_getc (s);
api.message = stream_getc (s);
@ -151,6 +152,7 @@ babel_zebra_read_ipv4 (int command, struct zclient *zclient,
/* Type, flags, message. */
api.type = stream_getc (s);
api.instance = stream_getw (s);
api.flags = stream_getc (s);
api.message = stream_getc (s);
@ -205,7 +207,7 @@ DEFUN (babel_redistribute_type,
return CMD_WARNING;
}
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type, 0);
return CMD_SUCCESS;
}
@ -229,7 +231,7 @@ DEFUN (no_babel_redistribute_type,
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... */
return CMD_SUCCESS;
}
@ -332,7 +334,7 @@ debug_babel_config_write (struct vty * vty)
void babelz_zebra_init(void)
{
zclient = zclient_new();
zclient_init(zclient, ZEBRA_ROUTE_BABEL);
zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0);
zclient->interface_add = babel_interface_add;
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);
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, " no redistribute babel%s", VTY_NEWLINE);

View File

@ -111,7 +111,8 @@ babel_config_write (struct vty *vty)
lines = 1 + babel_enable_if_config_write (vty);
/* list redistributed protocols */
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);
lines++;

View File

@ -324,7 +324,7 @@ main (int argc, char **argv)
/* Preserve name of myself. */
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);
/* BGP master init. */

View File

@ -2044,7 +2044,7 @@ bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
}
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_info *new;
@ -2052,6 +2052,7 @@ info_make (int type, int sub_type, struct peer *peer, struct attr *attr,
/* Make new BGP info. */
new = XCALLOC (MTYPE_BGP_ROUTE, sizeof (struct bgp_info));
new->type = type;
new->instance = instance;
new->sub_type = sub_type;
new->peer = peer;
new->attr = attr;
@ -2205,7 +2206,7 @@ bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
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. */
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. */
new = info_make(type, sub_type, peer, attr_new, rn);
new = info_make(type, sub_type, 0, peer, attr_new, rn);
/* Update MPLS tag. */
if (safi == SAFI_MPLS_VPN)
@ -3671,7 +3672,7 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p,
}
/* 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);
/* Nexthop reachability 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. */
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);
/* Nexthop reachability 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);
/* 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);
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)
{
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,
aggregate->as_set,
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)
{
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,
aggregate->as_set,
atomic_aggregate), rn);
@ -5766,7 +5767,7 @@ ALIAS (no_ipv6_aggregate_address_summary_only,
void
bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
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 listnode *node, *nnode;
@ -5778,6 +5779,7 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
struct attr *new_attr;
afi_t afi;
int ret;
struct bgp_redist *red;
/* Make default attribute. */
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);
if (bgp->redist[afi][type])
red = bgp_redist_lookup(bgp, afi, type, instance);
if (red)
{
struct attr attr_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;
bgp_attr_dup (&attr_new, &attr);
if (bgp->redist_metric_flag[afi][type])
attr_new.med = bgp->redist_metric[afi][type];
if (red->redist_metric_flag)
attr_new.med = red->redist_metric;
/* Apply route-map. */
if (bgp->rmap[afi][type].map)
if (red->rmap.map)
{
info.peer = bgp->peer_self;
info.attr = &attr_new;
SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE);
ret = route_map_apply (bgp->rmap[afi][type].map, p, RMAP_BGP,
&info);
ret = route_map_apply (red->rmap.map, p, RMAP_BGP, &info);
bgp->peer_self->rmap_type = 0;
@ -5835,7 +5837,7 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
/* Unintern original. */
aspath_unintern (&attr.aspath);
bgp_attr_extra_free (&attr);
bgp_redistribute_delete (p, type);
bgp_redistribute_delete (p, type, instance);
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);
SET_FLAG (new->flags, BGP_INFO_VALID);
@ -5902,19 +5904,21 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
}
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 listnode *node, *nnode;
afi_t afi;
struct bgp_node *rn;
struct bgp_info *ri;
struct bgp_redist *red;
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
{
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);
@ -5936,7 +5940,7 @@ bgp_redistribute_delete (struct prefix *p, u_char type)
/* Withdraw specified route type's route. */
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_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)
if (ri->peer == bgp->peer_self
&& ri->type == type)
&& ri->type == type
&& ri->instance == instance)
break;
if (ri)

View File

@ -105,6 +105,9 @@ struct bgp_info
#define BGP_ROUTE_STATIC 1
#define BGP_ROUTE_AGGREGATE 2
#define BGP_ROUTE_REDISTRIBUTE 3
u_short instance;
};
/* 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 *,
const struct in6_addr *, unsigned int ifindex,
u_int32_t, u_char, u_short);
extern void bgp_redistribute_delete (struct prefix *, u_char);
extern void bgp_redistribute_withdraw (struct bgp *, afi_t, int);
u_int32_t, u_char, u_short, u_short);
extern void bgp_redistribute_delete (struct prefix *, u_char, u_short);
extern void bgp_redistribute_withdraw (struct bgp *, afi_t, int, u_short);
extern void bgp_static_delete (struct bgp *);
extern void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static *,

View File

@ -2791,7 +2791,7 @@ bgp_route_map_process_update (void *arg, char *rmap_name, int route_update)
char buf[INET6_ADDRSTRLEN];
if (!bgp)
return;
return (-1);
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 (i = 0; i < ZEBRA_ROUTE_MAX; i++)
{
if (bgp->rmap[afi][i].name &&
(strcmp(rmap_name, bgp->rmap[afi][i].name) == 0))
{
bgp->rmap[afi][i].map =
route_map_lookup_by_name (bgp->rmap[afi][i].name);
struct list *red_list;
struct listnode *node;
struct bgp_redist *red;
if (bgp->redist[afi][i] && route_update)
{
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("Processing route_map %s update on "
"redistributed routes", rmap_name);
red_list = bgp->redist[afi][i];
if (!red_list)
continue;
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);
}
}
}
}

View File

@ -9639,7 +9639,8 @@ DEFUN (bgp_redistribute_ipv4,
vty_out (vty, "%% Invalid route type%s", VTY_NEWLINE);
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,
@ -9651,6 +9652,7 @@ DEFUN (bgp_redistribute_ipv4_rmap,
"Pointer to route-map entries\n")
{
int type;
struct bgp_redist *red;
type = proto_redistnum (AFI_IP, argv[0]);
if (type < 0 || type == ZEBRA_ROUTE_BGP)
@ -9659,8 +9661,9 @@ DEFUN (bgp_redistribute_ipv4_rmap,
return CMD_WARNING;
}
bgp_redistribute_rmap_set (vty->index, AFI_IP, type, argv[1]);
return bgp_redistribute_set (vty->index, AFI_IP, type);
red = bgp_redist_add(vty->index, AFI_IP, type, 0);
bgp_redistribute_rmap_set (red, argv[1]);
return bgp_redistribute_set (type, 0);
}
DEFUN (bgp_redistribute_ipv4_metric,
@ -9673,6 +9676,7 @@ DEFUN (bgp_redistribute_ipv4_metric,
{
int type;
u_int32_t metric;
struct bgp_redist *red;
type = proto_redistnum (AFI_IP, argv[0]);
if (type < 0 || type == ZEBRA_ROUTE_BGP)
@ -9682,8 +9686,9 @@ DEFUN (bgp_redistribute_ipv4_metric,
}
VTY_GET_INTEGER ("metric", metric, argv[1]);
bgp_redistribute_metric_set (vty->index, AFI_IP, type, metric);
return bgp_redistribute_set (vty->index, AFI_IP, type);
red = bgp_redist_add(vty->index, AFI_IP, type, 0);
bgp_redistribute_metric_set (red, metric);
return bgp_redistribute_set (type, 0);
}
DEFUN (bgp_redistribute_ipv4_rmap_metric,
@ -9698,6 +9703,7 @@ DEFUN (bgp_redistribute_ipv4_rmap_metric,
{
int type;
u_int32_t metric;
struct bgp_redist *red;
type = proto_redistnum (AFI_IP, argv[0]);
if (type < 0 || type == ZEBRA_ROUTE_BGP)
@ -9707,9 +9713,10 @@ DEFUN (bgp_redistribute_ipv4_rmap_metric,
}
VTY_GET_INTEGER ("metric", metric, argv[2]);
bgp_redistribute_rmap_set (vty->index, AFI_IP, type, argv[1]);
bgp_redistribute_metric_set (vty->index, AFI_IP, type, metric);
return bgp_redistribute_set (vty->index, AFI_IP, type);
red = bgp_redist_add(vty->index, AFI_IP, type, 0);
bgp_redistribute_rmap_set (red, argv[1]);
bgp_redistribute_metric_set (red, metric);
return bgp_redistribute_set (type, 0);
}
DEFUN (bgp_redistribute_ipv4_metric_rmap,
@ -9724,6 +9731,7 @@ DEFUN (bgp_redistribute_ipv4_metric_rmap,
{
int type;
u_int32_t metric;
struct bgp_redist *red;
type = proto_redistnum (AFI_IP, argv[0]);
if (type < 0 || type == ZEBRA_ROUTE_BGP)
@ -9733,11 +9741,171 @@ DEFUN (bgp_redistribute_ipv4_metric_rmap,
}
VTY_GET_INTEGER ("metric", metric, argv[1]);
bgp_redistribute_metric_set (vty->index, AFI_IP, type, metric);
bgp_redistribute_rmap_set (vty->index, AFI_IP, type, argv[2]);
return bgp_redistribute_set (vty->index, AFI_IP, type);
red = bgp_redist_add(vty->index, AFI_IP, type, 0);
bgp_redistribute_metric_set (red, metric);
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,
no_bgp_redistribute_ipv4_cmd,
"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);
return CMD_WARNING;
}
return bgp_redistribute_unset (vty->index, AFI_IP, type);
return bgp_redistribute_unset (vty->index, AFI_IP, type, 0);
}
ALIAS (no_bgp_redistribute_ipv4,
@ -9813,7 +9980,8 @@ DEFUN (bgp_redistribute_ipv6,
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,
@ -9825,6 +9993,7 @@ DEFUN (bgp_redistribute_ipv6_rmap,
"Pointer to route-map entries\n")
{
int type;
struct bgp_redist *red;
type = proto_redistnum (AFI_IP6, argv[0]);
if (type < 0 || type == ZEBRA_ROUTE_BGP)
@ -9833,8 +10002,9 @@ DEFUN (bgp_redistribute_ipv6_rmap,
return CMD_WARNING;
}
bgp_redistribute_rmap_set (vty->index, AFI_IP6, type, argv[1]);
return bgp_redistribute_set (vty->index, AFI_IP6, type);
red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
bgp_redistribute_rmap_set (red, argv[1]);
return bgp_redistribute_set (type, 0);
}
DEFUN (bgp_redistribute_ipv6_metric,
@ -9847,6 +10017,7 @@ DEFUN (bgp_redistribute_ipv6_metric,
{
int type;
u_int32_t metric;
struct bgp_redist *red;
type = proto_redistnum (AFI_IP6, argv[0]);
if (type < 0 || type == ZEBRA_ROUTE_BGP)
@ -9856,8 +10027,9 @@ DEFUN (bgp_redistribute_ipv6_metric,
}
VTY_GET_INTEGER ("metric", metric, argv[1]);
bgp_redistribute_metric_set (vty->index, AFI_IP6, type, metric);
return bgp_redistribute_set (vty->index, AFI_IP6, type);
red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
bgp_redistribute_metric_set (red, metric);
return bgp_redistribute_set (type, 0);
}
DEFUN (bgp_redistribute_ipv6_rmap_metric,
@ -9872,6 +10044,7 @@ DEFUN (bgp_redistribute_ipv6_rmap_metric,
{
int type;
u_int32_t metric;
struct bgp_redist *red;
type = proto_redistnum (AFI_IP6, argv[0]);
if (type < 0 || type == ZEBRA_ROUTE_BGP)
@ -9881,9 +10054,10 @@ DEFUN (bgp_redistribute_ipv6_rmap_metric,
}
VTY_GET_INTEGER ("metric", metric, argv[2]);
bgp_redistribute_rmap_set (vty->index, AFI_IP6, type, argv[1]);
bgp_redistribute_metric_set (vty->index, AFI_IP6, type, metric);
return bgp_redistribute_set (vty->index, AFI_IP6, type);
red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
bgp_redistribute_rmap_set (red, argv[1]);
bgp_redistribute_metric_set (red, metric);
return bgp_redistribute_set (type, 0);
}
DEFUN (bgp_redistribute_ipv6_metric_rmap,
@ -9898,6 +10072,7 @@ DEFUN (bgp_redistribute_ipv6_metric_rmap,
{
int type;
u_int32_t metric;
struct bgp_redist *red;
type = proto_redistnum (AFI_IP6, argv[0]);
if (type < 0 || type == ZEBRA_ROUTE_BGP)
@ -9907,9 +10082,10 @@ DEFUN (bgp_redistribute_ipv6_metric_rmap,
}
VTY_GET_INTEGER ("metric", metric, argv[1]);
bgp_redistribute_metric_set (vty->index, AFI_IP6, type, metric);
bgp_redistribute_rmap_set (vty->index, AFI_IP6, type, argv[2]);
return bgp_redistribute_set (vty->index, AFI_IP6, type);
red = bgp_redist_add(vty->index, AFI_IP6, type, 0);
bgp_redistribute_metric_set (red, metric);
bgp_redistribute_rmap_set (red, argv[2]);
return bgp_redistribute_set (type, 0);
}
DEFUN (no_bgp_redistribute_ipv6,
@ -9928,7 +10104,7 @@ DEFUN (no_bgp_redistribute_ipv6,
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,
@ -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++)
{
/* 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. */
bgp_config_write_family_header (vty, afi, safi, write);
struct list *red_list;
struct listnode *node;
struct bgp_redist *red;
/* "redistribute" configuration. */
vty_out (vty, " redistribute %s", zebra_route_string(i));
red_list = bgp->redist[afi][i];
if (!red_list)
continue;
if (bgp->redist_metric_flag[afi][i])
vty_out (vty, " metric %u", bgp->redist_metric[afi][i]);
for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
{
/* Display "address-family" when it is not yet diplayed. */
bgp_config_write_family_header (vty, afi, safi, write);
if (bgp->rmap[afi][i].name)
vty_out (vty, " route-map %s", bgp->rmap[afi][i].name);
vty_out (vty, "%s", VTY_NEWLINE);
/* "redistribute" configuration. */
vty_out (vty, " redistribute %s", zebra_route_string(i));
if (red->instance)
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;
@ -11264,6 +11450,16 @@ bgp_vty_init (void)
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_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
install_element (BGP_IPV6_NODE, &bgp_redistribute_ipv6_cmd);
install_element (BGP_IPV6_NODE, &no_bgp_redistribute_ipv6_cmd);

View File

@ -428,6 +428,7 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
/* Type, flags, message. */
api.type = stream_getc (s);
api.instance = stream_getw (s);
api.flags = 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))
{
char buf[2][INET_ADDRSTRLEN];
zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u tag %d",
zebra_route_string(api.type),
zlog_debug("Zebra rcvd: IPv4 route add %s[%d] %s/%d nexthop %s metric %u tag %d",
zebra_route_string(api.type), api.instance,
inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
p.prefixlen,
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);
}
bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL, ifindex,
api.metric, api.type, api.tag);
api.metric, api.type, api.instance, api.tag);
}
else
{
if (bgp_debug_zebra(&p))
{
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",
zebra_route_string(api.type),
zebra_route_string(api.type), api.instance,
inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
p.prefixlen,
inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
api.metric,
api.tag);
}
bgp_redistribute_delete((struct prefix *)&p, api.type);
bgp_redistribute_delete((struct prefix *)&p, api.type, api.instance);
}
return 0;
@ -515,6 +516,7 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
/* Type, flags, message. */
api.type = stream_getc (s);
api.instance = stream_getw (s);
api.flags = 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))
{
char buf[2][INET6_ADDRSTRLEN];
zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u tag %d",
zebra_route_string(api.type),
zlog_debug("Zebra rcvd: IPv6 route add %s[%d] %s/%d nexthop %s metric %u tag %d",
zebra_route_string(api.type), api.instance,
inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
p.prefixlen,
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);
}
bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop, ifindex,
api.metric, api.type, api.tag);
api.metric, api.type, api.instance, api.tag);
}
else
{
if (bgp_debug_zebra(&p))
{
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",
zebra_route_string(api.type),
zebra_route_string(api.type), api.instance,
inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
p.prefixlen,
inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
api.metric,
api.tag);
}
bgp_redistribute_delete ((struct prefix *) &p, api.type);
bgp_redistribute_delete ((struct prefix *) &p, api.type, api.instance);
}
return 0;
@ -942,7 +944,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (zclient->sock < 0)
return;
if (! zclient->redist[ZEBRA_ROUTE_BGP])
if (!zclient->redist[ZEBRA_ROUTE_BGP].enabled)
return;
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.type = ZEBRA_ROUTE_BGP;
api.instance = 0;
api.message = 0;
api.safi = safi;
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. */
api.flags = flags;
api.type = ZEBRA_ROUTE_BGP;
api.instance = 0;
api.message = 0;
api.safi = safi;
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)
return;
if (! zclient->redist[ZEBRA_ROUTE_BGP])
if (!zclient->redist[ZEBRA_ROUTE_BGP].enabled)
return;
peer = info->peer;
@ -1309,6 +1313,7 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi)
nexthop = &info->attr->nexthop;
api.type = ZEBRA_ROUTE_BGP;
api.instance = 0;
api.message = 0;
api.safi = safi;
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.type = ZEBRA_ROUTE_BGP;
api.instance = 0;
api.message = 0;
api.safi = safi;
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 */
}
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. */
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. */
if (zclient->redist[type])
if (redist_check_instance(&zclient->redist[type], instance))
return CMD_WARNING;
zclient->redist[type] = 1;
redist_add_instance(&zclient->redist[type], instance);
/* Return if zebra connection is not established. */
if (zclient->sock < 0)
return CMD_WARNING;
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. */
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, instance);
return CMD_SUCCESS;
}
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. */
if (zclient->sock < 0)
return -1;
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. */
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, instance);
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, instance);
return 0;
}
/* Redistribute with route-map specification. */
int
bgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type,
const char *name)
bgp_redistribute_rmap_set (struct bgp_redist *red, const char *name)
{
if (bgp->rmap[afi][type].name
&& (strcmp (bgp->rmap[afi][type].name, name) == 0))
if (red->rmap.name
&& (strcmp (red->rmap.name, name) == 0))
return 0;
if (bgp->rmap[afi][type].name)
free (bgp->rmap[afi][type].name);
bgp->rmap[afi][type].name = strdup (name);
bgp->rmap[afi][type].map = route_map_lookup_by_name (name);
if (red->rmap.name)
free (red->rmap.name);
red->rmap.name = strdup (name);
red->rmap.map = route_map_lookup_by_name (name);
return 1;
}
/* Redistribute with metric specification. */
int
bgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,
u_int32_t metric)
bgp_redistribute_metric_set (struct bgp_redist *red, u_int32_t metric)
{
if (bgp->redist_metric_flag[afi][type]
&& bgp->redist_metric[afi][type] == metric)
if (red->redist_metric_flag
&& red->redist_metric == metric)
return 0;
bgp->redist_metric_flag[afi][type] = 1;
bgp->redist_metric[afi][type] = metric;
red->redist_metric_flag = 1;
red->redist_metric = metric;
return 1;
}
/* Unset redistribution. */
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. */
bgp->redist[afi][type] = 0;
struct bgp_redist *red;
red = bgp_redist_lookup(bgp, afi, type, instance);
if (!red)
return CMD_SUCCESS;
/* Unset route-map. */
if (bgp->rmap[afi][type].name)
free (bgp->rmap[afi][type].name);
bgp->rmap[afi][type].name = NULL;
bgp->rmap[afi][type].map = NULL;
if (red->rmap.name)
free (red->rmap.name);
red->rmap.name = NULL;
red->rmap.map = NULL;
/* Unset metric. */
bgp->redist_metric_flag[afi][type] = 0;
bgp->redist_metric[afi][type] = 0;
red->redist_metric_flag = 0;
red->redist_metric = 0;
bgp_redist_del(bgp, afi, type, instance);
/* Return if zebra connection is disabled. */
if (! zclient->redist[type])
if (!redist_check_instance(&zclient->redist[type], instance))
return CMD_WARNING;
zclient->redist[type] = 0;
redist_del_instance(&zclient->redist[type], instance);
if (bgp->redist[AFI_IP][type] == 0
&& bgp->redist[AFI_IP6][type] == 0
if (!bgp_redist_lookup(bgp, AFI_IP, type, instance)
&& !bgp_redist_lookup(bgp, AFI_IP6, type, instance)
&& zclient->sock >= 0)
{
/* Send distribute delete message to zebra. */
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("Zebra send: redistribute delete %s",
zebra_route_string(type));
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
zlog_debug("Zebra send: redistribute delete %s %d",
zebra_route_string(type), instance);
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type, instance);
}
/* 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;
}
@ -1531,7 +1597,7 @@ bgp_zebra_init (void)
{
/* Set default values. */
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->interface_add = bgp_interface_add;
zclient->interface_delete = bgp_interface_delete;

View File

@ -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_withdraw (struct prefix *, struct bgp_info *, safi_t);
extern int bgp_redistribute_set (struct bgp *, afi_t, int);
extern int bgp_redistribute_resend (struct bgp *, afi_t, int);
extern int bgp_redistribute_rmap_set (struct bgp *, afi_t, int, const char *);
extern int bgp_redistribute_metric_set (struct bgp *, afi_t, int, u_int32_t);
extern int bgp_redistribute_unset (struct bgp *, afi_t, int);
extern struct bgp_redist *bgp_redist_lookup (struct bgp *, afi_t, u_char, u_short);
extern struct bgp_redist *bgp_redist_add (struct bgp *, afi_t, u_char, u_short);
extern int bgp_redistribute_set (int, u_short);
extern int bgp_redistribute_resend (struct bgp *, afi_t, int, u_short);
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_exact (struct in_addr *);

View File

@ -2397,7 +2397,7 @@ bgp_delete (struct bgp *bgp)
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
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))
{

View File

@ -70,6 +70,18 @@ struct bgp_rmap
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. */
struct bgp
{
@ -185,14 +197,7 @@ struct bgp
struct bgp_rmap table_map[AFI_MAX][SAFI_MAX];
/* BGP redistribute configuration. */
u_char 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];
struct list *redist[AFI_MAX][ZEBRA_ROUTE_MAX];
/* timer to dampen route map changes */
struct thread *t_rmap_update; /* Handle route map updates */

View File

@ -239,7 +239,7 @@ main (int argc, char **argv, char **envp)
/* Get the programname without the preceding path. */
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);
/* for reload */

View File

@ -236,7 +236,7 @@ isis_zebra_route_add_ipv4 (struct prefix *prefix,
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
return;
if (zclient->redist[ZEBRA_ROUTE_ISIS])
if (zclient->redist[ZEBRA_ROUTE_ISIS].enabled)
{
message = 0;
flags = 0;
@ -252,6 +252,8 @@ isis_zebra_route_add_ipv4 (struct prefix *prefix,
zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD);
/* type */
stream_putc (stream, ZEBRA_ROUTE_ISIS);
/* instance */
stream_putw (stream, 0);
/* flags */
stream_putc (stream, flags);
/* message */
@ -301,9 +303,10 @@ isis_zebra_route_del_ipv4 (struct prefix *prefix,
struct zapi_ipv4 api;
struct prefix_ipv4 prefix4;
if (zclient->redist[ZEBRA_ROUTE_ISIS])
if (zclient->redist[ZEBRA_ROUTE_ISIS].enabled)
{
api.type = ZEBRA_ROUTE_ISIS;
api.instance = 0;
api.flags = 0;
api.message = 0;
api.safi = SAFI_UNICAST;
@ -334,6 +337,7 @@ isis_zebra_route_add_ipv6 (struct prefix *prefix,
return;
api.type = ZEBRA_ROUTE_ISIS;
api.instance = 0;
api.flags = 0;
api.message = 0;
api.safi = SAFI_UNICAST;
@ -419,6 +423,7 @@ isis_zebra_route_del_ipv6 (struct prefix *prefix,
return;
api.type = ZEBRA_ROUTE_ISIS;
api.instance = 0;
api.flags = 0;
api.message = 0;
api.safi = SAFI_UNICAST;
@ -488,7 +493,7 @@ isis_zebra_route_update (struct prefix *prefix,
if (zclient->sock < 0)
return;
if (!zclient->redist[ZEBRA_ROUTE_ISIS])
if (!zclient->redist[ZEBRA_ROUTE_ISIS].enabled)
return;
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;
api.type = stream_getc (stream);
api.instance = stream_getw (stream);
api.flags = stream_getc (stream);
api.message = stream_getc (stream);
@ -570,7 +576,8 @@ isis_zebra_read_ipv6 (int command, struct zclient *zclient,
#endif
#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
isis_distribute_list_update (int routetype)
@ -591,7 +598,7 @@ void
isis_zebra_init ()
{
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->interface_add = isis_zebra_if_add;
zclient->interface_delete = isis_zebra_if_del;

View File

@ -150,6 +150,7 @@ time_print(FILE *fp, struct timestamp_control *ctl)
static void
vzlog (struct zlog *zl, int priority, const char *format, va_list args)
{
char proto_str[32];
struct timestamp_control tsctl;
tsctl.already_rendered = 0;
@ -181,6 +182,11 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args)
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. */
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);
if (zl->record_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);
vfprintf (zl->fp, format, ac);
va_end(ac);
@ -203,7 +209,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args)
time_print (stdout, &tsctl);
if (zl->record_priority)
fprintf (stdout, "%s: ", zlog_priority[priority]);
fprintf (stdout, "%s: ", zlog_proto_names[zl->protocol]);
fprintf (stdout, "%s", proto_str);
va_copy(ac, args);
vfprintf (stdout, format, ac);
va_end(ac);
@ -214,7 +220,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args)
/* Terminal monitor. */
if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR])
vty_log ((zl->record_priority ? zlog_priority[priority] : NULL),
zlog_proto_names[zl->protocol], format, &tsctl, args);
proto_str, format, &tsctl, args);
}
static char *
@ -600,7 +606,7 @@ _zlog_assert_failed (const char *assertion, const char *file,
/* Open log stream */
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)
{
struct zlog *zl;
@ -610,6 +616,7 @@ openzlog (const char *progname, zlog_proto_t protocol,
zl->ident = progname;
zl->protocol = protocol;
zl->instance = instance;
zl->facility = syslog_facility;
zl->syslog_options = syslog_flags;

View File

@ -73,6 +73,7 @@ struct zlog
{
const char *ident; /* daemon name (first arg to openlog) */
zlog_proto_t protocol;
u_short instance;
int maxlvl[ZLOG_NUM_DESTS]; /* maximum priority to send to associated
logging destination */
int default_lvl; /* maxlvl to use if none is specified */
@ -97,7 +98,7 @@ extern struct zlog *zlog_default;
/* Open zlog function */
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. */
extern void closezlog (struct zlog *zl);

View File

@ -327,8 +327,10 @@ vty_show_route_map_entry (struct vty *vty, struct route_map *map)
/* Print the name of the protocol */
if (zlog_default)
vty_out (vty, "%s:%s", zlog_proto_names[zlog_default->protocol],
VTY_NEWLINE);
vty_out (vty, "%s", zlog_proto_names[zlog_default->protocol]);
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)
{

View File

@ -78,10 +78,66 @@ zclient_free (struct 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
redistribute route type. */
void
zclient_init (struct zclient *zclient, int redist_default)
zclient_init (struct zclient *zclient, int redist_default, u_short instance)
{
int i;
@ -93,12 +149,13 @@ zclient_init (struct zclient *zclient, int redist_default)
/* Clear redistribution flags. */
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
redistribution. */
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. */
zclient->default_information = 0;
@ -142,7 +199,7 @@ void
zclient_reset (struct zclient *zclient)
{
zclient_stop (zclient);
zclient_init (zclient, zclient->redist_default);
zclient_init (zclient, zclient->redist_default, zclient->instance);
}
#ifdef HAVE_TCP_ZEBRA
@ -330,6 +387,7 @@ zebra_hello_send (struct zclient *zclient)
zclient_create_header (s, ZEBRA_HELLO);
stream_putc (s, zclient->redist_default);
stream_putw (s, zclient->instance);
stream_putw_at (s, 0, stream_get_endp (s));
return zclient_send_message(zclient);
}
@ -388,8 +446,15 @@ zclient_start (struct zclient *zclient)
/* Flush all redistribute request. */
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
if (i != zclient->redist_default && zclient->redist[i])
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, i);
if (zclient->redist[i].enabled)
{
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 (zclient->default_information)
@ -491,6 +556,7 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
/* Put type and nexthop. */
stream_putc (s, api->type);
stream_putw (s, api->instance);
stream_putc (s, api->flags);
stream_putc (s, api->message);
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. */
stream_putc (s, api->type);
stream_putw (s, api->instance);
stream_putc (s, api->flags);
stream_putc (s, api->message);
stream_putw (s, api->safi);
@ -627,7 +694,8 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
* sending client
*/
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;
@ -636,6 +704,7 @@ zebra_redistribute_send (int command, struct zclient *zclient, int type)
zclient_create_header (s, command);
stream_putc (s, type);
stream_putw (s, instance);
stream_putw_at (s, 0, stream_get_endp (s));
@ -1153,24 +1222,25 @@ zclient_read (struct thread *thread)
}
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 (zclient->redist[type])
if (redist_check_instance(&zclient->redist[type], instance))
return;
zclient->redist[type] = 1;
redist_add_instance(&zclient->redist[type], instance);
}
else
{
if (!zclient->redist[type])
if (!redist_check_instance(&zclient->redist[type], instance))
return;
zclient->redist[type] = 0;
redist_del_instance(&zclient->redist[type], instance);
}
if (zclient->sock > 0)
zebra_redistribute_send (command, zclient, type);
zebra_redistribute_send (command, zclient, type, instance);
}

View File

@ -34,6 +34,12 @@
/* Zebra header size. */
#define ZEBRA_HEADER_SIZE 6
struct redist_proto
{
u_char enabled;
struct list *instances;
};
/* Structure for the zebra client. */
struct zclient
{
@ -64,8 +70,9 @@ struct zclient
struct thread *t_write;
/* Redistribute information. */
u_char redist_default;
u_char redist[ZEBRA_ROUTE_MAX];
u_char redist_default; /* clients protocol */
u_short instance;
struct redist_proto redist[ZEBRA_ROUTE_MAX];
/* Redistribute defauilt. */
u_char default_information;
@ -112,6 +119,7 @@ struct zserv_header
struct zapi_ipv4
{
u_char type;
u_short instance;
u_char flags;
@ -134,7 +142,7 @@ struct zapi_ipv4
/* Prototypes of zebra client service functions. */
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 void zclient_stop (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 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. */
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. */
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. */
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
{
u_char type;
u_short instance;
u_char flags;

View File

@ -313,7 +313,7 @@ main (int argc, char *argv[], char *envp[])
master = thread_master_create ();
/* Initializations. */
zlog_default = openzlog (progname, ZLOG_OSPF6,
zlog_default = openzlog (progname, ZLOG_OSPF6, 0,
LOG_CONS|LOG_NDELAY|LOG_PID,
LOG_DAEMON);
zprivs_init (&ospf6d_privs);

View File

@ -70,21 +70,21 @@ ospf6_router_id_update_zebra (int command, struct zclient *zclient,
void
ospf6_zebra_redistribute (int type)
{
if (zclient->redist[type])
if (zclient->redist[type].enabled)
return;
zclient->redist[type] = 1;
redist_add_instance(&zclient->redist[type], 0);
if (zclient->sock > 0)
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type, 0);
}
void
ospf6_zebra_no_redistribute (int type)
{
if (! zclient->redist[type])
if (! zclient->redist[type].enabled)
return;
zclient->redist[type] = 0;
redist_del_instance(&zclient->redist[type], 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. */
@ -215,6 +215,7 @@ ospf6_zebra_read_ipv6 (int command, struct zclient *zclient,
/* Type, flags, message. */
api.type = stream_getc (s);
api.instance = stream_getw (s);
api.flags = stream_getc (s);
api.message = stream_getc (s);
@ -296,7 +297,7 @@ DEFUN (show_zebra,
vty_out (vty, " redistribute:");
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", VNL);
@ -336,7 +337,7 @@ config_write_ospf6_zebra (struct vty *vty)
vty_out (vty, "no router zebra%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, " 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);
api.type = ZEBRA_ROUTE_OSPF6;
api.instance = 0;
api.flags = 0;
api.message = 0;
api.safi = SAFI_UNICAST;
@ -470,7 +472,7 @@ ospf6_zebra_route_update (int type, struct ospf6_route *request)
void
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_remove = NULL;
@ -482,7 +484,7 @@ ospf6_zebra_route_update_add (struct ospf6_route *request)
void
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_remove = NULL;
@ -498,12 +500,13 @@ ospf6_zebra_add_discard (struct ospf6_route *request)
char buf[INET6_ADDRSTRLEN];
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))
{
api.type = ZEBRA_ROUTE_OSPF6;
api.flags = ZEBRA_FLAG_BLACKHOLE;
api.instance = 0;
api.message = 0;
api.safi = SAFI_UNICAST;
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
@ -541,13 +544,14 @@ ospf6_zebra_delete_discard (struct ospf6_route *request)
char buf[INET6_ADDRSTRLEN];
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))
{
api.type = ZEBRA_ROUTE_OSPF6;
api.flags = ZEBRA_FLAG_BLACKHOLE;
api.instance = 0;
api.message = 0;
api.safi = SAFI_UNICAST;
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
@ -583,10 +587,10 @@ DEFUN (redistribute_ospf6,
{
struct ospf6_route *route;
if (zclient->redist[ZEBRA_ROUTE_OSPF6])
if (zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
return CMD_SUCCESS;
zclient->redist[ZEBRA_ROUTE_OSPF6] = 1;
redist_add_instance(&zclient->redist[ZEBRA_ROUTE_OSPF6], 0);
if (ospf6 == NULL)
return CMD_SUCCESS;
@ -611,10 +615,10 @@ DEFUN (no_redistribute_ospf6,
{
struct ospf6_route *route;
if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
if (! zclient->redist[ZEBRA_ROUTE_OSPF6].enabled)
return CMD_SUCCESS;
zclient->redist[ZEBRA_ROUTE_OSPF6] = 0;
redist_del_instance(&zclient->redist[ZEBRA_ROUTE_OSPF6], 0);
if (ospf6 == NULL)
return CMD_SUCCESS;
@ -635,7 +639,7 @@ ospf6_zebra_init (void)
{
/* Allocate zebra structure. */
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->interface_add = ospf6_zebra_if_add;
zclient->interface_delete = ospf6_zebra_if_del;

View File

@ -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_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_add_discard (struct ospf6_route *request);
extern void ospf6_zebra_delete_discard (struct ospf6_route *request);

View File

@ -99,13 +99,14 @@ ospf_external_route_lookup (struct ospf *ospf,
/* Add an External info for AS-external-LSA. */
struct external_info *
ospf_external_info_new (u_char type)
ospf_external_info_new (u_char type, u_short instance)
{
struct external_info *new;
new = (struct external_info *)
XCALLOC (MTYPE_OSPF_EXTERNAL_INFO, sizeof (struct external_info));
new->type = type;
new->instance = instance;
ospf_reset_route_map_set_values (&new->route_map_set);
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. */
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,
u_short tag)
{
struct external_info *new;
struct route_node *rn;
struct ospf_external *ext;
/* Initialize route table. */
if (EXTERNAL_INFO (type) == NULL)
EXTERNAL_INFO (type) = route_table_init ();
ext = ospf_external_lookup(type, instance);
if (!ext)
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 (rn)
if (rn->info)
{
route_unlock_node (rn);
zlog_warn ("Redistribute[%s]: %s/%d already exists, discard.",
ospf_redist_string(type),
zlog_warn ("Redistribute[%s][%d]: %s/%d already exists, discard.",
ospf_redist_string(type), instance,
inet_ntoa (p.prefix), p.prefixlen);
/* XFREE (MTYPE_OSPF_TMP, rn->info); */
return rn->info;
}
/* Create new External info instance. */
new = ospf_external_info_new (type);
new = ospf_external_info_new (type, instance);
new->p = p;
new->ifindex = ifindex;
new->nexthop = nexthop;
@ -176,11 +178,16 @@ ospf_external_info_add (u_char type, struct prefix_ipv4 p,
}
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 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)
{
ospf_external_info_free (rn->info);
@ -191,10 +198,16 @@ ospf_external_info_delete (u_char type, struct prefix_ipv4 p)
}
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;
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)
{
route_unlock_node (rn);
@ -271,14 +284,19 @@ ospf_asbr_status_update (struct ospf *ospf, u_char status)
}
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 external_info *ei;
struct ospf_external *ext;
ext = ospf_external_lookup(type, instance);
if (!ext)
return;
/* Delete external info for specified type. */
if (EXTERNAL_INFO (type))
for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
if (EXTERNAL_INFO (ext))
for (rn = route_top (EXTERNAL_INFO (ext)); rn; rn = route_next (rn))
if ((ei = rn->info))
if (ospf_external_info_find_lsa (ospf, &ei->p))
{

View File

@ -35,6 +35,8 @@ struct external_info
/* Type of source protocol. */
u_char type;
u_short instance;
/* Prefix. */
struct prefix_ipv4 p;
@ -55,23 +57,23 @@ struct external_info
#define OSPF_ASBR_CHECK_DELAY 30
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 int ospf_route_map_set_compare (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,
unsigned int,
struct in_addr,
u_short);
extern void ospf_external_info_delete (u_char, struct prefix_ipv4);
extern struct external_info *ospf_external_info_lookup (u_char,
extern void ospf_external_info_delete (u_char, u_short, struct prefix_ipv4);
extern struct external_info *ospf_external_info_lookup (u_char, u_short,
struct prefix_ipv4 *);
extern struct ospf_route *ospf_external_route_lookup (struct ospf *,
struct prefix_ipv4 *);
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_schedule_asbr_check (void);
extern void ospf_asbr_route_install_lsa (struct ospf_lsa *);

File diff suppressed because it is too large Load Diff

View File

@ -92,19 +92,33 @@ ospf_external_info_check (struct ospf_lsa *lsa)
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
{
int redist_type = is_prefix_default (&p) ? DEFAULT_ROUTE : type;
if (ospf_is_type_redistributed (redist_type))
if (EXTERNAL_INFO (type))
{
rn = route_node_lookup (EXTERNAL_INFO (type),
(struct prefix *) &p);
if (rn)
{
route_unlock_node (rn);
if (rn->info != NULL)
return (struct external_info *) rn->info;
}
}
int redist_on = 0;
redist_on = is_prefix_default (&p) ? zclient->default_information :
zclient->redist[type].enabled;
if (redist_on)
{
struct list *ext_list;
struct listnode *node;
struct ospf_external *ext;
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;

View File

@ -1590,16 +1590,23 @@ ospf_get_nssa_ip (struct ospf_area *area)
#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
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 ?
DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
struct ospf_redist *red;
red = ospf_redist_lookup(ospf, src, instance);
return ((!red || red->dmetric.type < 0) ?
DEFAULT_METRIC_TYPE : red->dmetric.type);
}
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)
{
@ -1614,7 +1621,7 @@ metric_value (struct ospf *ospf, u_char src)
return ospf->default_metric;
}
return ospf->dmetric[src].value;
return red->dmetric.value;
}
/* 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;
int mtype;
int type;
u_short instance;
/* Put Network 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. */
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) ?
ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type, instance);
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. */
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 route_table *rt;
int type = THREAD_VAL (thread);
struct list *ext_list;
struct listnode *node;
struct ospf_external *ext;
ospf->t_external_lsa = NULL;
/* Originate As-external-LSA from all type of distribute source. */
if ((rt = EXTERNAL_INFO (type)))
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.");
ext_list = om->external[type];
if (!ext_list)
return 0;
for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
/* Originate As-external-LSA from all type of distribute source. */
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;
}
@ -2133,17 +2150,30 @@ ospf_default_external_info (struct ospf *ospf)
/* First, lookup redistributed default route. */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
{
rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
if (rn != NULL)
{
route_unlock_node (rn);
assert (rn->info);
if (ospf_redistribute_check (ospf, rn->info, NULL))
return rn->info;
}
}
{
struct list *ext_list;
struct listnode *node;
struct ospf_external *ext;
if (type == ZEBRA_ROUTE_OSPF)
continue;
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;
}
@ -2167,7 +2197,7 @@ ospf_default_originate_timer (struct thread *thread)
/* If there is no default route via redistribute,
then originate AS-external-LSA with nexthop 0 (self). */
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)))
@ -2298,15 +2328,18 @@ ospf_external_lsa_refresh_default (struct ospf *ospf)
}
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 external_info *ei;
struct ospf_external *ext;
if (type != DEFAULT_ROUTE)
if (EXTERNAL_INFO(type))
if ((ext = ospf_external_lookup(type, instance)) &&
EXTERNAL_INFO (ext))
/* 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 (!is_prefix_default (&ei->p))
{

View File

@ -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_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 *,
struct ospf_lsa *,
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 int is_prefix_default (struct prefix_ipv4 *);
extern int metric_type (struct ospf *, u_char);
extern int metric_value (struct ospf *, u_char);
extern int metric_type (struct ospf *, u_char, u_short);
extern int metric_value (struct ospf *, u_char, u_short);
extern struct in_addr ospf_get_nssa_ip (struct ospf_area *);
extern int ospf_translated_nssa_compare (struct ospf_lsa *, struct ospf_lsa *);

View File

@ -73,12 +73,13 @@ struct zebra_privs_t ospfd_privs =
};
/* Configuration filename and directory. */
char config_default[] = SYSCONFDIR OSPF_DEFAULT_CONFIG;
char config_default[100];
/* OSPFd options. */
struct option longopts[] =
{
{ "daemon", no_argument, NULL, 'd'},
{ "instance", required_argument, NULL, 'n'},
{ "config_file", required_argument, NULL, 'f'},
{ "pid_file", required_argument, NULL, 'i'},
{ "socket", required_argument, NULL, 'z'},
@ -99,7 +100,7 @@ struct option longopts[] =
struct thread_master *master;
/* Process ID saved for use by init system */
const char *pid_file = PATH_OSPFD_PID;
char pid_file[100];
#ifdef SUPPORT_OSPF_API
extern int ospf_apiserver_enable;
@ -116,6 +117,7 @@ usage (char *progname, int status)
printf ("Usage : %s [OPTION...]\n\
Daemon which manages OSPF.\n\n\
-d, --daemon Runs in daemon mode\n\
-n, --instance Set the instance id\n\
-f, --config_file Set configuration file name\n\
-i, --pid_file Set process identifier file name\n\
-z, --socket Set path of zebra socket\n\
@ -182,9 +184,11 @@ main (int argc, char **argv)
char *p;
char *vty_addr = NULL;
int vty_port = OSPF_VTY_PORT;
char vty_path[100];
int daemon_mode = 0;
char *config_file = NULL;
char *progname;
u_short instance = 0;
struct thread thread;
int dryrun = 0;
@ -203,13 +207,18 @@ main (int argc, char **argv)
{
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)
break;
switch (opt)
{
case 'n':
instance = atoi(optarg);
if (instance < 1 || instance > 65535)
exit(0);
break;
case 0:
break;
case 'd':
@ -222,7 +231,7 @@ main (int argc, char **argv)
vty_addr = optarg;
break;
case 'i':
pid_file = optarg;
strcpy(pid_file,optarg);
break;
case 'z':
zclient_serv_path_set (optarg);
@ -274,7 +283,7 @@ main (int argc, char **argv)
exit (1);
}
zlog_default = openzlog (progname, ZLOG_OSPF,
zlog_default = openzlog (progname, ZLOG_OSPF, instance,
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
/* OSPF master init. */
@ -296,7 +305,7 @@ main (int argc, char **argv)
/* OSPFd inits. */
ospf_if_init ();
ospf_zebra_init ();
ospf_zebra_init (instance);
/* OSPF vty inits. */
ospf_vty_init ();
@ -314,13 +323,17 @@ main (int argc, char **argv)
/* Need to initialize the default ospf structure, so the interface mode
commands can be duly processed if they are received before 'router ospf',
when quagga(ospfd) is restarted */
if (!ospf_get())
if (!ospf_get_instance(instance))
{
zlog_err("OSPF instance init failed: %s", strerror(errno));
exit (1);
}
/* 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);
/* Start execution only if not in dry-run mode */
@ -334,14 +347,23 @@ main (int argc, char **argv)
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. */
pid_output (pid_file);
/* Create VTY socket */
vty_serv_sock (vty_addr, vty_port, OSPF_VTYSH_PATH);
vty_serv_sock (vty_addr, vty_port, vty_path);
/* 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. */
while (thread_fetch (master, &thread))

View File

@ -719,9 +719,19 @@ nsm_change_state (struct ospf_neighbor *nbr, int state)
/* kevinm: refresh any redistributions */
for (x = ZEBRA_ROUTE_SYSTEM; x < ZEBRA_ROUTE_MAX; x++)
{
if (x == ZEBRA_ROUTE_OSPF || x == ZEBRA_ROUTE_OSPF6)
continue;
ospf_external_lsa_refresh_type (oi->ospf, x, force);
struct list *red_list;
struct listnode *node;
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
* this added to hack around defaults not refreshing after a timer

View File

@ -767,6 +767,9 @@ DEFUN (capability_opaque,
{
struct ospf *ospf = (struct ospf *) vty->index;
if (!ospf)
return CMD_SUCCESS;
/* Turn on the "master switch" of opaque-lsa capability. */
if (!CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
{
@ -794,6 +797,9 @@ DEFUN (no_capability_opaque,
{
struct ospf *ospf = (struct ospf *) vty->index;
if (!ospf)
return CMD_SUCCESS;
/* Turn off the "master switch" of opaque-lsa capability. */
if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
{

View File

@ -2889,7 +2889,7 @@ ospf_read (struct thread *thread)
{
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"
" but no ospf_interface",
inet_ntoa (iph->ip_src), ifp->name);

View File

@ -45,6 +45,7 @@ ospf_route_map_update (const char *name)
{
struct ospf *ospf;
int type;
u_short instance; // PENDING
/* If OSPF instatnce does not exist, return right now. */
ospf = ospf_lookup ();
@ -54,22 +55,33 @@ ospf_route_map_update (const char *name)
/* Update route-map */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
{
if (ROUTEMAP_NAME (ospf, type)
&& strcmp (ROUTEMAP_NAME (ospf, type), name) == 0)
{
/* Keep old route-map. */
struct route_map *old = ROUTEMAP (ospf, type);
struct list *red_list;
struct listnode *node;
struct ospf_redist *red;
/* Update route-map. */
ROUTEMAP (ospf, type) =
route_map_lookup_by_name (ROUTEMAP_NAME (ospf, type));
red_list = ospf->redist[type];
if (!red_list)
continue;
/* No update for this distribute type. */
if (old == NULL && ROUTEMAP (ospf, type) == NULL)
continue;
for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
{
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)
return;
/* Update route-map. */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
{
if (ROUTEMAP_NAME (ospf, type) && ROUTEMAP (ospf, type)
&& !strcmp (ROUTEMAP_NAME (ospf, type), name))
struct list *red_list;
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);
}
}
}
}

View File

@ -1473,6 +1473,10 @@ DEFUN (mpls_te,
{
struct listnode *node, *nnode;
struct mpls_te_link *lp;
struct ospf *ospf = vty->index;
if (!ospf)
return CMD_SUCCESS;
if (OspfMplsTE.status == enabled)
return CMD_SUCCESS;
@ -1511,6 +1515,10 @@ DEFUN (no_mpls_te,
{
struct listnode *node, *nnode;
struct mpls_te_link *lp;
struct ospf *ospf = vty->index;
if (!ospf)
return CMD_SUCCESS;
if (OspfMplsTE.status == disabled)
return CMD_SUCCESS;
@ -1537,6 +1545,10 @@ DEFUN (mpls_te_router_addr,
{
struct te_tlv_router_addr *ra = &OspfMplsTE.router_addr;
struct in_addr value;
struct ospf *ospf = vty->index;
if (!ospf)
return CMD_SUCCESS;
if (! inet_aton (argv[0], &value))
{

File diff suppressed because it is too large Load Diff

View File

@ -386,8 +386,9 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
#ifdef HAVE_NETLINK
int ol_cnt = 0, not_ol_cnt = 0;
#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;
flags = 0;
@ -414,6 +415,7 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
/* Put command, type, flags, message. */
zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD);
stream_putc (s, ZEBRA_ROUTE_OSPF);
stream_putw (s, ospf->instance);
stream_putc (s, flags);
stream_putc (s, message);
stream_putw (s, SAFI_UNICAST);
@ -529,8 +531,9 @@ ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
struct stream *s;
struct ospf_path *path;
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;
flags = 0;
@ -543,6 +546,7 @@ ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
/* Put command, type, flags, message. */
zclient_create_header (s, ZEBRA_IPV4_ROUTE_DELETE);
stream_putc (s, ZEBRA_ROUTE_OSPF);
stream_putw (s, ospf->instance);
stream_putc (s, flags);
stream_putc (s, message);
stream_putw (s, SAFI_UNICAST);
@ -610,10 +614,12 @@ void
ospf_zebra_add_discard (struct prefix_ipv4 *p)
{
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.instance = ospf->instance;
api.flags = ZEBRA_FLAG_BLACKHOLE;
api.message = 0;
api.safi = SAFI_UNICAST;
@ -634,10 +640,12 @@ void
ospf_zebra_delete_discard (struct prefix_ipv4 *p)
{
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.instance = ospf->instance;
api.flags = ZEBRA_FLAG_BLACKHOLE;
api.message = 0;
api.safi = SAFI_UNICAST;
@ -655,50 +663,180 @@ ospf_zebra_delete_discard (struct prefix_ipv4 *p)
}
}
int
ospf_is_type_redistributed (int type)
struct ospf_external *
ospf_external_lookup (u_char type, u_short instance)
{
return (DEFAULT_ROUTE_TYPE (type)) ?
zclient->default_information : zclient->redist[type];
struct list *ext_list;
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
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;
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;
}
if (mvalue != ospf->dmetric[type].value)
if (mvalue != red->dmetric.value)
{
ospf->dmetric[type].value = mvalue;
red->dmetric.value = mvalue;
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))
zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
ospf_redist_string(type),
metric_type (ospf, type), metric_value (ospf, type));
zlog_debug ("Redistribute[%s][%d]: Refresh Type[%d], Metric[%d]",
ospf_redist_string(type), instance,
metric_type (ospf, type, instance),
metric_value (ospf, type, instance));
return CMD_SUCCESS;
}
ospf->dmetric[type].type = mtype;
ospf->dmetric[type].value = mvalue;
red->dmetric.type = mtype;
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))
zlog_debug ("Redistribute[%s]: Start Type[%d], Metric[%d]",
ospf_redist_string(type),
metric_type (ospf, type), metric_value (ospf, type));
zlog_debug ("Redistribute[%s][%d]: Start Type[%d], Metric[%d]",
ospf_redist_string(type), instance,
metric_type (ospf, type, instance), metric_value (ospf, type, instance));
ospf_asbr_status_update (ospf, ++ospf->redistribute);
@ -706,25 +844,26 @@ ospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue)
}
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;
if (!ospf_is_type_redistributed (type))
if (!ospf_is_type_redistributed (type, instance))
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))
zlog_debug ("Redistribute[%s]: Stop",
ospf_redist_string(type));
zlog_debug ("Redistribute[%s][%d]: Stop",
ospf_redist_string(type), instance);
ospf->dmetric[type].type = -1;
ospf->dmetric[type].value = -1;
ospf_redist_del (ospf, type, instance);
/* 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);
@ -735,11 +874,17 @@ int
ospf_redistribute_default_set (struct ospf *ospf, int originate,
int mtype, int mvalue)
{
ospf->default_originate = originate;
ospf->dmetric[DEFAULT_ROUTE].type = mtype;
ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
struct ospf_redist *red;
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
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))
zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
ospf_redist_string(DEFAULT_ROUTE),
metric_type (ospf, DEFAULT_ROUTE),
metric_value (ospf, DEFAULT_ROUTE));
metric_type (ospf, DEFAULT_ROUTE, 0),
metric_value (ospf, DEFAULT_ROUTE, 0));
return CMD_SUCCESS;
}
@ -758,8 +903,8 @@ ospf_redistribute_default_set (struct ospf *ospf, int originate,
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
zlog_debug ("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]",
metric_type (ospf, DEFAULT_ROUTE),
metric_value (ospf, DEFAULT_ROUTE));
metric_type (ospf, DEFAULT_ROUTE, 0),
metric_value (ospf, DEFAULT_ROUTE, 0));
if (ospf->router_id.s_addr == 0)
ospf->external_origin |= (1 << DEFAULT_ROUTE);
@ -774,18 +919,19 @@ ospf_redistribute_default_set (struct ospf *ospf, int originate,
int
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;
ospf->default_originate = DEFAULT_ORIGINATE_NONE;
ospf->dmetric[DEFAULT_ROUTE].type = -1;
ospf->dmetric[DEFAULT_ROUTE].value = -1;
ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient);
if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
zlog_debug ("Redistribute[DEFAULT]: Stop");
//Pending: how does the external_info cleanup work in this case?
ospf_asbr_status_update (ospf, --ospf->redistribute);
return CMD_SUCCESS;
@ -836,7 +982,9 @@ ospf_redistribute_check (struct ospf *ospf,
{
struct route_map_set_values save_values;
struct prefix_ipv4 *p = &ei->p;
struct ospf_redist *red;
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)
*changed = 0;
@ -865,11 +1013,12 @@ ospf_redistribute_check (struct ospf *ospf,
ospf_reset_route_map_set_values (&ei->route_map_set);
/* apply route-map if needed */
if (ROUTEMAP_NAME (ospf, type))
red = ospf_redist_lookup (ospf, type, instance);
if (red && ROUTEMAP_NAME(red))
{
int ret;
ret = route_map_apply (ROUTEMAP (ospf, type), (struct prefix *) p,
ret = route_map_apply (ROUTEMAP (red), (struct prefix *) p,
RMAP_OSPF, ei);
if (ret == RMAP_DENYMATCH)
@ -893,23 +1042,23 @@ ospf_redistribute_check (struct ospf *ospf,
/* OSPF route-map set for redistribution */
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))
free (ROUTEMAP_NAME (ospf, type));
if (ROUTEMAP_NAME (red))
free (ROUTEMAP_NAME (red));
ROUTEMAP_NAME (ospf, type) = strdup (name);
ROUTEMAP (ospf, type) = route_map_lookup_by_name (name);
ROUTEMAP_NAME (red) = strdup (name);
ROUTEMAP (red) = route_map_lookup_by_name (name);
}
void
ospf_routemap_unset (struct ospf *ospf, int type)
ospf_routemap_unset (struct ospf_redist *red)
{
if (ROUTEMAP_NAME (ospf, type))
free (ROUTEMAP_NAME (ospf, type));
if (ROUTEMAP_NAME (red))
free (ROUTEMAP_NAME (red));
ROUTEMAP_NAME (ospf, type) = NULL;
ROUTEMAP (ospf, type) = NULL;
ROUTEMAP_NAME (red) = NULL;
ROUTEMAP (red) = NULL;
}
/* Zebra route add and delete treatment. */
@ -931,6 +1080,7 @@ ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
/* Type, flags, message. */
api.type = stream_getc (s);
api.instance = stream_getw (s);
api.flags = 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)
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)
/* 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) */
{
ospf_external_info_delete (api.type, p);
ospf_external_info_delete (api.type, api.instance, p);
if (is_prefix_default (&p))
ospf_external_lsa_refresh_default (ospf);
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 (DISTRIBUTE_LIST (ospf, type))
ospf_distribute_list_update (ospf, type);
ospf_distribute_list_update (ospf, type, 0);
return CMD_SUCCESS;
}
@ -1052,7 +1203,7 @@ ospf_distribute_list_out_unset (struct ospf *ospf, int type, const char *name)
{
/* Schedule update timer. */
if (DISTRIBUTE_LIST (ospf, type))
ospf_distribute_list_update (ospf, type);
ospf_distribute_list_update (ospf, type, 0);
/* Unset distribute-list. */
DISTRIBUTE_LIST (ospf, type) = NULL;
@ -1088,19 +1239,30 @@ ospf_distribute_list_update_timer (struct thread *thread)
/* foreach all external info. */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
{
rt = EXTERNAL_INFO (type);
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);
}
struct list *ext_list;
struct listnode *node;
struct ospf_external *ext;
ext_list = om->external[type];
if (!ext_list)
continue;
for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
{
rt = ext->external_info;
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)
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. */
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 ospf_external *ext;
/* External info does not exist. */
if (!(rt = EXTERNAL_INFO (type)))
ext = ospf_external_lookup(type, instance);
if (!ext || !(rt = EXTERNAL_INFO (ext)))
return;
/* 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 listnode *node;
/* If OSPF instatnce does not exist, return right now. */
/* If OSPF instance does not exist, return right now. */
ospf = ospf_lookup ();
if (ospf == NULL)
return;
@ -1147,12 +1312,20 @@ ospf_filter_update (struct access_list *access)
/* Update distribute-list, and apply filter. */
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
{
if (ROUTEMAP (ospf, type) != NULL)
{
/* if route-map is not NULL it may be using this access list */
ospf_distribute_list_update (ospf, type);
continue;
}
struct list *red_list;
struct listnode *node;
struct ospf_redist *red;
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),
* but no distribute list. */
@ -1175,7 +1348,7 @@ ospf_filter_update (struct access_list *access)
/* Schedule distribute-list update timer. */
if (DISTRIBUTE_LIST (ospf, type) == NULL ||
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++)
{
if (ROUTEMAP (ospf, type) != NULL)
{
/* If route-map is not NULL it may be using this prefix list */
ospf_distribute_list_update (ospf, type);
continue;
}
struct list *red_list;
struct listnode *node;
struct ospf_redist *red;
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. */
@ -1400,11 +1581,11 @@ ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
}
void
ospf_zebra_init ()
ospf_zebra_init (u_short instance)
{
/* Allocate zebra structure. */
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->interface_add = ospf_interface_add;
zclient->interface_delete = ospf_interface_delete;

View File

@ -54,25 +54,32 @@ extern int ospf_redistribute_check (struct ospf *, struct external_info *,
int *);
extern int ospf_distribute_check_connected (struct ospf *,
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 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_unset (struct ospf *);
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 void ospf_routemap_set (struct ospf *, int, const char *);
extern void ospf_routemap_unset (struct ospf *, int);
extern void ospf_routemap_set (struct ospf_redist *, const char *);
extern void ospf_routemap_unset (struct ospf_redist *);
extern int ospf_distance_set (struct vty *, struct ospf *, const char *,
const char *, const char *);
extern int ospf_distance_unset (struct vty *, struct ospf *, const char *,
const char *, const char *);
extern void ospf_zebra_init (void);
extern void ospf_zebra_init (u_short);
#endif /* _ZEBRA_OSPF_ZEBRA_H */

View File

@ -153,12 +153,13 @@ ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
/* Allocate new ospf structure. */
static struct ospf *
ospf_new (void)
ospf_new (u_short instance)
{
int i;
struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
new->instance = instance;
new->router_id.s_addr = htonl (0);
new->router_id_static.s_addr = htonl (0);
@ -187,8 +188,6 @@ ospf_new (void)
/* Distribute parameter init. */
for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
{
new->dmetric[i].type = -1;
new->dmetric[i].value = -1;
new->dtag[i] = 0;
}
new->default_metric = -1;
@ -248,6 +247,23 @@ ospf_lookup ()
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
ospf_add (struct ospf *ospf)
{
@ -268,7 +284,29 @@ ospf_get ()
ospf = ospf_lookup ();
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);
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 listnode *node, *nnode;
int i;
u_short instance;
#ifdef HAVE_OPAQUE_LSA
ospf_opaque_type11_lsa_term (ospf);
@ -419,7 +458,17 @@ ospf_finish_final (struct ospf *ospf)
/* Unregister redistribution */
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);
for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
@ -557,23 +606,43 @@ ospf_finish_final (struct ospf *ospf)
list_delete (ospf->areas);
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))
{
if (rn->info == NULL)
continue;
XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
rn->info = NULL;
route_unlock_node (rn);
}
{
struct list *ext_list;
struct listnode *node;
struct ospf_external *ext;
ext_list = om->external[i];
if (!ext_list)
continue;
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);
route_table_finish (ospf->distance_table);
if (!CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
instance = ospf->instance;
ospf_delete (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 external_info *ei;
struct ospf_external *ext;
if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT, 0))
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))
{
if ((ei = rn->info) != NULL)

View File

@ -76,6 +76,12 @@
#define OSPF_LS_REFRESH_SHIFT (60 * 15)
#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. */
struct ospf_master
{
@ -89,8 +95,8 @@ struct ospf_master
struct list *iflist;
/* Redistributed external information. */
struct route_table *external_info[ZEBRA_ROUTE_MAX + 1];
#define EXTERNAL_INFO(T) om->external_info[T]
struct list *external[ZEBRA_ROUTE_MAX + 1];
#define EXTERNAL_INFO(E) (E->external_info)
/* OSPF start time. */
time_t start_time;
@ -100,9 +106,34 @@ struct ospf_master
#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. */
struct ospf
{
/* OSPF instance ID */
u_short instance;
/* OSPF Router ID. */
struct in_addr router_id; /* Configured automatically. */
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_LIST(O,T) (O)->dlist[T].list
/* 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 [ZEBRA_ROUTE_MAX + 1];
/* OSPF redistribute configuration */
struct list *redist[ZEBRA_ROUTE_MAX + 1];
/* 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. */
#define OSPF_LSA_REFRESHER_GRANULARITY 10
@ -514,7 +531,9 @@ extern int ospf_zlog;
/* Prototypes. */
extern const char *ospf_redist_string(u_int route_type);
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_instance (u_short);
extern void ospf_finish (struct ospf *);
extern void ospf_router_id_update (struct ospf *ospf);
extern int ospf_network_set (struct ospf *, struct prefix_ipv4 *,

View File

@ -201,7 +201,7 @@ main (int argc, char **argv)
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
/* 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);
/* Command line option parse. */

View File

@ -41,9 +41,10 @@ rip_zebra_ipv4_add (struct prefix_ipv4 *p, struct in_addr *nexthop,
{
struct zapi_ipv4 api;
if (zclient->redist[ZEBRA_ROUTE_RIP])
if (zclient->redist[ZEBRA_ROUTE_RIP].enabled)
{
api.type = ZEBRA_ROUTE_RIP;
api.instance = 0;
api.flags = 0;
api.message = 0;
api.safi = SAFI_UNICAST;
@ -72,9 +73,10 @@ rip_zebra_ipv4_delete (struct prefix_ipv4 *p, struct in_addr *nexthop,
{
struct zapi_ipv4 api;
if (zclient->redist[ZEBRA_ROUTE_RIP])
if (zclient->redist[ZEBRA_ROUTE_RIP].enabled)
{
api.type = ZEBRA_ROUTE_RIP;
api.instance = 0;
api.flags = 0;
api.message = 0;
api.safi = SAFI_UNICAST;
@ -107,6 +109,7 @@ rip_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
/* Type, flags, message. */
api.type = stream_getc (s);
api.instance = stream_getw (s);
api.flags = stream_getc (s);
api.message = stream_getc (s);
@ -255,13 +258,13 @@ rip_redistribute_set (int type)
static int
rip_redistribute_unset (int type)
{
if (! zclient->redist[type])
if (! zclient->redist[type].enabled)
return CMD_SUCCESS;
zclient->redist[type] = 0;
redist_del_instance(&zclient->redist[type], 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. */
rip_redistribute_withdraw (type);
@ -272,7 +275,7 @@ rip_redistribute_unset (int type)
int
rip_redistribute_check (int type)
{
return (zclient->redist[type]);
return (zclient->redist[type].enabled);
}
void
@ -282,13 +285,13 @@ rip_redistribute_clean (void)
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)
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. */
rip_redistribute_withdraw (redist_type[i].type);
@ -302,7 +305,7 @@ DEFUN (rip_redistribute_rip,
"Redistribute information from another routing protocol\n"
"Routing Information Protocol (RIP)\n")
{
zclient->redist[ZEBRA_ROUTE_RIP] = 1;
redist_add_instance(&zclient->redist[ZEBRA_ROUTE_RIP], 0);
return CMD_SUCCESS;
}
@ -313,7 +316,7 @@ DEFUN (no_rip_redistribute_rip,
"Redistribute information from another routing protocol\n"
"Routing Information Protocol (RIP)\n")
{
zclient->redist[ZEBRA_ROUTE_RIP] = 0;
redist_del_instance(&zclient->redist[ZEBRA_ROUTE_RIP], 0);
return CMD_SUCCESS;
}
@ -331,7 +334,7 @@ DEFUN (rip_redistribute_type,
redist_type[i].str_min_len) == 0)
{
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient,
redist_type[i].type);
redist_type[i].type, 0);
return CMD_SUCCESS;
}
}
@ -384,7 +387,7 @@ DEFUN (rip_redistribute_type_routemap,
redist_type[i].str_min_len) == 0)
{
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;
}
}
@ -442,7 +445,7 @@ DEFUN (rip_redistribute_type_metric,
redist_type[i].str_min_len) == 0)
{
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;
}
}
@ -503,7 +506,7 @@ DEFUN (rip_redistribute_type_metric_routemap,
{
rip_redistribute_metric_set (redist_type[i].type, metric);
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;
}
}
@ -607,7 +610,7 @@ config_write_zebra (struct vty *vty)
vty_out (vty, "no router zebra%s", VTY_NEWLINE);
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, " no redistribute rip%s", VTY_NEWLINE);
@ -622,7 +625,8 @@ config_write_rip_redistribute (struct vty *vty, int config_mode)
int 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)
{
@ -667,7 +671,7 @@ rip_zclient_init ()
{
/* Set default value to the zebra client structure. */
zclient = zclient_new ();
zclient_init (zclient, ZEBRA_ROUTE_RIP);
zclient_init (zclient, ZEBRA_ROUTE_RIP, 0);
zclient->interface_add = rip_interface_add;
zclient->interface_delete = rip_interface_delete;
zclient->interface_address_add = rip_interface_address_add;

View File

@ -200,7 +200,7 @@ main (int argc, char **argv)
/* get program name */
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);
while (1)

View File

@ -48,9 +48,10 @@ ripng_zebra_ipv6_add (struct prefix_ipv6 *p, struct in6_addr *nexthop,
{
struct zapi_ipv6 api;
if (zclient->redist[ZEBRA_ROUTE_RIPNG])
if (zclient->redist[ZEBRA_ROUTE_RIPNG].enabled)
{
api.type = ZEBRA_ROUTE_RIPNG;
api.instance = 0;
api.flags = 0;
api.message = 0;
api.safi = SAFI_UNICAST;
@ -73,9 +74,10 @@ ripng_zebra_ipv6_delete (struct prefix_ipv6 *p, struct in6_addr *nexthop,
{
struct zapi_ipv6 api;
if (zclient->redist[ZEBRA_ROUTE_RIPNG])
if (zclient->redist[ZEBRA_ROUTE_RIPNG].enabled)
{
api.type = ZEBRA_ROUTE_RIPNG;
api.instance = 0;
api.flags = 0;
api.message = 0;
api.safi = SAFI_UNICAST;
@ -107,6 +109,7 @@ ripng_zebra_read_ipv6 (int command, struct zclient *zclient,
/* Type, flags, message. */
api.type = stream_getc (s);
api.instance = stream_getw (s);
api.flags = stream_getc (s);
api.message = stream_getc (s);
@ -153,13 +156,13 @@ ripng_zclient_reset (void)
static int
ripng_redistribute_unset (int type)
{
if (! zclient->redist[type])
if (! zclient->redist[type].enabled)
return CMD_SUCCESS;
zclient->redist[type] = 0;
redist_del_instance(&zclient->redist[type], 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);
@ -169,7 +172,7 @@ ripng_redistribute_unset (int type)
int
ripng_redistribute_check (int type)
{
return (zclient->redist[type]);
return (zclient->redist[type].enabled);
}
static void
@ -229,13 +232,13 @@ ripng_redistribute_clean ()
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)
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. */
ripng_redistribute_withdraw (redist_type[i].type);
@ -273,7 +276,7 @@ DEFUN (ripng_redistribute_ripng,
"Redistribute information from another routing protocol\n"
"RIPng route\n")
{
zclient->redist[ZEBRA_ROUTE_RIPNG] = 1;
redist_add_instance(&zclient->redist[ZEBRA_ROUTE_RIPNG], 0);
return CMD_SUCCESS;
}
@ -284,7 +287,7 @@ DEFUN (no_ripng_redistribute_ripng,
"Redistribute information from another routing protocol\n"
"RIPng route\n")
{
zclient->redist[ZEBRA_ROUTE_RIPNG] = 0;
redist_del_instance(&zclient->redist[ZEBRA_ROUTE_RIPNG], 0);
return CMD_SUCCESS;
}
@ -304,7 +307,7 @@ DEFUN (ripng_redistribute_type,
return CMD_WARNING;
}
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type, 0);
return CMD_SUCCESS;
}
@ -352,7 +355,7 @@ DEFUN (ripng_redistribute_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;
}
@ -384,7 +387,7 @@ DEFUN (ripng_redistribute_type_routemap,
}
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;
}
@ -421,7 +424,7 @@ DEFUN (ripng_redistribute_type_metric_routemap,
ripng_redistribute_metric_set (type, metric);
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;
}
@ -440,7 +443,8 @@ ripng_redistribute_write (struct vty *vty, int config_mode)
int 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)
{
@ -480,7 +484,7 @@ zebra_config_write (struct vty *vty)
vty_out (vty, "no router zebra%s", VTY_NEWLINE);
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, " no redistribute ripng%s", VTY_NEWLINE);
@ -502,7 +506,7 @@ zebra_init ()
{
/* Allocate zebra structure. */
zclient = zclient_new ();
zclient_init (zclient, ZEBRA_ROUTE_RIPNG);
zclient_init (zclient, ZEBRA_ROUTE_RIPNG, 0);
zclient->interface_up = ripng_interface_up;
zclient->interface_down = ripng_interface_down;

View File

@ -46,7 +46,7 @@ main (void)
master = thread_master_create ();
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);
zlog_set_level (NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
zlog_set_level (NULL, ZLOG_DEST_STDOUT, LOG_DEBUG);

View File

@ -35,7 +35,7 @@ $ignore{'"ip vrf NAME"'} = "ignore";
$ignore{'"router rip"'} = "ignore";
$ignore{'"router ripng"'} = "ignore";
$ignore{'"router ospf"'} = "ignore";
$ignore{'"router ospf <0-65535>"'} = "ignore";
$ignore{'"router ospf <1-65535>"'} = "ignore";
$ignore{'"router ospf6"'} = "ignore";
$ignore{'"router babel"'} = "ignore";
$ignore{'"router bgp " "<1-4294967295>"'} = "ignore";

View File

@ -30,6 +30,10 @@
#include <readline/readline.h>
#include <readline/history.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include "command.h"
#include "memory.h"
#include "vtysh/vtysh.h"
@ -46,19 +50,22 @@ char *vtysh_pager_name = NULL;
struct vtysh_client
{
int fd;
const char *name;
char *name;
int flag;
const char *path;
} vtysh_client[] =
char *path;
struct vtysh_client *next;
};
struct vtysh_client vtysh_client[] =
{
{ .fd = -1, .name = "zebra", .flag = VTYSH_ZEBRA, .path = ZEBRA_VTYSH_PATH},
{ .fd = -1, .name = "ripd", .flag = VTYSH_RIPD, .path = RIP_VTYSH_PATH},
{ .fd = -1, .name = "ripngd", .flag = VTYSH_RIPNGD, .path = RIPNG_VTYSH_PATH},
{ .fd = -1, .name = "ospfd", .flag = VTYSH_OSPFD, .path = OSPF_VTYSH_PATH},
{ .fd = -1, .name = "ospf6d", .flag = VTYSH_OSPF6D, .path = OSPF6_VTYSH_PATH},
{ .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH},
{ .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH},
{ .fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .path = BABEL_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, .next = NULL},
{ .fd = -1, .name = "ripngd", .flag = VTYSH_RIPNGD, .path = RIPNG_VTYSH_PATH, .next = NULL},
{ .fd = -1, .name = "ospfd", .flag = VTYSH_OSPFD, .path = OSPF_VTYSH_PATH, .next = NULL},
{ .fd = -1, .name = "ospf6d", .flag = VTYSH_OSPF6D, .path = OSPF6_VTYSH_PATH, .next = NULL},
{ .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH, .next = NULL},
{ .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH, .next = NULL},
{ .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. */
#define ERR_WHERE_STRING "vtysh(): vtysh_client_config(): "
static int
vtysh_client_config (struct vtysh_client *vclient, char *line)
vtysh_client_config_one (struct vtysh_client *vclient, char *line)
{
int ret;
char *buf;
@ -186,7 +193,28 @@ vtysh_client_config (struct vtysh_client *vclient, char *line)
}
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;
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
vtysh_exit_ripd_only (void)
{
@ -1005,6 +1054,14 @@ DEFUNSH (VTYSH_OSPFD,
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,
router_ospf6,
router_ospf6_cmd,
@ -2177,6 +2234,114 @@ vtysh_connect (struct vtysh_client *vclient)
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
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. */
if (vtysh_client[i].flag == VTYSH_RIPD)
ripd_client = &vtysh_client[i];
}
rc += vtysh_connect_all_instances(&vtysh_client[i]);
}
}
if (!matches)
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);
#endif
install_element (CONFIG_NODE, &router_ospf_cmd);
install_element (CONFIG_NODE, &router_ospf_instance_cmd);
#ifdef HAVE_IPV6
install_element (CONFIG_NODE, &router_ospf6_cmd);
#endif

View File

@ -1336,7 +1336,7 @@ main(int argc, char **argv)
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);
zlog_set_level(NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
if (daemon_mode)

View File

@ -207,10 +207,10 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
if (prefix_ipv4_any (&p))
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);
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);
rib_update ();
@ -323,9 +323,9 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc)
return;
/* 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 ();
}
@ -410,7 +410,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
return;
#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);
rib_update ();
@ -496,7 +496,7 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
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 ();
}

View File

@ -934,16 +934,16 @@ rtm_read (struct rt_msghdr *rtm)
* to specify the route really
*/
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);
if (rtm->rtm_type == RTM_GET
|| rtm->rtm_type == RTM_ADD
|| 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);
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);
}
#ifdef HAVE_IPV6
@ -976,16 +976,16 @@ rtm_read (struct rt_msghdr *rtm)
* to specify the route really
*/
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);
if (rtm->rtm_type == RTM_GET
|| rtm->rtm_type == RTM_ADD
|| 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);
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);
}
#endif /* HAVE_IPV6 */

View File

@ -228,7 +228,7 @@ main (int argc, char **argv)
/* preserve my name */
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);
while (1)

View File

@ -142,7 +142,7 @@ zebra_redistribute_default (struct zserv *client)
/* Redistribute routes. */
static void
zebra_redistribute (struct zserv *client, int type)
zebra_redistribute (struct zserv *client, int type, u_short instance)
{
struct rib *newrib;
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))
RNODE_FOREACH_RIB (rn, newrib)
if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
&& newrib->type == type
&& newrib->type == type
&& newrib->instance == instance
&& newrib->distance != DISTANCE_INFINITY
&& 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))
RNODE_FOREACH_RIB (rn, newrib)
if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
&& newrib->type == type
&& newrib->type == type
&& newrib->instance == instance
&& newrib->distance != DISTANCE_INFINITY
&& zebra_check_addr (&rn->p))
{
@ -187,7 +189,8 @@ redistribute_add (struct prefix *p, struct rib *rib)
{
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)
{
@ -203,7 +206,7 @@ redistribute_add (struct prefix *p, struct rib *rib)
#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)
{
@ -235,7 +238,8 @@ redistribute_delete (struct prefix *p, struct rib *rib)
{
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)
zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
@ -247,8 +251,8 @@ redistribute_delete (struct prefix *p, struct rib *rib)
#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)
zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p, rib);
#ifdef HAVE_IPV6
@ -263,16 +267,18 @@ void
zebra_redistribute_add (int command, struct zserv *client, int length)
{
int type;
u_short instance;
type = stream_getc (client->ibuf);
instance = stream_getw (client->ibuf);
if (type == 0 || type >= ZEBRA_ROUTE_MAX)
return;
if (! client->redist[type])
if (!redist_check_instance(&client->redist[type], instance))
{
client->redist[type] = 1;
zebra_redistribute (client, type);
redist_add_instance(&client->redist[type], instance);
zebra_redistribute (client, type, instance);
}
}
@ -280,13 +286,19 @@ void
zebra_redistribute_delete (int command, struct zserv *client, int length)
{
int type;
u_short instance;
type = stream_getc (client->ibuf);
instance = stream_getw (client->ibuf);
if (type == 0 || type >= ZEBRA_ROUTE_MAX)
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

View File

@ -48,6 +48,9 @@ struct rib
/* Type fo this route. */
int type;
/* Source protocol instance */
u_short instance;
/* Which routing 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:
* All rib_add_ipv[46]* functions will not just add prefix into RIB, but
* 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,
unsigned int ifindex, u_int32_t vrf_id,
u_int32_t, u_char, 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,
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_close (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;
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
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,
u_int32_t metric, u_char distance, safi_t safi);
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);
extern struct rib *rib_lookup_ipv6 (struct in6_addr *);

View File

@ -743,7 +743,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
p.prefixlen = rtm->rtm_dst_len;
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);
else
{
@ -809,7 +809,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
memcpy (&p.prefix, dest, 16);
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);
}
#endif /* HAVE_IPV6 */
@ -948,7 +948,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
if (h->nlmsg_type == RTM_NEWROUTE)
{
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);
else
{
@ -1007,7 +1007,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
}
}
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);
}
@ -1034,9 +1034,9 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
}
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
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);
}
#endif /* HAVE_IPV6 */

View File

@ -89,7 +89,7 @@ handle_route_entry (mib2_ipRouteEntry_t *routeEntry)
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);
}

View File

@ -96,7 +96,7 @@ proc_route_read (void)
p.prefixlen = ip_masklen (tmpmask);
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);

View File

@ -215,7 +215,7 @@ main (int argc, char **argv)
/* preserve my name */
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);
while (1)

View File

@ -2029,7 +2029,7 @@ rib_delnode (struct route_node *rn, struct rib *rib)
}
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,
unsigned int ifindex, u_int32_t vrf_id,
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)
continue;
if (rib->instance != instance)
continue;
if (rib->type != ZEBRA_ROUTE_CONNECT)
{
same = rib;
@ -2092,6 +2094,7 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
/* Allocate new rib structure. */
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
rib->type = type;
rib->instance = instance;
rib->distance = distance;
rib->flags = flags;
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: refcnt == %lu, uptime == %lu, type == %u, table == %d",
"%s: refcnt == %lu, uptime == %lu, type == %u, instance == %d, table == %d",
func,
rib->refcnt,
(unsigned long) rib->uptime,
rib->type,
rib->instance,
rib->table
);
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))
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)
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 */
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 route_table *table;
@ -2437,6 +2442,8 @@ rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
if (rib->type != type)
continue;
if (rib->instance != instance)
continue;
if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
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->type = ZEBRA_ROUTE_STATIC;
rib->instance = 0;
rib->distance = si->distance;
rib->metric = 0;
rib->table = zebrad.rtm_table_default;
@ -2876,7 +2884,7 @@ rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
}
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,
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)
continue;
if (rib->instance != instance)
continue;
if (rib->type != ZEBRA_ROUTE_CONNECT)
{
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->type = type;
rib->instance = instance;
rib->distance = distance;
rib->flags = flags;
rib->metric = metric;
@ -3029,6 +3040,10 @@ rib_add_ipv6_multipath (struct prefix_ipv6 *p, struct rib *rib, safi_t safi,
continue;
}
if (same->instance != rib->instance) {
continue;
}
if (same->table != rib->table) {
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 */
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 route_table *table;
@ -3125,6 +3140,8 @@ rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
if (rib->type != type)
continue;
if (rib->instance != instance)
continue;
if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
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->type = ZEBRA_ROUTE_STATIC;
rib->instance = 0;
rib->distance = si->distance;
rib->metric = 0;
rib->table = zebrad.rtm_table_default;
@ -3616,7 +3634,7 @@ rib_sweep_route (void)
/* Remove specific by protocol routes from 'table'. */
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 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))
continue;
if (rib->type == proto)
if (rib->type == proto && rib->instance == instance)
{
rib_delnode (rn, rib);
n++;
@ -3641,10 +3659,10 @@ rib_score_proto_table (u_char proto, struct route_table *table)
/* Remove specific by protocol routes. */
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))
+rib_score_proto_table (proto, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
return rib_score_proto_table (proto, instance, vrf_table (AFI_IP, SAFI_UNICAST, 0))
+rib_score_proto_table (proto, instance, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
}
/* Close RIB and clean up kernel routes. */

View File

@ -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",
inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
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);
if (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)
{
/* Prefix information. */
len = vty_out (vty, "%c%c%c %s/%d",
zebra_route_char (rib->type),
len = vty_out (vty, "%c", 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 (nexthop->flags, NEXTHOP_FLAG_FIB)
? '*' : ' ',
inet_ntop (AF_INET, &rn->p.u.prefix, buf, BUFSIZ),
rn->p.prefixlen);
/* Distance and metric display. */
if (rib->type != ZEBRA_ROUTE_CONNECT
&& rib->type != ZEBRA_ROUTE_KERNEL)
@ -1348,6 +1353,42 @@ DEFUN (show_ip_route_protocol,
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,
show_ip_route_addr_cmd,
"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 (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_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_prefix_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_nht_cmd);
install_element (ENABLE_NODE, &show_ipv6_nht_cmd);

View File

@ -66,15 +66,6 @@ zserv_delayed_close(struct thread *thread)
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
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. */
stream_putc (s, rib->type);
stream_putw (s, rib->instance);
stream_putc (s, rib->flags);
/* marker for message flags field */
@ -1032,6 +1024,7 @@ zread_ipv4_add (struct zserv *client, u_short length)
/* Type, flags, message. */
rib->type = stream_getc (s);
rib->instance = stream_getw (s);
rib->flags = stream_getc (s);
message = stream_getc (s);
safi = stream_getw (s);
@ -1133,6 +1126,7 @@ zread_ipv4_delete (struct zserv *client, u_short length)
/* Type, flags, message. */
api.type = stream_getc (s);
api.instance = stream_getw (s);
api.flags = stream_getc (s);
api.message = stream_getc (s);
api.safi = stream_getw (s);
@ -1195,7 +1189,7 @@ zread_ipv4_delete (struct zserv *client, u_short length)
else
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->v4_route_del_cnt++;
return 0;
@ -1259,6 +1253,7 @@ zread_ipv6_add (struct zserv *client, u_short length)
/* Type, flags, message. */
rib->type = stream_getc (s);
rib->instance = stream_getw (s);
rib->flags = stream_getc (s);
message = stream_getc (s);
safi = stream_getw (s);
@ -1375,6 +1370,7 @@ zread_ipv6_delete (struct zserv *client, u_short length)
/* Type, flags, message. */
api.type = stream_getc (s);
api.instance = stream_getw (s);
api.flags = stream_getc (s);
api.message = stream_getc (s);
api.safi = stream_getw (s);
@ -1426,9 +1422,9 @@ zread_ipv6_delete (struct zserv *client, u_short length)
api.tag = 0;
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
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++;
return 0;
@ -1477,7 +1473,10 @@ zread_hello (struct zserv *client)
{
/* type of protocol (lib/zebra.h) */
u_char proto;
u_short instance;
proto = stream_getc (client->ibuf);
instance = stream_getw (client->ibuf);
/* accept only dynamic routing protocols */
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",
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->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. */
static void
zebra_client_close (struct zserv *client)
@ -1525,8 +1502,12 @@ zebra_client_close (struct zserv *client)
/* Close file descriptor. */
if (client->sock)
{
unsigned long nroutes;
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;
}
@ -1814,7 +1795,6 @@ zebra_serv ()
return;
}
memset (&route_type_oaths, 0, sizeof (route_type_oaths));
memset (&addr, 0, sizeof (struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons (ZEBRA_PORT);
@ -1885,8 +1865,6 @@ zebra_serv_un (const char *path)
return;
}
memset (&route_type_oaths, 0, sizeof (route_type_oaths));
/* Make server socket. */
memset (&serv, 0, sizeof (struct sockaddr_un));
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 wbuf[ZEBRA_TIME_BUF], nhbuf[ZEBRA_TIME_BUF], mbuf[ZEBRA_TIME_BUF];
vty_out (vty, "Client: %s %s",
zebra_route_string(client->proto), VTY_NEWLINE);
vty_out (vty, "Client: %s", zebra_route_string(client->proto));
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, "FD: %d %s", client->sock, VTY_NEWLINE);
vty_out (vty, "Route Table ID: %d %s", client->rtm_table, VTY_NEWLINE);

View File

@ -26,6 +26,7 @@
#include "if.h"
#include "workqueue.h"
#include "routemap.h"
#include "zclient.h"
/* Default port information. */
#define ZEBRA_VTY_PORT 2601
@ -59,7 +60,7 @@ struct zserv
int rtm_table;
/* This client's redistribute flag. */
u_char redist[ZEBRA_ROUTE_MAX];
struct redist_proto redist[ZEBRA_ROUTE_MAX];
/* Redistribute default route flag. */
u_char redist_default;
@ -72,6 +73,7 @@ struct zserv
/* client's protocol */
u_char proto;
u_short instance;
/* Statistics */
u_int32_t redist_v4_add_cnt;